干运维这几年,磁盘管理和LVM一直是我最常用也最怕出错的两个基本功。尤其是碰到线上服务器磁盘不够用、数据盘要扩容、系统重装要保住数据这些场景,LVM(逻辑卷管理)几乎是绕不开的解决方案。很多人一开始只会fdisk分区、mount挂载,一看见PV、VG、LV、PE就头皮发麻,其实搞懂之后就会发现,它就是把一堆物理磁盘“揉”成一个资源池,再按需切成任意大小的逻辑卷而已。下面这些内容基本覆盖了从设备认盘、分区挂载,到LVM创建扩容、缩容快照,再到重装系统前安全拆数据盘的全过程,所有命令都是我在真实环境里验证过的。适合刚接触Linux的运维新人和准备面试想系统梳理一遍的同学参考。
1. 先搞懂Linux怎么认盘:磁盘管理的第一课
1.1 设备命名规则:sda、vda、nvme0n1都代表啥
Linux下一切设备都以文件形式暴露在/dev目录里。传统SATA/SAS硬盘通常是/dev/sda、/dev/sdb这种命名,sda中的a是顺序编号;在KVM、Xen这类虚拟机里,磁盘走virtio驱动时会看到/dev/vda、/dev/vdb;NVMe固态硬盘则是/dev/nvme0n1、/dev/nvme0n2这种形式,中间的n1代表第1个命名空间;还有SD卡和eMMC设备会显示成/dev/mmcblk0。设备名看着乱,其实背后是内核的驱动探测顺序,一个非常重要的经验是:不要在生产环境里把/dev/sda这种名字直接写进配置,因为它可能因为插拔硬盘、内核版本升级而改变。更稳的做法是用UUID或文件系统标签来引用设备,这也是后面写/etc/fstab时的关键点。
1.2 查看磁盘和空间占用:lsblk、df、fdisk、blkid一次说清
先看最常用的一组命令。
lsblk # 查看块设备拓扑和挂载点 df -h # 查看文件系统使用率 fdisk -l # 查看分区表信息 blkid # 查看设备UUID和文件系统类型第一类是lsblk,它会输出类似“sda 8:0 0 100G 0 disk ├─sda1 ... └─sda2 ...”的树状结构,能一眼看出谁是谁的分区,加了LVM后还会看到“vgdata-lvdata”这样的逻辑卷挂在下面。第二类是df -h,它看的是已挂载文件系统的容量,排查“磁盘满没满”最先跑的命令就是它。第三类fdisk -l看的是底层分区表,适合确认磁盘有没有被分区、分区类型是什么。第四类blkid输出UUID、PARTUUID和文件系统类型,写/etc/fstab时特别有用。日常排查我还喜欢补一个du -sh /data,先把目录占用挖出来,再往下定位大文件,后面接上find或ncdu,基本能把空间去向摸得清清楚楚。
1.3 从裸盘到可用目录:分区、格式化、挂载标准流程
假设新加了一块/dev/sdb,目标挂到/data,标准流程分成四步。
第一步分区。新盘容量小于2T可以用fdisk,大于2T必须用GPT分区表,fdisk新版直接支持GPT,老版本建议改用parted。操作是fdisk /dev/sdb,进入交互界面后按n新建分区、p选主分区、默认扇区、w写入。第二步格式化:mkfs.ext4 /dev/sdb1或mkfs.xfs /dev/sdb1,选择哪种文件系统看业务,比如大文件存储用XFS,普通目录强调通用性和缩容能力用ext4。第三步挂载:mkdir -p /data && mount /dev/sdb1 /data。第四步写开机自动挂载:先用blkid /dev/sdb1拿到UUID,然后往/etc/fstab里加一行UUID=xxxx /data ext4 defaults 0 0,最后mount -a验证。如果盘是NAS导出的NFS共享,挂载方式类似:mount -t nfs 192.168.1.10:/data /data,只不过fstab里要加_netdev选项,避免开机时网络还没起来就尝试挂载导致失败。这些基础流程不熟,后面玩LVM就容易把概念搞混。
2. LVM的核心逻辑:把一堆硬盘变成一块“橡皮泥”
2.1 四个缩写一次讲透:PV、VG、LV、PE
LVM的全称是Logical Volume Manager,核心抽象出四层概念。
- PV(Physical Volume,物理卷):可以是整块磁盘,也可以是一个分区,相当于提供原始空间的“砖块”。
- VG(Volume Group,卷组):把多个PV汇集成一个大的空间池,相当于把这些砖块砌成了一面墙。
- LV(Logical Volume,逻辑卷):从VG里划分出来的“房间”,格式化后就是最终挂载使用的逻辑盘。
- PE(Physical Extent,物理扩展块):VG内部的存储单位,默认4MB,LVM在分配空间时按PE的整数倍切割。
用一个生活类比:PV是成包的水泥,VG是把几包水泥倒进一个桶里搅拌均匀,LV就是从这个桶里舀出来的每一杯,PE就是“一勺”的最小单位。系统看到的是LV,底层数据分布在哪一个PV的哪个PE上,由LVM的元数据自己记录和映射,用户不需要关心。所以“逻辑卷”这个名字起得很准确:它本身不是一个真实的物理分区,而是一套映射关系,这也是它能跨盘、能动态调整的根本原因。
2.2 LVM和传统分区相比,优缺点到底是什么
先说缺点,这样才客观。LVM多了一层映射和元数据,会带来轻微性能开销;卷组结构一旦损坏,恢复比普通分区更麻烦;启动时需要initramfs加载LVM模块,如果内核和initramfs没配合好,开机会直接进救援模式;XFS文件系统不支持缩容,想缩小逻辑卷还得考虑文件系统兼容性。这些缺点在服务器场景里通常可以接受,但在单盘家用环境、嵌入式设备、追求极致性能和极简内核的场景下,传统分区反而更合适。
再看优点,列成表格最直观。
| 对比项 | 传统分区 | LVM |
|---|---|---|
| 扩容 | 需要新增分区后重新规划挂载,数据迁移麻烦 | lvextend直接在线扩,无需停机 |
| 跨多块磁盘 | 不支持,一个分区只能位于单盘上 | VG可以跨盘,多个PV合并成资源池 |
| 缩容 | 分区本身无法直接缩 | ext4可缩,xfs不行 |
| 快照 | 不支持 | 原生支持LV快照,秒级生成 |
| 性能 | 少一层映射,略高 | 有少量映射开销 |
| 复杂度 | 低,适合简单场景 | 中高,适合动态扩容需求 |
一句话总结:如果你管理的是数据库服务器、云主机数据盘、需要频繁扩容的业务系统,直接用LVM;如果是单块盘装个个人桌面系统、跑个嵌入式设备,传统分区足够了。
2.3 面试题常考:LVM的读写映射和PE大小怎么选
面试运维岗时,LVM几乎是必考内容。最常见的问题有两个:第一个是“LVM怎么把逻辑卷映射到物理磁盘?”答案要点在于LV由若干段(segment)组成,每一段映射到VG内某个PV上连续的一段PE,逻辑地址到物理地址的转换由device-mapper完成,这就是为什么你会看到/dev/mapper/vg-lv这样的路径。第二个问题是“PE大小什么时候需要改?”创建VG时可以用vgcreate -s指定PE大小。PE越小,空间分配越精细,但映射表更大;PE越大,映射表更小,但分配粒度粗,浪费也多。如果业务以大量小文件为主、需要精细控制空间,建议用1MB或2MB的PE;如果是大容量存储、数据库文件,默认4MB甚至更大也够用。回答时如果能补一句“修改PE大小必须在创建VG时确定,后面很难直接改”,面试官会认为你真的碰过生产环境。
3. 实操:手把手创建、扩容、缩容和快照LVM
3.1 从裸盘到LVM全流程(新盘不是只能分区)
环境假设:有一块新盘/dev/sdb,目标是做成LVM并挂载到/data。
第一步,用lsblk和pvs确认设备状态,千万别写错盘符。第二步,创建PV并组建VG、创建LV:
pvcreate /dev/sdb vgcreate vgdata /dev/sdb lvcreate -L 200G -n lvdata vgdata这里我直接把整块/dev/sdb做成PV,没有分区。如果习惯分区,可以先用fdisk建一个类型为8e的LVM分区,然后再pvcreate /dev/sdb1。整块盘直接做PV省事,但有些环境对分区对齐有要求,或者需要保留传统分区表标识,那就老老实实先分区。第三步,格式化逻辑卷:
mkfs.xfs /dev/vgdata/lvdata # 如果改成ext4:mkfs.ext4 /dev/vgdata/lvdata第四步,挂载并写入开机自动挂载:
mkdir -p /data mount /dev/vgdata/lvdata /data echo "UUID=$(blkid -s UUID -o value /dev/vgdata/lvdata) /data xfs defaults 0 0" >> /etc/fstab mount -a df -h这里有个细节:/dev/mapper/vgdata-lvdata和/dev/vgdata/lvdata指向同一个设备,只是路径不同。写fstab时优先用blkid查到的UUID,比设备路径更可靠。如果不小心把错误UUID写进fstab,开机会直接进emergency mode,排查起来很折腾。
3.2 懒人扩容:lvextend -r 一条命令在线搞定
场景:/data空间不够,VG还有剩余空间。先看剩余空间:
vgs vgdisplay vgdata看到Free空间后,执行:
lvextend -r -L +50G /dev/vgdata/lvdata重点是这个-r参数,它会自动识别文件系统类型并完成resize:ext4自动调用resize2fs,xfs自动调用xfs_growfs。如果没有-r,需要手动执行,XFS和ext4命令不一样:
# xfs,必须在挂载状态下执行 xfs_growfs /data # ext4,可以对未挂载的设备执行 resize2fs /dev/vgdata/lvdata扩容后记得用df -h确认容量变化。如果VG剩余空间不够,先给VG扩容:新增一块盘,pvcreate /dev/sdc,然后vgextend vgdata /dev/sdc,再回到lvextend -r。整个过程不用停机,业务几乎无感知,这就是LVM最诱人的价值。我实际扩容根分区时也用过这个套路,只要系统盘所在VG还能扩,很多“根分区满了”的问题都能在线解决。
3.3 缩容逻辑卷:XFS用户请直接放弃
缩容比扩容风险高很多。XFS不支持缩容,如果想缩小XFS文件系统,只能把数据备份出去、重建LV、再导回来;ext4支持缩容,但执行顺序绝对不能错:
umount /data e2fsck -f /dev/vgdata/lvdata resize2fs /dev/vgdata/lvdata 80G lvreduce -L 80G /dev/vgdata/lvdata mount /data注意顺序:先缩文件系统,再缩LV。如果反了,LV先变小,文件系统数据可能已经被截断,轻则文件系统损坏,重则数据丢失。命令里的e2fsck -f强制检查必不可少,缩容前必须保证文件系统干净。如果是不敢停机的生产环境,缩容前最稳妥的做法是先用LVM快照备份,或者干脆把数据迁到新LV上再删除旧LV。我的建议是:没有特殊理由不要缩容,空间管理靠“按需扩容”就够了,毕竟扩容是零风险操作,缩容却是高危操作。
3.4 快照:升级前的一颗后悔药
LVM原生快照能在秒级生成一个逻辑卷的某个时间点副本,命令只有一行:
lvcreate -s -L 20G -n snap_lvdata /dev/vgdata/lvdata这会生成一个20G的快照卷/dev/vgdata/snap_lvdata。快照卷保存的是源LV的“变化前”数据,所以它的大小由快照期间实际写入的数据量决定,不是源LV总大小。如果快照期间写入超过20G,快照会“满掉”并自动失效,因此快照空间要给足。使用场景很明确:数据库备份前、系统升级前、大版本更新前。可以在快照卷上做备份,也可以临时挂载快照检查数据。
需要恢复源LV时,先卸载源LV和快照,然后执行:
lvconvert --merge /dev/vgdata/snap_lvdata合并时源LV和快照必须都处于卸载状态,否则命令会报错。合并完成后快照自动被移除,源LV恢复到快照那一刻的状态。生产环境中“升级前打快照,出问题后回滚”是标准操作,成本低、速度又快,比折腾备份恢复省心太多。
4. 生产环境避坑:重装系统、数据盘分离与常见故障
4.1 云电脑/云主机重装系统前,请先安全拆掉LVM数据盘
你可能会遇到这样一个场景:云电脑或云主机使用了LVM,并且把一块数据盘加进了卷组,现在要重装系统,如果不做任何处理直接把数据盘从控制台分离,新系统启动后大概率会遇到“Volume group not found”或者VG重名冲突。原因很简单:LVM元数据写在PV上,数据盘里带着“我是某个VG的一部分”的信息,重装后设备映射关系变了,新系统可能激活不了旧VG,或者激活了错误逻辑卷,导致挂载失败甚至数据不可见。
所以,重装前要按下面顺序“解绑”数据盘:
- 先备份重要数据,备份到单独对象存储或本地其他机器,别只放在待分离盘上。
- 确认当前LVM拓扑:
pvs vgs lvs lsblk - 卸载所有LV挂载点:
umount /data - 停用LV和VG:
停用后,内核不再创建设备映射。lvchange -an vgdata/lvdata vgchange -an vgdata - 执行
sync确保缓存落盘。 - 从云控制台分离数据盘。
如果数据盘上只有独立的VG,没有和系统盘混在一起,步骤到这就够了。重装完系统再接回数据盘时,用pvscan、vgscan重新扫描,再用vgchange -ay vgdata激活VG,最后挂载LV就能看到数据。
如果数据盘是某个同时包含系统盘的VG的一部分,情况要复杂一些,需要把数据盘从VG里先抽出去:
pvmove /dev/sdb # 把数据盘上的数据迁移到同VG其他PV vgreduce vgdata /dev/sdb # 从VG中移除该PV pvremove /dev/sdb # 清除PV标记(可选)这个操作要等到pvmove完全结束后再继续,期间不要断电。pvmove处理的是磁盘上所有PE的搬移,时间长短取决于数据量。完成后数据盘就不再属于LVM,重装系统后把它当普通数据盘挂载就行。还有一种更简单的思路:如果数据盘足够大,干脆把它做成独立VG,不往系统盘所在VG里塞,这样重装前只需要vgchange -an停用,永远不用做危险的pvmove,这也是我在云主机上习惯用“系统盘VG和数据盘VG拆开”的原因。
4.2 磁盘满的经典排查:No space left on device
日常经常会遇到“磁盘明明显示满了,但清理文件后还是报No space left on device”。这里有几个隐藏坑值得说清楚。
第一个是文件系统真的满,找大文件就行。用du -x --max-depth=1 /data逐层定位,或者直接装ncdu交互式查看。第二个是文件被删除但进程还持有句柄,空间没有真正释放。这种情况用lsof | grep deleted找出占用进程,重启或让进程释放文件描述符后空间才会回来。第三个是inode满了,和容量没有直接关系,用df -i看,再用find /data -xdev -type f | wc -l统计文件数量。如果inode满,就算df -h显示还有空间,也写不进任何新文件,常见于邮件系统、消息队列这类海量小文件的目录。第四个就是LVM场景下的容量限制:LV和文件系统都可能达到上限,但VG还有剩余空间。在这种情况里直接lvextend -r -L +20G /dev/vgdata/lvdata扩容,在线就能解决,不需要停机。换句话说,LVM把“空间不够”从“硬件运维问题”变成了“一条命令问题”,这也是它适合服务器的最重要原因。
4.3 常见报错与排查速查表
生产环境中我整理过一张LVM和磁盘相关报错速查表,分享出来。
| 报错信息 | 可能原因 | 解决办法 |
|---|---|---|
| Volume group "vgdata" not found | VG未激活或元数据丢失 | vgscan扫描,vgchange -ay vgdata激活,再pvs确认PV |
| Failed to find physical volume "/dev/sdb" | PV设备名变了或驱动未加载 | 先lsblk确认设备是否还在,再用vgimport导入VG |
| Not a valid LVM magic | 设备不是LVM PV,或PV标记损坏 | 确认数据已备份后重新pvcreate初始化 |
| /dev/mapper/vgdata-lvdata does not exist | LV未被激活 | lvchange -ay vgdata/lvdata或vgchange -ay |
| lvextend: Size must be a multiple of PE | 扩容大小不是PE整数倍 | 使用-L +10G这种PE整倍数的写法 |
| 挂载提示 unknown filesystem type 'LVM2_member' | 直接挂载了PV而不是LV | 应该挂载/dev/vgdata/lvdata,而不是/dev/sdb |
| xfs_growfs: XFS not present on disk | 试图缩容XFS或挂载路径不对 | XFS不支持缩容,只能备份重建 |
| fstab配置错误导致开机进入emergency mode | 挂载项设备不存在或格式错误 | 进入维护模式,注释错误行,用mount -a验证 |
这些报错大部分都是“设备路径引用错误”和“VG没有激活”两类,养成“先pvs、vgs、lvs,再动手”的习惯能避免大多数问题。另外,平时记得用vgcfgbackup备份LVM元数据,改/etc/fstab前先备份,这些操作成本极低,但关键时候能救命。
4.4 国产Linux发行版(如麒麟)扩LVM,原理一样,命令通用
国产Linux发行版比如麒麟、统信UOS,底层都是Linux内核,LVM命令和机制与其他发行版完全一致。在麒麟系统里扩LVM,依然可以用lsblk确认磁盘,用vgcreate、lvextend、xfs_growfs这些命令操作。和CentOS/Rocky系一样,麒麟一般用yum或dnf安装软件包,Ubuntu/Debian系用apt,包名基本都是lvm2:
yum install -y lvm2 # 麒麟/Rocky/CentOS系 apt install -y lvm2 # Ubuntu/Debian系碰到“Permission denied”或“Device busy”,先确认是否用sudo执行,以及LV是否处于挂载状态。分享一个真实案例:同事在麒麟服务器上扩根分区,VG空间明明充足,但lvextend一直报“Read-only file system”,排查半天才发现根分区挂载成了只读模式,执行mount -o remount,rw /重新挂载后再扩容就好了。这类问题在任何Linux发行版上都会出现,所以排查思路完全可以复用:先看挂载状态,再看权限,再检查VG空间,最后才怀疑工具本身。
最后分享一个我自己的习惯:每次要对生产环境的LVM动手之前,先执行df -h; pvs; vgs; lvs; lsblk这五条命令,把当前状态记录到终端日志里,再决定下一步。前阵子帮客户扩根分区,因为没看VG剩余空间就直接lvextend,结果命令报错,我又反复试了几次,虽然没造成数据丢失,但那种心跳加速的感觉真不想再来第二次。LVM本身不复杂,绝大多数事故都出在“没看现状就动手”和“没备份就缩容”。如果你能把PV、VG、LV的关系,以及lvextend、vgchange、lvconvert这几个常用命令背熟,再对照上面的报错速查表,日常磁盘管理里八成以上的问题都能稳稳解决。