拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CentOS7新盘挂载与LVM扩容:分区、格式化、fstab实战

CentOS7新盘挂载与LVM扩容:分区、格式化、fstab实战

1. 服务器加了块盘,为什么系统里看不到

机房那台老业务机最近天天报磁盘告警,df -h一看根分区已经吃到 92%,日志都快写不进去了。跟运维申请了一块 500G 的新盘,插上去之后兴冲冲敲df -h,结果什么都没多出来。这种情况我第一次遇到的时候也懵了几分钟——硬盘明明插了,BIOS 里也能认到,为什么系统里连个影子都没有?

答案其实很简单:物理上接了盘,不等于操作系统上能直接用它。一块裸盘从硬件到能存文件,中间要经过分区、格式化文件系统、挂载三个动作,每一步都有它存在的理由。很多人(包括几年前的我)以为新盘插上就能用,是因为平时用的 U 盘、移动硬盘出厂时厂家已经帮你把这三步做完了一半——它们预置了分区表和文件系统,插上即识别。服务器上采购的裸盘不会替你干这些活,得自己来。

这篇内容主要讲清楚两件事:一块全新的数据盘怎么从零挂载到 CentOS7 上正常使用,以及当原有分区空间不够时,怎么在不动数据的前提下把新盘的空间扩进去。前者是"从无到有",后者是"从小到大"。写这篇文章的初衷是我在带新人的时候发现,很多人会挂载但不会扩容,会扩容又搞不清楚pv、vg、lv这套逻辑关系。文中所有命令我都在 CentOS 7.9 上实测过,同时也会把 Ubuntu 这类发行版的差异点标出来,方便你换环境时对照。

2. 动手之前,先把 lsblk 和 fdisk 的脾气摸清

2.1 找盘:为什么别名要认 /dev/sdb 而不是 /dev/sda

新盘接上之后第一件事不是急着分区,而是确认系统到底认没认到这块盘、它被分配了哪个设备名。lsblk是我最推荐的第一个命令,输出干净,一眼能看出设备树的层级关系:

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 99G 0 part ├─centos-root 253:0 0 50G 0 lvm / └─centos-swap 253:1 0 49G 0 lvm [SWAP] sdb 8:16 0 500G 0 disk

注意最后那行sdb后面没有 part、没有 MOUNTPOINT,这说明它是一块还没被使用的裸盘,正是我们要操作的盘。这里有个经验:sda通常是系统盘,能不动就不动;新增的数据盘基本都是sdb、sdc往后的字母。但设备名不是永久不变的,它会受插槽、控制器扫描顺序影响,机器重启或者换插槽后sdb有可能变成sdc。所以后面挂载时不要用/dev/sdb这种设备名写死到/etc/fstab,要用 UUID,这个坑我后面会专门说。

再补一个fdisk -l看更详细的信息:

fdisk -l /dev/sdb

如果你敲完发现根本没有sdb这一段,那说明系统还没扫描到新硬件。这种情况不用重启,用下面这条命令让内核重新扫描 SCSI 总线就行:

echo "- - -" > /sys/class/scsi_host/host0/scan

如果 host0 没反应,就依次试 host1、host2,或者用ls /sys/class/scsi_host/看看到底有哪些 host。

2.2 分区:MBR 和 GPT 到底选哪个

确认盘认到了之后,接下来是分区。这一步很多人会问:我就挂一块盘存数据,能不能不分区直接用?技术上可以,直接mkfs.ext4 /dev/sdb也行,但我强烈建议还是分一个区。原因是很多工具、备份软件、监控脚本都假设磁盘有分区表,裸设备直接用有时候会踩到一些奇怪的兼容问题。分区成本很低,没必要省这一步。

选分区表格式的时候有个判断标准:盘容量超过 2T 就必须用 GPT。MBR 分区表受限于 32 位寻址,单盘最大只能识别到 2T 左右,而且主分区最多 4 个。500G 这种盘两种都行,但既然 GPT 是现在的主流,没有特殊下游系统兼容要求的话直接上 GPT 更省心。

用parted做 GPT 分区:

parted /dev/sdb (parted) mklabel gpt (parted) mkpart primary ext4 0% 100% (parted) print (parted) quit

mkpart里的0% 100%是相对单位,表示从盘头到盘尾,这样不用去算具体扇区号。如果你的系统上压根没装 parted(最小化安装经常没有),用fdisk交互式操作也完全没问题:

fdisk /dev/sdb # 依次输入:n(新建)p(主分区)1(分区号)回车(默认起始)回车(默认结束)w(保存)

保存之后内核会提示需要重新读取分区表,有时候执行partprobe /dev/sdb或者partx -a /dev/sdb让它生效,避免后面格式化时提示"找不到设备"。

2.3 格式化:文件系统选 xfs 还是 ext4

CentOS 7 时代默认文件系统是 XFS,这也是 RedHat 系从 RHEL7 开始全面转向 XFS 的原因。XFS 在超大文件、高并发读写、在线扩容方面表现比 ext4 更稳,尤其适合数据库、日志这类场景。ext4 的优势在于生态老、工具链成熟、删除恢复方案多。

我的选择习惯是这样:

  • 纯数据盘、存文件、存日志、做备份:XFS,CentOS7 下省事,也是官方默认。
  • 有大量小文件并且需要频繁fsck检查:ext4 会更顺手,修复时间相对短。
  • 担心后期要缩容:注意 XFS不支持缩小,只能扩不能缩;ext4 支持缩容但流程繁琐。如果业务上确实有缩容预期,选 ext4 并规划得保守一点。

格式化的命令:

# XFS mkfs.xfs /dev/sdb1 # 或者 ext4 mkfs.ext4 /dev/sdb1

mkfs.xfs默认会给你一个比较均衡的参数,一般不建议乱改su、sw这些条带参数,除非你清楚底层阵列的几何结构。我有次为了"优化"给一块 RAID 盘手动设了 stripe 参数,结果反而比默认慢,后来老老实实退回默认值。

3. 临时挂载和开机自动挂载,差别不止一个 -a

3.1 临时挂载:先用 mount 验证一次再写配置

格式化完不要直接改/etc/fstab,先用mount手动挂一次,确认盘真的能用:

mkdir -p /data mount /dev/sdb1 /data df -h | grep data

能正常看到/data的容量和使用率,说明从分区到文件系统这一整条链路是通的。如果这一步就报错,那就先别往下走,回去查格式化和分区有没有问题。

临时挂载的缺点是重启就丢——挂载关系只存在内存里,系统一重启就没了。所以真正要长期使用,必须写进/etc/fstab。

3.2 写 fstab 之前,先拿到 UUID

这是我在生产环境里见过最多故障的一个点。很多人图省事直接在 fstab 里写/dev/sdb1 /data xfs defaults 0 0,然后某天换了个插槽或者加了新盘,设备名顺序一变,sdb1变成了系统盘上别的分区,系统直接进不去救援模式,只能挂光盘进去改 fstab。

正确的做法是用 UUID:

blkid /dev/sdb1

输出类似:

/dev/sdb1: UUID="a1b2c3d4-xxxx-xxxx-xxxx-xxxxxxxxxxxx" TYPE="xfs"

把这串 UUID 抄进 fstab:

UUID=a1b2c3d4-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data xfs defaults 0 0

fstab 的六个字段分别是:设备标识、挂载点、文件系统类型、挂载参数、dump 备份标志、fsck 检查顺序。最后两个字段基本都是0 0,数据盘不需要开机 fsck,设成 0 能让开机快一点,也避免大容量盘 fsck 卡住启动。

3.3 用 mount -a 验证而不是直接重启

写完 fstab 之后千万别直接重启去验,重启失败就要进救援模式了。正确姿势是用:

mount -a

它会把 fstab 里所有还没挂载的条目都挂一遍,有语法错误或者 UUID 写错会当场报错,不会等到重启才暴露。报错信息一般很直白,告诉你哪一行有问题。确认mount -a无报错、df -h能看到新挂载点,再去做别的。

提示:如果你的挂载点路径之前已经有数据(比如/data目录下本来就有一堆文件),挂载之后这些文件会被"遮住",实际访问的是新盘的目录。要么提前把原目录清空,要么换个空目录当挂载点。

还有一个隐藏细节:写进 fstab 的挂载选项里,defaults其实是个很多选项的集合,包含rw、suid、dev、exec、auto、nouser、async。如果这块盘只是用来存备份、不需要执行任何程序,加上noexec,nosuid会更安全一些,能防止有人在上面放个脚本被意外执行。

4. LVM 才是扩容的真正主角

4.1 为什么扩容要绕道 LVM,而不是直接 resize

上面讲的是"新盘挂载",属于从无到有。但更常见也更让人头疼的场景是:某个已有分区(尤其根分区/或者/home)空间快满了,想把新加的硬盘容量扩进去。这个场景下如果原来是直接分区格式化的(比如/dev/sda2直接是 ext4),扩容会非常别扭,因为设备是固定大小,往里扩没有中间层可以周转。

LVM(逻辑卷管理)解决的正是这个问题。它通过三层抽象把物理磁盘和最终文件系统解耦:

层级全称作用
PVPhysical Volume 物理卷把物理分区/磁盘标记为 LVM 可用
VGVolume Group 卷组由多个 PV 组成的"存储池",容量可动态增减
LVLogical Volume 逻辑卷从 VG 里切出来的"虚拟分区",就是最终格式化的对象

理解这三层之后,扩容的逻辑就变得非常自然:新硬盘先变成 PV,加入已有的 VG 扩容存储池,再从 VG 里给目标 LV 分空间,最后对文件系统做扩容让系统认这块新空间。整个过程原有数据完全不动,也不需要卸载分区。

用pvs、vgs、lvs三个命令可以快速看当前 LVM 布局:

pvs vgs lvs

CentOS 7 默认装系统时就会建一个叫centos的卷组,根分区/是里面的root逻辑卷。这就是为什么很多人发现自己的根分区明明没分区,却能被 LVM 管理着。

4.2 从新盘到还能用的额外空间,完整链路

假设我们要把新的 500G 盘(/dev/sdb)加进现有 VG,并把空间全部分给根分区。整个链路是这样:

# 1. 把新盘做成 PV pvcreate /dev/sdb # 2. 查看现有 VG 名字(假设是 centos) vgs # 3. 把新 PV 加入 VG vgextend centos /dev/sdb # 4. 确认 VG 空间已经变大 vgs # 5. 给根 LV 扩容,lvextend 加 -r 会自动同步扩容文件系统 lvextend -r -l +100%FREE /dev/centos/root

第 5 步的-l +100%FREE表示把 VG 里剩余的所有空闲空间都加给这个 LV。如果你不想全用完、要留一部分给别的 LV,可以写-L +200G这样的绝对大小。-r参数是最省事的技巧,它会自动调用xfs_growfs或resize2fs把文件系统同步扩上去,省得你手动再执行一次文件系统扩容命令。

如果不用-r,那就要分两步走:

# 先扩 LV lvextend -l +100%FREE /dev/centos/root # XFS 用这个 xfs_growfs / # ext4 用这个 resize2fs /dev/centos/root

这里有个新手最容易踩的坑:lvextend只是把逻辑卷的边界扩大了,文件系统本身并不知道,所以df -h看到的容量还是老的。必须执行xfs_growfs或resize2fs,df -h才会显示新容量。我第一次扩容的时候就在这一步卡了半天,还以为扩容失败了。

注意 XFS 的xfs_growfs参数是挂载点(比如/),而 ext4 的resize2fs参数是设备路径(比如/dev/centos/root或/dev/sdb1),这俩别搞混,弄错会报错。

4.3 新盘不加入老 VG 的另一种做法

不是所有场景都适合把新盘塞进已有 VG。如果你的目的是新建一个独立的挂载点,比如把备份数据、日志数据单独放一块盘上,便于管理和迁移,那就不要动 LVM,直接按第 2、3 节的流程走分区、格式化、挂载就行。

判断标准很简单:

  • 目标是把新空间并到已有分区(比如/或/home不够用)→ 走 LVM 扩容链路。
  • 目标是新开一个独立的数据目录(比如/backup、/data2)→ 直接挂载新盘,不用碰 LVM。

我个人的项目里,业务数据的盘倾向独立挂载,方便单独做快照备份和故障隔离;系统盘和运行目录则用 LVM,方便后期统一扩容。

5. 几个我实际踩过、文档里不会写的坑

5.1 扩容前忘了留空间,swap 被吃掉了

有次给一台测试机扩容,我用lvextend -l +100%FREE /dev/centos/root把 VG 掏得一干二净,结果后来发现这台机器 memory 偏小、swap 用得很勤,需要扩 swap 的时候发现 VG 里一点空闲都没有了,只能再加新盘。这个教训是:如果 VG 里还有别的 LV(尤其 swap),扩容前先vgs看一眼空闲空间,用-L +xxxG精确给量,不要无脑+100%FREE。

5.2 /etc/fstab 用设备名,重启后系统进不去

前面提过一次,这里再强调,因为它真的是最高频的生产事故。设备名会变,UUID 不会变。养成习惯:fstab 里一律写 UUID。如果已经写错了导致系统起不来,进救援模式后要先用mount -o remount,rw /让根分区可写,再改 fstab。

5.3 分区后忘记 partprobe,格式化报"设备不存在"

用 fdisk 建完分区,有时候/dev/sdb1这个设备节点还没被内核创建出来,直接mkfs.xfs /dev/sdb1会提示 No such file or directory。这时候执行:

partprobe /dev/sdb

或者:

partx -a /dev/sdb

内核重新读一遍分区表,设备节点就有了。

5.4 XFS 不能缩容,别指望 reverse

经常有人问怎么把 XFS 的分区缩小。答案是不能缩,只能通过xfsdump备份数据、重建小分区、xfsrestore还原这个笨办法。所以规划 XFS 分区时宁可小一点,后期加盘扩容,也不要一开始就分得很大然后想缩。ext4 虽然支持缩容,但必须先umount,而且缩容前要e2fsck检查,流程也不轻松。

5.5 挂载点如果有旧数据会被隐藏

挂载一个盘到已经存在的非空目录,原目录的内容会被临时隐藏,df看的是新盘的容量,但原数据其实还在那个目录的底层。如果你挂载后发现"文件没了",别慌,先umount再看看。要避免这种情况,挂载点用专门新建的空目录。

5.6 虚拟机环境下的额外一步

如果你是在 VMware 或 VirtualBox 里做实验,光在虚拟机的"硬件设置"里加了新盘还不够。VMware 下加完盘一般能热识别,但部分版本需要重启虚拟机;VirtualBox 加完盘基本都建议重启一次,或者用echo "- - -" > /sys/class/scsi_host/host0/scan手动触发扫描。我见过好几次在图形界面加了盘、进去lsblk死活看不到,纠结半天最后才发现虚拟机需要重启。

6. 一套可以直接抄走的验证清单

每次挂载或扩容做完,我都会习惯性走一遍下面这套检查,三分钟之内就能确认一切正常:

检查项命令预期结果
设备是否识别lsblk新盘出现在列表里,有分区和挂载点
容量是否正确df -h挂载点容量和磁盘实际大小吻合
fstab 语法是否正确mount -a无任何报错输出
开机挂载是否生效findmnt /data能看到挂载源是 UUID=xxx
扩容后文件系统是否同步df -h对比lvsLV 大小和 df 显示容量一致
是否有磁盘错误dmesg -T | tail -50没有 I/O error、EXT4-fs error 之类

findmnt这个命令比mount | grep好用,输出结构化,能直接看到挂载源、挂载点、文件系统类型和挂载选项,排查 fstab 问题特别顺手。

另外,如果要把这套流程做成可复用脚本,我一般会加set -e让任何一步失败就立刻停止,避免在某个命令失败之后继续往下执行把盘搞得更乱。磁盘操作这种东西,出错的前一步和出错的这一步之间往往就差一个回车,谨慎比什么都重要。

Ubuntu 环境下有个小差异:默认文件系统是 ext4,LVM 卷组名通常是ubuntu-vg,逻辑卷是ubuntu-lv。另外 Ubuntu 上分区工具用fdisk或parted都行,但xfs_growfs默认可能没装,需要apt install xfsprogs。这些差异不影响整体思路,只是命令里的名字和包名要对照着换。

我个人的经验是,磁盘这块的东西一次搞懂、反复受用。分区、格式化、挂载、LVM 扩容这套链路看起来步骤不少,但本质上就是一句话:把一块物理盘变成能用的存储空间,需要一层层往上叠抽象。理解了 PV、VG、LV 的分层逻辑,扩容就不再是靠背命令,而是能自己推出来下一步该干什么。下次再遇到"加盘了但是看不到"这种问题,你应该能条件反射地先问一句:是盘没识别,还是分区没建,还是只是挂载关系还没配。

返回列表