zpool replace のディスク交換を中断2018年04月08日 07時57分21秒

ZFS でディスクを交換するときは、zpool replace pool old-device new-device で始める。そうすると、resilver が始まり、データの移行が進められる。

何らかの理由により、ディスクの交換を中断したいときがある。そんな時は、zpool detach pool new-deviceで中断できる。

$ zpool status
  pool: scratch
 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 Thu Apr  5 23:54:13 2018
        959G scanned out of 2.35T at 11.4M/s, 36h6m to go
        458G resilvered, 39.83% done
config:


        NAME                                    STATE     READ WRITE CKSUM
        zfs                                     DEGRADED     1     0   453
          raidz1-0                              DEGRADED     1     0 1.62K
            gpt/zfs1                            ONLINE       0     0     0
            replacing-1                         ONLINE       0     0   106
              gpt/zfs2                          ONLINE       2     0     0  (resilvering)
              gpt/zfs6                          ONLINE       0     0     0  (resilvering)
            gpt/zfs3                            ONLINE       1     0     0  (resilvering)
            replacing-3                         DEGRADED     2     0     0
              15470053991832379715              UNAVAIL      0     0     0  was
/dev/gpt/zfs4
              gpt/zfs5                          ONLINE       2     0     0  (resilvering)


$ zpool detach scratch /dev/gpt/zfs6
$ zpool status
  pool: scratch
 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 Thu Apr  5 23:54:13 2018
        961G scanned out of 2.35T at 11.4M/s, 36h5m to go
        458G resilvered, 39.83% done
config:


        NAME                                    STATE     READ WRITE CKSUM
        zfs                                     DEGRADED     1     0   453
          raidz1-0                              DEGRADED     1     0 1.62K
            gpt/zfs1                            ONLINE       0     0     0
            gpt/zfs2                            ONLINE       2     0     0  (resilvering)
ering)
            gpt/zfs3                            ONLINE       1     0     0  (resilvering)
            replacing-3                         DEGRADED     2     0     0
              15470053991832379715              UNAVAIL      0     0     0  was
/dev/gpt/zfs4
              gpt/zfs5                          ONLINE       2     0     0  (resilvering)
resilver が発生していたディスクはそのまま作業が進められるようだ。

zpool status -v で見られる変な名前のファイル2018年04月08日 13時01分12秒

zpool status で zfs のプールの状態を表示できる。zpool status だけなら一般ユーザでも実行できる。さらに、-v を付けたし、zpool status -v を行うと損傷を受けているファイルの一覧が見られる。こちらは特権ユーザの権限が必要になる。
$ zpool status -v
  pool: scratch
 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 Thu Apr  5 23:54:13 2018
        961G scanned out of 2.35T at 11.4M/s, 36h5m to go
        458G resilvered, 39.83% done
config:


        NAME                                    STATE     READ WRITE CKSUM
        zfs                                     DEGRADED     1     0   453
          raidz1-0                              DEGRADED     1     0 1.62K
            gpt/zfs1                            ONLINE       0     0     0
            gpt/zfs2                            ONLINE       2     0     0  (resilvering)
ering)
            gpt/zfs3                            ONLINE       1     0     0  (resilvering)
            replacing-3                         DEGRADED     2     0     0
              15470053991832379715              UNAVAIL      0     0     0  was
/dev/gpt/zfs4
              gpt/zfs5                          ONLINE       2     0     0  (resilvering)

errors: Permanent errors have been detected in the following files:

        scratch/media@2017:/freebsd/FreeBSD-10.2-RELEASE-i386-disc1.iso
        /mnt/scratch/media/freebsd/FreeBSD-11.1-RELEASE-i386-disc1.iso
        <0x202>:<0x2a>
        <0x2a>:<0x3f>
        <0x2a>:<0x49>
        <0x2a>:<0x57>

これを見れば、幾つか気が付くと思うが、スナップショットのファイルが損傷した場合と、スナップショットが取られていないファイルが損傷のファイルパスが若干異なるようだ。

そして、もう一つ括弧に囲まれた不思議な文字の羅列がある。これは、損傷が確認されたが既に消されているファイルになる。ファイルを削除したり、スナップショットを削除しても、zpool clear を行わないとそのまま残る様だ。

スナップショットに入っていると、恐らく、それ以降の全てのコピーが損傷している。当該ファイルが入っているスナップショットを全て消すと、ファイル名ではなく、この括弧連弾が表示される。スナップショットに入っていないファイルだと、rm で消すと、括弧連弾になる。

zfs send は破損したファイルがあると使えない2018年04月08日 23時36分06秒

ハードディスクが故障し、新しいディスクが届いたので、復旧作業をしている。

念のためにバックアップを確認してから進めている。他から手に入れたファイルや、既にバックアップとして保存されていたファイルは、別には保持していなかった。その様な優先度の低いファイルも再取得の手間を減らすために、再バックアップを進めている。

その中で、zfs send でうまく行かないファイルシステムがあった。

$ zfs list -r -t all scratch/media
NAME                   USED  AVAIL  REFER  MOUNTPOINT
scratch/media          281G  1.04T   280G  /mnt/zfs/media
scratch/media@2016     407K      -   143G  -
scratch/media@2017     150M      -   270G  -
scratch/media@2018     279K      -   279G  -
$ zfs send -v scratch/media@2016 > /dev/null
full send of scratch/media@2016 estimated size is 144G
total estimated size is 144G
TIME        SENT   SNAPSHOT
14:25:42   70.2K   scratch/media@2016
14:25:43   25.8M   scratch/media@2016
14:25:44   58.5M   scratch/media@2016
14:25:45   62.1M   scratch/media@2016
...
14:26:32   1.44G   scratch/media@2016
14:26:33   1.46G   scratch/media@2016
14:26:34   1.48G   scratch/media@2016
14:26:35   1.50G   scratch/media@2016
warning: cannot send 'scratch/media@2016': Input/output error
途中で止まっている。気がかりは数日前には既にあった。zpool で確認すると、このスナップショットには壊れたファイルがある。
$ zpool status -v
  pool: scratch
 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: resilvered 465G in 36h43m with 112 errors on Sat Apr  7 12:37:58 2018
config:

        NAME                                    STATE     READ WRITE CKSUM
        zfs                                     DEGRADED     1     0   453
          raidz1-0                              DEGRADED     1     0 1.62K
            gpt/zfs1                            ONLINE       0     0     0
            gpt/zfs2                            ONLINE       2     0     0  (resilvering)
ering)
            gpt/zfs3                            ONLINE       1     0     0  (resilvering)
            15470053991832379715                UNAVAIL      0     0     0  was
/dev/gpt/zfs4

errors: Permanent errors have been detected in the following files:

        scratch/media@2017:/freebsd/FreeBSD-10.2-RELEASE-i386-disc1.iso
        /mnt/scratch/media/freebsd/FreeBSD-11.1-RELEASE-i386-disc1.iso
        <0x202>:<0x2a>
        <0x2a>:<0x3f>
        <0x2a>:<0x49>
        <0x2a>:<0x57>

特に復旧できなくても大きな問題ではないので、rsync でファイルをコピーした。

実は、これ以外にも壊れていたファイルがあって、こまめにスナップショットを取っていたファイルシステムは難を逃れることが出来た。zfs スナップショットはある程度こまめに、そして各スナップショットのサイズを考慮して保持しておいた方が、復旧に楽だ。

上の例では、scratch/media の FreeBSD 11.1 RELEASE の ISO ファイルは壊れていた。また、media@2017 のスナップショットも壊れている。ただ、media@2017 は他の場所に既に、zfs send のバックアップが保存されていた。そのため、FreeBSD-11.1-RELEASE-i386-disc1.iso のファイルを消し、media@2018_04 のスナップショットを取った。

$ zfs send -i 2017 scratch/media@2018_04
幸いにも、この差分には壊れたファイルは存在しない。FreeBSD-10.2-RELEASE-i386-disc1.iso はスナップショット上では壊れているが、送られる必要が無いからだ。

これを契機に、zfs スナップショットは 50GB ぐらい毎に保持する事にした。こうすることで、ファイルが破損しても zfs send で送れるスナップショットが残る可能性があがる。また、一つのスナップショットが大きくなると、転送に時間が掛かるのも一つの理由だ。