618的时候借机搞了几张 1TB 的 SSD ,用来扩容、替换掉原来工作机以及服务器上的 RAID1 阵列。

记录一下操作的思路、过程以及参考资料。

btrfs 复制磁盘

首先推荐认真读一下 trfs 自己的资料 1

情景说明一下,原来的单张 256GB ,文件系统已经是 btrfs ,现在想扩容将硬盘更换 为一块 512GB 。 离线使用 rsync 会出现个问题, hard link 文件以及 btrfs 的 subvolume 内 容会重复复制,造成空间占满。

这里假定离线维护(例如使用 SystemRescueCD)

  • 将文件系统挂载到 /mnt/old
  • 旧磁盘为 /dev/sda2
  • 新磁盘为 /dev/sdb2

过程中磁盘数据会过三遍,前两遍整个分区数据,最后一遍是 meta 信息。

这里笔者也尝试使用了其他例如 btrfs send | btrfs recv ,但是各种报错均不成功, 也许是使用方法不正确。

另外一点需要注意的是,新磁盘的分区,理论上不能比老的分区小。否则的话, 建议(没装满的话)先缩小老的分区(shrink) 。

# 在新磁盘准备分区,创建 btrfs 文件系统
$ mkfs.btrfs /dev/sdb2

# 挂载原来的分区
$ mount /dev/sda2 /mnt/old

# 将新分区添加到原来的 btrfs 文件系统,后面是挂载点
$ btrfs device add /dev/sdb2 /mnt/old

# 触发数据再平衡,这里 -d 表示数据, -m 表示 meta 信息,均使用 raid1 模式
$ btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt/old

# 查看平衡进度
$ btrfs balance status /mnt/old

看一下操作步骤,其实在线维护也是可以的。不过既然磁盘会同步数据,还是离线维护, 减少干扰比较好。 此时两个设备相当于组成了 RAID1 。 待再平衡完成后,卸载文件系统,标记旧磁盘下线(或者关机,将磁盘拿掉)

# 将 /dev/sda 从系统中标记离线删除,再使用 lsblk 或者检查 /dev/sda 是否还存在。无效的话关机将磁盘拆掉
$ echo 1 | sudo tee /sys/block/sda/device/delete

# 挂载新磁盘,注意参数 -o degraded 表示阵列降级,允许 raid1 缺失设备情况下挂载
$ mount -o degraded /dev/sdb2 /mnt/new

# 触发数据再平衡
$ btrfs balance start -dconvert=single -mconvert=single /mnt/new

# 平衡完成后
$ btrfs device remove missing /mnt/new

继续等待再平衡结束,即将 /dev/sdb2 的分区降级回单盘。此时卸载重新 挂载 mount /dev/sdb2 /mnt/new 将不会出错。

最后再整理一遍 meta 信息。

$ btrfs balance start -mconvert=dup /mnt/new

此时已完成新磁盘的复制工作。

LVM raid 复制磁盘

同样推荐先认真读一下 Linux 软 RAID 的资料 2

同样说明一下情景与假设。 已经有两块 1TB 的磁盘中,两个分区组成了 dm-raid raid1 阵列,希望使用新的两块磁盘扩容替换。 我们采取逐块替换方式,都采用 RAID1 自身的数据修复功能。

假定

  • 离线维护
  • /dev/sda2/dev/sdb2 组成 /dev/md0
  • 新设备 /dev/sdc2/dev/sdd2 (不过我们后面会先拆掉一块磁盘, 替换,保持系统里只有2块设备)
  • 使用 md-raid ,与具体文件系统无关。

如果阵列是系统节点 (rootfs) 那么 必须要离线维护。

不过, 假如硬件上足够挂载4个磁盘设备,其实是 可以将 /dev/md0 与 新组件一个 /dev/md1 ,然后通过与上述 btrfs 相同的手法,在线复制的。相当于在 md-raid raid1 的基础上再加了一层 btrfs raid1 。

# 标记 /dev/sdb2 设备故障
$ mdadm --manage /dev/md0 --fail /dev/sdb2

# 从阵列中移除设备,这步如果报 device busy ,那么说明还有资源使用,
# 请确认文件系统没有挂载
# mdadm --manage /dev/md0 --remove /de/sdb2

# 检查 md 设备状态,正常的 RAID1 是 [UU] ,此时变成类似 [U_]
$ cat /proc/mdstat

*注意*:如果硬件设备最多只能使用2个设备,此时重启 md 设备也是可以 正常挂载的,但状态如上。这里我们假定将 /dev/sdb 拆掉,装上新的设备。

准备新磁盘的分区,这里也是要求新分区不能比原来的分区小。

如果新旧设备的容量一模一样的话,这里有个偷懒的办法:

$ sfdisk -d /dev/sda | sfdisk /dev/sdb

加入新设备

$ mdadm --manage /dev/md0 --add /dev/sdb2

# 再次检查状态
$ cat /proc/mdstat

Personalities : [linear] [multipath] [raid0] [raid1] [raid5] [raid4] [raid6] [raid10]
md0 : active raid1 sda1[0] sdb1[1]
      24418688 blocks [2/1] [U_]
      [=>...................]  recovery =  9.9% (2423168/24418688) finish=2.8min speed=127535K/sec

我们会看到数据已经开始同步, 此时关机,重启等操作都不影响同步进度,开机会自动继续。

完成后再对另外一块磁盘做相同的操作即可完成整个替换工作。

实测结果:

  • 7200RPM + 32MB 缓存的 HDD 向 MX500 1TB 同步,离线大约 110MB/s
  • 7200RPM + 32MB 缓存的 HDD 向 MX500 1TB 同步,在线大约 95MB/s
  • 1TB 数据同步大约使用 2.5 小时
  • MX500 1TB 向 MX500 1TB 同步,离线大约 200 MB/s
  • 1TB 数据同步大约使用 1.2 小时

参考

__END__


  1. https://btrfs.wiki.kernel.org/index.php/Using_Btrfs_with_Multiple_Devices

  2. http://www.tldp.org/HOWTO/Software-RAID-HOWTO.html