阿里云 ECS 数据盘迁移实战:ext4 分区盘与 LVM 逻辑卷迁移
本文整理自一次阿里云 ECS 数据盘迁移实践,覆盖两类常见场景:普通 ext4 分区盘迁移,以及 LVM 逻辑卷自动挂载配置。重点记录迁移流程、停写一致性、
fstab写法、数据库占用排查,以及几个生产环境里很容易踩到的坑。
1. 背景说明
云服务器数据盘迁移,本质上不是简单的“复制文件”,而是一次需要兼顾 数据一致性、可回滚、可验证、可自动挂载 的生产变更。
这次迁移主要涉及两个场景:
| 场景 | 原挂载 | 新目标 | 重点 |
|---|---|---|---|
| 普通 ext4 分区盘迁移 | /dev/vdb1 -> /G4B | /dev/vdc1 -> /G4B | rsync 双阶段迁移、停库、切换挂载点 |
| LVM 逻辑卷挂载 | /dev/vde1 -> vgdata-lvdata -> /G4B/uploadfile | 开机自动挂载 | 使用 UUID 写入 /etc/fstab |
其中 /G4B 目录下存在数据库相关数据,可能涉及 MySQL、MongoDB、PostgreSQL。因此迁移过程中最关键的一点是:最终同步和切换挂载前,必须停止业务写入。
2. 迁移目标
2.1 场景 A:普通 ext4 分区盘迁移
当前磁盘情况如下:
示例输出:
块设备情况:
示例结构:
迁移目标:
- 将旧盘
/dev/vdb1上的数据迁移到新盘/dev/vdc1。 - 保持业务目录仍然使用
/G4B,减少应用配置改动。 - 迁移后通过 UUID 写入
/etc/fstab,确保 ECS 重启后自动挂载。 - 旧盘先保留一段时间,作为回滚保障。
2.2 场景 B:LVM 逻辑卷自动挂载
当前逻辑卷结构:
目标:
- 确认 LVM 逻辑卷文件系统类型与 UUID。
- 将逻辑卷挂载信息写入
/etc/fstab。 - 保证系统重启后
/G4B/uploadfile能自动挂载。
说明:云盘通常不建议走“原盘缩容”路线,尤其是生产环境。更稳妥的方式是:新盘创建、数据迁移、挂载切换、验证、保留旧盘、最后释放旧盘。XFS 文件系统不支持缩小,ext4 虽然支持离线缩小,但生产风险较高,不建议作为首选。
3. 迁移前检查清单
迁移前不要急着执行 rsync 或格式化新盘,先把以下内容确认清楚。
3.1 确认挂载点与文件系统
重点看四个信息:
/G4B当前挂载在哪块盘上。- 新盘设备名是否确认,例如
/dev/vdc。 - 文件系统类型是 ext4、xfs 还是其他。
/G4B/uploadfile是否由 LVM 逻辑卷提供。
3.2 确认数据库数据目录
数据库数据目录如果在 /G4B 下,迁移时就不能只当普通文件处理。必须确认数据库是否持续写入。
MySQL:
MongoDB:
PostgreSQL:
3.3 做好云盘快照和回滚预案
生产环境建议至少做好三件事:
- 在阿里云控制台给旧数据盘打快照。
- 迁移完成后旧盘不要马上释放,先保留观察。
- 明确回滚方式:如果新盘启动异常,可重新挂回旧盘 UUID 或旧设备。
4. 方案一:ext4 普通分区盘迁移
推荐流程如下:
4.1 新盘分区
注意:下面命令会清空
/dev/vdc,执行前必须确认/dev/vdc是新盘,不是旧数据盘。
4.2 格式化 ext4
如果这是数据盘,可以适当降低 ext4 默认预留块比例,例如设置为 1%:
说明:
- ext4 默认会预留一部分空间给 root 使用。
- 对大容量数据盘而言,默认预留比例可能浪费较多空间。
- 业务数据盘设置为 1% 较常见,但仍需根据实际环境评估。
4.3 临时挂载新盘
确认新盘已经挂载到 /mnt/G4B_new 后,再开始同步数据。
4.4 rsync 第一遍预同步
第一遍同步可以在业务不停机的情况下执行,目的是先把大部分数据复制过去,减少最终停机窗口。
参数说明:
| 参数 | 作用 |
|---|---|
-a | 归档模式,保留权限、时间、软链接等 |
-H | 尽量保留硬链接 |
-A | 保留 ACL |
-X | 保留扩展属性 |
--numeric-ids | 按 UID/GID 数字同步,避免用户名映射异常 |
--info=progress2 | 显示整体同步进度 |
5. 切换窗口:停止写入并做最终同步
5.1 为什么必须停写入
如果 /G4B 下有数据库数据文件,迁移时数据库仍在写入,就可能出现以下问题:
- 数据文件正在变化,rsync 复制到的是中间状态。
- WAL、binlog、journal 与数据文件时间点不一致。
- 目标盘数据库启动失败,或者更糟糕:能启动但存在隐性数据损坏。
所以正确做法是:
第一遍 rsync 可以不停业务;第二遍 rsync 前必须停止写入。
5.2 排查 /G4B 被哪些进程占用
尝试将挂载点改为只读时,可能会遇到:
报错:
这说明仍有进程正在访问 /G4B。使用 fuser 反查:
常见占用进程包括:
mysqldmongodpostmaster/postgres- 当前 shell 的工作目录在
/G4B下
建议先执行:
避免自己的 shell 占用挂载点。
5.3 停止数据库服务
使用 systemd 停止常规服务:
再次确认:
如果仍然有进程占用,需要逐个处理。
5.4 MongoDB 找不到 service 名的处理方式
这次迁移中遇到一个典型问题:MongoDB 进程存在,但 systemctl stop mongod 停不掉。通过 PID 反查:
看到类似结果:
这说明 MongoDB 很可能不是由独立的 mongod.service 管理,而是通过 SSH 会话手工启动后 fork 到后台。
优先使用 MongoDB 自身命令优雅关闭:
如果 mongosh 不在 PATH 中,可以先找二进制路径:
无法优雅关闭时,再使用信号终止:
kill -KILL是最后手段,生产环境不建议一上来就使用。能通过数据库自身机制关闭,就不要强杀。
5.5 rsync 第二遍最终同步
确认业务写入已经停止后,执行最终同步:
这里必须加 --delete,确保目标目录与源目录完全一致。
6. 切换挂载点
6.1 不推荐直接使用 mount --move
本次迁移中曾尝试:
但遇到错误:
原因是当前挂载点处于 shared mount propagation 场景下,mount --move 会受到限制。
6.2 稳妥切换方式:umount + mount
更稳妥的方式是直接卸载旧挂载和临时挂载,再把新盘挂载到原目录:
确认 /G4B 已经挂载到新盘后,再继续修改 /etc/fstab。
7. 配置 /etc/fstab 自动挂载
7.1 使用 UUID,不建议使用 /dev/vdc1
云服务器磁盘设备名可能因为重启、热插拔、挂载顺序变化而发生变化。生产环境建议使用 UUID 挂载。
查看新盘 UUID:
示例:
编辑 /etc/fstab:
写入或替换 /G4B 对应行:
更推荐的云服务器写法:
字段说明:
| 字段 | 说明 |
|---|---|
UUID=<NEW_UUID> | 使用文件系统 UUID 定位磁盘 |
/G4B | 挂载点 |
ext4 | 文件系统类型 |
defaults | 默认挂载参数 |
nofail | 挂载失败不阻塞系统启动 |
x-systemd.device-timeout=10s | systemd 等待设备出现的超时时间 |
0 | 不使用 dump 备份 |
2 | 非根分区 fsck 检查顺序 |
验证 fstab 是否正确:
注意:修改
/etc/fstab后一定要执行mount -a。如果这里报错,说明重启后大概率也会挂载失败。
8. 启动服务并验证
启动数据库服务:
检查监听端口:
建议进一步验证:
如果业务有健康检查接口,也建议立即验证:
9. 方案二:LVM 逻辑卷自动挂载
如果数据目录是 LVM 逻辑卷,例如:
可以按下面方式配置自动挂载。
9.1 查看 LVM 信息
确认逻辑卷路径、UUID、文件系统类型。
9.2 写入 /etc/fstab
推荐写法:
如果文件系统是 ext4:
验证:
9.3 LVM 自动激活检查
大多数 Linux 发行版默认会自动激活 LVM。如果担心重启后没有激活,可以检查:
通常情况下,只要 pvs、vgs、lvs 正常,fstab 写 UUID 即可。
10. 常见故障与处理
10.1 mount -o remount,ro /G4B 报 busy
原因:
- 有进程打开了
/G4B下的文件。 - 有进程工作目录在
/G4B下。 - 数据库、日志服务、备份脚本仍在访问该目录。
处理:
根据输出停服务。最后手段才考虑:
10.2 MongoDB 不受 systemd 管理
现象:
没有效果,或者找不到 unit。
排查:
如果看到 mongod 挂在 sshd.service 下面,说明它大概率是手工启动的。
建议后续补充 systemd unit,避免生产服务脱离进程管理。
10.3 mount --move 报 shared mount 不支持
现象:
处理:
不需要强行研究 mount --make-rprivate,生产变更中优先选择简单、可控、可回滚的方式。
10.4 mount -a 报错
常见原因:
- UUID 写错。
- 文件系统类型写错,例如实际是 xfs,却写成 ext4。
- 挂载点目录不存在。
/etc/fstab有多余空格、不可见字符或字段缺失。
排查命令:
11. 生产环境最佳实践
11.1 迁移前
- 阿里云控制台创建旧数据盘快照。
- 确认新盘设备名,避免误格式化旧盘。
- 使用
df -Th、lsblk -f、findmnt盘点挂载关系。 - 确认 MySQL、MongoDB、PostgreSQL 数据目录是否在迁移目录下。
- 提前评估停机窗口,第一遍 rsync 尽量提前完成。
11.2 迁移中
- 新盘分区、格式化、临时挂载。
- 第一遍 rsync 预同步。
- 停止业务写入,尤其是数据库。
- 使用
fuser -vm确认挂载点没有占用。 - 第二遍 rsync 使用
--delete做最终对齐。 - 使用
umount + mount切换挂载点。 - 使用 UUID 更新
/etc/fstab。 - 执行
mount -a验证配置。
11.3 迁移后
- 使用
df -Th和findmnt确认挂载到新盘。 - 启动数据库并检查端口、日志、健康检查接口。
- 验证业务读写是否正常。
- 保留旧盘观察一段时间,不要立即释放。
- 将手工启动的 MongoDB 等服务纳入 systemd 管理。
- 补充变更记录,记录旧盘、新盘、UUID、迁移时间和回滚方式。
12. 常用命令速查
13. 总结
这类数据盘迁移最容易出问题的点,不在于 rsync 命令本身,而在于三个细节:
- 是否确认了真实写入进程:数据库、日志、脚本都可能占用挂载点。
- 最终同步时是否真正停止写入:数据库文件迁移必须保证一致性。
- 自动挂载是否经过验证:
fstab写完必须执行mount -a或findmnt --verify。
生产环境里,迁移成功的关键不是操作有多快,而是每一步都能验证、能回滚、能解释。只要做到“快照兜底、双阶段同步、停写切换、UUID 挂载、旧盘保留”,这类 ECS 数据盘迁移就会稳很多。
讨论 0