ZFS在线替换硬盘
安装了Freebsd-12.1-RELEASE,发现硬盘太小,且有坏道,想用新盘替换。
原系统的硬盘信息为:
> gpart show /dev/diskid/DISK-4MT0PQB6
=> 40 312581728 diskid/DISK-4MT0PQB6 GPT (149G)
40 1024 1 freebsd-boot (512K)
1064 304086016 2 freebsd-zfs (145G)
304087080 8388608 3 freebsd-swap (4.0G)
312475688 106080 - free - (52M)
/dev/ada0
和/dev/ada1
之类的路径表示硬盘。但我的机器支持硬盘热插拔,且经常因手贱各种捣鼓,硬盘位可能会改变,所以用/dev/diskid/...
的方式更保险。
当然还可以用disklabel命令给每块硬盘取个名字并且贴上标签。因暂时我只有两块硬盘,还无需简单问题复杂化。
现在有一块新硬盘(DISK-9QF4ATCW),需格掉原来的windows分区,建立和DISK-4MT0PQB6一样的分区表。 根分区和这块盘做成mirror即可自动同步。 同步完毕后对新盘的freebsd-boot分区写入启动项。 最后对新磁盘扩容。
由于老磁盘的freebsd-swap在第3个分区,freebsd-zfs和free的磁盘空间不连续,为扩容方便,新磁盘的分区格式最好是像下面这样。 ZFS分区和老盘的大小一样,所以在复制完毕后还要对新盘的pool和分区都进行扩容。
1 freebsd-boot (512K)
2 freebsd-swap (4.0G)
3 freebsd-zfs (145G)
- free - (84G)
小贴士:建议安装FreeBSD时把可能需要扩容的freebsd-zfs格式分区放在分区表的最后。
1. 新硬盘建立分区表¶
1.1 清除新盘的分区¶
> gpart destroy -F /dev/diskid/DISK-9QF4ATCW
diskid/DISK-9QF4ATCW destroyed
-F
为强行抹去分区表,如果硬盘原来被挂载过,不加此参数可能会显示Devise Busy的错误。
1.2 设置磁盘为GPT分区表¶
> gpart create -s GPT /dev/diskid/DISK-9QF4ATCW
diskid/DISK-9QF4ATCW created
> gpart bootcode -b /boot/pmbr /dev/diskid/DISK-9QF4ATCW
bootcode written to diskid/DISK-9QF4ATCW
1.3 建立freebsd-boot分区¶
该分区大小为1024K:
> gpart add -b 40 -s 1024 -t freebsd-boot /dev/diskid/DISK-9QF4ATCW
diskid/DISK-9QF4ATCWp1 added
> gpart bootcode -p /boot/gptboot -i 1 /dev/diskid/DISK-9QF4ATCW
partcode written to diskid/DISK-9QF4ATCWp1
1.4 建立swap分区¶
为和老磁盘一致,这里也建立一个4GB的swap分区,但完全可以分得更大或更小:
> gpart add -s 4G -t freebsd-swap /dev/diskid/DISK-9QF4ATCW
diskid/DISK-9QF4ATCWp2 added
1.5 建立用于同步根目录的zfs分区¶
> gpart add -s 145G -t freebsd-zfs /dev/diskid/DISK-9QF4ATCW
diskid/DISK-9QF4ATCWp3 added
> gpart show /dev/diskid/DISK-9QF4ATCW
=> 40 488397088 diskid/DISK-9QF4ATCW GPT (233G)
40 1024 1 freebsd-boot (512K)
1064 8388608 2 freebsd-swap (4.0G)
8389672 304087040 3 freebsd-zfs (145G)
312476712 175920416 - free - (84G)
2. 存储池(zpool)同步¶
2.1 检查操作系统zpool¶
如果Freebsd安装在ZFS分区上,默认会有一个名为root的zpool,而在线镜像复制需将新盘作为mirror加入root存储池。
> zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
root 144G 117G 27.0G - - 39% 81% 1.00x ONLINE -
> zpool status root
pool: root
state: ONLINE
scan: resilvered 117G in 0 days 01:00:06 with 0 errors on Wed May 20 07:56:42 2020
config:
NAME STATE READ WRITE CKSUM
root ONLINE 0 0 0
diskid/DISK-4MT0PQB6p2 ONLINE 0 0 0
errors: No known data errors
pool: root
下只有老磁盘的第2分区。
2.2 增加硬盘镜像¶
将新磁盘的第3分区作为镜像attach到root存储池里:
> zpool attach root /dev/diskid/DISK-4MT0PQB6p2 /dev/diskid/DISK-9QF4ATCWp3
2.3 查看zpool状态¶
> zpool status root
pool: root
state: ONLINE
status: One or more devices is currently being resilvered. The pool will
continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
scan: resilver in progress since Wed May 20 08:14:26 2020
117G scanned at 1.48G/s, 849M issued at 10.7M/s, 117G total
840M resilvered, 0.71% done, 0 days 03:04:58 to go
config:
NAME STATE READ WRITE CKSUM
root ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
diskid/DISK-4MT0PQB6p2 ONLINE 0 0 0
diskid/DISK-9QF4ATCWp3 ONLINE 0 0 0
errors: No known data errors
2.4 继续查看zpool状态¶
> zpool status root
pool: root
state: ONLINE
scan: resilvered 117G in 0 days 01:00:53 with 0 errors on Wed May 20 03:01:06 2020
config:
NAME STATE READ WRITE CKSUM
root ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
diskid/DISK-4MT0PQB6p2 ONLINE 0 0 0
diskid/DISK-9QF4ATCWp3 ONLINE 0 0 0
errors: No known data errors
2.5 在新磁盘启动分区写入启动代码¶
> gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 /dev/diskid/DISK-9QF4ATCW
partcode written to diskid/DISK-9QF4ATCWp1
bootcode written to diskid/DISK-9QF4ATCW
-i 1
表示启动代码写入DISK-9QF4ATCW的第1分区,即freebsd-boot分区。
2.6 在root存储池里删掉老磁盘¶
> zpool detach root /dev/diskid/DISK-4MT0PQB6p2
3. 新磁盘扩容¶
3.1 将freebsd-root分区扩容¶
由于新磁盘的ZFS根分区在最后,分区扩容非常方便:
> gpart resize -i 3 /dev/diskid/DISK-9QF4ATCWp3
diskid/DISK-9QF4ATCWp3 resized
> gpart show /dev/diskid/DISK-9QF4ATCW
=> 40 488397088 diskid/DISK-9QF4ATCW GPT (233G)
40 1024 1 freebsd-boot (512K)
1064 8388608 2 freebsd-swap (4.0G)
8389672 480007456 3 freebsd-zfs (229G)
3.2 将root存储池扩容¶
虽然新磁盘的容量已扩大为229G,但操作系统的root存储池仍然是老系统的114G,如下:
> zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
root 144G 117G 26.7G - - 40% 81% 1.00x ONLINE -
> zpool online -e root /dev/diskid/DISK-9QF4ATCWp3
> zpool list
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
root 228G 117G 111G - - 25% 51% 1.00x ONLINE -
总结¶
在ZFS下在线扩容或更换硬盘非常简单。硬盘分区应尽量把数据区放在分区表的最后。
以上更换硬盘的方法是利用ZFS的镜像功能复制了整个根分区,然后在新硬盘启动分区中写入启动代码。