本文以资深运维视角重写,讲清 Linux 存储栈、磁盘介质、分区、RAID、LVM、ext4/XFS/Btrfs/ZFS、挂载、性能、容量、故障排查和企业实践。基线为 Linux 7.x/6.18 LTS 内核,工具以 util-linux、e2fsprogs、xfsprogs、lvm2、mdadm、smartmontools、fio 为准。
存储栈全景 一次写入大致经过:
应用 → VFS(系统调用、page cache) → 文件系统(ext4/XFS/Btrfs/ZFS) → 块层(bio、IO 调度、合并) → device mapper / LVM / md RAID → HBA / NVMe / SCSI → SSD/HDD/云盘
关键点:
page cache :写先到内存,fsync/fdatasync 才保证落盘
文件系统 :负责元数据、分配、日志、一致性
块层 :合并、排序、调度、限流
LVM/RAID :逻辑卷、条带、镜像、校验
设备 :介质特性决定 IOPS、延迟、寿命
读路径通常走 page cache;未命中才到设备。写路径受 dirty_ratio、回写、文件系统日志和 fsync 影响。
磁盘与介质 HDD
机械寻道 + 旋转延迟,随机 IO 差
顺序吞吐高,适合大文件、备份、冷数据
RAID 重建时间长,容量越大风险越高
关注 SMART、重分配扇区、pending sector、CRC 错误
SSD
随机 IO 强,延迟低
写入放大、磨损、GC 影响寿命
需要 TRIM/discard 或周期性 fstrim
关注 wear leveling、available spare、media errors
企业级 SSD 有掉电保护(PLP),消费级不适合数据库
NVMe
多队列、低延迟、高 IOPS
常用 none/mq-deadline 调度器
关注队列深度、温度、寿命、PCIe 错误
nvme list、nvme smart-log、nvme error-log
扇区与对齐
512e:物理 4K,逻辑 512
4Kn:物理/逻辑都是 4K
分区和文件系统要 4K 对齐,否则读改写放大
parted/sgdisk 默认按 MiB 对齐,优先使用
介质指标
指标
含义
IOPS
每秒 IO 次数
Throughput
每秒字节数
Latency
单次 IO 延迟
Queue Depth
并发 IO 深度
Write Amplification
写入放大倍数
Endurance
TBW/DWPD
不要只看 IOPS:数据库更关心延迟和尾延迟(p99/p999)。
分区 MBR vs GPT
维度
MBR
GPT
最大磁盘
2TiB
很大
分区数
4 主分区
128+
备份分区表
无
有
校验
无
CRC
推荐
旧系统
现代系统
生产优先 GPT。
常用命令 lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,MODEL,SERIAL blkid parted -l sgdisk -p /dev/sdb
创建 GPT 分区:
parted /dev/sdb --script mklabel gpt parted /dev/sdb --script mkpart primary 1MiB 100% partprobe /dev/sdb
对齐
起始扇区按 1MiB 对齐
parted 使用 %/MiB 单位通常自动对齐
分区对齐错误会导致 SSD 读改写放大、HDD 跨磁道
RAID 常见级别
级别
最少盘
容错
容量利用率
适用
RAID0
2
无
100%
临时/缓存,不推荐生产
RAID1
2
1 盘
50%
系统盘、小容量关键数据
RAID5
3
1 盘
(n-1)/n
读多写少,谨慎
RAID6
4
2 盘
(n-2)/n
大容量、重建风险高
RAID10
4
每组 1 盘
50%
数据库、高 IO
JBOD
-
无
100%
分布式存储/对象存储
关键原理
RAID5/6 用校验恢复,写有 read-modify-write,写放大
RAID5 有大盘重建时间长、二次故障风险、write hole
RAID10 重建快、写性能好,但容量利用率低
硬件 RAID 依赖 BBU/超级电容,注意电池失效导致写策略变化
软件 RAID 用 mdadm,灵活但消耗 CPU
mdadm 常用 mdadm --create /dev/md0 --level=10 --raid-devices=4 /dev/sd[b-e] mdadm --detail /dev/md0 cat /proc/mdstatmdadm --fail /dev/md0 /dev/sdb1 mdadm --remove /dev/md0 /dev/sdb1 mdadm --add /dev/md0 /dev/sdf1 mdadm --grow /dev/md0 --raid-devices=5 mdadm --assemble --scan mdadm --stop /dev/md0
注意:
创建时 metadata 建议 1.2
重建期间性能下降,避免同时做高 IO
写意图位图(write-intent bitmap)加快重建,但增加写开销
--assume-clean 只用于确认数据一致的恢复,不能随便用
替换盘容量不小于原盘
监控 /proc/mdstat、mdadm --detail、SMART
LVM 层次 物理卷 PV(/dev/sdb1) → 卷组 VG(vg_data) → 逻辑卷 LV(lv_mysql) → 文件系统(xfs/ext4)
LVM 提供:
灵活扩容
快照
条带/镜像/RAID
thin provisioning
在线迁移 pvmove
常用命令 pvcreate /dev/sdb1 /dev/sdc1 vgcreate vg_data /dev/sdb1 /dev/sdc1 lvcreate -L 500G -n lv_mysql vg_data lvextend -L +100G /dev/vg_data/lv_mysql resize2fs /dev/vg_data/lv_mysql xfs_growfs /mount/mysql lvreduce -L -50G /dev/vg_data/lv_mysql pvs; vgs; lvs lvs -a -o +segtype,devices
扩容
先扩 LV,再扩文件系统
ext4:resize2fs 可在线扩
XFS:xfs_growfs 只能扩,不能缩
Btrfs:btrfs filesystem resize
扩 PV:pvresize,再扩 LV
缩容
XFS 不支持缩容
ext4 可以离线缩容,先 e2fsck,再 resize2fs,再 lvreduce
缩容风险高,生产优先“新建 + 迁移”,不要原地缩
快照 lvcreate -L 20G -s -n lv_mysql_snap /dev/vg_data/lv_mysql
快照是 COW,写入多时快照空间会增长
快照空间满会失效
快照不是备份,不能替代异地备份
用于备份窗口、升级回滚、测试
Thin Provisioning lvcreate -L 1T --thinpool tp_data vg_data lvcreate -V 500G --thin -n lv_app tp_data
按需分配,提升利用率
必须监控 data/meta 使用率
超配会导致写失败
删除/快照要关注 discard
缓存与 RAID
lvconvert --type cache 用 SSD 给 HDD 做缓存
lvconvert --type raid1/raid5/raid6/raid10 做 LVM RAID
缓存/RAID 增加复杂度,故障排查要熟悉映射
恢复 vgcfgbackup -f /root/vg_data.backup vg_data vgcfgrestore -f /root/vg_data.backup vg_data pvscan; vgscan; lvscan dmsetup ls
LVM 元数据在 /etc/lvm/backup 和 /etc/lvm/archive,误删/损坏时先备份再恢复。
文件系统 VFS 与通用概念
inode :元数据(权限、大小、块指针、时间)
dentry :目录项缓存
page cache :文件页缓存
journal :日志,保证崩溃一致性
COW :写时复制,Btrfs/ZFS
extent :连续块范围,减少元数据
delayed allocation :延迟分配,减少碎片
ext4 特点:
成熟稳定,兼容性好
日志、extent、delayed allocation、在线扩容
适合通用系统盘、中小型数据库
不支持在线缩容(需离线)
最大文件/卷取决于块大小和特性
常用:
mkfs.ext4 -L data /dev/vg_data/lv_data tune2fs -l /dev/vg_data/lv_data dumpe2fs -h /dev/vg_data/lv_data e2fsck -f /dev/vg_data/lv_data resize2fs /dev/vg_data/lv_data
调优:
noatime/relatime
errors=remount-ro
data=ordered(默认)
discard 或周期性 fstrim
预留块比例 tune2fs -m,大容量数据盘可降到 1%
XFS 特点:
高并发、大文件、大容量
Allocation Group(AG)并行
B+tree 索引
在线扩容,不支持缩容
reflink、DAX(特定场景)
适合大数据、日志、容器、数据库
常用:
mkfs.xfs -L data /dev/vg_data/lv_data xfs_info /mount/data xfs_growfs /mount/data xfs_repair -n /dev/vg_data/lv_data xfs_repair /dev/vg_data/lv_data xfs_fsr /mount/data
注意:
xfs_repair 要在未挂载状态执行
先 -n 只检查,不要直接修
XFS 不能缩容
大容量 XFS 的 inode 动态分配,通常不需要预分配
Btrfs 特点:
COW、子卷、快照、压缩、校验、RAID
适合快照、测试、部分容器/虚拟化场景
RAID5/6 有 write hole 和恢复风险,生产谨慎
需要定期 scrub/balance
常用:
mkfs.btrfs -L data /dev/sdb btrfs filesystem show btrfs filesystem df /mount/data btrfs filesystem usage /mount/data btrfs subvolume create /mount/data/@app btrfs subvolume snapshot /mount/data/@app /mount/data/@app-snap btrfs scrub start -B /mount/data btrfs balance start -dusage=50 /mount/data btrfs check --readonly /dev/sdb
注意:
btrfs check --repair 风险高,先只读检查
balance 会消耗大量 IO,低峰执行
快照不是备份
空间不足时先看 data/metadata/system 三类
ZFS 特点:
COW、校验、快照、send/recv、RAIDZ、ARC
不是 Linux 主线文件系统,需 DKMS/发行版支持
内存消耗大,ARC 可调
适合需要端到端校验和快照的场景
常用:
zpool create tank mirror /dev/sdb /dev/sdc zfs create tank/data zfs snapshot tank/data@snap zfs send tank/data@snap | zfs receive backup/data zpool scrub tank zpool status -v
对比
维度
ext4
XFS
Btrfs
ZFS
稳定性
高
高
中高
高
大文件/大容量
好
很好
好
很好
在线扩容
是
是
是
是
缩容
离线
否
是
否
快照
有限
无原生
强
强
校验
元数据
元数据
数据+元数据
数据+元数据
复杂度
低
中
中高
高
典型场景
系统盘/通用
大数据/日志/DB
快照/测试
存储池/备份
挂载 fstab UUID=xxxx /data xfs defaults,noatime 0 0 UUID=yyyy /backup ext4 defaults,nofail 0 2
建议:
用 UUID 或 LABEL,不要用 /dev/sdb(顺序会变)
非关键盘加 nofail,避免启动卡住
网络盘加 _netdev
需要等待设备时用 x-systemd.device-timeout
修改后 mount -a 验证,再重启
常用选项
noatime:不更新访问时间,减少写
relatime:默认,兼顾性能和 atime
discard:在线 TRIM,可能影响性能;也可用 fstrim.timer
errors=remount-ro:ext4 出错只读
inode64:XFS 大容量 inode 寻址
space_cache=v2:Btrfs 空间缓存
compress=zstd:Btrfs 压缩
nobarrier:不要用,barrier 默认开启保证一致性
查看 findmnt mount | column -t df -hTlsblk -f
性能分析 先看什么
应用延迟和 IO 模式(随机/顺序、读/写、块大小、队列深度)
iostat -x 1:r/s、w/s、rkB/s、wkB/s、await、aqu-sz、%util
iotop/pidstat -d:谁在 IO
vmstat 1:bi/bo、wa
blktrace/btt/biolatency:块层延迟分解
fio:复现和基线
注意:
%util 对多队列/NVMe 不完全准确
await 包含排队时间
svctm 已无意义,不要用
先区分“应用慢”还是“磁盘慢”
fio 示例 随机读 IOPS:
fio --name=randread --ioengine=libaio --direct=1 --rw=randread \ --bs=4k --iodepth=32 --numjobs=4 --size=1G --runtime=60 \ --time_based --group_reporting
顺序写吞吐:
fio --name=seqwrite --ioengine=libaio --direct=1 --rw=write \ --bs=1M --iodepth=16 --numjobs=1 --size=10G --runtime=60 \ --time_based --group_reporting
延迟测试:
fio --name=lat --ioengine=libaio --direct=1 --rw=randread \ --bs=4k --iodepth=1 --size=1G --runtime=60 --time_based
IO 调度器 cat /sys/block/sdb/queue/scheduler
none:NVMe/多队列常用
mq-deadline:通用
kyber:低延迟
bfq:桌面/交互
数据库/分布式存储通常按厂商和内核调优,不要盲目改。
Page Cache 与回写 sysctl vm.dirty_ratio vm.dirty_background_ratio sysctl vm.dirty_expire_centisecs vm.dirty_writeback_centisecs
dirty 比例过高会导致突发回写、延迟抖动
数据库通常依赖 fsync,不要用 nobarrier 换性能
sync、fsync、fdatasync 语义不同
容量与 inode 查看 df -hTdf -idu -sh /data/*ncdu /data lsof +L1
常见问题
磁盘满但 du 不大 :删除的文件仍被进程打开,lsof +L1
inode 满 :小文件太多,df -i;扩 inode 需要重建或迁移
预留块 :ext4 默认 5%,大容量数据盘可调低
稀疏文件 :ls -ls 看实际占用,du 与 ls 不一致
快照/回收站 :Btrfs/LVM 快照、HDFS 回收站会占空间
日志/临时文件 :/var/log、/tmp、数据库 binlog
容量规划
数据增长 × 副本/RAID 冗余 × 余量
预留 20%–30%
考虑快照、备份、重建、临时空间
监控增长趋势,不要等 90% 才扩容
数据安全 SMART smartctl -H /dev/sdb smartctl -a /dev/sdb smartctl -t short /dev/sdb smartctl -t long /dev/sdb smartctl -l selftest /dev/sdb nvme smart-log /dev/nvme0
关注:
Reallocated_Sector_Ct
Current_Pending_Sector
Offline_Uncorrectable
CRC_Error_Count
SSD Wear_Leveling_Count / Percentage_Used / Available_Spare
温度
文件系统检查 e2fsck -f /dev/vg_data/lv_data xfs_repair -n /dev/vg_data/lv_data xfs_repair /dev/vg_data/lv_data btrfs check --readonly /dev/sdb btrfs scrub start -B /mount/data
原则:
已挂载文件系统不要直接 fsck
先只读检查,再决定修复
修复前备份(如果还能读)
记录 superblock 备份:mke2fs -n、e2fsck -b
坏道与救援 badblocks -sv /dev/sdb ddrescue /dev/sdb /dev/sdc rescue.map
坏道盘先镜像再修
dd 遇到坏道会卡住,用 ddrescue
不要在有数据的盘上随意 blkdiscard
备份
快照不是备份
RAID 不是备份
备份要异地、加密、可恢复
定期恢复演练
数据库用逻辑备份 + 物理备份 + binlog
扩容与缩容 分区扩容 growpart /dev/sda 2 resize2fs /dev/sda2 xfs_growfs /mount/data
LVM 扩容 pvresize /dev/sdb lvextend -L +100G /dev/vg_data/lv_data resize2fs /dev/vg_data/lv_data xfs_growfs /mount/data
缩容
XFS 不支持
ext4 离线缩容:e2fsck → resize2fs → lvreduce
优先新建卷 + 数据迁移,避免原地缩容
缩容前备份,确认文件系统支持
在线 vs 离线
在线扩容通常安全
在线缩容风险高,很多文件系统不支持
扩容后验证 df、dumpe2fs/xfs_info、业务写入
故障排查 IO 卡住 / D 状态 ps -eo pid,stat ,wchan:32,cmd | awk '$2 ~ /D/' cat /proc/<pid>/stackdmesg -T | tail -100
常见原因:
磁盘故障/掉线
HBA/驱动/固件
网络存储超时
文件系统/块层死锁
LVM/RAID 降级
磁盘掉线 dmesg -T | grep -iE 'sd|nvme|ata|error|timeout' lsblk cat /proc/mdstatmdadm --detail /dev/md0 smartctl -a /dev/sdb
处理:
先确认是单盘还是控制器/背板
RAID 降级时尽快更换,避免二次故障
不要在重建时做高 IO
记录序列号、槽位、固件版本
文件系统损坏
先只读检查
备份可读数据
修复后再次检查
挂载失败看 dmesg、journalctl -k
ext4 超级块损坏可用备份超级块
LVM 异常 pvscan; vgscan; lvscan vgcfgrestore -f /etc/lvm/backup/vg_data vg_data dmsetup ls
不要手工改 /dev/mapper 下设备
先备份 /etc/lvm
确认 PV 是否被误删/被其他系统占用
mdadm 异常 mdadm --detail /dev/md0 mdadm --examine /dev/sdb1 mdadm --assemble --scan
不要用 --create 覆盖原阵列
先 --examine 确认成员和事件计数
--assemble --force 只在确认数据一致时使用
企业实践 存储分层
系统盘:RAID1/RAID10,小容量
数据库:NVMe/企业级 SSD,RAID10
日志/大数据:大容量 HDD/SSD 混合,RAID6/RAID10
备份/归档:大容量 HDD/JBOD/对象存储
缓存:NVMe,独立寿命监控
RAID 选择
数据库:RAID10
大容量顺序读:RAID6
系统盘:RAID1
临时/缓存:RAID0(可丢)
分布式存储:JBOD + 副本/纠删码
容量与寿命
SSD 按 DWPD/TBW 估算寿命
预留 OP(over-provisioning)
监控写入量、磨损、可用备用块
HDD 按年故障率和重建时间评估
大盘 RAID5 重建风险高,优先 RAID6/RAID10
监控
磁盘:SMART、温度、错误、寿命
RAID:降级、重建进度、BBU
LVM:thin pool data/meta、快照使用率
文件系统:使用率、inode、只读挂载、错误
性能:IOPS、吞吐、await、队列、尾延迟
备份:成功率、恢复演练
变更
分区/文件系统/LVM 变更要有回滚
扩容先在测试环境验证
缩容默认禁止,走审批
换盘要记录槽位和序列号
变更窗口避开业务高峰
故障演练
单盘故障/RAID 降级
磁盘满/inode 满
文件系统只读
LVM 元数据损坏
备份恢复
磁盘 IO hang
反模式
用 RAID5 跑大容量数据库
用快照代替备份
不做 SMART 监控
用 nobarrier 换性能
直接 fsck -y 挂载中的文件系统
用 --assume-clean 恢复 RAID
不预留容量,等 100% 才扩容
不监控 inode 和 thin pool
附录 常用命令 lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,MODEL,SERIAL blkid parted -l sgdisk -p /dev/sdb cat /proc/mdstatmdadm --detail /dev/md0 mdadm --examine /dev/sdb1 pvs; vgs; lvs lvs -a -o +segtype,devices vgcfgbackup -f /root/vg.backup vg_data df -hT; df -ifindmnt xfs_info /mount/data dumpe2fs -h /dev/vg_data/lv_data btrfs filesystem usage /mount/data iostat -x 1 iotop -o pidstat -d 1 fio --name=test --ioengine=libaio --direct=1 --rw=randread --bs=4k --iodepth=32 --size=1G --runtime=60 smartctl -a /dev/sdb nvme smart-log /dev/nvme0
官方参考