磁盘与存储管理
问题
请详细介绍 Linux 磁盘管理,包括分区、格式化、LVM、RAID 和存储监控。
答案
磁盘基础
查看磁盘信息
# 块设备列表
lsblk
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
# sda 8:0 0 100G 0 disk
# ├─sda1 8:1 0 1G 0 part /boot
# ├─sda2 8:2 0 50G 0 part /
# └─sda3 8:3 0 49G 0 part
# ├─vg0-data 253:0 0 30G 0 lvm /data
# └─vg0-var 253:1 0 19G 0 lvm /var
# 磁盘分区信息
fdisk -l /dev/sda
# 设备 UUID
blkid
# 文件系统使用情况
df -hT
# Filesystem Type Size Used Avail Use% Mounted on
# /dev/sda2 xfs 50G 15G 35G 30% /
# /dev/mapper/vg0-data ext4 30G 10G 20G 34% /data
# 磁盘 I/O 统计
iostat -xz 1 5
# 重点关注:%util(磁盘使用率)、await(平均 I/O 等待时间)、r/s w/s(IOPS)
分区管理
# fdisk(MBR 分区,最大 2TB)
fdisk /dev/sdb
# 常用命令:n(新建) d(删除) p(打印) w(保存退出) q(不保存退出)
# parted(GPT 分区,支持超大磁盘)
parted /dev/sdb
# mklabel gpt
# mkpart primary ext4 0% 100%
# print
# quit
# 格式化
mkfs.ext4 /dev/sdb1
mkfs.xfs /dev/sdb1
mkfs.xfs -f /dev/sdb1 # 强制覆盖
# 挂载
mkdir -p /data
mount /dev/sdb1 /data
# 永久挂载(写 fstab)
echo "UUID=$(blkid -s UUID -o value /dev/sdb1) /data xfs defaults 0 0" >> /etc/fstab
mount -a # 测试 fstab
MBR vs GPT
| 特性 | MBR | GPT |
|---|---|---|
| 最大磁盘 | 2 TB | 9.4 ZB |
| 最大分区数 | 4 主分区 | 128 分区 |
| 引导方式 | BIOS | UEFI |
| 冗余 | 无 | 有备份 GPT |
现代服务器推荐 GPT + UEFI。
LVM 逻辑卷管理
LVM(Logical Volume Manager)在物理分区之上提供灵活的卷管理,支持在线扩容:
# === 创建 LVM ===
# 1. 创建物理卷 PV
pvcreate /dev/sdb1 /dev/sdc1
pvs # 查看 PV
# 2. 创建卷组 VG
vgcreate vg_data /dev/sdb1 /dev/sdc1
vgs # 查看 VG
# 3. 创建逻辑卷 LV
lvcreate -L 50G -n lv_app vg_data # 指定大小
lvcreate -l 100%FREE -n lv_log vg_data # 使用剩余全部空间
lvs # 查看 LV
# 4. 格式化和挂载
mkfs.ext4 /dev/vg_data/lv_app
mkdir -p /opt/app
mount /dev/vg_data/lv_app /opt/app
# === 在线扩容(最常用操作)===
# 方式 1:VG 有剩余空间,直接扩 LV
lvextend -L +10G /dev/vg_data/lv_app # 增加 10G
resize2fs /dev/vg_data/lv_app # ext4 扩展文件系统
# 或 xfs_growfs /opt/app # xfs 扩展文件系统
# 一条命令搞定(推荐)
lvextend -L +10G -r /dev/vg_data/lv_app # -r 自动 resize
# 方式 2:VG 空间不足,先加新磁盘
pvcreate /dev/sdd1 # 新磁盘创建 PV
vgextend vg_data /dev/sdd1 # 加入 VG
lvextend -L +50G -r /dev/vg_data/lv_app # 扩展 LV
# === 缩容(危险操作,需要先缩文件系统)===
# 注意:XFS 不支持缩容!
umount /opt/app
e2fsck -f /dev/vg_data/lv_app # 检查文件系统
resize2fs /dev/vg_data/lv_app 40G # 先缩文件系统
lvreduce -L 40G /dev/vg_data/lv_app # 再缩 LV
mount /dev/vg_data/lv_app /opt/app
# === LVM 快照 ===
lvcreate -L 5G -s -n lv_app_snap /dev/vg_data/lv_app # 创建快照
mount -o ro /dev/vg_data/lv_app_snap /mnt/snap # 挂载快照
# 用完删除
lvremove /dev/vg_data/lv_app_snap
LVM 在线扩容要点
- ext4:使用
resize2fs,支持在线扩容和离线缩容 - XFS:使用
xfs_growfs,只能扩容不能缩容 - 扩容不需要卸载(在线操作),缩容必须先卸载
lvextend -r参数自动调用resize2fs/xfs_growfs
RAID 磁盘阵列
| 级别 | 最少磁盘 | 容量 | 冗余 | 性能 | 适用场景 |
|---|---|---|---|---|---|
| RAID 0 | 2 | N×单盘 | 无 | 读写都快 | 临时数据、缓存 |
| RAID 1 | 2 | 单盘 | 1 块盘 | 读快,写同 | 系统盘、小数据高可用 |
| RAID 5 | 3 | (N-1)×单盘 | 1 块盘 | 读快,写较慢 | 通用存储 |
| RAID 6 | 4 | (N-2)×单盘 | 2 块盘 | 读快,写更慢 | 大容量高可靠 |
| RAID 10 | 4 | N/2×单盘 | 每组 1 块 | 读写都快 | 数据库、高性能 |
# 使用 mdadm 创建软件 RAID
# RAID 1(镜像)
mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb /dev/sdc
# RAID 5
mdadm --create /dev/md0 --level=5 --raid-devices=3 /dev/sdb /dev/sdc /dev/sdd
# RAID 10
mdadm --create /dev/md0 --level=10 --raid-devices=4 /dev/sdb /dev/sdc /dev/sdd /dev/sde
# 查看 RAID 状态
cat /proc/mdstat
mdadm --detail /dev/md0
# 替换故障盘
mdadm /dev/md0 --fail /dev/sdc # 标记故障
mdadm /dev/md0 --remove /dev/sdc # 移除
mdadm /dev/md0 --add /dev/sdf # 添加新盘
# 保存配置
mdadm --detail --scan >> /etc/mdadm/mdadm.conf
Swap 交换空间
# 查看 Swap
swapon --show
free -h
# 创建 Swap 文件
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
# 永久生效
echo '/swapfile swap swap defaults 0 0' >> /etc/fstab
# 调整 Swap 使用倾向(0-100,越小越倾向使用内存)
sysctl vm.swappiness=10 # 服务器推荐 10
echo "vm.swappiness=10" >> /etc/sysctl.conf
I/O 监控
# iostat - I/O 统计
iostat -xz 1
# 关键指标:
# %util: 磁盘使用率(>70% 需关注)
# await: 平均 I/O 等待时间(ms)
# r/s, w/s: 每秒读写次数(IOPS)
# rkB/s, wkB/s: 每秒读写带宽
# iotop - 按进程查看 I/O
iotop -o # 只显示有 I/O 的进程
# 查看某个进程的 I/O
cat /proc/<PID>/io
# dstat - 综合监控
dstat -tdD sda 1 5 # 磁盘 I/O 统计
常见面试问题
Q1: 磁盘空间满了怎么处理?
答案:
# 1. 确认哪个分区满了
df -h
# 2. 找到大文件/大目录
du -sh /* | sort -rh | head -10
du -sh /var/log/* | sort -rh | head -10
# 3. 清理方案
# - 清理日志:truncate -s 0 /var/log/xxx.log(不要 rm,进程可能持有)
# - 清理旧包:apt autoremove / yum autoremove
# - 清理 Docker:docker system prune -af
# - 清理 journal:journalctl --vacuum-size=500M
# 4. 检查已删除但仍被占用的文件(空间不释放)
lsof +L1
# 找到进程后重启即可释放
# 5. 长期方案:LVM 扩容、加磁盘
Q2: LVM 的优势是什么?
答案:
- 灵活扩容:在线扩展容量无需停机
- 快照:创建时间点快照用于备份
- 跨磁盘:多块物理盘合并为一个卷组
- 条带化:类似 RAID 0 的条带写入提升性能
- 灵活管理:可以任意调整逻辑卷大小
生产环境推荐对 /data、/var 等数据分区使用 LVM,便于后续扩容。
Q3: RAID 5 和 RAID 10 怎么选?
答案:
- RAID 5:空间利用率高((N-1)/N),适合读多写少的场景(文件服务器、归档存储)。写性能受限于校验计算
- RAID 10:性能最好(镜像+条带),适合读写密集的场景(数据库、虚拟化)。空间利用率 50%
数据库推荐 RAID 10,牺牲空间换性能和可靠性。
Q4: df 显示磁盘已满但 du 统计没那么大,为什么?
答案:
最常见的原因是已删除但仍被进程打开的文件。文件被 rm 后目录条目删除,但进程仍持有文件描述符,磁盘空间不会释放。
# 查找这类文件
lsof +L1
# 或
lsof | grep deleted
# 解决:重启持有文件的进程
# 或者:如果是日志文件,可以用 > /proc/<PID>/fd/<FD> 清空
其他可能原因:
- 预留空间(ext4 默认 5%):
tune2fs -m 1 /dev/sda1 - 隐藏挂载点:某目录先写入文件,再挂载其他分区覆盖