抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

本文以资深运维视角重写,讲清 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/mdstat
mdadm --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 # ext4
xfs_growfs /mount/mysql # XFS
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 -hT
lsblk -f

性能分析

先看什么

  1. 应用延迟和 IO 模式(随机/顺序、读/写、块大小、队列深度)
  2. iostat -x 1:r/s、w/s、rkB/s、wkB/s、await、aqu-sz、%util
  3. iotop/pidstat -d:谁在 IO
  4. vmstat 1:bi/bo、wa
  5. blktrace/btt/biolatency:块层延迟分解
  6. 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 -hT
df -i
du -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
  • 温度

文件系统检查

# ext4
e2fsck -f /dev/vg_data/lv_data
# XFS(未挂载)
xfs_repair -n /dev/vg_data/lv_data
xfs_repair /dev/vg_data/lv_data
# Btrfs
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 # ext4
xfs_growfs /mount/data # XFS

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>/stack
dmesg -T | tail -100

常见原因:

  • 磁盘故障/掉线
  • HBA/驱动/固件
  • 网络存储超时
  • 文件系统/块层死锁
  • LVM/RAID 降级

磁盘掉线

dmesg -T | grep -iE 'sd|nvme|ata|error|timeout'
lsblk
cat /proc/mdstat
mdadm --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

# RAID
cat /proc/mdstat
mdadm --detail /dev/md0
mdadm --examine /dev/sdb1

# LVM
pvs; vgs; lvs
lvs -a -o +segtype,devices
vgcfgbackup -f /root/vg.backup vg_data

# 文件系统
df -hT; df -i
findmnt
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

官方参考