LVM硬盘移除与缩容方法
- 2026-04-01 21:31:00
- 丁国栋
- 原创 6
LVM硬盘移除与缩容方法
现在有一台云服务器,上面有多个硬盘组成的lvm,现在文件系统的空间使用率非常低。文件系统空间大小4.4T实际使用636G。现在需要将一些不再使用的硬盘从lvm中移除。应该如何做?
这是一个典型的 LVM 缩容与物理卷(PV)移除需求。由于你提到“文件系统空间使用率非常低”,这通常意味着数据已经集中迁移或删除,重点在于安全地释放物理设备。
重要警告:LVM 缩容(特别是涉及物理盘移除)是高风险操作。请务必在操作前对重要数据进行完整备份,并在测试环境验证流程。
一、 操作前:关键信息确认
在执行任何命令前,请先通过以下命令摸清家底,记录下关键信息(如 VG 名、PV 路径、LV 名):
-
查看物理卷(PV)状态:确认哪些 PV 属于该 VG,以及它们的使用情况。
pvs -
查看卷组(VG)详情:确认 VG 名称、总大小、空闲空间。
vgs vgdisplay <你的VG名称> -
查看逻辑卷(LV)详情:确认 LV 名称、路径(如
/dev/mapper/vg0-lv_data)及挂载点。lvs lvdisplay <你的VG名称> df -hT # 确认文件系统类型和挂载点 -
确认文件系统:你提到“文件系统空间大小 4.4T”,这通常是
xfs或ext4。这一步至关重要,因为 xfs 不支持在线缩容,而 ext4 支持。df -hT | grep /dev/mapper
二、 场景一:ext4 文件系统(相对简单,支持在线缩容)
如果你的文件系统是 ext4,操作流程相对直接,可以在线操作。
操作流程
-
卸载文件系统(可选,但更安全) 如果业务允许,建议卸载。如果必须在线操作,跳过此步,但风险增加。
umount /你的/挂载点 -
检查文件系统(强制步骤)
e2fsck -f /dev/你的VG/你的LV -
缩小文件系统(必须先于LV缩容) 将文件系统缩小到略小于你最终目标的大小(例如你目标留 1T,这里缩到 900G,留点缓冲)。
resize2fs /dev/你的VG/你的LV 900G -
缩小逻辑卷(LV)
lvreduce -L 1T /dev/你的VG/你的LV注意:
resize2fs和lvreduce的顺序不能反,且lvreduce的大小不能小于当前文件系统占用。 -
再次调整文件系统以填满LV
resize2fs /dev/你的VG/你的LV -
重新挂载(如果卸载了)
mount /dev/你的VG/你的LV /你的/挂载点 -
从卷组中移除空闲的PV 现在 VG 中应该有大量空闲空间,你可以将不再使用的物理卷移出。
vgreduce <你的VG名称> /dev/sdX # /dev/sdX 是你要移除的硬盘 -
移除物理卷头(可选) 如果确定该硬盘不再用于 LVM,可以抹掉 PV 标签。
pvremove /dev/sdX
实际操作
[z@backup:~$] df -h | grep -vP '(tmpfs|overlay|shm|kubelet|efivarfs|loop|snap|udev)'
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 29G 8.3G 78% /
/dev/mapper/vg01-pm1 4.4T 636G 3.6T 15% /home/data
cgmfs 100K 0 100K 0% /run/cgmanager/fs
[z@backup:~$]
[z@backup:~$] sudo lsof|grep /home/data
[z@backup:~$] cat /etc/fstab
# # /etc/fstab: static file system information.
# #
# # Use 'blkid' to print the universally unique identifier for a
# # device; this may be used with UUID= as a more robust way to name devices
# # that works even if disks are added and removed. See fstab(5).
# #
# # <file system> <mount point> <type> <options> <dump> <pass>
# # / was on /dev/sda1 during installation
# UUID=fe5d9ef3-0382-4b4d-9057-f09962f7d00d / ext4 errors=remount-ro 0 1
# UUID=175bf173-8178-4488-b85c-13b44e2068ad /home/data ext4 errors=remount-ro 0 1
# UUID=ee937963-6266-4d99-95cf-3831fd297c33 /home/data1 ext4 errors=remount-ro 0 1
#
# # swap was on /dev/sdb1 during installation
# LABEL=YUNIFYSWAP none swap sw 0 0
# Above content backup at 2024-09-02 16:49:52
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/sda1 during installation
UUID=fe5d9ef3-0382-4b4d-9057-f09962f7d00d / ext4 errors=remount-ro 0 1
# swap was on /dev/sdb1 during installation
LABEL=YUNIFYSWAP none swap sw 0 0
#UUID=175bf173-8178-4488-b85c-13b44e2068ad /home/data ext4 errors=remount-ro 0 1
UUID=ee937963-6266-4d99-95cf-3831fd297c33 /home/data ext4 errors=remount-ro 0 1
[z@backup:~$] sudo umount /home/data
[z@backup:~$] e2fsck -f /dev/mapper/
control vg01-pm1
[z@backup:~$] sudo e2fsck -f /dev/mapper/vg01-pm1
e2fsck 1.44.1 (24-Mar-2018)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/vg01-pm1: 4073384/294912000 files (0.2% non-contiguous), 185015801/1179640832 blocks
[z@backup:~$] sudo resize2fs /dev/mapper/vg01-pm1 900G
resize2fs 1.44.1 (24-Mar-2018)
Resizing the filesystem on /dev/mapper/vg01-pm1 to 235929600 (4k) blocks.
The filesystem on /dev/mapper/vg01-pm1 is now 235929600 (4k) blocks long.
[z@backup:~$]
z@backup:~$] sudo vgs
VG #PV #LV #SN Attr VSize VFree
vg01 7 1 0 wz--n- 4.39t 3.39t
[z@backup:~$] sudo vgreduce vg01 /dev/vdi
Removed "/dev/vdi" from volume group "vg01"
[z@backup:~$] udevadm info --query=all --name=/dev/vdi
P: /devices/pci0000:00/0000:00:0d.0/virtio9/block/vdi
N: vdi
S: disk/by-id/lvm-pv-uuid-970nAu-hSeE-HKbb-Ei62-3dvu-7S1E-QAAn8K
S: disk/by-id/virtio-vos-10dohijl
S: disk/by-path/pci-0000:00:0d.0
S: disk/by-path/virtio-pci-0000:00:0d.0
E: DEVLINKS=/dev/disk/by-path/virtio-pci-0000:00:0d.0 /dev/disk/by-id/lvm-pv-uuid-970nAu-hSeE-HKbb-Ei62-3dvu-7S1E-QAAn8K /dev/disk/by-id/virtio-vos-10dohijl /dev/disk/by-path/pci-0000:00:0d.0
E: DEVNAME=/dev/vdi
E: DEVPATH=/devices/pci0000:00/0000:00:0d.0/virtio9/block/vdi
E: DEVTYPE=disk
E: ID_FS_TYPE=LVM2_member
E: ID_FS_USAGE=raid
E: ID_FS_UUID=970nAu-hSeE-HKbb-Ei62-3dvu-7S1E-QAAn8K
E: ID_FS_UUID_ENC=970nAu-hSeE-HKbb-Ei62-3dvu-7S1E-QAAn8K
E: ID_FS_VERSION=LVM2 001
E: ID_MODEL=LVM PV 970nAu-hSeE-HKbb-Ei62-3dvu-7S1E-QAAn8K on /dev/vdi
E: ID_PATH=pci-0000:00:0d.0
E: ID_PATH_TAG=pci-0000_00_0d_0
E: ID_SERIAL=vos-10dohijl
E: MAJOR=252
E: MINOR=128
E: SUBSYSTEM=block
E: SYSTEMD_ALIAS=/dev/block/252:128
E: SYSTEMD_READY=1
E: SYSTEMD_WANTS=lvm2-pvscan@252:128.service
E: TAGS=:systemd:
E: USEC_INITIALIZED=7238811
[z@backup:~$] sudo pvremove /dev/vdi
Labels on physical volume "/dev/vdi" successfully wiped.
[z@backup:~$]
[z@backup:~$] sudo vgreduce vg01 /dev/vdg
Physical volume "/dev/vdg" still in use
[z@backup:~$] sudo pvmove /dev/vdg
/dev/vdg: Moved: 0.00%
/dev/vdg: Moved: 0.08%
/dev/vdg: Moved: 0.17%
/dev/vdg: Moved: 0.26%
/dev/vdg: Moved: 0.34%
/dev/vdg: Moved: 0.43%
/dev/vdg: Moved: 0.51%
/dev/vdg: Moved: 0.58%
/dev/vdg: Moved: 0.65%
/dev/vdg: Moved: 0.74%
...
/dev/vdg: Moved: 100.00%
[z@backup:~$]
执行 vgreduce vg01 /dev/vdg 时提示 Physical volume "/dev/vdg" still in use 这个报错意味着 /dev/vdg 这个物理卷(PV)上仍有数据(即逻辑卷的物理盘区),LVM 出于保护机制拒绝直接移除。你需要先通过数据迁移(pvmove)把这块硬盘上的数据清空,才能安全移除。
一、 为什么报错?
LVM 的底层逻辑是:数据是分散在多个 PV 上的。即使文件系统使用率低,数据也可能恰好分布在你想要移除的这块盘上。
当前状态:
- 卷组(VG)
vg01中,PV/dev/vdg上仍包含活跃的逻辑卷(LV)数据。 - 直接
vgreduce相当于“抽掉地基”,会导致数据丢失,因此被 LVM 阻止。
二、 解决方案:使用 pvmove 迁移数据
核心思路:将 /dev/vdg 上的数据块全部搬移到 VG 内的其他空闲硬盘上,使其变为“空闲 PV”,再移除。
1. 检查 PV 使用情况
先确认 /dev/vdg 是否真的被占用,以及是否有其他空闲 PV 可以接收数据。
sudo pvs -o+pv_used
输出示例:
PV VG Fmt Attr PSize PFree Used
/dev/vdb vg01 lvm2 a-- 1.00t 1.00t 0
/dev/vdc vg01 lvm2 a-- 1.00t 500g 500g
/dev/vdg vg01 lvm2 a-- 1.00t 200g 800g <-- 这个 Used 不为 0
2. 执行数据迁移(关键步骤)
使用 pvmove 命令将数据从 /dev/vdg 搬走。确保 VG 内有其他 PV 且有足够空闲空间。
# 将 /dev/vdg 上的所有数据迁移到 VG 内的其他 PV
sudo pvmove /dev/vdg
命令会显示进度,大硬盘耗时较长。如果只想迁到特定 PV(如 /dev/vdb),可用 sudo pvmove /dev/vdg /dev/vdb。
3. 确认迁移完成
迁移完成后,再次检查状态,确认 /dev/vdg 的 Used 变为 0。
sudo pvs -o+pv_used
4. 移除 PV
此时数据已清空,可以安全移除。
sudo vgreduce vg01 /dev/vdg
5. 彻底清理(可选)
如果该硬盘不再用于 LVM,移除 PV 标签。
sudo pvremove /dev/vdg
三、 如果迁移失败(无空闲空间)
如果你执行 pvmove 时提示 Insufficient free space,说明 VG 内其他 PV 没有足够空间接收 /dev/vdg 上的数据。此时你有两个选择:
方案 A:先缩容文件系统(释放空间)
如果你文件系统确实只用了 636G,但 LV 分配了 4.4T,可以先缩小 LV 和文件系统(参考之前的 ext4/xfs 流程),腾出 VG 空闲空间,再进行 pvmove。
方案 B:添加临时硬盘
在云平台挂载一块临时云盘,将其加入 VG 作为“中转站”。
# 假设新挂载的盘为 /dev/vdh
sudo pvcreate /dev/vdh
sudo vgextend vg01 /dev/vdh
sudo pvmove /dev/vdg /dev/vdh # 迁移数据到临时盘
sudo vgreduce vg01 /dev/vdg # 移除旧盘
# 之后若需回收临时盘,再反向操作 pvmove 回来并移除
四、 风险提示
- 数据安全:
pvmove是底层数据搬运,操作前务必对重要数据做备份或云盘快照。 - 业务影响:迁移过程中 I/O 压力较大,建议在业务低峰期操作。
- 云环境:如果是云服务器,移除 PV 后记得去云控制台卸载云盘,否则可能继续计费。
[z@backup:~$] sudo pvs -o+pv_used
PV VG Fmt Attr PSize PFree Used
/dev/vdc vg01 lvm2 a-- <500.00g 0 <500.00g
/dev/vdd vg01 lvm2 a-- <200.00g 75.99g 124.00g
/dev/vde vg01 lvm2 a-- <500.00g <500.00g 0
/dev/vdf vg01 lvm2 a-- <500.00g <500.00g 0
/dev/vdg vg01 lvm2 a-- <900.00g 0 <900.00g
/dev/vdh vg01 lvm2 a-- <500.00g <100.00g 400.00g
[z@backup:~$]
[z@backup:~$] sudo pvs -o+pv_used
PV VG Fmt Attr PSize PFree Used
/dev/vdc vg01 lvm2 a-- <500.00g 0 <500.00g
/dev/vdd vg01 lvm2 a-- <200.00g 75.99g 124.00g
/dev/vde vg01 lvm2 a-- <500.00g <500.00g 0
/dev/vdf vg01 lvm2 a-- <500.00g <500.00g 0
/dev/vdg vg01 lvm2 a-- <900.00g 0 <900.00g
/dev/vdh vg01 lvm2 a-- <500.00g <100.00g 400.00g
[z@backup:~$] sudo vgreduce vg01 /dev/vde
Removed "/dev/vde" from volume group "vg01"
[z@backup:~$] sudo vgreduce vg01 /dev/vdf
Removed "/dev/vdf" from volume group "vg01"
[z@backup:~$] sudo pvremove /dev/vde
Labels on physical volume "/dev/vde" successfully wiped.
[z@backup:~$] sudo pvremove /dev/vdf
Labels on physical volume "/dev/vdf" successfully wiped.
[z@backup:~$]
[z@backup:~$] udevadm info --query=all --name=/dev/vde |grep ID_SERIAL
E: ID_SERIAL=vos-x2qv6vg9
[z@backup:~$] udevadm info --query=all --name=/dev/vdf |grep ID_SERIAL
E: ID_SERIAL=vos-iwi6o9zu
[z@backup:~$]
三、 场景二:xfs 文件系统(不支持在线缩容,需迁移数据)
XFS 不支持缩小! 这是很多人的误区。你不能直接对已挂载的 XFS 执行 xfs_growfs 缩容。唯一安全的方法是:创建新LV -> 迁移数据 -> 替换。
操作流程
-
创建新的、小容量的 LV 利用你 VG 中空闲的 PV(或者确保有足够空间)创建一个新的 LV,大小为你需要的目标大小(如 1T)。
lvcreate -L 1T -n lv_new <你的VG名称> -
在新 LV 上创建文件系统
mkfs.xfs /dev/你的VG/lv_new -
挂载新 LV 并迁移数据
mkdir /mnt/new mount /dev/你的VG/lv_new /mnt/new rsync -avP /原挂载点/ /mnt/new/ # 使用 rsync 同步数据 -
切换挂载点 确认数据同步无误后(
diff检查),停服(如果是在线业务),然后切换挂载点。umount /原挂载点 umount /mnt/new mount /dev/你的VG/lv_new /原挂载点 -
删除旧 LV 并释放 PV 确认业务运行正常后,删除旧的大 LV,此时 VG 空间释放,可以移除旧的 PV。
lvremove /dev/你的VG/lv_old vgreduce <你的VG名称> /dev/sdX # 移除不再使用的硬盘
四、 关键风险点与建议
- 备份!备份!备份!:误操作可能导致数据丢失,云服务器建议先打快照。
- 确认文件系统类型:
xfs和ext4的缩容策略完全不同,切勿混淆。 - 顺序不能错:ext4 必须是
fsck->resize2fs->lvreduce。 - 预留缓冲空间:缩容时不要卡着
636G用,建议预留 20%-30% 的缓冲空间。 - 云盘注意事项:如果是云硬盘(如阿里云、腾讯云),移除 PV 后,记得在云控制台卸载云盘,否则可能继续计费。