第 11 章:数据迁移
第 11 章:数据迁移
11.1 迁移方案概述
11.1.1 迁移方式对比
| 方式 | 原地转换 | 数据迁移(rsync) | 数据迁移(Send/Receive) |
|---|
| 需要额外磁盘 | ❌ | ✅ | ✅ |
| 数据风险 | 中 | 低 | 低 |
| 耗时 | 中等 | 较长 | 较长 |
| 保留原系统 | ❌(覆盖) | ✅(保留) | ✅(保留) |
| 子卷布局 | 自动生成 | 手动规划 | 手动规划 |
| 回滚难度 | 高 | 低 | 低 |
| 推荐场景 | 快速迁移 | 新服务器 | 已有 Btrfs 备份 |
11.1.2 迁移前检查清单
11.2 原地转换(ext4 → Btrfs)
11.2.1 原理
btrfs-convert 工具可以在不丢失数据的情况下将 ext4 文件系统转换为 Btrfs:
转换前 (ext4):
┌─────────────────────────────────────┐
│ ext4 数据 | ext4 元数据 | 空闲空间 │
└─────────────────────────────────────┘
转换后 (btrfs):
┌───────────────────────────────────────────────────────┐
│ Btrfs 元数据 | ext4 数据映射 | Btrfs 新数据 | 空闲空间 │
│ | (只读回滚用) | | │
└───────────────────────────────────────────────────────┘
11.2.2 转换步骤
# 1. ⚠️ 备份!备份!备份!
sudo rsync -av /important-data/ /backup/
# 2. 卸载文件系统
sudo umount /data
# 3. 检查 ext4 文件系统
sudo e2fsck -f /dev/sdb1
# 必须完全干净才能转换
# 4. 执行转换
sudo btrfs-convert /dev/sdb1
# Creating filesystem with 26214400 4k blocks and 6553600 inodes
# ...
# Conversion complete
# 5. 挂载转换后的文件系统
sudo mount /dev/sdb1 /data
# 6. 验证数据
ls /data
# 应该能看到所有原有数据
# 7. 创建子卷布局(可选但推荐)
sudo btrfs subvolume create /data/@
sudo btrfs subvolume create /data/@home
# ... 移动数据到子卷 ...
# 8. 压缩已有数据(可选)
sudo btrfs filesystem defragment -r -czstd /data
# 9. 确认一切正常后,删除 ext4 回滚映像以释放空间
# ⚠️ 删除后无法回滚到 ext4!
sudo btrfs subvolume delete /data/ext2_saved
# 或
sudo btrfs balance start /data
11.2.3 转捔回滚
# 如果转换后出现问题,可以回滚到 ext4
# ⚠️ 只有在未删除 ext2_saved 子卷时才能回滚!
sudo umount /data
sudo btrfs-convert -r /dev/sdb1
sudo mount /dev/sdb1 /data
# 文件系统已恢复为 ext4
11.2.4 转换注意事项
| 事项 | 说明 |
|---|
| 空间要求 | 需要足够的空闲空间存储 ext4 元数据副本 |
| e2fsck | 转换前必须完整检查,任何错误都可能导致转换失败 |
| 回滚映像 | ext2_saved 子卷是回滚的关键,确认无误前不要删除 |
| 性能 | 转换后的数据布局不是最优的,建议后续做 balance |
| 大文件系统 | 转换 1TB+ 可能需要数小时 |
11.3 数据迁移(rsync)
11.3.1 准备新 Btrfs 文件系统
# 1. 创建新 Btrfs 文件系统
sudo mkfs.btrfs -L "new-data" /dev/sdc1
# 2. 挂载并创建子卷布局
sudo mount /dev/sdc1 /mnt/new
sudo btrfs subvolume create /mnt/new/@
sudo btrfs subvolume create /mnt/new/@home
sudo btrfs subvolume create /mnt/new/@var
# 3. 设置默认子卷
DEFAULT_ID=$(sudo btrfs subvolume list /mnt/new | grep "path @$" | awk '{print $2}')
sudo btrfs subvolume set-default "$DEFAULT_ID" /mnt/new
11.3.2 迁移数据
# 1. 确保源系统为只读或单用户模式
sudo systemctl isolate rescue.target
# 2. 挂载源和目标
sudo mount /dev/sdb1 /mnt/old # 源 ext4
sudo mount /dev/sdc1 /mnt/new # 目标 Btrfs
# 3. rsync 迁移
sudo rsync -avHAXS --progress /mnt/old/ /mnt/new/@/
# 参数说明:
# -a 归档模式(保留权限、时间戳等)
# -v 详细输出
# -H 保留硬链接
# -A 保留 ACL
# -X 保留扩展属性
# -S 稀疏文件处理
# --progress 显示进度
11.3.3 迁移 /home 目录
# 如果 /home 是独立分区
sudo rsync -avHAXS /mnt/old/home/ /mnt/new/@home/
# 如果 /home 在根分区中
sudo rsync -avHAXS /mnt/old/home/ /mnt/new/@home/
# 然后从根目录中排除 home
11.3.4 更新引导配置
# 1. 更新 fstab
# 获取新 Btrfs 分区的 UUID
NEW_UUID=$(sudo blkid -s UUID -o value /dev/sdc1)
# 生成新的 fstab 条目
cat << EOF | sudo tee /etc/fstab
UUID=$NEW_UUID / btrfs subvol=/@,defaults,compress=zstd:1 0 0
UUID=$NEW_UUID /home btrfs subvol=/@home,defaults,compress=zstd:3 0 0
UUID=$NEW_UUID /var btrfs subvol=/@var,defaults 0 0
EOF
# 2. 更新 GRUB
sudo grub-install /dev/sda
sudo update-grub
# 3. 更新 initramfs
sudo update-initramfs -u
11.4 数据迁移(Send/Receive)
11.4.1 从 ext4 转换后使用 Send/Receive
# 1. 在转换后的 Btrfs 上创建只读快照
sudo btrfs subvolume snapshot -r /mnt/old/@ /mnt/old/@snap-full
# 2. 发送到新文件系统
sudo btrfs send /mnt/old/@snap-full | sudo btrfs receive /mnt/new/
# 3. 在新系统上重命名
sudo mv /mnt/new/@snap-full /mnt/new/@
11.4.2 从现有 Btrfs 迁移到新 Btrfs
# 场景:迁移到更大的磁盘
# 1. 在旧系统上创建快照
sudo btrfs subvolume snapshot -r /mnt/old/@ /mnt/old/@snap
# 2. 发送到新文件系统
sudo btrfs send /mnt/old/@snap | sudo btrfs receive /mnt/new/
# 3. 在新系统上设置
sudo btrfs subvolume snapshot /mnt/new/@snap /mnt/new/@
sudo btrfs subvolume delete /mnt/new/@snap
11.5 迁移后优化
11.5.1 空间优化
# 1. 执行 balance 回收空间
sudo btrfs balance start -dusage=50 /mnt/data
# 2. 启用压缩并碎片整理
sudo btrfs filesystem defragment -r -czstd /mnt/data
# 3. 查看压缩效果
sudo compsize /mnt/data
11.5.2 子卷优化
# 重新组织数据到子卷
# 假设迁移后所有数据都在 @ 子卷根目录
# 创建子卷结构
sudo btrfs subvolume create /mnt/data/@home
sudo btrfs subvolume create /mnt/data/@var
sudo btrfs subvolume create /mnt/data/@snapshots
# 移动数据
sudo mv /mnt/data/@/home/* /mnt/data/@home/
sudo mv /mnt/data/@/var/* /mnt/data/@var/
# 更新 fstab
11.6 回滚方案
11.6.1 原地转换的回滚
# 如果保留了 ext2_saved 子卷
sudo umount /data
sudo btrfs-convert -r /dev/sdb1
sudo mount /dev/sdb1 /data
11.6.2 数据迁移的回滚
# 数据迁移保留了原始磁盘,直接挂载回原系统
sudo umount /mnt/new
sudo mount /dev/sdb1 /data # 原 ext4 系统
# 更新 fstab 恢复原 UUID
11.6.3 混合回滚
# 1. 从 Btrfs 备份恢复数据到 ext4
sudo mount /dev/sdb1 /mnt/ext4
sudo rsync -av /mnt/btrfs-backup/ /mnt/ext4/
# 2. 更新引导配置
sudo update-grub
sudo update-initramfs -u
11.7 本章小结
| 方式 | 命令 | 适用场景 |
|---|
| 原地转换 | btrfs-convert /dev/sdX | 快速,无需额外磁盘 |
| rsync 迁移 | rsync -avHAXS /src/ /dst/ | 最灵活,推荐 |
| Send/Receive | btrfs send | btrfs receive | Btrfs 到 Btrfs |
关键要点:
- 永远先备份,至少两份
- 原地转换方便但风险稍高
- rsync 迁移最灵活,推荐新部署
- 转换后删除
ext2_saved 前确认一切正常 - 迁移后需要更新 fstab 和 GRUB
扩展阅读