Proxmox上面的用来启动系统的data pool里面发现一个坏掉的磁盘。本文记录一下更换磁盘的操作流程。

前提

我这里的Proxmox上面,boot drive用的是两个旧的笔记本上面拆下来的2.5英寸HDD。性能什么的自然是惨不忍睹,但是HDD一个好处是,坏的时候,是一种 gradually的坏,而SSD可能坏掉的时候就是彻底崩溃。

这个datapool是在安装Proxmox的时候就创建的。是ZFS Mirror。按照Proxmox的习惯,这个pool的名字都是 rpool.

过程

zpool status rpool 发现有坏盘:

root@pve0:~# zpool status rpool
  pool: rpool
 state: DEGRADED
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-9P
  scan: scrub repaired 2.88M in 00:25:09 with 0 errors on Wed Aug  2 14:42:06 2023
config:

        NAME                                      STATE     READ WRITE CKSUM
        rpool                                     DEGRADED     0     0     0
          mirror-0                                DEGRADED     0     0     0
            ata-ST500LT012-9WS142_XXXXXX-part3  ONLINE       0     0     0
            ata-ST95005620AS_XXXXXX-part3       DEGRADED     0     0    96  too many errors

官方的文档在这里:ZFS on Linux - Proxmox VE

决定用闲置的 500GB的Crucial MX500来顶替坏掉的HDD。并没有什么特别的理由,只是因为手头500GB的SATA SSD只有这么一块。当前MX500的设备地址是/dev/sde,而rpool里面依旧正常的那个盘是 /dev/sda。

首先是确定一下自己的boot是用的 grub还是systemd boot。这一步推荐用这个命令:

$ efibootmgr -v

如果正常显示出 Linux Boot Manager 和 UEFI OS 之类的,就可以确定一定是 systemd boot了。另外如果启动的时候 Proxmox的选项是黑底白色选项框,那肯定也是 systemd boot了。还有就是,Proxmox 7之后系统默认都是 Systemd boot。如果你的系统是Proxmox 7之后的版本,那肯定就是Systemd boot了。以下的步骤都是根据 Systemd boot来做的。

首先是复制Partition Table。这点跟一般的ZFS pool 不一样。用来Boot的ZFS pool实际上是先有分区的。也就是说,ZFS的部分实际上只是一个 Partition。这个做法实际上在ZFS里面应该是不推荐的,ZFS实际上永远希望你用整个盘为单位创建Pool。但是Boot partition的情况其实也比较特殊,因为启动之后这个分区肯定是不会读写的了(基本上读写为0),所以可能并不会对ZFS造成什么困扰。

$ sgdisk /dev/sda -R /dev/sde
$ sgdisk /dev/sde

然后是 zpool replace 。这里需要注意的是,zpool是不能用 /dev/sdx 这种磁盘标注方式的,一般都是用 /dev/disk/by-id/xxxxx-xxx-xxx 这种。/dev/sdx 这种实际上是经常有可能发生变化的,并不可靠。而ID可以说是可靠的,硬盘的型号和序列号都会在里面。

# you can't use '/dev/sdx' here
$ zpool replace  rpool /dev/disk/by-id/ata-ST95005620AS_XXXXXXXX-part3 /dev/disk/by-id/ata-CT500MX500SSD1_XXXXXXXXXXX-part3

这一步需要一点点等待,ZFS会进行 resilver,完成之后parition 3上面的ZFS mirror部分就完成了。

期间如果跑 zpool status rpool 输出大概如下,会看到有一个磁盘正在 replace。

root@pve0:~# zpool status rpool
  pool: rpool
 state: DEGRADED
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 Sun Aug  6 08:29:23 2023
        88.4G scanned at 4.91G/s, 778M issued at 43.2M/s, 88.4G total
        777M resilvered, 0.86% done, 00:34:36 to go
config:
 
        NAME                                         STATE     READ WRITE CKSUM
        rpool                                        DEGRADED     0     0     0
          mirror-0                                   DEGRADED     0     0     0
            ata-ST500LT012-9WS142_XXXXXX-part3     ONLINE       0     0     0
            replacing-1                              DEGRADED     0     0     0
              ata-ST95005620AS_XXXXXXX-part3        DEGRADED     0     0    96  too many errors
              ata-CT500MX500SSD1_XXXXXXXX-part3  ONLINE       0     0     0  (resilvering)
 
errors: No known data errors

最后是在新的磁盘的Partition 2写入boot。

$ proxmox-boot-tool format /dev/disk/by-id/ata-CT500MX500SSD1_XXXXXX-part2
 
$ proxmox-boot-tool init /dev/disk/by-id/ata-CT500MX500SSD1_XXXXXX-part2

之后最好再用 proxmox-boot-tool status 检查一下状态。

测试

Boot的部分没有什么好办法,把原来的系统盘拔出来,看看用新的盘能不能启动。这一步关机是没法避免的。不过经过这次操作,可以确定这个流程是靠谱的。

ZFS的部分,只要 zpool status 没有报错,就应该是没有问题了。

还有疑问的小伙伴可以参考这篇文章:Proxmox VE 7 replace zfs boot disk