不懂LVM的时候,我吃过一个很大的亏:系统盘就分了一个根分区,数据盘也是纯物理分区挂载,跑了大半年的业务,磁盘满了,想扩容,结果发现分区后面没有预留空间,只能停机,用U盘进Live系统,小心翼翼地把分区往后挪。那次维护窗口排了整整一夜,整个人都是麻的。后来把新服务器全部切到LVM,才算是从这种拆东墙补西墙的被动局面里彻底解脱出来。这篇文章记录的,就是我在Linux环境里从零配置LVM、做挂载、再完成在线扩容的完整过程,其中每一个操作、每一段命令,都是实际跑过的,不是从网上抄来的。
如果你手头只有一台测试机,或者正在规划生产环境的磁盘方案,这篇内容都适合你。读完你会知道LVM是怎么解决“分区不给力”这个问题的,也会拿到一套可以直接照做的命令流程,甚至能避开我当年踩过的好几个坑。
1. LVM到底解决了什么问题
1.1 传统分区的痛点:为什么大家开始用LVM
在没有LVM的年代,磁盘管理是件很“刚性”的事。一块硬盘物理上有多大,你能用的分区空间就多大。装系统的时候,你说给/home分500GB,它就固定500GB;等业务跑起来,发现/var/log把空间吃完了,而/home那边还剩300GB闲着,你想把这300GB匀给/var/log,对不起,做不到。
传统分区还有一个更让人头疼的限制:一个分区大小不能超过它所在磁盘的容量。数据盘是2TB的,分区最大就是2TB,想要更大的单个文件系统,得做RAID或者硬件阵列,成本直接上去了。
而且,调整分区大小本身也是高危操作。fdisk删掉分区重建,搞不好文件系统就废了;哪怕是GParted这类图形工具,对已经在使用的分区做大范围调整,也得先卸载、再离线操作,停机几乎是必然的。对线上业务来说,这基本等同于事故。
LVM的理念就是绕开这些限制。它的核心思路是:不要直接拿物理分区当文件系统容器,而是先让物理分区变成“原材料”,再在这个原材料之上建一个抽象的“空间池子”,最后从池子里切出逻辑空间给文件系统用。这样以来,物理磁盘的大小、数量变化,都不会直接冲击上层文件系统,扩容、迁移、缩容都变得灵活很多。
1.2 LVM的核心组成:PV、VG、LE/PE与LV
理解LVM的关键是四个缩写:PV、VG、LV,还有这个LE(有的地方也叫PE)。
物理卷PV(Physical Volume)是最底层的概念。它本质上就是一块硬盘,或者硬盘上的一个分区,只不过被pvcreate命令初始化过,写入了LVM自己的元数据。初始化之后,这块硬盘就不再是普通的“存储介质”,而变成了LVM可以识别的“原材料”。
卷组VG(Volume Group)是PV的集合。你可以把VG理解成一个“存储资源池”。三块4TB的硬盘,各自做成PV,然后再把它们加进同一个VG,这个池子的总容量就是12TB。VG最重要的特性是:它屏蔽了下层物理磁盘的边界,往上提供的是一个动态的、连续的空间池。
逻辑卷LV(Logical Volume)就是从VG池子里切出来的逻辑分区。怎么切、切多大,完全由你说了算。LV创建之后,它的角色等价于传统分区里的/dev/sda1或/dev/sdb2,但它的底层对应关系却要灵活得多,一个LV的数据可以横跨多块物理硬盘,也可以只落在其中一小块区域上。
PE(Physical Extent)和LE(Logical Extent)是LVM内部管理空间的基本单位。VG组建的时候,空间会被均匀切成4MB大小的小块,这些小块叫PE;LV里的对应单位叫LE。打个比方:VG是一整盒乐高积木,PE就是每一颗积木块,LV就是你用这些积木搭出来的模型,lvextend就是往模型上继续拼接积木,不需要重新搭地基。
1.3 LVM的优势:用生活类比拆解核心价值
很多人第一次接触LVM,觉得概念绕。我习惯用一个仓库的类比来解释。
假设你开了家工厂,需要原材料仓库。传统分区方案相当于:你买了一个固定大小的库房,这个库房只能放一种零件,放满了就得再买整个库房,而且不同库房之间的物料不能互相借用。LVM则像是你租了一个大的物流园区,园区里有好几栋库房(PV),你并不关心零件具体存在哪栋楼里,只关心“仓储池”(VG)总共有多少面积,然后按需划一块区域(LV)给你的产线用。产线要多备货了,就从池子里再划一块地出来,不用动其他产线。
这个类比背后藏着一个核心优势:LVM把“物理存储边界”和“逻辑空间边界”彻底解耦了。对上层应用来说,它看到的只是LV,无论这个LV背后是一块1TB磁盘还是由两块3TB磁盘拼起来的,都不重要;而改变LV的大小,也不影响物理磁盘本身的布局,只要池子里有剩余空间。
LVM还有一个很实用的“隐藏技能”——快照。在LVM的机制里,你可以给一个LV创建快照,这个快照记录了LV在某一时刻的数据状态,而且首次创建快照时几乎不占空间,后续只有被修改的数据块才会被复制。这意味着你在给数据库做备份、或者准备执行高风险变更之前,可以先拍一个快照,万一操作出错,10秒就能回滚。这个功能在传统分区方案下基本没法做到,是LVM让我觉得“这个机制值得用”的最重要理由之一。
2. 环境准备与基础卷创建
2.1 磁盘规划与应用场景适配
开始动手之前,先确认两件事:操作系统里认出了几块盘,以及这些盘的分区表类型。执行lsblk看整体拓扑,再执行fdisk -l看看有没有异常盘。下面是一份典型的输出:
$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 200G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 199G 0 part / sdb 8:16 0 2T 0 disk sdc 8:32 0 2T 0 disk这个环境里,sdb和sdc是两块全新的2TB数据盘,专门拿来给数据目录用。我的规划是:把这两块盘都做成PV,然后加入同一个VG,最后切成一个2TB的LV挂到/data。之所以不是切4TB,是想先留一半空间在池子里,给后面在线扩容做演示,留着余地,这也是线上环境里一个很实用的习惯。
这里要特别提一下分区表的选择。如果你的磁盘容量超过2TB,建议直接用GPT分区表,不要再碰MBR。MBR虽然兼容性好,但它最多识别2TB,而且在一些老机器的BIOS环境下会有奇奇怪怪的限制。用parted或者fdisk都能做GPT,操作前要确认你的服务器主板和系统内核都支持GPT引导,数据盘一般没有问题,系统盘如果要做GPT,引导方式得改成UEFI,这个要提前规划好。
如果你拿到的是一块已经存在分区表的盘,先别急着pvcreate。用wipefs -a /dev/sdb把旧的签名清掉,防止后续LVM元数据和旧文件系统签名打架。
2.2 PV与VG创建:从裸盘到存储池
环境准备好之后,第一步是把物理盘初始化为物理卷。这一步执行后就完成了物理卷的标记:
# 初始化物理卷 pvcreate /dev/sdb /dev/sdc如果提示“Device /dev/sdb not found (or ignored by filtering)”,多半是multipath或者udev的过滤规则在干扰,可以试试用pvcreate --metadatasize 128M --device /dev/sdb这种带参数的命令,也可以直接查看/etc/lvm/lvm.conf里的filter配置。实在不行,先执行partprobe刷新一下分区表再重试。
第二步是把PV加入卷组。将选定的物理卷组成卷组vgdata:
# 创建卷组,名字叫vgdata vgcreate vgdata /dev/sdb /dev/sdc这里的vgdata是卷组名称,可以自由指定,但建议用有意义的命名,比如vgdata、vgbackup,不要用vg0这种模糊的名字,服务器多了以后,命名规范能省很多排查时间。
创建完成后,用vgdisplay vgdata查看卷组信息,重点关注Free PE / Size这一项,这就是池子里还能用的空间。如果显示“Free PE / Size 102398 / 3.99 TiB”类似字样,说明两块2TB盘已经成功融进池子了。
这一步有个很容易出问题的地方:如果你之前把sdb和sdc做成过其他VG或者RAID成员,直接vgcreate可能报“Physical volume /dev/sdb is already in a volume group”之类的错。这时要确认这块盘确实不需要保留原有数据,然后用vgreduce、pvremove把旧信息清理掉再重新创建。
2.3 创建LV与文件系统选型
池子有了,接下来从池子取出4TB中的2TB来做逻辑卷:
# 创建逻辑卷,大小2TB,名称lvdata lvcreate -L 2T -n lvdata vgdata创建完的LV设备路径出现在/dev/mapper/vgdata-lvdata下。有些旧习惯会用/dev/vgdata/lvdata这个路径,它在部分发行版上也存在,但推荐直接使用/dev/mapper路径,解析最可靠,不会因为符号链接变化而掉链子。
接下来的动作是格式化。文件系统的选择直接决定你后面扩容时用哪个命令:
- ext4:老牌稳定,支持在线扩容和在线缩容(缩容虽然不建议,但至少支持)。
- xfs:当前Red Hat系和很多云厂商的默认首选,性能好、扩展性强,但只能扩容,不能缩容。
- btrfs:自带子卷、快照、校验和,功能很全,但高负载场景下的稳定性和运维生态还差一点,需要谨慎评估。
我自己的习惯是:如果只是普通数据目录,用xfs;如果是跑MySQL等数据库,或者对缩容能力有执念,用ext4。命令分别如下:
# 格式化为xfs mkfs.xfs /dev/mapper/vgdata-lvdata # 格式化为ext4 mkfs.ext4 /dev/mapper/vgdata-lvdata格式化之前,务必确认这个设备路径下面没有你还要的数据,mkfs是一个“确认即毁灭”的操作,不看清楚就执行,翻车概率接近百分之百。
3. 挂载与开机自启:关于重启后消失的问题
3.1 手动挂载的基础操作
文件系统创建好了,但系统不会自动知道它,需要通过挂载动作把LV关联到目录上。先建一个挂载点,标准的做法是用目录的“语义”来命名,比如数据就放在/data:
mkdir -p /data mount /dev/mapper/vgdata-lvdata /data执行完mount之后,用df -hT查看一下,看到/dev/mapper/vgdata-lvdata挂载在/data、文件系统类型是xfs或者ext4,就说明第一步成功了。这里一个小细节:df -hT里的T参数会显示文件系统类型,排查问题的时候非常有用,很多人习惯只用-h,结果类型和inode信息都看不到,遇到异常会比较被动。
挂载完成后,可以测一下读写,确认文件系统真的能用:
echo "lvm test" > /data/test.txt cat /data/test.txt rm -f /data/test.txt读写正常,说明挂载链路是通的。但这时候还有一个隐患:如果你现在重启机器,这个挂载关系会直接丢失,/data目录会变成一个普通的空目录,里面的数据“看起来”好像不见了。要解决这个问题,得把它写进fstab。
3.2 fstab配置:实现开机自动挂载
在线下环境或者虚拟机里,很多人都会遇到“mount挂载新硬盘重启没了”的尴尬。其实问题的答案很简单:你少了fstab这一步。Linux开机时会读取/etc/fstab,按里面的配置自动挂载文件系统,不配置就意味着每次开机都要手动mount。
我推荐先获取设备的UUID,再用UUID写fstab,因为设备路径(如/dev/sdb)在系统重启后可能因为内核识别顺序变化而改变,UUID则是文件系统创建时生成的唯一标识,稳定得多:
# 查看文件系统UUID blkid /dev/mapper/vgdata-lvdata输出里有一个UUID=xxxx-xxxx-xxxx,把这段记下来。然后编辑/etc/fstab,追加一行:
UUID=xxxx-xxxx-xxxx /data xfs defaults 0 0对于ext4文件系统,对应改为:
UUID=xxxx-xxxx-xxxx /data ext4 defaults 0 0然后执行mount -a测试fstab配置是否正确。mount -a会读取fstab里所有尚未挂载的条目并尝试挂载,如果这一行配置有问题,mount -a会立刻报错,不会等到重启才发现。
注意:执行mount -a之前,务必先确保这行配置没问题。如果fstab写错了,开机过程可能会卡在“Waiting for device”阶段,系统要等timeout才能继续进,轻则启动变慢,重则直接进入emergency mode。最稳的做法是:先手动umount /data,再mount -a,如果挂载成功,说明fstab配置是正确的,再重启也不迟。
3.3 关于UUID、设备名和文件系统参数的选择
写fstab时还有几个常见的选项,我逐个说下含义和适用场景。
defaults包括了rw、suid、dev、exec、auto、nouser、async这些常规选项,绝大多数场景直接用defaults就够了。如果有特殊需求,比如禁止执行二进制文件,可以追加noexec;如果挂载的目录要被多个用户同时读写,可以追加nofail,这样设备不存在时系统不会卡启动。nofail这个选项,对移动硬盘、U盘这类随时可能拔掉的设备特别有用,但对服务器上的数据盘,我反而不太推荐nofail,因为一旦磁盘异常,它可能掩盖问题,让你以为数据还稳稳地在上面,实际上底下的盘已经丢了,没有任何报警。
还有一个在云服务器上很常见的选项是_netdev,它告诉系统等网络就绪后再挂载。如果你的LV底层依赖网络存储(比如iSCSI、云盘),fstab里最好加上这个选项。但普通的本地LVM卷,不需要_netdev,写上去反而可能让系统启动时多等一轮网络状态检测,拖慢启动速度。
fstab写完之后,重启验证一次,这是确认配置正确最不折腾的方式。如果不方便重启,也可以执行systemctl daemon-reload之后再mount -a,但这无法完整模拟开机时的挂载时序,所以有条件的话还是建议重启。
4. 在线扩容完整实操:从LV到文件系统一步到位
4.1 扩容前的准备:给/etc/fstab留好安全带
现在到了这篇文章的重头戏——在线扩容。LVM最吸引人的能力之一就在这里:不用停机,不用卸载分区,就可以把LV和文件系统扩大。
但先别急着敲命令,有两个准备工作必须做。
第一,确认你的VG里确实还有空闲空间。用vgdisplay vgdata,看Free PE这一项,如果数量为0,那扩容就无从谈起。磁盘满了想扩容,但池子里也没空间,这时候的下一步是:加一块新硬盘,pvcreate /dev/sdd,vgextend vgdata /dev/sdd,然后才轮到lvextend。这也是LVM比分区好的地方——新盘加进池子,整个过程对上层文件系统完全透明。
第二,写一个“回家的路”。扩容过程中,如果因为断电、内核崩溃等原因导致元数据异常,重启后系统可能找不到LV。这时fstab里的配置不会变,但LV设备要能正常激活。这里有一个值得长期养成的习惯:把当前LVM的元数据做一次备份。
vgcfgbackup -f /root/vgdata-backup-$(date +%F).txt vgdata这行命令会把vgdata的元数据导出到一个文本文件,最多也就是几十KB。真出问题的时候,vgcfgrestore可以把它原样恢复回来。我见过一个案例,机房断电后LVM元数据损坏,因为没有备份,只能手动重建PV、VG、LV,数据能不能完整找回全靠运气。备份一个文本文件只要一秒钟,别偷懒。
另外,扩容前最好看一眼文件系统的已用空间和当前总容量:
df -hT /data记录一下扩容前的状态,后面好对照验证。
4.2 lvextend与resize文件系统:在线扩容的核心命令
假设现在/data的LV是2TB,池子里还有2TB空闲。我要把LV扩大到3TB,先执行lvextend:
# 扩展到3TB lvextend -L 3T /dev/mapper/vgdata-lvdata注意,lvextend -L 3T的含义是“把LV扩大到3TB”,而lvextend -L +1T的含义是“增加1TB”。差一个加号,结果完全不同。很多人扩容时没想清楚这个,多执行一次,容量直接变成4TB,虽然不至于出错,但会让你误以为自己的空间预算比实际宽松很多。
lvextend执行完之后,lvdisplay或者lvs看一下LV大小,确认LV层面已经是3T了。但此时文件系统还没变,df -hT看到的容量依然是2T。因为LV变大了,但文件系统还没有感知到这个变化。要让文件系统“吃下”新增的空间,还得执行文件系统级别的扩容操作。
如果你是ext4:
resize2fs /dev/mapper/vgdata-lvdata如果你是xfs:
xfs_growfs /dataext4的resize2fs可以不指定参数,它会自动把所有可用空间扩展进文件系统;xfs的xfs_growfs则需要指定挂载点,它的作用是让挂载在这个目录下的文件系统扩展到对应LV的最大容量。一个常见的问题是搞混了这两个命令,ext4的挂在/dev/mapper设备名上,xfs的挂在挂载点上,记反了就会报错。
执行完,再df -hT看看,容量应该已经变成3T了。整个过程不用卸载、不用重启、不影响正在写入的进程。这就是在线扩容的核心操作,两条命令而已。
这里有一个既关键又容易被忽略的点:很多教程会说“先lvextend,再resize2fs/xfs_growfs”,但在某些版本里,lvextend已经支持-r参数,可以一步完成LV和文件系统的扩容:
lvextend -r -L 3T /dev/mapper/vgdata-lvdata-r会自动判断文件系统类型并调用正确的扩容命令,省得自己记resize2fs和xfs_growfs的区别。不过在极老的系统上,-r参数可能不完善,扩容前先确认lvextend --help里能看到resize选项,再决定用哪种方式。
4.3 单块新盘加入VG:池子不够时的扩容路径
如果VG里的空间已经被用完了,比如之前把2TB+2TB全部切成了4TB的LV,此时想再扩大文件系统,就得先给VG增加新的物理存储。
流程是这样的:
# 1. 新硬盘sdd做PV pvcreate /dev/sdd # 2. 加进vgdata vgextend vgdata /dev/sdd # 3. 扩大LV(新增2TB) lvextend -L +2T /dev/mapper/vgdata-lvdata # 4. 扩大文件系统 xfs_growfs /data # 或者 resize2fs /dev/mapper/vgdata-lvdata整个过程同样可以在线完成,业务无感知。这就是LVM在磁盘管理和扩容上最大的优势:扩存储容量的动作,从“物理上的替换”变成了“资源池里的加法”,底层磁盘是什么型号、多大容量,都不影响上层的持续读写。
从raid5为啥不能在线扩容这个热搜词也能侧面看出这个痛点。传统硬RAID扩容,要么靠阵列卡的热备盘重建,要么需要迁移数据重新配置阵列,过程复杂、耗时长,而且一旦阵列卡不支持在线扩展,免不了停机。LVM把存储池和文件系统解耦之后,这个问题的复杂度就低多了。
4.4 缩容与日常工作流建议
LVM也支持缩容,但我必须说清楚:缩容的风险比扩容高得多,尤其是对XFS文件系统——它压根不支持缩容,尝试用xfs_growfs加参数去缩小,只会报错。ext4倒是可以缩小,但必须按严格顺序操作:先缩小文件系统,再缩小LV。而且缩容过程中一旦掉电,文件系统损坏的概率比扩容高好几个数量级。
我个人的原则是:生产环境的LV只扩不缩。空间规划的时候留足余量,数据真的冷下来了,直接把整个LV删掉重建,或者迁移到新盘,而不是在同一块卷上玩缩容。缩容这种操作,适合在测试环境里验证恢复流程,不适合在线上拿生产数据冒险。
日常运维中,建议定期执行lvs、vgs、pvs这三个命令,它们是LVM当前状态的“仪表盘”。lvs看逻辑卷,vgs看卷组空闲空间,pvs看物理卷的分布。写个简单脚本,每周自动记录一次输出,配合监控阈值,磁盘空间预警就能做到心里有数。
5. 常见问题与排查技巧实录
5.1 挂载、开机自启与扩容故障速查表
下面这些坑,都是我实际遇到过、或者帮别人排查过的问题。整理成一个速查表,希望能帮你少走弯路。
| 现象 | 常见原因 | 解决办法 |
|---|---|---|
| reboot后挂载目录是空的,数据“消失” | fstab没有配置或配置错误 | 用blkid获取UUID,正确写入fstab,执行mount -a验证 |
| 开机卡在Waiting for device,进不了系统 | fstab里设备名写错,或盘符因重启改变 | 进emergency mode修改fstab,优先使用UUID |
| 扩容后df看到容量没变 | 执行了lvextend,但没执行resize2fs/xfs_growfs | 根据文件系统类型,补做文件系统扩容 |
| resize2fs报错“Couldn't find valid filesystem superblock” | 设备路径写错,或用xfs_growfs去处理ext4 | 确认LV路径和文件系统类型匹配 |
| lvextend后xfs_growfs提示“not enough space” | LV空间其实已经用尽,或者扩容命令写成了-L而不是-L + | 检查lvs和vgdisplay里的Free PE |
| vgdisplay显示VG状态为not available | 系统启动时LV没有被激活 | 执行vgchange -ay vgdata激活,并排查fstab顺序 |
| pvcreate报“Device is not a valid LUKS device” | 磁盘上已经有旧签名 | 用wipefs -a清掉旧签名,再重试 |
| lvcreate报“Volume group has insufficient free space” | 池子空间不足 | 用vgextend加新盘,或用vgreduce释放已离线盘的空间 |
5.2 在线扩容为什么会失败以及如何快速回退
在线扩容失败最常见的场景,不是lvextend本身出错,而是后续的文件系统扩容命令执行失败。比如,你格式化的明明是个ext4,却错误地用了xfs_growfs;又比如LV已经扩到3T了,但resize2fs报错说找不到文件系统,这时候别慌,你的数据大概率还是安全的,因为LV扩容本质上只是在元数据里记录“这个LV可以更大”,它并没有动原本的数据块。
最理性的回退操作是这样的:
- 先确认文件系统当前状态。执行fsck或者mount检查一下数据是否可以正常读写。
- 如果数据正常,只是文件系统没扩成功,那就静下心把文件系统类型确认清楚,再执行正确的扩容命令。
- 如果实在不确定,最保险的方法是:LV保持扩容后的状态不变,先不要做任何破坏性操作,在另一块测试盘上重建同样场景,模拟一遍完整流程,确认无误后再处理线上。
这里有一个值得养成的习惯:把所有数据处理类操作写进一个操作日志。哪怕只是在文本文件里记录“2025-xx-xx 扩展了lvdata,从2T到3T,命令是lvextend -L 3T /dev/mapper/vgdata-lvdata”,将来排查问题时,这份日志就是最宝贵的线索。我见过太多人出问题后,连自己执行过什么命令都回忆不起来。
5.3 那些年我踩过的LVM坑:独家避坑经验
第一个坑,是没有预留空间。刚开始用LVM时,我习惯把所有空闲空间一次性切给LV,省得以后再扩容。后来发现这其实是个坏习惯:一旦LV占满了VG,你想给另一个目录扩容,就得先缩容或者再加盘,反而把自己逼到墙角。正确做法是:LV按“满足当前需求+一定余量”来切,VG里始终保留20%左右的空闲空间。这样做的好处是,当某个目录空间告急时,你只需要lvextend + resize,几分钟完事,而不是被“要做挂载新盘、重新规划空间”这些事牵着走。
第二个坑,是忽视了fstab里的dump和fsck选项。很多人写fstab时直接抄defaults 0 0就完了。第5列(dump)和第6列(fsck)看似不痛不痒,但在系统异常掉电后,fsck的检查顺序会影响文件系统的自动修复行为。对于根分区和数据分区,如果设置不当,开机可能需要手动干预,尤其对没有物理控制台的服务器来说,这可能是灾难。我的建议是:根分区保持系统默认,数据分区可以显式写成defaults 0 2或者defaults 0 0,你需要知道自己写的是什么,而不是盲目复制。
第三个坑,是在fstab里直接用了/dev/sdX路径。举例来说,你执行lvextend之后重启,Linux内核可能会因为设备识别顺序变化,把原本的sdb识别成sdc,这时候fstab里的设备路径就跟着失效。所以再次强调:挂载LVM卷最好走/dev/mapper/xxx路径或者UUID,不要用/dev/sdX。对于多盘服务器来说,这个习惯能救你很多次。
第四个坑,是忽略快照的必要性。虽然日常操作中LVM非常稳,但我依然建议在做重大变更(比如大容量扩容、迁移数据、升级内核)之前,先创建一个临时快照。命令很简单:
# 为lvdata创建快照,指定快照大小为200G lvcreate -s -L 200G -n lvdata-snap /dev/mapper/vgdata-lvdata如果后续操作有问题,几秒就能恢复:
# 如果有需要,可以将LV恢复至快照时刻的状态 lvconvert --merge /dev/mapper/vgdata-lvdata-snap别忘了,快照本身也是占用VG空间的。快照创建后,原LV的数据只要发生变化,变化前的旧数据就会被复制到快照空间里,快照越大、变化越频繁,快照空间消耗得越快。快照空间耗尽了,快照就会失效。所以快照只是短期保险,不是长期备份,用完之后尽快删除。
5.4 下一步还能做点什么
LVM这套方案,在上面示例里虽然只挂了本地数据盘,但它的能力边界远不止于此。如果你愿意再进一步,有三个方向很有性价比。
第一个方向是结合thin pool。Thin pool(精简配置)允许你创建看起来很大、但实际占用按需增长的LV。比如你给一个应用分配5TB的LV,但实际可能只需要500GB,底层只占用实际写入的部分。这对虚拟化环境、容器存储这类“空间需求波动大”的场景特别有用,能显著提高存储利用率。但注意,thin池要密切关注实际使用量和池容量,否则会出现“LV明明显示有5T,但实际没空间了”的尴尬。
第二个方向是把LVM和远程存储结合起来。前面提到的iSCSI、云盘,都可以先做PV再纳入VG,这样你得到的不只是扩容能力,还有跨设备的存储池抽象。把数据盘从“一块物理盘”变成“一个逻辑池子”,很多运维问题都会简单化。但远程存储的延迟、带宽和稳定性,需要另外做监控,不能当作本地盘一样盲目信任。
第三个方向是做好监控告警。LVM本身不解决“空间满了才发现”的问题,你需要配合监控系统(比如Prometheus的node_exporter、Zabbix、甚至简单的crontab脚本加df命令),在磁盘空间超过阈值时及时报警。等业务真的写不进数据再去看,那就只能处理事故了。
回到我开头讲的那个经历。如果当年就有LVM这套方案,那块分区满了的服务器,我不需要熬夜、不需要停机、不需要拿U盘进Live系统,只需要扩容LV、扩展文件系统,几分钟就能让业务恢复平稳运行。这也是我写这篇文章的初衷:想让你在遇到类似问题之前,就知道有一条更从容的路可以走。
最后分享一个我到现在还在用的小技巧:给每个LV的挂载目录建一个说明文件,比如在/data/.README里写上“此目录使用LVM卷vgdata/lvdata,文件系统xfs,创建于2025年,如有扩容需求请先查vgdisplay确认空闲空间”。一台服务器可能一年只动一两次,但就是这一两次,你能快速想起整套方案的来龙去脉,比翻聊天记录、翻Wiki高效得多。运维这件事,很多时候拼的不是技术,而是这些不起眼的“留一手”。