字数 1452,阅读大约需 8 分钟
LVM管理中经常会遇到换掉坏盘、扩容加盘、淘汰旧盘等场景,所有这些场景都靠 pvmove 在线迁移。本篇讲清 pvmove 的原理、用法和最佳实践。
一、为什么需要 pvmove?
场景:服务器运行 3 年,磁盘寿命到期或容量不够,要换新盘。
传统方案:
LVM 方案(pvmove):
pvmove 在背后做的是:把旧 PV 上的所有 PE(数据块)重新映射到新 PV 上的 PE。
二、最佳实践:pvmove 完整流程
2.1 准备工作
# 1. 看哪些盘要换
$ pvs
PV VG Fmt Attr PSize PFree
/dev/sdb vg_data lvm2 a-- 500.00g 0 # ← 这块满了,要换
/dev/sdc vg_data lvm2 a-- 500.00g 100.00g
# 2. 准备新盘(物理上插上 /dev/sdd 或虚拟机里加新盘)
# 3. 把新盘做成 PV
$ pvcreate /dev/sdd
Physical volume "/dev/sdd" successfully created.
# 4. 加入 VG
$ vgextend vg_data /dev/sdd
Volume group "vg_data" successfully extended
2.2 启动 pvmove
# 把 /dev/sdb 上所有数据迁到 VG 内其他盘
$ pvmove /dev/sdb
可选参数:
# 显式指定目标盘(推荐,更可控)
$ pvmove -n lv_db /dev/sdb /dev/sdd # 只迁移 lv_db 的数据到 sdd
# 按字节数限制 I/O 速率(避免影响业务)
$ pvmove /dev/sdb --rate 50M
# 后台运行
$ pvmove -b /dev/sdb
2.3 看进度
$ lvs vg_data
LV VG Attr LSize Move%
lv_db vg_data -wi-ao---- 400.00g 45.32 # ← 45% 完成
# 实时监控
$ watch -n 5 'lvs -a -o lv_name,move_percent'
2.4 完成后清理
# 1. 确认迁移完成
$ pvs /dev/sdb
PV VG Fmt Attr PSize PFree
/dev/sdb vg_data lvm2 a-- 500.00g 500.00g # ← 已全部释放
# 2. 从 VG 移除旧 PV
$ vgreduce vg_data /dev/sdb
Removed "/dev/sdb" from volume group "vg_data"
# 3. 清除 LVM 标签
$ pvremove /dev/sdb
Labels on physical volume "/dev/sdb" successfully wiped
# 4. 物理拔盘
三、典型场景案例
场景 1:磁盘故障,更换同位置新盘
# 1. 故障盘识别
$ pvs
/dev/sdb vg_data lvm2 a-- 500.00g 0 # ← sdb 故障但还在 VG
# dmesg 看 /dev/sdb 错误
# 2. 物理换盘(同槽位新盘,设备名仍是 /dev/sdb)
# 3. 重新加入
$ pvcreate /dev/sdb
$ vgextend vg_data /dev/sdb
# 4. 修复 RAID/LV
$ lvconvert --repair vg_data/lv_db # 镜像/RAID 场景
# 或
$ pvmove /dev/sdc /dev/sdb # 把其他盘的数据迁回新盘
场景 2:业务盘容量不够,加新盘扩容
# 1. 加新盘
$ pvcreate /dev/sdd
$ vgextend vg_data /dev/sdd
# 2. 扩 LV(参考 04 教程)
$ lvextend -L +200G /dev/vg_data/lv_db -r
场景 3:缩减 VG,移除一块盘
# 1. 把要移除的盘上的数据先迁到其他盘
$ pvmove /dev/sdb /dev/sdc
# 2. 确认 sdb 已空
$ pvs /dev/sdb
/dev/sdb vg_data lvm2 a-- 500.00g 500.00g
# 3. 从 VG 移除
$ vgreduce vg_data /dev/sdb
# 4. 清除标签
$ pvremove /dev/sdb
场景 4:迁移到新服务器(拆硬盘带走)
# 旧服务器
$ pvmove /dev/sdb /dev/sdc # 把 sdb 的数据迁到 sdc
$ vgreduce vg_data /dev/sdb
$ pvremove /dev/sdb
# 物理拔盘 → 插到新服务器
# 新服务器
$ pvscan # 应能识别 sdb
$ vgimport vg_data # 如果 UUID 冲突
四、pvmove 的限制
| |
|---|
| 单次 pvmove 只能到一个目标盘(除非用 -n 指定 LV) |
| |
| 镜像 LV 的数据分布复杂,要先 lvconvert |
| |
| |
五、pvmove 高级用法
5.1 只迁某个 LV
$ pvmove -n lv_db /dev/sdb /dev/sdd
5.2 多盘互迁
# 把 sdb 和 sdc 的数据全部迁到 sdd 和 sde
# 这是分两步:先把 sdb 迁到 sdd,再把 sdc 迁到 sde
$ pvmove /dev/sdb /dev/sdd
$ pvmove /dev/sdc /dev/sde
5.3 中途暂停与恢复
# 暂停
$ pvmove --abort /dev/sdb
# 恢复(重启继续)
$ pvmove /dev/sdb /dev/sdd
5.4 看 pvmove 进度细节
# 看更详细的状态
$ lvs -a -o+move_percent,copy_percent
$ pvs -a -o+pvmove_allocated,pvmove_free
六、VG 拆分与合并
6.1 拆分 VG
# 把 VG 拆分:把一部分 PV 拆出来组成新 VG
$ vgsplit vg_data vg_new /dev/sdd /dev/sde
6.2 合并 VG
# 把 vg_new 合并回 vg_data
$ vgmerge vg_data vg_new
要求:
七、生产环境注意事项
7.1 限速是关键
pvmove 会吃满磁盘 I/O,影响业务。一定要限速:
# 看当前 I/O
$ iostat -x 1
# 根据业务空闲度设置 rate
$ pvmove /dev/sdb --rate 100M # 限速 100MB/s
经验值:
7.2 监控 pvmove 进度
# 1. 用 watch 实时看
$ watch -n 5 'lvs -a -o lv_name,move_percent vg_data'
# 2. Zabbix / Prometheus 监控 move_percent 字段
7.3 中途出问题怎么办
如果 pvmove 中途异常(如断电、设备消失):
# 1. 看状态
$ pvs
$ lvs -a
# 2. 中止 pvmove
$ pvmove --abort
# 3. 重新启动
$ pvmove /dev/sdb /dev/sdd
# 4. 还不行就还原 metadata
$ vgcfgrestore vg_data
7.4 整机迁移注意事项
如果要把数据从旧机器迁到新机器:
- 3. 新机器:
vgimport(如果与已有 VG UUID 冲突)
八、本篇小结
| |
|---|
| pvcreate |
| pvmove /dev/old /dev/new |
| pvmove --rate 100M |
| lvs -o move_percent |
| pvmove --abort |
| vgreduce |
| vgsplit |
| vgmerge |
口诀:
- • 故障盘先看
dmesg,不要贸然 pvremove