强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 11 章:数据迁移

第 11 章:数据迁移

11.1 迁移方案概述

11.1.1 迁移方式对比

方式原地转换数据迁移(rsync)数据迁移(Send/Receive)
需要额外磁盘
数据风险
耗时中等较长较长
保留原系统❌(覆盖)✅(保留)✅(保留)
子卷布局自动生成手动规划手动规划
回滚难度
推荐场景快速迁移新服务器已有 Btrfs 备份

11.1.2 迁移前检查清单

  • 确认内核版本 >= 5.10(推荐 6.1+)
  • 确认 btrfs-progs 版本 >= 6.0
  • 完整数据备份(至少 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/Receivebtrfs send | btrfs receiveBtrfs 到 Btrfs

关键要点

  1. 永远先备份,至少两份
  2. 原地转换方便但风险稍高
  3. rsync 迁移最灵活,推荐新部署
  4. 转换后删除 ext2_saved 前确认一切正常
  5. 迁移后需要更新 fstab 和 GRUB

扩展阅读