mkfs —— 格式化文件系统
一句话定义
mkfs 在块设备上创建文件系统(写元数据 / inode 表 / 超级块等)。这是不可逆操作——执行后原有数据基本不可恢复。mkfs 是一组命令的统称(mkfs.ext4 / mkfs.xfs / mkfs.btrfs 等),按文件系统类型分。
典型场景
- 新盘上线第一次格式化:
mkfs.ext4 /dev/sdb1 - K8s 数据盘准备:通常 ext4 或 xfs
- 临时盘 / swap 准备
- 损坏盘重新格式化(先备份)
⚠️ 不可逆警告
mkfs.ext4 /dev/sdb1
# 写入元数据,原有文件系统 / 数据基本失效
跑 mkfs 之前必须做的检查:
# 1. 这是你要的盘吗
lsblk /dev/sdb1
df -h /dev/sdb1 # 已挂载?
mount | grep /dev/sdb1 # 挂在哪?
# 2. 有没有现有数据
file -s /dev/sdb1 # ext4 filesystem data, ...
blkid /dev/sdb1 # 看现有 UUID / TYPE
# 3. 备份过了吗
ls -la /backup/...
# 4. 跑 mkfs 时强制确认
mkfs.ext4 -F /dev/sdb1 # -F 跳过提示(自动化),不加默认会提示
mkfs 是少数会让你"备份过了再做"的命令。一定要 lsblk 看清楚设备名,不要在 ssh 多窗口下错盘。
主流文件系统对比
| FS | 适合场景 | 优势 | 劣势 |
|---|---|---|---|
| ext4 | 通用、首选 | 稳定、工具齐全、社区大 | 大文件不如 xfs |
| xfs | 大文件、数据库 | 高吞吐、大文件优秀 | 不能缩容(只能扩容) |
| btrfs | snapshot 需求 | 写时复制、子卷 | 性能波动、生产慎用 |
| zfs | 数据完整性 | snapshot + 校验 + 压缩 | 不在主线内核(许可证) |
| tmpfs | 临时存储 | 内存中、超快 | 重启就没 |
训练营建议:
- K8s 数据盘默认 ext4(最稳)
- 数据库 / 大文件场景考虑 xfs(CentOS 7+ 默认)
- 别用 btrfs / zfs,除非你完全清楚为什么
mkfs.ext4 —— 最常用
mkfs.ext4 /dev/sdb1 # 默认
mkfs.ext4 -L data /dev/sdb1 # 加 label
mkfs.ext4 -L data -m 1 /dev/sdb1 # m 1 = 给 root 保留 1%(默认 5%)
mkfs.ext4 -L data -m 0 -E lazy_itable_init=0,lazy_journal_init=0 /dev/sdb1
# 立即初始化(慢、但马上能用满速度)
mkfs.ext4 -F /dev/sdb1 # 强制(已格式化也允许)
常用 flag
| flag | 含义 |
|---|---|
-L <label> | 卷标(强烈建议) |
-m <%> | 给 root 保留多少(默认 5%;大盘可以 0 或 1) |
-T <type> | 用途类型(largefile / news / default),影响 inode 数 |
-N <count> | 直接指定 inode 数(专家级) |
-b <size> | 块大小(默认 4096) |
-E lazy_itable_init=0 | 立即初始化 inode 表 |
-F | 强制(已格式化也允许) |
-q | 安静(不输出进度) |
-v | verbose |
-m 调整保留空间(大盘必改)
ext4 默认 5% 给 root 使用——10TB 盘 = 500GB 浪费。
mkfs.ext4 -m 1 /dev/sdb1 # 1% 够了
# 或者已经格式化的:
tune2fs -m 1 /dev/sdb1
K8s 数据盘 / 备份盘可以设 -m 0。
mkfs.xfs
mkfs.xfs /dev/sdb1 # 默认
mkfs.xfs -L data /dev/sdb1 # label
mkfs.xfs -f /dev/sdb1 # 强制(已格式化也允许)
mkfs.xfs -d agcount=32 /dev/sdb1 # 调 allocation groups(高并发)
xfs 默认参数已经很好,多数场景不需要调。
xfs 注意点
- 不能缩容——只能
xfs_growfs扩容。要缩盘只能 mkfs 重做。 - inode 数自动管理,不像 ext4 要预估
- 大文件性能比 ext4 略好
label 和 UUID
mkfs 之后两个标识:
blkid /dev/sdb1
# /dev/sdb1: LABEL="data" UUID="abc-def-..." TYPE="ext4"
- LABEL 你给的名字(mkfs 时
-L) - UUID mkfs 自动生成的唯一标识
挂载和 fstab 永远用 UUID(设备名 /dev/sdX 可能变):
mount UUID=abc-def-... /data
# 或在 fstab 里:
UUID=abc-def-... /data ext4 defaults,noatime 0 2
详见 fstab.md。
修改已有 ext4 参数:tune2fs
不重新格式化也能改一些参数:
tune2fs -L newlabel /dev/sdb1 # 改 label
tune2fs -U $(uuidgen) /dev/sdb1 # 重新生成 UUID(罕见)
tune2fs -m 1 /dev/sdb1 # 改保留 %
tune2fs -c 0 /dev/sdb1 # 不强制 fsck(默认每 N 次 mount 一次)
tune2fs -i 0 /dev/sdb1 # 不按时间触发 fsck
tune2fs -l /dev/sdb1 # 列出所有参数
tune2fs -l 看现有文件系统信息(创建时间、上次 fsck 时间、超级块备份位置等)。
xfs 的等价是 xfs_admin:
xfs_admin -L newlabel /dev/sdb1
xfs_admin -u /dev/sdb1 # 看 UUID
扩容文件系统(重要)
底层盘扩了之后,文件系统也要扩才能用新空间。
ext4
# 先扩分区(用 parted / growpart)
# 然后
resize2fs /dev/sdb1 # 扩到分区全部
resize2fs /dev/sdb1 50G # 指定大小
resize2fs 支持在线扩容(不需要 umount)。
xfs
xfs_growfs /data # 注意:参数是**挂载点**,不是设备
xfs 只能扩、不能缩。
K8s 场景:PVC 扩容
K8s 的 PVC 扩容流程(StorageClass 支持的话):
kubectl edit pvc my-pvc改 spec.resources.requests.storage- CSI driver 在云端扩底层盘
- CSI 在节点上
resize2fs/xfs_growfs扩文件系统
某些 driver 需要 pod 重启才能完成。
检查 / 修复:fsck
fsck /dev/sdb1 # 检查(必须先 umount)
fsck -y /dev/sdb1 # 自动修复(生产慎用)
fsck.ext4 -f /dev/sdb1 # 强制检查(即使看着 clean)
xfs_repair /dev/sdb1 # xfs 专用
fsck 之前一定要 umount。在线跑 fsck 会破坏数据。
fsck 修复的是文件系统元数据问题,不修硬件。硬件坏了的盘 fsck 救不了——准备好换盘。
实战流程:装机数据盘
Day0 装机后给 m4/m5 各加一个数据盘 /dev/sdb:
# 1. 看
ssh m4 'lsblk'
# /dev/sdb 500G 没分区、没挂载
# 2. 分区(GPT)
ssh m4 'parted /dev/sdb mklabel gpt'
ssh m4 'parted -a optimal /dev/sdb mkpart primary ext4 0% 100%'
ssh m4 'lsblk /dev/sdb'
# 应该看到 sdb 和 sdb1
# 3. 格式化(带 label)
ssh m4 'mkfs.ext4 -L k8s-data -m 1 /dev/sdb1'
# 4. 看 UUID
ssh m4 'blkid /dev/sdb1'
# UUID="abc-def-..."
# 5. 挂载点
ssh m4 'mkdir -p /var/lib/k8s-data'
# 6. fstab
UUID=$(ssh m4 'blkid -s UUID -o value /dev/sdb1')
ssh m4 "echo 'UUID=$UUID /var/lib/k8s-data ext4 defaults,noatime,nofail 0 2' >> /etc/fstab"
# 7. 挂
ssh m4 'mount -a'
ssh m4 'df -h /var/lib/k8s-data'
# 8. 验证 reboot 之后还在
ssh m4 'reboot'
sleep 60
ssh m4 'df -h /var/lib/k8s-data' # 必须还在
常见踩坑
坑 1:格式化错盘
mkfs.ext4 /dev/sda # ❌ 不是 /dev/sdb,是 /dev/sda
# 系统盘被格式化 → 立刻挂
预防:跑 mkfs 之前必须 lsblk 看一眼,确认设备名、大小、挂载点。lsblk -f 看 MOUNTPOINTS 列——已挂的盘不可能是新盘。
坑 2:在分区上还是在整盘上
mkfs.ext4 /dev/sdb # 在整盘上格式化(无分区表)
mkfs.ext4 /dev/sdb1 # 在分区上格式化
两种都可以,但通常建议先分区再格式化:
- 易扩展
- 工具兼容性好
- 引导兼容(虽然数据盘不引导)
云厂商盘 / 临时盘有时直接整盘格式化(特别 NVMe)也行。
坑 3:mkfs.ext4 慢、占资源
mkfs.ext4 /dev/sdb1
# 大盘可能跑几分钟
ext4 默认 lazy init(先快速建元数据,后台慢慢清 inode 表)。mkfs 跑完不代表盘"完全好"——后台还在初始化。
立刻能跑高 IO 测试 → 加 -E nodiscard,lazy_itable_init=0,lazy_journal_init=0 (慢但马上达全速)。
坑 4:xfs 不能缩
xfs_growfs /data 100G # ❌ xfs 不支持缩容
要"缩盘" → 备份 + mkfs 重建 + 还原。
坑 5:-m 5% 浪费太多
10TB 盘默认保留 500GB 给 root → 浪费。大盘 mkfs 时加 -m 1 或 -m 0。
已格式化的:tune2fs -m 1 /dev/sdb1。
坑 6:UUID 重复
# 老盘备份到新盘后克隆 → 两个盘 UUID 一样
blkid
# /dev/sdb1: UUID="abc..."
# /dev/sdc1: UUID="abc..."
mount UUID=abc... 不知道挂哪个。修:
tune2fs -U random /dev/sdc1 # 给 sdc1 重新生成 UUID
xfs:xfs_admin -U generate /dev/sdc1。
坑 7:mkfs 在 LVM / mdraid 上
mkfs.ext4 /dev/mapper/vg-data # LVM 卷
mkfs.ext4 /dev/md0 # 软 RAID
支持,但有额外考虑(条带对齐 / stride 等)。生产环境调优需要文档。
坑 8:discard 在 mkfs 时太慢
mkfs.ext4 /dev/sdb1
# Discarding device blocks: ... 几分钟
ext4 默认 mkfs 时给整盘发 TRIM。SSD 偶尔很慢(特别是用过的盘)。跳过:
mkfs.ext4 -E nodiscard /dev/sdb1
之后定期 fstrim 即可。
坑 9:损坏盘格式化失败
mkfs.ext4 /dev/sdb1
# error: Input/output error
盘真坏了。看 dmesg 有没有 I/O error。换盘。