Linux · · Code & Light

Linux 磁盘管理实战:lsblk、LVM、ext4 与 XFS 完全指南

从查看磁盘、分区、PV/VG/LV 到 ext4、XFS 格式化、挂载、在线扩容、离线缩容与故障排查;包含 4 个完整运维场景和高风险操作检查清单。

在 Linux 服务器上,lsblk、LVM、ext4、XFS 并不是四个互相独立的工具:前者用于识别块设备,LVM 负责弹性分配空间,ext4/XFS 负责把空间组织成文件,最后通过挂载点供应用使用。真正的运维挑战是识别每一层、确定变更顺序,以及知道哪些操作不能在生产环境直接执行。

这篇文章按「概念 → 命令 → 操作 → 验证 → 故障排查」展开,包含普通分区和 LVM 两种存储布局,并覆盖四个真实工作中常见的容量调整流程。

阅读方法:每组命令后附有「命令解释」,重点说明做什么、重要参数代表什么、会不会修改数据、应如何验证;重复命令在实战章节也会按当前上下文简要解释。

环境与安全约定

  • 主要面向 Debian 12 / Ubuntu 22.04、24.04、Rocky Linux / RHEL 9 一类使用 util-linux、lvm2、e2fsprogs、xfsprogs 的发行版;不同版本的工具参数和默认行为应以本机 --help 与 man 为准。
  • 示例使用专门准备的实验数据盘 /dev/vdb(100 GiB)、/dev/vdc(50 GiB),以及卷组 vgdata、逻辑卷 lvdata;并非所有机器都有这些设备。你的机器可能是 /dev/sdb、/dev/nvme1n1 或云平台专有磁盘路径。
  • 标有 mklabel、mkfs、pvcreate、lvreduce、lvremove、vgreduce、pvremove 的操作会覆盖元数据或可能导致不可恢复的数据丢失;不能对生产盘直接照抄。开始前确认设备序列号、挂载点、现有业务、可恢复备份和维护窗口。
  • 示例命令不包含终端 $ 提示符。命令中的路径和容量是演示值,不代表通用安全参数。
  • 本文依据 Linux 工具手册和发行版文档整理,不是特定生产服务器的实测验收记录。

1. Linux 存储体系:先认清每一层

1.1 从磁盘到目录

普通文件系统的典型路径是:

物理磁盘 / 云盘 / 虚拟磁盘     /dev/vdb (100G)
               │
               ├─ 可选分区表 GPT / MBR
               │
               └─ 分区            /dev/vdb1
                     │
                     ├── 直接格式化 ext4 / XFS ──→ 挂载 /data
                     │
                     └── 可选 LVM
                           PV /dev/vdb1
                                ↓
                           VG vgdata
                                ↓
                           LV /dev/vgdata/lvdata
                                ↓
                           ext4 或 XFS
                                ↓
                           挂载目录 /data

不是每一层都必须存在:文件系统可以直接建在整块数据盘、分区、RAID 设备或逻辑卷上;LVM 的 PV 也可以是整盘或分区。这里选择「GPT 分区 → LVM → 文件系统」用于演示,是因为它能清楚展示层次,不代表只有这一种正确架构。

层级典型对象它解决的问题
块设备/dev/vdb、/dev/nvme1n1向系统提供可寻址的数据块
分区/dev/vdb1将设备划分为逻辑区间
PV(Physical Volume)/dev/vdb1将底层设备纳入 LVM
VG(Volume Group)vgdata汇聚一个或多个 PV 的可分配空间
LV(Logical Volume)/dev/vgdata/lvdata从 VG 分配给业务的块设备
文件系统ext4 / XFS管理目录、文件、权限与元数据
挂载点/data将文件系统接入 Linux 目录树

1.2 四类容易混淆的“大小”

  • lsblk 中的磁盘 SIZE:块设备本身的容量;可能还包含未分区的空间。
  • pvs / vgs / lvs:PV、VG、LV 的容量与可用扩展块,包含 LVM 元数据及分配粒度差异。
  • df -hT:已挂载文件系统的总量、已使用量和可用量,受文件系统开销、预留空间等影响。
  • du -sh:目录树中可见文件占用的空间,与删除但仍被打开的文件、快照、硬链接等情况未必一致。

容量扩容常常必须经过多层。把云盘从 100G 调到 200G,不代表分区、PV、LV、文件系统都会自动变成 200G。

1.3 操作前的三项核对

# 查询真实块设备与文件系统
lsblk -o NAME,PATH,SIZE,TYPE,FSTYPE,UUID,MOUNTPOINTS

# 已挂载文件系统视图
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS
df -hT

# LVM 对象与可用容量
sudo pvs
sudo vgs
sudo lvs -a -o lv_name,vg_name,lv_size,segtype,devices

命令解释:

  • lsblk -o ...:-o 指定输出列;NAME/PATH 看设备路径,SIZE 看块设备容量,FSTYPE/UUID 看文件系统类型及标识,MOUNTPOINTS 看挂载位置。
  • findmnt -o ...:查看已挂载文件系统的目标目录 TARGET、来源设备 SOURCE、类型 FSTYPE、挂载参数 OPTIONS。
  • df -hT:-h 用易读单位显示容量,-T 显示文件系统类型;关注的是文件系统空间,不是 VG 的空闲 PE。
  • pvs / vgs / lvs 分别展示物理卷、卷组、逻辑卷;lvs -a 包含内部/隐藏逻辑卷,-o 指定显示的字段。全部属于查询操作。

先用 lsblk 的父子关系确定目标是否是系统盘,再通过挂载路径、UUID、云控制台磁盘 ID 等多重信息确认,不能只凭盘符字母判断是不是空盘。

2. lsblk:查看与识别磁盘

lsblk 属于 util-linux,读取系统的块设备拓扑和相关 udev 信息,适合做磁盘管理第一步;它本身不会创建分区或格式化磁盘。

2.1 常用查看方式

# 树形展示(默认)
lsblk

# 文件系统、UUID、挂载点
lsblk -f

# 更适合脚本和排查的完整路径
lsblk -p -o NAME,SIZE,TYPE,FSTYPE,UUID,MOUNTPOINTS

# 查看拓扑与磁盘型号、序列号(并非所有云盘都会提供)
lsblk -d -o NAME,TRAN,MODEL,SERIAL,SIZE,ROTA

# 输出 JSON,供自动化工具解析
lsblk -J -o NAME,PATH,SIZE,TYPE,FSTYPE,MOUNTPOINTS

# 查看设备主要号/次要号与只读状态
lsblk -o NAME,MAJ:MIN,RM,RO,SIZE,TYPE,MOUNTPOINTS

命令解释:

  • lsblk:按父子关系展示磁盘、分区、LVM 等设备。-f 增加文件系统、UUID 等信息;-p 输出完整的 /dev/... 路径。
  • -o 字段列表:自定义显示哪些列,适合只查看指定信息;-d 只列顶层设备、不递归列分区;-J 输出 JSON,方便脚本消费。
  • TRAN 是传输类型,MODEL/SERIAL 是设备型号与序列号(可能为空);ROTA 表示旋转设备标志;MAJ:MIN 是内核主/次设备号,RM 表示可移除设备,RO 表示只读。这些命令均不修改磁盘。

关键字段:

字段含义
NAME / PATH设备名称和绝对路径
TYPEdisk、part、lvm、rom 等
FSTYPE文件系统或签名类型,例如 ext4、xfs、LVM2_member
UUID文件系统标识(通常用于 fstab)
MOUNTPOINTS当前全部挂载点,比旧式单个 MOUNTPOINT 更完整
ROTA旋转介质标志;为 0 通常意味着非旋转设备,但不是绝对性能保证

2.2 与其他工具如何分工

# 更准确地识别签名与 UUID(只读查询)
sudo blkid

# 分区表与扇区信息
sudo fdisk -l

# 查看文件系统挂载
findmnt -T /data

# 当前可用空间与 inode
df -hT /data
df -i /data

# 目录下文件实际占用
sudo du -xhd1 /data

命令解释:

  • blkid:查询文件系统或块设备的签名、类型、UUID;示例中的 sudo 是为了避免遗漏受权限保护的信息。
  • fdisk -l:-l 表示列出磁盘与分区表,不是创建分区;如果仅检查某块盘可加 /dev/vdb。
  • findmnt -T /data:-T 指定路径并查找覆盖此路径的实际挂载点,适合核对 /data 是否处于预期文件系统。
  • df -hT /data 查看挂载文件系统的容量和类型;df -i 查看 inode 使用量,两者反映不同的“空间不足”原因。
  • du -xhd1 /data:-x 不跨到其他文件系统,-h 易读单位,-d1 仅统计目录本身与下一层目录的大小;大目录上可能扫描较久。

当设备刚热插入、udev 事件还没处理完时,lsblk 与 blkid 的输出可能暂时不同步;系统有权限限制时也可能看不到全部签名。必要时先检查 dmesg、udevadm settle 和虚拟化平台识盘状态。

2.3 SATA、NVMe、LVM 与其他设备

  • /dev/sdX:常见 SCSI/SATA/USB/虚拟磁盘命名,不保证每次重启顺序相同。
  • /dev/nvme0n1、/dev/nvme0n1p1:NVMe 命名;p1 才是分区后缀。
  • /dev/mapper/vgdata-lvdata、/dev/vgdata/lvdata:同一 LVM 逻辑卷的常见访问路径。
  • loop:常见于镜像文件或 Snap 挂载,不应把它误判为新数据盘。
  • md、crypt、mpath:软件 RAID、加密映射、多路径设备;它们可能位于 LVM 或文件系统之下。

如果系统存在 RAID、LUKS、Ceph RBD 或多路径,先画清实际层级,不能直接把本文的「单块数据盘」示例当成最终生产操作方案。

3. 磁盘分区与初始化

3.1 GPT 与 MBR

属性GPTMBR(DOS)
设计定位现代主流方案传统兼容方案
大容量磁盘适合受扇区大小等条件限制,常见 512B 扇区约 2 TiB 边界
分区数量一般支持较多分区传统主分区最多 4 个,可通过扩展分区处理
元数据冗余包含备份 GPT 等机制不具备相同的 GPT 元数据设计

新建大容量数据盘通常优先 GPT,但已有生产磁盘不要为了统一风格随意重建分区表。

3.2 查看分区并准备实验盘

下面只适用于已经确认为空白、没有数据和挂载的实验盘 /dev/vdb;会写入新的 GPT 分区表,原有布局和分区数据可能丢失。

# 只读确认目标设备
lsblk -p -o NAME,SIZE,FSTYPE,TYPE,MOUNTPOINTS /dev/vdb
sudo wipefs -n /dev/vdb
sudo parted /dev/vdb print

# 危险:仅对专用空白实验盘执行
sudo parted -s /dev/vdb mklabel gpt
sudo parted -s /dev/vdb mkpart primary 1MiB 100%

# 请求内核重新读取分区表,再验证
sudo partprobe /dev/vdb
lsblk -p /dev/vdb

命令解释(这里尤其要分清“查看”和“清除”):

命令实际作用是否修改磁盘
lsblk -p -o ... /dev/vdb只查看目标设备的路径、容量、类型、文件系统和挂载点否
wipefs -n /dev/vdb仅预览磁盘上检测到的文件系统、RAID、分区表等签名;-n / --no-act 表示不执行擦除否
parted /dev/vdb print查看分区表布局否
parted -s /dev/vdb mklabel gpt-s 非交互模式;mklabel gpt 写入新的 GPT 分区表,原分区信息可能损坏是,高风险
parted -s /dev/vdb mkpart primary 1MiB 100%创建从 1 MiB 对齐位置到磁盘末尾的分区;primary 在 GPT 场景是分区名称,不是传统 MBR 主分区数量限制是
partprobe /dev/vdb通知内核重新读取分区表;设备忙时可能失败改变内核分区视图

特别注意:wipefs -n /dev/vdc 与这里的 /dev/vdb 完全同理,只是检查另一块盘。去掉 -n 不代表自动擦除;wipefs 通常还需要指定擦除范围选项(如 -a),但这类操作具有破坏性,不能作为“确认空盘”的默认流程。即使 wipefs -n 没有列出签名,也不等于确认设备没有业务数据,仍要检查 VG、RAID、挂载关系和云盘身份。

完成后通常出现 /dev/vdb1。如果内核报告设备忙、无法重读分区表,不要一边对原有分区使用、一边继续格式化;先检查设备是否被挂载、是否在 VG/RAID/Swap 中,必要时安排维护窗口或重启重新识别。

3.3 热添加云盘与在线扩盘

# 内核是否发现新设备、是否有存储 I/O 报错
lsblk
dmesg -T | tail -n 80

# 查看块设备及其分区
sudo fdisk -l /dev/vdb

# 选用的系统若提供 cloud-guest-utils / cloud-utils-growpart
growpart --help

命令解释:

  • dmesg -T 查看内核日志,并尽量将时间戳转成人类可读的形式;管道符 | 把结果交给 tail -n 80,只显示最后 80 行,用来找热插拔、控制器和 I/O 错误。
  • fdisk -l /dev/vdb 只列出指定设备的分区表;growpart --help 只显示该工具支持的选项、不会扩容任何分区。
  • 这些命令用于发现问题,并非“让磁盘自动上线”的命令。

SCSI 设备有时可以经 sysfs 触发重扫描,但设备地址依环境变化,不能盲目向整个系统所有 host 扫描;在 VMware、KVM、云厂商等环境中优先按平台官方扩盘流程执行,确认内核看到新磁盘容量后再处理分区和 LVM。

3.4 什么时候不需要分区?

如果整块独立数据盘全部用于一个 LVM PV,pvcreate /dev/vdb 是可行的;直接在 /dev/vdb 建 ext4/XFS 也可行。是否分区取决于团队规范、平台工具、后续扩容与设备迁移的管理方式。对正在使用的整盘 PV,不要再额外执行创建 GPT 分区表。

4. LVM:从 PV、VG、LV 到扩容和迁移

LVM 的价值是把底层设备容量组织成可分配池,让业务卷可以跨多个 PV 扩容,减少直接移动分区的麻烦。它不是 RAID 或备份方案:如果某个线性 LV 的数据跨两块盘,其中一块损坏也可能导致整个文件系统不可用。

4.1 安装与状态查询

# Debian / Ubuntu
sudo apt update
sudo apt install -y lvm2

# Rocky Linux / RHEL(如尚未安装)
sudo dnf install -y lvm2

# 只读概览
sudo pvs -o pv_name,vg_name,pv_size,pv_free
sudo vgs -o vg_name,vg_size,vg_free,vg_extent_size
sudo lvs -a -o lv_path,lv_size,segtype,devices
sudo pvdisplay
sudo vgdisplay
sudo lvdisplay

命令解释:

  • apt update 刷新 Debian/Ubuntu 的软件源索引;apt install -y lvm2 安装 LVM 工具,-y 自动确认安装提示。RHEL/Rocky 使用对应的 dnf install -y lvm2;两类发行版不需要都执行。
  • pvs -o ...、vgs -o ...、lvs -a -o ...:-o 精确指定字段,例如 pv_free 为 PV 未分配容量、vg_free 为 VG 剩余容量、devices 展示逻辑卷使用哪些 PV;-a 包括隐藏的内部 LV。
  • pvdisplay / vgdisplay / lvdisplay 是相应对象的详情查询,不会创建或改变卷。

4.2 理解 PE 与 VG 可用空间

VG 由一组 Physical Extent(PE)组成,LV 的大小通常按扩展块整数倍分配。假设 VG 的 PE 为 4 MiB,创建 1 GiB 的 LV 大约需要 256 个 PE;最终容量还受 LVM 元数据、对齐和现有空闲空间影响。

注意 vgs 的 VFree 才是 VG 尚未分配给 LV 的空间。df 显示的“剩余空间”是文件系统内部空闲块,不能直接拿它当成 VG 可分配空间。

4.3 创建 PV、VG 和 LV

继续使用上一步准备好的空白实验分区 /dev/vdb1:

# 危险:会写 LVM PV 元数据,必须核实分区没有数据
sudo pvcreate /dev/vdb1

# 新建名为 vgdata 的卷组
sudo vgcreate vgdata /dev/vdb1

# 从 VG 创建 60G 的逻辑卷
sudo lvcreate -L 60G -n lvdata vgdata

# 查看映射链
sudo pvs
sudo vgs
sudo lvs -o lv_path,lv_size,vg_name
lsblk -f

命令解释:

  • pvcreate /dev/vdb1:将确认无数据的分区初始化为 LVM 物理卷 PV,会写入 LVM 元数据。
  • vgcreate vgdata /dev/vdb1:建立名为 vgdata 的卷组,将该 PV 加入容量池。
  • lvcreate -L 60G -n lvdata vgdata:-L 60G 指定 60 GiB 级别的 LV 大小,-n lvdata 指定名称,vgdata 是来源卷组。
  • pvs、vgs、lvs -o ... 与 lsblk -f 用来核对结果;创建 LV 并不等于格式化文件系统或挂载。

建立 LV 不等于创建了文件系统,需要在下一章选择 ext4 或 XFS 其中之一,绝不能先格式化 ext4 再用 mkfs.xfs 覆盖同一 LV。

4.4 添加新磁盘,扩大卷组

假设新的实验数据盘 /dev/vdc 是全新、未使用的 50G 空盘;这里特意演示整盘作为 PV,说明分区不是必须步骤:

lsblk -p -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS /dev/vdc
sudo wipefs -n /dev/vdc

# 危险:仅针对确认无数据的 /dev/vdc
sudo pvcreate /dev/vdc
sudo vgextend vgdata /dev/vdc

sudo pvs
sudo vgs

命令解释:

  • lsblk ... /dev/vdc 检查这块盘的容量和当前从属关系;wipefs -n /dev/vdc 的 -n 是 no-act(仅查看签名、不擦除),用来发现已有文件系统、分区表或 RAID/LVM 签名。
  • pvcreate /dev/vdc 将整块盘初始化为 PV,真的会写数据结构;执行前必须确认 /dev/vdc 没有旧数据或其他用途。
  • vgextend vgdata /dev/vdc 把 PV 加入现有 VG,扩充 VG 可分配容量;它不会自动增加已有 LV 和文件系统的容量。
  • pvs、vgs 用于验证新 PV 属于哪个 VG,以及 VFree 是否增加。

4.5 扩容 LV:增量与剩余全部空间

# 给现有 LV 额外增加 20 GiB(不会自动扩文件系统)
sudo lvextend -L +20G /dev/vgdata/lvdata

# 或者,把 VG 全部剩余可用空间分配给 LV(与上句二选一)
# sudo lvextend -l +100%FREE /dev/vgdata/lvdata

sudo lvs -o lv_path,lv_size

命令解释:

  • lvextend -L +20G /dev/vgdata/lvdata:-L 按容量指定大小,前面的 + 表示增加 20G;若写成 -L 20G,则表示把目标大小设置为 20G,两者不能混淆。
  • lvextend -l +100%FREE ...:小写 -l 按 PE 数量/比例指定,+100%FREE 表示分配 VG 当前全部剩余空间。文章两种写法只能按需要选一种,不能连续执行。
  • lvs -o lv_path,lv_size:确认 LV 新容量;此时 df -hT /data 可能仍是旧值,因为文件系统还未扩容。

在兼容的文件系统与工具版本上,lvextend -r 可以调用辅助工具一起尝试扩容文件系统,但生产排障建议清楚区分 LV 层和文件系统层;本篇示例用显式两步操作,更便于确认每一步的效果。

4.6 缩容、磁盘迁移和删除

缩小 LV 是高风险操作:先确认其中的文件系统是否支持缩容,以及已使用容量、工具能力、备份是否满足要求。绝不先对含数据的 LV 执行 lvreduce,再试图收缩文件系统。ext4 的安全步骤见第 9 章,XFS 不支持原地缩容。

如果要从 VG 安全移除某个 PV,且 VG 还有其他 PV 有足够空闲 extents,可在维护计划内执行:

# 查询数据在哪些 PV 上
sudo lvs -a -o lv_name,vg_name,devices
sudo pvs -o pv_name,vg_name,pv_free

# 演示:将 /dev/vdc 上分配的数据迁往其他 PV
# 操作前必须确认目标 PV 有足够空间、数据有备份
sudo pvmove /dev/vdc

# 确认不再占用后,将它从 VG 移除
sudo vgreduce vgdata /dev/vdc

# 危险:仅确认 /dev/vdc 不再属于任何 VG 且可销毁时
# sudo pvremove /dev/vdc

命令解释:

  • lvs -a -o ...devices:查看 LV 的数据实际使用哪些 PV;pvs -o ...pv_free 则告诉你可迁移到其他 PV 的空闲空间。
  • pvmove /dev/vdc:尝试把 /dev/vdc 上已分配的 LVM extents 迁移到其他可用 PV;它并不是复制某个普通目录,且可能涉及大量在线数据搬运与 I/O。
  • vgreduce vgdata /dev/vdc:只有确认该 PV 已无 LV 分配后,才从 VG 中解除它的成员身份。
  • pvremove /dev/vdc:进一步清除 PV 的 LVM 标识,会改写设备元数据,这里保持为注释示例,不应对有数据的盘执行。

删除对象的顺序通常与创建相反:文件系统卸载与确认数据迁移 → 删除 LV → 删除空 VG → 清理不再使用的 PV。lvremove、vgremove、pvremove 都可能造成永久数据损失,本篇不提供针对有数据卷的一键删除流水线。

4.7 LVM 快照不是备份

LVM 的传统快照与 thin snapshot 可以协助创建时间点一致的视图,但需要空间监控;快照空间耗尽、原卷损坏或数据库尚未落盘的事务都可能影响可恢复性。数据库数据目录还需要应用协调、文件系统冻结或数据库自身的一致性备份机制,不能仅凭创建了快照就认定备份成功。

5. ext4 文件系统:创建、检查与扩缩容

5.1 ext4 适合什么场景?

ext4 是成熟的通用 Linux 日志文件系统,支持常见文件权限、ACL、扩展属性和广泛的工具生态。其重要特点是可以在挂载状态下扩容,并可以在卸载状态下、满足条件时缩容。

本文实验 LV 如果选择 ext4,可以这样创建:

# 破坏性操作:只允许未格式化的实验 LV
sudo mkfs.ext4 /dev/vgdata/lvdata

# 查看 UUID 与文件系统信息
sudo blkid /dev/vgdata/lvdata
sudo tune2fs -l /dev/vgdata/lvdata
sudo dumpe2fs -h /dev/vgdata/lvdata

命令解释:

  • mkfs.ext4 /dev/vgdata/lvdata:在指定逻辑卷上新建 ext4 文件系统(mkfs = make filesystem);若原卷已有数据,可能造成严重破坏。
  • blkid 查询创建后的文件系统类型和 UUID,方便后续 fstab 挂载。
  • tune2fs -l:-l 是列出 ext2/3/4 文件系统参数,这里不执行调整;dumpe2fs -h:-h 只输出超级块头部信息,避免打印所有块组细节。

mkfs.ext4 会创建新的文件系统元数据,覆盖旧文件系统的管理结构。对已有业务卷切勿为了“修复错误”随意重复格式化。

5.2 ext4 的在线扩容

假设 LV 已经过 lvextend 扩大,且文件系统挂载在 /data:

findmnt /data
lsblk -f /dev/vgdata/lvdata
sudo lvs -o lv_path,lv_size

# 将 ext4 文件系统扩到 LV 当前可用大小
sudo resize2fs /dev/vgdata/lvdata

df -hT /data

命令解释:

  • findmnt /data 验证预期挂载点;lsblk -f 检查该 LV 确实是 ext4;lvs -o lv_path,lv_size 核实底层 LV 已先扩容。
  • resize2fs /dev/vgdata/lvdata:在不指定新目标大小时,将 ext4 尝试扩展到当前块设备可用大小;对支持的 ext4 挂载状态可在线执行。
  • df -hT /data:验证最终文件系统容量与类型。这些步骤中只有 resize2fs 会改变文件系统大小。

在线扩容前底层 LV 必须已经足够大。resize2fs 并不会自动替你扩展分区或 LV。

5.3 文件系统检查与修复

# 需要先正常卸载目标文件系统
sudo umount /data

# 只读、不执行修复,检查 ext4 状态
sudo e2fsck -fn /dev/vgdata/lvdata

# 经维护窗口、备份和风险评估后,执行交互式检查修复
# sudo e2fsck -f /dev/vgdata/lvdata

命令解释:

  • umount /data:解除 /data 的挂载(不是拼写成 unmount),可能因为仍有进程使用而失败;先停止业务。
  • e2fsck -fn /dev/vgdata/lvdata:-f 强制执行检查,即使文件系统标记为 clean;-n 对修复问题回答 No,不写入更改,用于预检查。
  • e2fsck -f ...:去掉 -n 后可能实际修改元数据以完成修复,只能在正确卸载、备份和维护安排下执行;不要对正在挂载读写的文件系统使用。

e2fsck 不适合直接对正在读写挂载的 ext4 运行修复;对根文件系统等无法卸载的目标,需使用救援模式/离线环境。-n 虽不写入,但只读检查结果仍需要结合设备状态和文件系统日志解释。

5.4 inode 与 ext4 预留空间

df -i /data
df -hT /data

# 读取 ext4 已预留块比例、inode 总数
sudo tune2fs -l /dev/vgdata/lvdata

命令解释:

  • df -i /data:以 inode 计数展示已用与剩余数量;inode 用尽时,即使 df -hT 仍显示剩余字节,也可能无法新建文件。
  • df -hT:检查字节空间,-h 人类可读,-T 显示类型。
  • tune2fs -l:只读取 ext4 超级块参数,例如 Reserved block count(预留块)和 Inode count;并未改变预留比例。

ext4 的 inode 数量通常在创建文件系统时确定;大量小文件可能出现“空间没满但 inode 用尽”。同时 ext4 可能预留一部分数据块给特权操作,普通账号看到的可用容量与 df 的统计会受到影响。

tune2fs -m 可以调整 ext4 预留块比例,但不应在未确认根盘/数据盘用途、容量与应急运维需求之前直接设置为 0。

5.5 ext4 缩容的限制

  • 通常必须卸载文件系统,提前做完整且已验证的备份。
  • 先确认实际数据占用、resize2fs -P 的估算与目标大小边界;该估算并非所有场景都绝对精准。
  • 先缩文件系统,再缩 LV,不能颠倒。
  • 文件系统边界与 LV 边界应留安全空间,不建议把两者直接设置成完全一样的极限值。
  • 对根卷、加密设备、快照、RAID、thin pool 等特殊拓扑,应走专用操作流程。

6. XFS 文件系统:在线扩容与修复

6.1 XFS 的基本特征

XFS 是面向大文件和并行 I/O 场景常见的高性能日志文件系统,具备 extent、延迟分配、动态 inode 分配等机制。很多 RHEL 系列系统选择 XFS 作为默认文件系统;但默认使用 XFS 不意味着它在所有业务上都比 ext4 更快。

6.2 格式化与查看

以下与第 5 章的 ext4 二选一:只对另一个尚未格式化的实验 LV 使用,或先明确销毁整个实验 LV 上的数据。

# 仅在专门准备的空白实验 LV 上执行
sudo mkfs.xfs /dev/vgdata/lvdata

# 假设它已挂载至 /data,查询 XFS 信息
sudo xfs_info /data

# 查看签名与空间
lsblk -f
df -hT /data

命令解释:

  • mkfs.xfs /dev/vgdata/lvdata:在目标 LV 上新建 XFS 文件系统,会覆盖原文件系统结构,不能在已有 ext4 上当作升级命令使用。
  • xfs_info /data:显示已挂载在 /data 上的 XFS 几何和元数据参数(如 block size、allocation group),不是查看 Linux 用户权限。
  • lsblk -f 确认底层确实是 XFS,df -hT /data 确认挂载点与容量。

XFS 提供 xfs_info、xfs_admin、xfs_db、xfs_quota、xfs_repair 等工具,但底层编辑/调试命令可能危险,生产场景不应尝试未经验证的修复参数。

6.3 XFS 在线扩容的关键:传入挂载点

# 第一步:先扩大底层逻辑卷
sudo lvextend -L +20G /dev/vgdata/lvdata

# 第二步:XFS 必须处于已挂载状态,使用挂载点扩容
sudo xfs_growfs /data

# 第三步:验证
xfs_info /data
df -hT /data

命令解释:

  • lvextend -L +20G ...:先将 LV 增加 20G,只改变 LVM 逻辑卷大小。
  • xfs_growfs /data:在 XFS 已挂载时把文件系统增长到可用空间;这里的参数是挂载点,不是 /dev/vgdata/lvdata 设备路径。
  • xfs_info 查询 XFS 几何信息;df -hT 用于确认业务看到的文件系统容量确实增加。

与 ext4 常用的 resize2fs /dev/vgdata/lvdata 不同,xfs_growfs 典型参数是 挂载点 /data。底层 LV 容量不够时,单纯运行 xfs_growfs 无法扩大空间。

6.4 XFS 为什么不能直接缩容?

XFS 不支持原地缩容。即使 VG 有大量空闲空间,也不能把一个已经创建的 XFS 文件系统通过 resize2fs 或 xfs_growfs 缩小;lvreduce 只会缩底层设备,可能立即破坏文件系统。

需要释放 LV 空间时,正确方向是:准备更小的新 LV / 新文件系统 → 一致性备份 → 复制/恢复数据 → 停止写入并最终同步 → 切换挂载点 → 验证 → 下线旧 LV。具体示例见第 9.4 节。

6.5 XFS 检查与修复

# 先卸载;不要对活动读写挂载的 XFS 执行修复
sudo umount /data

# 不修改的预检查
sudo xfs_repair -n /dev/vgdata/lvdata

# 仅在已备份且确认修复方案时使用:
# sudo xfs_repair /dev/vgdata/lvdata

命令解释:

  • umount /data:卸载后才能开展 XFS 的离线检查/修复。
  • xfs_repair -n /dev/vgdata/lvdata:-n 为不修改的检查模式,可用于评估可见损坏,但对于需要日志回放等场景输出可能并不全面。
  • xfs_repair ...(无 -n):可能实际修改损坏的文件系统元数据,必须事先备份、正确卸载并评估日志情况;不要直接使用会清零日志的 -L 选项。

XFS 日志未正常落盘时,xfs_repair 可能要求先通过正常挂载让日志回放,再卸载检查。xfs_repair -L 会清零日志、可能丢失元数据与数据,不是遇到报错就直接执行的万能修复命令。此外 fsck.xfs 在很多发行版只是兼容入口,不能替代 xfs_repair 的实际检查。

7. ext4 与 XFS:如何选型?

对比项ext4XFS
在线扩容支持(resize2fs)支持(xfs_growfs)
缩容可离线缩容(条件限制)不支持直接缩容
检查修复e2fsckxfs_repair
inode创建时规划数量更重要动态分配,仍受元数据和资源条件约束
典型定位通用、工具成熟、灵活大文件、并发 I/O、RHEL 生态常见
大小与性能依工作负载而变依工作负载而变
配额支持支持(xfs_quota 等)

7.1 具体怎么选?

  • 需要保留缩容能力、通用云主机数据盘或开发/测试环境:可以优先考虑 ext4。
  • RHEL/Rocky 生态、大数据集、文件服务器、面向稳定增长的容量规划:XFS 是合理选择。
  • PostgreSQL/openGauss 数据目录:两者均可作为底层文件系统;实际选型要结合发行版支持、fsync/写入模式、存储阵列、备份与恢复设计、数据量及监控,而不是简单说“XFS 一定比 ext4 快”。
  • 根文件系统:不要为了测试就直接更换;按照发行版支持与安装器方案决定。

7.2 性能没有脱离场景的绝对排名

性能差异取决于设备延迟、RAID/NVMe、缓存、队列深度、同步写入比例、小文件数量、挂载选项和内核版本。若要下结论,应在相同硬件与相同业务负载下通过 fio、应用压测和可靠的延迟/吞吐监控验证,不能套用网络上的单一跑分。

8. 挂载、fstab 与开机自动挂载

8.1 临时挂载并检查

假设 /dev/vgdata/lvdata 已格式化为一种文件系统:

sudo mkdir -p /data
sudo mount /dev/vgdata/lvdata /data

# 挂载完成后检查文件系统、容量和实际来源
findmnt /data
df -hT /data
lsblk -f

# 按业务账号与权限规划后,再有针对性地设置归属
# sudo chown appuser:appgroup /data

命令解释:

  • mkdir -p /data:创建挂载目录;-p 在目录已经存在时不报错,并能创建中间父目录。
  • mount /dev/vgdata/lvdata /data:将这个 LV 上已经创建的文件系统挂到 /data,不是格式化命令。
  • findmnt、df、lsblk:分别验证挂载源、容量/类型、设备层级。
  • chown appuser:appgroup /data(被注释):把目录所有者/组设置为示例账号/用户组,不会创建账号;对已有目录及业务权限须按实际服务用户评估。

不要对已有重要目录随意挂载:挂载会把该目录原有内容暂时隐藏(原数据通常仍在底层文件系统中),可能造成应用路径看起来“丢数据”。生产场景应先确认目录用途和挂载源。

8.2 为什么 fstab 优先 UUID?

/dev/sdb、/dev/vdb 等盘符可能因设备枚举变化而改变;文件系统的 UUID 通常更适合用于长期挂载。

sudo blkid /dev/vgdata/lvdata

# 查看当前挂载点对应的持久设备
findmnt -no SOURCE,FSTYPE,UUID /data

# 编辑之前备份原文件
sudo cp /etc/fstab /etc/fstab.bak
sudoedit /etc/fstab

命令解释:

  • blkid /dev/vgdata/lvdata:读取目标文件系统的 UUID、TYPE 等信息,UUID 用来填写 fstab。
  • findmnt -no SOURCE,FSTYPE,UUID /data:-n 去掉表头,-o 自选字段,仅看实际挂载源、类型及 UUID,方便对照 fstab。
  • cp /etc/fstab /etc/fstab.bak:备份已有开机挂载配置;sudoedit 通过管理员安全编辑机制修改文件,替代直接用 root 编辑器。
  • 注意:示例中的 UUID=<替换为实际UUID> 是占位值,不能原样投入 fstab;ext4/XFS 的挂载类型必须与实际相符。

ext4 的示例 /etc/fstab 行:

UUID=<替换为实际UUID>  /data  ext4  defaults,nofail  0  2

如果上一步选择 XFS,则应改成对应的真实 UUID 和类型:

UUID=<替换为实际UUID>  /data  xfs  defaults,nofail  0  0

两行只能选择符合真实文件系统的一行。nofail 允许磁盘缺失时系统继续启动,适合非关键附加盘;如果数据库等关键服务必须依赖此挂载,不宜机械套用 nofail 而让应用悄悄写进根盘目录,应配合 systemd 挂载依赖与启动条件设计。最后两列是 dump 与 fsck pass 字段,不同文件系统建议遵循发行版工具处理方式。

8.3 验证配置而不是直接重启赌运气

sudo findmnt --verify --verbose

# systemd 系统修改 /etc/fstab 后按实际提示刷新
sudo systemctl daemon-reload

# 谨慎验证尚未挂载的条目
sudo mount -a

# 确认最终状态
findmnt /data
df -hT /data

命令解释:

  • findmnt --verify --verbose:校验 /etc/fstab 条目及部分可检出的挂载问题,--verbose 输出更详细的结果;并不保证所有重启场景都无问题。
  • systemctl daemon-reload:让 systemd 重新载入单元定义,包括按 fstab 生成的挂载单元;不会自动替你把数据盘挂载好。
  • mount -a:尝试挂载 fstab 中适用但尚未挂载的条目,可能实际发起挂载,并非只读检查。
  • findmnt /data、df -hT /data:核对最终是否挂载到正确来源、容量和类型。

mount -a 会尝试加载其他未挂载的 fstab 条目,生产环境需先检查所有条目。不要在不知道远程 SSH 根目录与挂载依赖关系时直接重启系统“试试看”。

8.4 mount、umount、fstrim 与挂载选项

# 只读查看已挂载目录
mount | grep ' /data '
findmnt -T /data

# 了解谁正在占用目录(卸载失败时)
sudo fuser -vm /data

# SSD/虚拟块存储是否支持 TRIM
lsblk -D
systemctl status fstrim.timer

命令解释:

  • mount | grep ' /data ':在当前挂载列表里搜索 /data(grep 只是过滤文本);findmnt -T /data 能更精确找出路径所属的文件系统。
  • fuser -vm /data:列出可能占用挂载点的进程,-m 按挂载文件系统查找、-v 给出详细列表;此处仅查询,不发送信号。
  • lsblk -D:显示块设备的 discard/TRIM 能力;systemctl status fstrim.timer 查询周期性 TRIM 任务状态,不会立即对磁盘执行 TRIM。

noatime 可减少访问时间写入,fstrim 可帮助支持 discard 的存储回收空间;是否启用、周期和效果取决于块设备、虚拟化层及文件系统。不要在不了解存储后端的情况下为了“优化”强制使用在线 discard。

9. 综合实战:从新磁盘到在线扩容与缩容

以下四个场景是独立操作示例,有些共享相同的演示名称,但不能对同一个数据目录把 A、B、C、D 无脑串行执行。每个场景都必须从自己的前置状态开始,明确 ext4 或 XFS 的实际类型。

9.1 场景 A:新增 100G 磁盘,创建 LVM 与文件系统

目标:全新、没有任何业务数据的 /dev/vdb,创建 GPT + /dev/vdb1、VG vgdata、LV lvdata(60G),格式化并挂载 /data。

操作前检查:

lsblk -p -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS /dev/vdb
sudo wipefs -n /dev/vdb
sudo pvs
findmnt /data

操作前检查命令解释:

  • lsblk -p -o ... /dev/vdb:确认这块盘的完整设备路径、分区、容量与挂载情况。
  • wipefs -n /dev/vdb:仅列出可能存在的磁盘签名;-n = no-act,不会擦除任何签名。这与 wipefs -n /dev/vdc 完全相同,只是设备不同。
  • pvs:如果磁盘或分区属于 LVM,检查其是否已加入 VG;findmnt /data:检查业务目标路径是否已有挂载。
  • 以上检查不能单独证明盘是空的,仍须结合云平台磁盘标识与业务记录确认。

确认目标是专用空白实验盘后依次执行:

# 这两步会重写分区表;只用于实验空盘
sudo parted -s /dev/vdb mklabel gpt
sudo parted -s /dev/vdb mkpart primary 1MiB 100%
sudo partprobe /dev/vdb

# 仅对确认空白的分区初始化 LVM
sudo pvcreate /dev/vdb1
sudo vgcreate vgdata /dev/vdb1
sudo lvcreate -L 60G -n lvdata vgdata

# 二选一:以下演示选择 ext4
sudo mkfs.ext4 /dev/vgdata/lvdata

sudo mkdir -p /data
sudo mount /dev/vgdata/lvdata /data

lsblk -f
sudo lvs -o lv_path,lv_size
df -hT /data
sudo blkid /dev/vgdata/lvdata

初始化过程中的命令解释:

  1. 分区层:parted -s ... mklabel gpt 在空盘写分区表;mkpart primary 1MiB 100% 建一个覆盖剩余空间的分区;partprobe 让内核重新识别分区;这几步会更改底层盘布局。
  2. LVM 层:pvcreate /dev/vdb1 将空分区标记成 PV,vgcreate vgdata ... 汇聚 PV 为 VG,lvcreate -L 60G -n lvdata vgdata 从 VG 分出 60G、名为 lvdata 的 LV。
  3. 文件系统层:mkfs.ext4 真正写入 ext4 文件系统元数据;mkdir -p /data 准备目录;mount ... /data 将文件系统交给业务使用。
  4. 验收层:lsblk -f 看设备关系/文件系统,lvs -o ... 确认 LV 大小,df -hT /data 看应用可用容量,blkid 获取 UUID。 风险:mklabel、pvcreate、mkfs.ext4 都不是可随意重复运行的“初始化检查”命令。

如果选择 XFS,则把 mkfs.ext4 改成 mkfs.xfs,而不是两个都执行。最后再根据第 8 章的实际 UUID 和 FSTYPE 配置 fstab。

验收:lsblk 显示 disk → part → lvm;df -hT /data 显示 ext4(或 XFS),容量约 60G;findmnt /data 指向正确的 LV,重启验证需在维护安排内进行。

9.2 场景 B:LVM 增加一块 50G 磁盘,业务在线扩容

前提:已有 vgdata/lvdata 挂载到 /data,现有文件系统正常,新的 /dev/vdc 是完全空白的实验盘。

# 先确认新增盘与当前文件系统
lsblk -p -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
findmnt -no SOURCE,FSTYPE,TARGET /data
sudo vgs -o vg_name,vg_size,vg_free

# 仅在确认 /dev/vdc 无数据后加入 VG
sudo pvcreate /dev/vdc
sudo vgextend vgdata /dev/vdc

# 只增加 20G
sudo lvextend -L +20G /dev/vgdata/lvdata

sudo lvs -o lv_path,lv_size

命令解释:

  • lsblk -p -o ... 识别新盘;findmnt -no SOURCE,FSTYPE,TARGET /data 用 -n 去表头、-o 指定列,确认旧卷的文件系统类型与挂载来源;vgs -o ...vg_free 查询卷组剩余空间。
  • pvcreate /dev/vdc 在确认空白的新增盘写 PV 元数据;vgextend vgdata /dev/vdc 扩大 VG 容量池。
  • lvextend -L +20G ... 只将目标 LV 额外扩大 20G;lvs -o ... 验证 LV 是否变大。下一步仍要按 ext4/XFS 类型扩容文件系统。

然后按实际的 FSTYPE 二选一:

# ext4:可以对已挂载的 ext4 在线扩容
sudo resize2fs /dev/vgdata/lvdata

命令解释(ext4 路径):resize2fs /dev/vgdata/lvdata 按 LV 当前大小扩大 ext4 文件系统,传入的是块设备路径;请先验证 findmnt -no FSTYPE /data 返回 ext4,切勿在 XFS 上运行。

# XFS:必须以实际挂载点扩容
sudo xfs_growfs /data

命令解释(XFS 路径):xfs_growfs /data 在线增长已经挂载在 /data 的 XFS,传入的是挂载点;请先确认 findmnt -no FSTYPE /data 返回 xfs,且 LV 已先扩大。

# 最终共同验收
df -hT /data
lsblk -f
sudo vgs -o vg_name,vg_free

验收命令解释:df -hT /data 是文件系统视角的最终可用容量;lsblk -f 复核文件系统位于正确的 LV 上;vgs -o vg_name,vg_free 查看扩容后卷组还剩多少空间。这些都是只读查询。

风险:VG 可能把一个 LV 的数据分布在两块磁盘,后续不能直接拔掉新增盘。想移除需先在满足空间约束的情况下正确 pvmove 和 vgreduce,还需业务级备份。

9.3 场景 C:云盘原地从 100G 增至 200G

前提:云控制台已经完成扩盘,Linux 已发现 /dev/vdb 从 100G 增加到 200G;第 1 分区 /dev/vdb1 是位于磁盘末尾、允许扩展的 LVM PV 分区,后面没有其他障碍分区;其上的 VG/LV 与 /data 均已核对。

先不要修改,检查每层:

lsblk -p -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS /dev/vdb
sudo parted /dev/vdb print
sudo pvs -o pv_name,pv_size,pv_free
sudo vgs -o vg_name,vg_free
sudo lvs -o lv_path,lv_size
findmnt -no SOURCE,FSTYPE,TARGET /data

命令解释:

  • lsblk -p -o ... /dev/vdb:确认底层块设备的新容量、分区和 LVM 映射关系。
  • parted /dev/vdb print:只读展示 GPT/MBR 布局,判断待扩容分区是否位于磁盘末尾。
  • pvs / vgs / lvs:分别检查 PV 总量、VG 空闲容量、LV 已分配容量,-o 字段里 pv_free 与 vg_free 不是文件系统剩余空间。
  • findmnt -no SOURCE,FSTYPE,TARGET /data:确定 /data 使用哪个 LV、是 ext4 还是 XFS;只有找准对应设备才可继续。

已备份并确认在线扩分区可行后:

# cloud-guest-utils(Debian/Ubuntu)或 cloud-utils-growpart(RHEL 系)
# 先检查命令是否存在
command -v growpart

# 扩大 /dev/vdb 上的第 1 分区
sudo growpart /dev/vdb 1

# 仅在设备状态允许时刷新分区表
sudo partprobe /dev/vdb

# 内核必须真的识别到扩大的 /dev/vdb1;未更新则停止后续步骤
lsblk -p /dev/vdb

# 扩大 PV 可用范围,然后查看 VG 新增空闲容量
sudo pvresize /dev/vdb1
sudo pvs
sudo vgs

# 只增加所需的 80G,不一定要占满 200G
sudo lvextend -L +80G /dev/vgdata/lvdata

扩盘命令解释(按底层 → 上层执行):

命令作用与关键参数
command -v growpart检查当前 PATH 是否能找到 growpart 命令;本身不改磁盘
growpart /dev/vdb 1将磁盘 /dev/vdb 的第 1 个分区扩展到可用边界(通常是末尾未分配空间);会写分区表
partprobe /dev/vdb请求内核重新读取分区信息;如果设备忙而无法更新,必须停止后续步骤
lsblk -p /dev/vdb确认扩大的 /dev/vdb1 大小已被内核识别
pvresize /dev/vdb1告诉 LVM 该 PV 现在拥有更大的底层分区,释放新的 VG 可分配空间
pvs / vgs验证 PV 扩大、VG Free 增加
lvextend -L +80G ...从 VG 再给目标 LV 分配 80G;前面的 + 表示增量,不会自动扩大 ext4/XFS

执行边界: 如果 growpart 不存在、分区不位于合适位置或内核尚未识别到新分区容量,不能直接跳到后面的 pvresize 或 lvextend。

按照真实文件系统执行 resize2fs /dev/vgdata/lvdata 或者 xfs_growfs /data,再检查 df -hT /data。

注意:growpart 适用于符合条件的末尾可增长分区;如果空间前面存在其他分区、LUKS 层、RAID 或云盘尚未在内核中变大,这个模板不一定可用。内核无法重读在线分区表时,先安排重启或适当维护方案,不要对仍旧大小的分区继续执行 pvresize/lvextend。

9.4 场景 D:ext4 缩容和 XFS 迁移重建

目标:说明 ext4 为什么可以缩容、XFS 为什么必须迁移。两种路径互斥。

D1. ext4 的离线缩容示范

假设目标 LV 现在为 80G、实际已用数据足够少,准备把 ext4 文件系统先缩到 40G,随后将 LV 调至 45G 并重新扩充 ext4 占满这个 LV。数字仅为说明「文件系统必须小于最终 LV」的安全顺序,生产必须重新计算目标空间、元数据开销并验证备份。

前置要求:业务停止写入、/data 成功卸载、容量与风险评估完成、有已验证的完整备份;如涉及根盘,需从独立救援系统操作。

# 只读检查
findmnt /data
df -hT /data
sudo lvs -o lv_path,lv_size

# 停止业务后正常卸载
sudo umount /data

# 离线检查,确认文件系统没有待修复的错误
sudo e2fsck -f /dev/vgdata/lvdata

# 先把 ext4 收缩到 40G;前提是实际数据能安全放入该容量
sudo resize2fs /dev/vgdata/lvdata 40G

# 再将 LV 缩到 45G,保留大于文件系统的空间余量
# 破坏性操作:若 FS 实际大于 45G 会造成不可恢复的数据丢失
sudo lvreduce -L 45G /dev/vgdata/lvdata

# 检查并将 ext4 扩至新的 LV 完整大小
sudo e2fsck -f /dev/vgdata/lvdata
sudo resize2fs /dev/vgdata/lvdata

# 重新挂载验证
sudo mount /dev/vgdata/lvdata /data
df -hT /data
sudo lvs -o lv_path,lv_size

缩容流程中每条关键命令的含义:

  • findmnt、df -hT、lvs -o ...:核实源文件系统的实际类型、使用量与逻辑卷容量。
  • umount /data:在业务停写后卸载文件系统;只有确认成功后才能执行离线文件系统检查。
  • e2fsck -f ...:强制检查 ext4 文件系统,必要时修复错误;可能写入修改,事先需要备份。
  • resize2fs ... 40G:首先把 ext4 文件系统缩到 40G;必须确保真实文件与元数据能放下,不能凭 df 估计。
  • lvreduce -L 45G ...:随后将底层 LV 的最终容量设为 45G(注意无 +),如果文件系统仍大于这个值将直接损坏数据。
  • 第二次 resize2fs ... 不指定大小,是将 ext4 重新扩展到 45G 的 LV 边界;mount 恢复挂载,df、lvs 验证结果。 不能把 lvreduce 放在 resize2fs ... 40G 之前,更不能在 XFS 上使用这套步骤。

不要只看 df 已用容量就推断一定能安全缩到 40G:inode 表、元数据布局、文件系统特性等都可能限制缩容;应先在同规模测试环境演练,生产中可使用更保守的余量或者选择备份重建。中途任何一步异常,必须停止,不能继续执行下一条破坏性命令。

D2. XFS 要缩容:新建小卷并迁移

假设旧的 /data 为 XFS,准备换成更小的新 LV。推荐的高层流程:

  1. 事先创建另一块足够容纳全部数据、元数据和未来增长空间的目标 LV,并使用 mkfs.xfs 格式化目标新卷,绝不格式化旧卷。
  2. 在 /mnt/newdata 挂载新卷,备份并校验文件与 ACL、xattr、属主、硬链接等。
  3. 让应用进入维护模式停止写入,完成最后一次增量同步或应用一致性备份。
  4. 校验数据、应用权限与挂载目录切换,更新 /etc/fstab 对应 UUID。
  5. 在新卷完成生产验收、备份可恢复之前,保留旧卷用于回退;之后才评估是否释放旧 LV 空间。

数据复制示意(需要足够磁盘空间且旧目录保持可访问):

# 新卷挂载点是 /mnt/newdata;不要把目标设备设为旧卷
sudo mkdir -p /mnt/newdata

# 假设新卷已经完成格式化并挂载
findmnt /mnt/newdata
findmnt /data

# 初次复制:保留权限、ACL、扩展属性、硬链接及 UID/GID
sudo rsync -aHAX --numeric-ids --one-file-system /data/ /mnt/newdata/

# 业务最终停写后,再执行一次真正的增量同步(不能带 -n)
sudo rsync -aHAX --numeric-ids --one-file-system /data/ /mnt/newdata/

# 只读预演:确认是否还有未同步变化;不要在未核查时加 --delete
sudo rsync -aHAXn --numeric-ids --one-file-system /data/ /mnt/newdata/

# 核对容量与文件系统类型
df -hT /data /mnt/newdata

复制与校验命令解释:

  • mkdir -p /mnt/newdata 准备挂载目录;findmnt 确认旧卷与新卷确实分别挂载,避免把数据复制回同一文件系统。
  • rsync -aHAX --numeric-ids --one-file-system /data/ /mnt/newdata/:-a 归档方式保留常见时间/权限/符号链接;-H 保留硬链接;-A 保留 ACL;-X 保留扩展属性;--numeric-ids 使用数字 UID/GID;--one-file-system 不跨入源目录中其他文件系统。源路径末尾的 / 表示复制目录内容。
  • rsync ... -n:-n / --dry-run 只预览差异、不真正同步。停写后必须再次执行没有 -n 的实际 rsync,然后再用 -n 对比;仅运行 dry-run 不等于完成切换。
  • df -hT /data /mnt/newdata 比较新旧文件系统容量与类型,之后还要校验文件、业务读写和启动依赖。

注意:普通 rsync 不等于数据库一致性备份,活动 PostgreSQL/openGauss 数据目录应该使用数据库自身的备份与停写方案。新卷切换可能涉及 systemd 单元、SELinux 上下文、容器卷或其他业务配置,需要逐项验收后再下线旧卷。

10. 常见故障与排查路径

10.1 新磁盘出现不了

lsblk
dmesg -T | tail -n 100
sudo fdisk -l
ls /sys/class/block/

命令解释:lsblk 查看内核已经识别的块设备;dmesg -T | tail -n 100 查询最近 100 行内核日志(-T 转换时间显示),查磁盘热插拔与 I/O 错误;fdisk -l 只列分区;ls /sys/class/block/ 枚举内核块设备类中的节点。这里所有命令都是诊断而非初始化。

先检查云控制台是否真正挂盘、虚拟机控制器是否连接、内核是否发现设备、是否有硬件 I/O 错误;不要用格式化作为识盘故障的解决方法。

10.2 云盘扩了,df 仍显示原大小

按顺序检查:

lsblk -p -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
sudo pvs
sudo vgs
sudo lvs
df -hT

命令解释:lsblk 检查云盘、分区、LVM 的设备大小是否已经同步;pvs 查看 PV 识别到的容量;vgs 看 VG 是否出现新的可用空间;lvs 看 LV 大小;df -hT 最后看应用可见的文件系统容量。五条输出按顺序比较,就能定位是哪一层没有扩容。

若磁盘变大但分区未变,考虑分区层;分区变大但 PV 未变,考虑 pvresize;VG 空间增加但 LV 未变,考虑 lvextend;LV 变大但 df 未变,最后检查 resize2fs 或 xfs_growfs 是否已经在正确文件系统执行。

10.3 VG 有空间,LV 仍无法扩容

sudo vgs -o vg_name,vg_size,vg_free
sudo lvs -a -o lv_path,lv_size,segtype,devices
sudo pvs -o pv_name,vg_name,pv_free
sudo lvs -a -o +data_percent,metadata_percent

命令解释:

  • vgs -o vg_name,vg_size,vg_free:查看 VG 总量和可用 extents 对应的空间。
  • lvs -a -o ...segtype,devices:-a 包括内部 LV,segtype 判断是普通 linear、thin 或 RAID 等类型,devices 查看它依赖哪些设备。
  • pvs -o ...pv_free:检查各个 PV 的实际空闲空间分布。
  • lvs -a -o +data_percent,metadata_percent:字段前的 + 表示在默认输出列追加 thin pool 的 Data%/Meta% 等指标(不是扩容),用来发现薄池数据或元数据耗尽。

可能涉及 LV 类型、thin pool / metadata 空间、条带/RAID 分配限制、可用 PE 不满足分配策略、权限或设备缺失。尤其 thin pool 的 Data% / Meta% 接近满时,会导致写入异常,不能只看 VG VFree。

10.4 No space left on device,但 df -h 未满

df -hT /data
df -i /data
sudo du -xhd1 /data

# 已删除但仍被进程打开的文件
sudo lsof +L1

命令解释:

  • df -hT /data 检查字节空间剩余量;df -i /data 则检查inode 数量,有剩余字节不意味着还能创建新文件。
  • du -xhd1 /data:按目录汇总 /data 中实际可见文件的占用,-x 避免跨挂载;与 df 差别很大时可继续查“已删除但仍打开”的文件。
  • lsof +L1:列出链接计数小于 1、但仍被进程保持打开的文件,常用于定位删除后空间未释放的日志;它不关闭文件,也不会回收占用。

常见原因:inode 用尽、应用写到了另一个挂载点、用户配额、已删除但仍打开的日志文件、薄池耗尽、容器 Overlay/存储后端限额。lsof +L1 可识别典型已删除打开文件,但也要判断具体文件描述符是否由长期服务占用,优先安排日志轮转/安全重启,不能凭经验直接 kill -9。

10.5 文件系统只读、I/O error 或 metadata corruption

findmnt -no SOURCE,FSTYPE,OPTIONS /data
dmesg -T | grep -i -E 'I/O error|ext4|xfs|read-only|corrupt' | tail -n 60
journalctl -k --no-pager -n 100

命令解释:findmnt -no SOURCE,FSTYPE,OPTIONS /data 只输出挂载来源、文件系统类型和选项(-n 无表头,-o 选字段);dmesg -T | grep -i -E '...' | tail -n 60 通过忽略大小写的扩展正则匹配(-i -E)过滤内核报错;journalctl -k --no-pager -n 100 只显示最近 100 条内核日志,不用分页器。都是取证查询,不要据此直接格式化或清零日志。

先区分底层块设备硬件故障、文件系统损坏、只读挂载和存储服务失联。备份/镜像后安排离线检查:ext4 常用 e2fsck,XFS 常用 xfs_repair -n。遇到 I/O 错误时,反复对故障磁盘执行重写式修复可能进一步扩大损失,有条件先做块级镜像并寻求专业恢复。

10.6 umount: target is busy

findmnt -T /data
sudo fuser -vm /data
sudo lsof +D /data

命令解释:findmnt -T /data 确认路径所属挂载点;fuser -vm /data 按挂载点列出占用进程(-v 详细,-m 查文件系统),未包含发送终止信号的选项;lsof +D /data 递归枚举打开该目录下文件的进程,目录很大时可能执行很慢。先查清占用者,再决定如何安全停止应用。

排查进程当前工作目录、打开文件、子挂载和容器占用。lsof +D 会递归遍历,大目录可能很慢;生产不要默认用 umount -l(懒卸载)掩盖仍然有进程使用文件系统的问题。

10.7 fstab 配错导致启动异常

先在正常运行时执行 findmnt --verify --verbose 并备份 /etc/fstab;如系统启动进入 emergency mode,应从控制台/救援模式查看 journalctl -xb、块设备 UUID 和挂载失败日志,恢复错误条目后再验证。远程服务器不要未经控制台可用性确认就把系统盘挂载配置当作练习题。

10.8 LVM PV 丢失或 VG 不完整

sudo pvs -o pv_name,vg_name,pv_uuid,pv_size
sudo vgs -o vg_name,vg_attr,pv_count,lv_count,vg_free
sudo lvs -a -o lv_name,lv_attr,devices

# 检查 LVM 是否识别到了设备
sudo pvscan
sudo vgscan

命令解释:

  • pvs -o ...pv_uuid:核对 LVM PV 的持久 UUID,识别异常缺失或设备映射改变。
  • vgs -o vg_attr,pv_count,lv_count,...:查看 VG 的状态标志、PV 个数、LV 个数、剩余容量;vg_attr 可帮助发现部分卷组或权限异常。
  • lvs -a -o lv_attr,devices:查看 LV 状态标志和底层 PV 映射,帮助判断是否存在缺失设备。
  • pvscan / vgscan:扫描并发现 LVM 物理卷与卷组信息,属于发现过程,不等于自动修好损坏的元数据。

可能是设备没出现、云盘解除挂载、LVM 设备过滤规则、multipath、UUID 冲突或底层磁盘故障。不要直接用 vgcfgrestore、pvcreate --uuid、--partial 等高风险恢复参数试错;应先保存 /etc/lvm/backup、/etc/lvm/archive 的可用元数据,核查设备映射与备份方案再决定修复步骤。

11. 生产安全规范与命令速查

11.1 操作分级

级别示例命令操作要求
只读识别lsblk、blkid、pvs、vgs、lvs、df、findmnt可优先使用,注意敏感设备信息
更改容量但通常可在线完成pvresize、lvextend、resize2fs(扩)、xfs_growfs备份、确认目标及业务低峰、验收
影响挂载/业务umount、mount、fstab 修改停写或维护窗口、回滚入口
高风险/破坏性mklabel、mkfs.*、lvreduce、lvremove、pvremove、xfs_repair -L需要明确审批、经验证备份及完整回退方案

11.2 日常命令对照

目标建议命令
查看块设备lsblk -f
设备标识blkid
分区表fdisk -l / parted ... print
查看 PV / VG / LVpvs / vgs / lvs
创建 PV / VG / LVpvcreate / vgcreate / lvcreate
VG 增加 PVvgextend
扩大分区growpart(满足条件时)
扩大 PVpvresize
扩大 LVlvextend
扩大 ext4resize2fs <设备>
扩大 XFSxfs_growfs <挂载点>
检查 ext4e2fsck(离线)
检查 XFSxfs_repair -n(离线)
挂载查询findmnt / df -hT
inodedf -i
开机挂载校验findmnt --verify --verbose
空间占用du -xhd1 / lsof +L1

11.3 生产变更检查清单

  1. 确认设备:记录当前块设备序列、UUID、VG/LV、挂载点、实际容量和业务进程。
  2. 有可恢复的备份:备份并验证恢复路径,特别是数据库、系统盘与不能直接缩容的 XFS。
  3. 先做只读检查:预测可用空间、文件系统类型、分区位置及 RAID/LUKS/thin pool 等特殊限制。
  4. 划清维护边界:在线扩容、离线缩容、挂载切换影响不同,安排对应窗口与监控。
  5. 逐层验证:每改完一层检查结果,不盲目连跑后续命令。
  6. 回退与验收:核对 df、findmnt、lvs、应用读写与重启挂载,预留旧卷或快照恢复通道。

参考资料

本文命令以 Linux 原生工具手册及发行版存储文档为主:

本文最后的建议:如果只记住一条原则,那就是——先识别块设备的实际层级,扩容按底层到上层,缩容必须先确认文件系统是否支持并做好离线备份;不要把 lvextend 的成功提示当成文件系统已经扩容。