CentOS磁盘扩容实战:LVM、分区、挂载与fstab全攻略
2026/9/24 18:22:42 网站建设 项目流程

磁盘满了这件事,基本每个搞过 Linux 运维的人都躲不掉。我上个月刚处理完一台 CentOS 老服务器的根分区告警,使用率飙到 97%,监控连续报警,业务日志写不进去。这次扩容过程踩了不少坑,也把几年前积累的一些经验重新捡了起来,索性整理成这篇记录,把 CentOS 挂载、分区、扩容的完整套路讲清楚。这篇文章适合刚接触 Linux 的新手,也适合那些平时不怎么碰磁盘操作、一遇到扩容就紧张的老运维。我会把 LVM 扩容、裸设备扩容、新盘挂载、fstab 持久化、常见坑和排查思路都过一遍,这些都是实际生产环境里真正用得到的东西。

1. 开工前先摸底:分区结构决定了扩容路线

1.1 先看磁盘使用率和文件系统类型

拿到一台磁盘告警的服务器,别急着敲fdisk,先按顺序做三件事:看使用率、看挂载结构、看文件系统类型。这三步的结果直接决定你后面用哪套扩容方案。

df -h lsblk blkid

df -h用来确认哪个分区满了,lsblk看整个磁盘的树形结构和挂载点,blkid看设备 UUID 和文件系统类型。这里特别要留意文件系统类型,因为 CentOS 7 默认用的是 xfs,CentOS 6 及以前常用 ext4,两种文件系统扩容时用的命令完全不一样。xfs 只能扩大不能缩小,ext4 虽然能缩但风险高,生产环境没人敢随便缩。

我处理过一台云服务器,根分区就是 xfs,同事直接拿 ext4 的resize2fs命令去扩,当场报错Bad magic number in super-block,其实就是文件系统类型不匹配。后面排查时还发现设备名也被认错了,整个操作完全没按实际情况来。所以说,开工前先确认这三个信息,比什么都重要。

1.2 分清 LVM 与裸设备:扩容路线完全不同

在 CentOS 里,磁盘分区有两种常见的组织方式:一种是直接用物理分区挂载,比如/dev/sda1挂到/boot,这种叫裸设备分区;另一种是通过 LVM(逻辑卷管理)来管理,比如/dev/mapper/centos-root挂到/,云服务器和大部分物理机装系统时默认走的都是 LVM。

判断方式很简单,看/dev/mapper/路径就知道。如果df -h显示的是/dev/mapper/xxx-root,说明根分区在 LVM 逻辑卷上;如果显示的是/dev/sda1,那就是普通分区。

LVM 的扩容逻辑可以理解为:物理硬盘是“原料仓”,卷组是一个“资源池”,逻辑卷是分配出去的“配额”。要扩容逻辑卷,先往资源池里加原料(新磁盘或新分区),再把资源池的容量划拨给逻辑卷,最后让文件系统感知到容量变化。裸设备的扩容就麻烦得多,因为它没有中间这层资源池,要么直接调分区大小,要么只能迁移数据。

我在实际工作中遇到的最大的坑,就是很多人不确认分区结构,上来就用 LVM 的命令去扩裸设备,或者反过来用分区工具动 LVM 的物理卷。结果要么操作不生效,要么在操作中途把系统搞崩。

2. 场景一:LVM 逻辑卷扩容,最顺滑的路线

2.1 新磁盘加入卷组:从 pvcreate 到 lvextend

假设你的 CentOS 是标准 LVM 安装,现在加了块新磁盘/dev/sdb,想把容量划给根分区,完整操作分五步,顺序不能乱。

第一步,确认新盘已被系统识别:

lsblk

如果没有看到/dev/sdb,可能是虚拟化平台的磁盘没有重新扫描,可以执行echo "- - -" > /sys/class/scsi_host/host0/scan或直接重启,云服务器一般控制台挂载后就能看到。

第二步,把整块盘或某个分区初始化为物理卷:

pvcreate /dev/sdb

如果要用整块盘做 PV,不需要分区,直接对磁盘初始化即可。但有些环境里更规范的做法是先分区再pvcreate /dev/sdb1,这样后续如果要多分区管理会更清晰。

第三步,把物理卷加入卷组。先确认卷组名:

vgs

CentOS 默认卷组名一般是centoscl,然后执行:

vgextend centos /dev/sdb

第四步,扩展逻辑卷。先看一下逻辑卷路径:

lvs

比如逻辑卷是/dev/mapper/centos-root,想把新盘全部空间加进去:

lvextend -l +100%FREE /dev/mapper/centos-root

这里的-l +100%FREE表示把卷组剩余的所有空间都分配给该逻辑卷。如果只想加指定大小,用-L +50G,注意+不能省略,表示增加,而不是扩充到某个绝对值。

第五步,调整文件系统大小。这是最关键的一步,xfs 和 ext4 命令不同:

# xfs 文件系统 xfs_growfs /dev/mapper/centos-root # ext4 文件系统 resize2fs /dev/mapper/centos-root

执行完再跑一下df -h,容量就变了。

2.2 虚拟机磁盘扩容后再分区建 PV

如果你用的是 VMware 或 VirtualBox,扩容通常不是加新盘,而是在虚拟化层面把原有虚拟磁盘调大。这种情况下原盘/dev/sda会多出一段未分配空间,要把它利用起来。

操作顺序是:虚拟机设置中扩大磁盘容量 -> 操作系统识别新空间 -> 创建新分区 -> 建 PV -> 加入卷组 -> 扩展逻辑卷 -> grow 文件系统。

系统里先确认空间是否被识别:

lsblk

如果显示的大小没变,执行下面的命令重新扫描 SCSI 设备:

echo 1 > /sys/class/scsi_device/0:0:0:0/device/rescan

然后创建分区。这里推荐用parted,因为它既能处理 MBR,也能处理 GPT,而且用起来更直观。假设新空间在/dev/sda的剩余部分:

parted /dev/sda # 进入交互界面后执行 print free mkpart primary ext4 40GB 100GB quit

分区号可能会是/dev/sda3(取决于原来有几个分区),创建后让它重新读取分区表,也可以重启或者执行partprobe /dev/sda

接着按 LVM 流程走:

pvcreate /dev/sda3 vgextend centos /dev/sda3 lvextend -l +100%FREE /dev/mapper/centos-root xfs_growfs /dev/mapper/centos-root

这套操作是完全在线进行的,不影响业务。不过有个细节要提醒,如果你用的是 MBR 分区表,主分区最多只能建四个,新的扩展分区请确保没有超过这个限制,否则分区表会拒绝写入。

2.3 在线扩容为什么必须 lvextend 和 grow 命令配合

我见过不少新手只做lvextend,不去执行文件系统扩大的操作,结果df -h里看到的容量根本没变化,于是怀疑自己操作失败。其实逻辑卷层面已经变大了,但文件系统还没有被“撑”到新的大小。

这里解释一下底层逻辑:逻辑卷扩容只是改变了逻辑卷设备的块设备大小,而文件系统是在块设备之上维护自己的元数据和空间管理信息。如果不主动让文件系统去感知新的大小,它依然以旧尺寸工作。xfs_growfsresize2fs就是干这个活的,而且它们都支持在线扩容,不用卸载分区。

实际操作中,我建议先搞清楚自己的文件系统再动手,别一上来就resize2fs。xfs 用resize2fs会直接报错,ext4 用xfs_growfs同样不行,两个工具互不兼容。

3. 场景二:非 LVM 裸设备分区的扩容

3.1 裸设备扩容为什么让人头大

如果你的磁盘没有走 LVM,比如/dev/sdb1直接挂载到某个目录,扩容的复杂度会立刻上升。裸设备的问题在于,每个分区的大小受限于它后面的相邻空间,如果相邻空间已经被占用,你没办法“中间插一脚”把它扩大。

更麻烦的是,有些服务器的根分区/也在裸设备上,它后面紧跟着的就是 swap 分区,两边互不相让,想扩根分区就不得不把 swap 挪走,整体操作风险极高。在生产环境我一般不建议动裸设备的现有分区结构,除非你有完整的备份和充分的维护窗口。

3.2 通过 parted 调整分区大小的实操流程

如果确认可以离线操作,或者分区后面确实有可用空间,可以用parted去调整分区大小。先看一下当前分区布局:

parted /dev/sdb print free

假设输出显示/dev/sdb1后面有一段 Free Space,就用 resizepart 指令来扩大:

parted /dev/sdb resizepart 1 100%

这里的1是分区号,100%表示扩展到磁盘末尾。执行完成后让内核重新读取分区表:

partprobe /dev/sdb

然后根据文件系统类型在线扩大:

# xfs xfs_growfs /mount/point # ext4 resize2fs /dev/sdb1

如果分区后面是已分配的空间,没有空闲区域,那就不是单纯调整分区大小能解决的了,只能把后面的分区删除重建(数据另存),或者放弃裸设备方案,迁移到 LVM。

这里强烈建议,新规划的服务器一律用 LVM。裸设备一时省事,以后扩容会加倍还回来。

3.3 实在没空间可扩时的补救方案

还有一种常见场景,磁盘本身已经满了,而且底层虚拟磁盘也没法在系统运行时扩大,连/都写不进新文件。这时候只能走临时挂盘的方案。

操作思路是,挂载一块新磁盘到系统里,把它格式化为目标文件系统,然后做数据迁移或目录绑定。具体做法可以参考下面第 4 节的挂载流程。如果只是想快速腾空间,可以把大文件目录迁移到新盘上,再用 bind mount 把新盘的目录映射回原路径,对用户无感知:

mkdir -p /data/newdisk mount /dev/sdc1 /data/newdisk rsync -av /var/lib/mysql/ /data/newdisk/ mount --bind /data/newdisk /var/lib/mysql

这种方式本质是换了个存储后端。但要注意,bind mount 不是永久的,需要写进/etc/fstab才能重启后保留。

4. 新增数据盘的挂载全流程,含 fstab 最佳实践

4.1 格式化、挂载、持久化一条龙

加数据盘和加根分区容量是两个概念。数据盘通常是独立分区或独立磁盘,挂载到新目录,逻辑上更清晰。流程如下:

第一步,确认设备名并格式化为目标文件系统:

lsblk mkfs.xfs /dev/sdc

这里用整块盘做文件系统不分区也是可以的,但如果生产环境建议分区,便于将来调整。格式化前一定想清楚设备名对不对,mkfs是毁灭性操作,写错盘符数据就没了。

第二步,创建挂载点并挂载:

mkdir -p /data mount /dev/sdc /data

第三步,确认挂载成功并设置开机自动挂载。先把 UUID 查出来:

blkid /dev/sdc

然后把下面这行写入/etc/fstab

UUID=你的UUID值 /data xfs defaults 0 0

写入前最好先备份一下/etc/fstab

cp /etc/fstab /etc/fstab.bak

第四步,测试 fstab 是否正确:

mount -a df -h

这一步是在不重启的情况下验证 fstab 的配置是否有误。如果mount -a报错,说明配置有问题,立即改正,避免重启后系统进不去。

4.2 为什么推荐用 UUID 而不是设备名挂载

很多老教程会教你写/dev/sdc /data xfs defaults 0 0,这在物理服务器上或许没问题,但在云服务器和虚拟化环境里非常危险。设备名不稳定,系统每次启动时设备的识别顺序可能不同,原来/dev/sdc可能变成/dev/sdd,结果就是挂载失败,或者更糟,挂错盘。

blkid输出的 UUID 是文件系统创建时唯一生成的标识,不会因为设备顺序变化而改变。因此 fstab 里优先用 UUID 挂载,这是一个非常值得养成的好习惯。

还有一个小细节,fstab 的最后一列“dump”和“fsck”两项,数据盘一般写0 0,表示不参与 dump 备份和开机自动 fsck,否则某些系统开机会因为 fsck 检查非 root 分区失败而卡在紧急模式。

4.3 挂载参数 defaults 和 noatime 的选择

defaults包含 rw、suid、dev、exec、auto、nouser、async 等选项,是一组最常用的默认挂载参数。对一般数据盘来说没问题,但对高 IO 负载的数据库或日志盘,我会额外加noatime,避免每次读取文件都更新访问时间戳,减少不必要的磁盘写入。

UUID=xxx /data xfs defaults,noatime 0 0

如果是数据库目录,还可以考虑barrier=1(xfs 默认开启)或者nobarrier这种性能取向的调整,但这不是通用建议,建议按实际场景测试后再用。

5. 常见问题与排查记录

5.1 典型问题速查表

现象大概率原因解决办法
resize2fsBad magic number in super-block文件系统是 xfs,用了 ext4 工具改用xfs_growfs
df -h没变化执行了 lvextend 但没执行 grow 文件系统按文件系统类型执行对应 grow 命令
parted创建分区提示无法识别磁盘原本无分区表,未初始化mklabel gpt再分区
fstab 写错导致开机进入 emergency mode挂载项有误或设备不存在输入 root 密码执行mount -o remount,rw /后修改 fstab
mkfs报设备忙磁盘已被挂载使用umount再格式化
大于 2T 的盘无法使用fdisk分区MBR 分区表最大只支持 2Tparted切 GPT 分区表
扩容后根分区容量仍在 100%可能有已删除但未释放的文件lsof | grep deleted排查并重启对应进程

5.2 扩容实战中容易忽略的几个细节

第一次给客户虚拟机扩容时,我在parted里创建了分区,结果系统里看不到新的分区名/dev/sda3。后来发现是内核还没有重新读取分区表,执行partprobe后问题解决。这个细节现在看起来很基础,但第一次遇到时真的会卡很久。

还有一次是 fstab 里用了设备名挂载,结果服务器重启后设备顺序变了,系统直接进入了维护模式。当时是异地机房,幸好可以远程进入紧急模式才把 fstab 改回来。从那以后我坚持所有 fstab 配置都使用 UUID。

另一个常见问题是磁盘满了之后,服务的表现往往不是“写不进去”那么直接。数据库可能一直报 read-only 表,Java 应用可能卡在文件写入上不报错,df -h一看才发现根分区 100%。下次如果你遇到服务无规律异常,先看一眼磁盘使用率,很多疑难杂症其实都是磁盘满导致的。

5.3 检查文件系统是否真的扩容成功

扩容完别急着收工,做一次完整验证:

df -h pvs vgs lvs

如果 pvs 里的物理卷容量正常,vgs 里卷组容量变大了,但逻辑卷没有变大,说明lvextend没执行成功。如果逻辑卷变大了但df -h没变化,说明 grow 文件系统那一步没做或者没生效。

对 xfs 文件系统,可以额外用xfs_info /mount/point查看文件系统的真实大小,确认 grow 后的数据块数量和df输出一致。

6. 结尾的一点个人经验

这次扩容记录写下来,最大的感受是 CentOS 磁盘管理核心就三件事:确认现状、选择正确路线、按顺序执行。LVM 方案确实省心,但前提是最初装系统时选了 LVM 布局。如果你手里还有老服务器用的是裸设备,我建议找维护窗口做一次数据迁移,把关键业务目录整合到 LVM 或者新盘上,一劳永逸。

最后再分享一个小技巧:扩容前一定先看/etc/fstab内容,确认现有挂载项是设备名还是 UUID。如果是设备名,顺手改成 UUID,别等出问题再后悔。磁盘操作虽然不像删库那么高危,但一旦操作目标写错,后果一样严重。每次执行mkfspvcreateresizepart之前,默念一遍“设备名对不对”,能帮你省掉无数麻烦。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询