19.3. `zpool` 管理
前一頁 | 章 19. Z 檔案系統 (ZFS) | 下一頁

## 19.3. `zpool` 管理

ZFS 管理分成兩個主要的工具。`zpool` 工具用來控制儲存池的運作並可處理磁碟的新增、移除、更換與管理。`zfs` 工具用來建立、摧毀與管理檔案系統 (File system) 與磁碟區 (Volume) 的資料集。

### 19.3.1. 建立與摧毀儲存池

建立 ZFS 儲存池 (zpool) 要做幾個涉及長遠規劃的決定，因為建立儲存池之後便無法再更改儲存池的結構。最重要的決定是要使用那一種型態的 vdev 來將實體磁碟設為同一群組。請參考 vdev 型態 的清單來取得有關可用選項的詳細資訊。大部份的 vdev 型態不允許在建立儲存池之後再加入額外的磁碟，鏡像 (Mirror) 是可以允許加入額外的磁碟到 vdev 的其中一個例外，另一個則是串連 (Stripe)，可以加入額外的磁碟到 vdev 來升級為鏡像。雖然可以加入額外的 vdev 來擴充儲存池，但儲存池的配置在建立之後便無法更改，若要要更改，則必須先備份資料，把儲存池摧毀後再重新建立。

建立一個簡單的鏡像儲存池：

    # zpool create mypool mirror /dev/ada1 /dev/ada2
    # zpool status
      pool: mypool
     state: ONLINE
      scan: none requested
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada1    ONLINE       0     0     0
                ada2    ONLINE       0     0     0

    errors: No known data errors

可以一次建立數個 vdev，磁碟群組間使用 vdev 型態關鍵字來區隔，在這個例子使用 `mirror`：

    # zpool create mypool mirror /dev/ada1 /dev/ada2 mirror /dev/ada3 /dev/ada4
      pool: mypool
     state: ONLINE
      scan: none requested
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada1    ONLINE       0     0     0
                ada2    ONLINE       0     0     0
              mirror-1  ONLINE       0     0     0
                ada3    ONLINE       0     0     0
                ada4    ONLINE       0     0     0

    errors: No known data errors

儲存池也可以不使用整個磁碟而改使用分割區 (Partition) 來建立。把 ZFS 放到不同的分割區可讓同一個磁碟有其他的分割區可做其他用途，尤其是有 Bootcode 與檔案系統要用來開機的分割區，這讓磁碟可以用來開機也同樣可以做為儲存池的一部份。在 FreeBSD 用分割區來替代整個磁碟並不會對效能有影響。使用分割區也讓管理者可以對磁碟容量做 少算的預備，使用比完整容量少的容量，未來若要替換的磁碟號稱與原磁碟相同，但實際上卻比較小時，也可符合這個較小的分割區容量，以使用替換的磁碟。

使用分割區建立一個 RAID-Z2 儲存池：

    # zpool create mypool raidz2 /dev/ada0p3 /dev/ada1p3 /dev/ada2p3 /dev/ada3p3 /dev/ada4p3 /dev/ada5p3
    # zpool status
      pool: mypool
     state: ONLINE
      scan: none requested
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              raidz2-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0
                ada2p3  ONLINE       0     0     0
                ada3p3  ONLINE       0     0     0
                ada4p3  ONLINE       0     0     0
                ada5p3  ONLINE       0     0     0

    errors: No known data errors

不需使用的儲存池可以摧毀，來讓磁碟可以再次使用。摧毀一個儲存池要先卸載所有該儲存池的資料集。若資料集在使用中，卸載的操作會失敗且儲存池不會被摧毀。儲存池的摧毀可以使用 `-f` 來強制執行，但這可能造成那些有開啟這些資料集之中檔案的應用程式無法辨識的行為。

### 19.3.2. 加入與移除裝置

加入磁碟到儲存池 (zpool) 會有兩種情形：使用 `zpool attach` 加入一個磁碟到既有的 vdev，或使用 `zpool add` 加入 vdev 到儲存池。只有部份 vdev 型態 允許在 vdev 建立之後加入磁碟。

由單一磁碟所建立的儲存池缺乏備援 (Redundancy) 功能，可以偵測到資料的損壞但無法修復，因為資料沒有其他備份可用。備份數 (Copies) 屬性可以讓您從較小的故障中復原，如磁碟壞軌 (Bad sector)，但無法提供與鏡像或 RAID-Z 同樣層級的保護。由單一磁碟所建立的儲存池可以使用 `zpool attach` 來加入額外的磁碟到 vdev，來建立鏡像。`zpool attach` 也可用來加入額外的磁碟到鏡像群組，來增加備援與讀取效率。若使用的磁碟已有分割區，可以複製該磁碟的分割區配置到另一個，使用 `gpart backup` 與 `gpart restore` 可讓這件事變的很簡單。

加入 `ada1p3` 來升級單一磁碟串連 (stripe) vdev `ada0p3` 採用鏡像型態 (mirror)：

    # zpool status
      pool: mypool
     state: ONLINE
      scan: none requested
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              ada0p3    ONLINE       0     0     0

    errors: No known data errors
    # zpool attach mypool ada0p3 ada1p3
    Make sure to wait until resilver is done before rebooting.

    If you boot from pool 'mypool', you may need to update
    boot code on newly attached disk 'ada1p3'.

    Assuming you use GPT partitioning and 'da0' is your new boot disk
    you may use the following command:

            gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0
    # gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
    bootcode written to ada1
    # zpool status
      pool: mypool
     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 Fri May 30 08:19:19 2014
            527M scanned out of 781M at 47.9M/s, 0h0m to go
            527M resilvered, 67.53% done
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0  (resilvering)

    errors: No known data errors
    # zpool status
      pool: mypool
     state: ONLINE
      scan: resilvered 781M in 0h0m with 0 errors on Fri May 30 08:15:58 2014
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0

    errors: No known data errors

若不想選擇加入磁碟到既有的 vdev ，對 RAID-Z 來說，可選擇另一種方式，便是加入另一個 vdev 到儲存池。額外的 vdev 可以提供更高的效能，分散寫入資料到 vdev 之間，每個 vdev 會負責自己的備援。也可以混合使用不同的 vdev 型態，但並不建議，例如混合使用 `mirror` 與 `RAID-Z`，加入一個無備援的 vdev 到一個含有 mirror 或 RAID-Z vdev 的儲存池會讓資料損壞的風險擴大整個儲存池，由於會分散寫入資料，若在無備援的磁碟上發生故障的結果便是遺失大半寫到儲存池的資料區塊。

在每個 vdev 間的資料是串連的，例如，有兩個 mirror vdev，便跟 RAID 10 一樣在兩個 mirror 間分散寫入資料，且會做空間的分配，因此 vdev 會在同時達到全滿 100% 的用量。若 vdev 間的可用空間量不同則會影響到效能，因為資料量會不成比例的寫入到使用量較少的 vdev。

當連接額外的裝置到一個可以開機的儲存池，要記得更新 Bootcode。

連接第二個 mirror 群組 (`ada2p3` 及 `ada3p3`) 到既有的 mirror：

    # zpool status
      pool: mypool
     state: ONLINE
      scan: resilvered 781M in 0h0m with 0 errors on Fri May 30 08:19:35 2014
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0

    errors: No known data errors
    # zpool add mypool mirror ada2p3 ada3p3
    # gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
    bootcode written to ada2
    # gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada3
    bootcode written to ada3
    # zpool status
      pool: mypool
     state: ONLINE
      scan: scrub repaired 0 in 0h0m with 0 errors on Fri May 30 08:29:51 2014
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0
              mirror-1  ONLINE       0     0     0
                ada2p3  ONLINE       0     0     0
                ada3p3  ONLINE       0     0     0

    errors: No known data errors

現在已無法從儲存池上移除 vdev，且磁碟只能夠在有足夠備援空間的情況下從 mirror 移除，若在 mirror 群組中只剩下一個磁碟，便會取消 mirror 然後還原為 stripe，若剩下的那個磁碟故障，便會影響到整個儲存池。

從一個三方 mirror 群組移除一個磁碟：

    # zpool status
      pool: mypool
     state: ONLINE
      scan: scrub repaired 0 in 0h0m with 0 errors on Fri May 30 08:29:51 2014
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0
                ada2p3  ONLINE       0     0     0

    errors: No known data errors
    # zpool detach mypool ada2p3
    # zpool status
      pool: mypool
     state: ONLINE
      scan: scrub repaired 0 in 0h0m with 0 errors on Fri May 30 08:29:51 2014
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0

    errors: No known data errors

### 19.3.3. 檢查儲存池狀態

儲存池的狀態很重要，若有磁碟機離線或偵測到讀取、寫入或校驗碼 (Checksum) 錯誤，對應的錯誤計數便會增加。`status` 會顯示儲存池中每一個磁碟機的設定與狀態及整個儲存池的狀態。需要處置的方式與有關最近清潔 (`Scrub`) 的詳細資訊也會一併顯示。

    # zpool status
      pool: mypool
     state: ONLINE
      scan: scrub repaired 0 in 2h25m with 0 errors on Sat Sep 14 04:25:50 2013
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              raidz2-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0
                ada2p3  ONLINE       0     0     0
                ada3p3  ONLINE       0     0     0
                ada4p3  ONLINE       0     0     0
                ada5p3  ONLINE       0     0     0

    errors: No known data errors

### 19.3.4. 清除錯誤

當偵測到錯誤發生，讀取、寫入或校驗碼 (Checksum) 的計數便會增加。使用 `zpool clear `mypool`` 可以清除錯誤訊息及重置計數。清空錯誤狀態對當儲存池發生錯誤要使用自動化 Script 通知的管理者來說會很重要，因在舊的錯誤尚未清除前不會回報後續的錯誤。

### 19.3.5. 更換運作中的裝置

可能有一些情況會需要更換磁碟為另一個磁碟，當要更換運作中的磁碟，此程序會維持舊有的磁碟在更換的過程為上線的狀態，儲存池不會進入降級 (Degraded) 的狀態，來減少資料遺失的風險。`zpool replace` 會複製所有舊磁碟的資料到新磁碟，操作完成之後舊磁碟便會與 vdev 中斷連線。若新磁碟容量較舊磁碟大，也可以會增加儲存池來使用新的空間，請參考 擴增儲存池。

更換儲存池中正在運作的狀置：

    # zpool status
      pool: mypool
     state: ONLINE
      scan: none requested
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0

    errors: No known data errors
    # zpool replace mypool ada1p3 ada2p3
    Make sure to wait until resilver is done before rebooting.

    If you boot from pool 'zroot', you may need to update
    boot code on newly attached disk 'ada2p3'.

    Assuming you use GPT partitioning and 'da0' is your new boot disk
    you may use the following command:

            gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0
    # gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada2
    # zpool status
      pool: mypool
     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 Mon Jun  2 14:21:35 2014
            604M scanned out of 781M at 46.5M/s, 0h0m to go
            604M resilvered, 77.39% done
    config:

            NAME             STATE     READ WRITE CKSUM
            mypool           ONLINE       0     0     0
              mirror-0       ONLINE       0     0     0
                ada0p3       ONLINE       0     0     0
                replacing-1  ONLINE       0     0     0
                  ada1p3     ONLINE       0     0     0
                  ada2p3     ONLINE       0     0     0  (resilvering)

    errors: No known data errors
    # zpool status
      pool: mypool
     state: ONLINE
      scan: resilvered 781M in 0h0m with 0 errors on Mon Jun  2 14:21:52 2014
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada2p3  ONLINE       0     0     0

    errors: No known data errors

### 19.3.6. 處理故障裝置

當儲存池中的磁碟故障，該故障硬碟所屬的 vdev 便會進入降級 (Degraded) 狀態，所有的資料仍可使用，但效能可能會降低，因為遺失的資料必須從可用的備援資料計算才能取得。要將 vdev 恢復完整運作的狀態必須更換故障的實體裝置。然後 ZFS 便會開始修復 (Resilver，古代鏡子的修復稱 Resilver) 作業，會從可用的備援資料計算出故障磁碟中的資料並寫入到替換的裝置上。完成後 vdev 便會重新返回上線 (Online) 的狀態。

若 vdev 沒有任何備援資料或有多個裝置故障，沒有足夠的備援資料可以補償，儲存池便會進入故障 (Faulted) 的狀態。

更換故障的磁碟時，故障磁碟的名稱會更換為裝置的 GUID，若替換裝置要使用相同的裝置名稱，則在 `zpool replace` 不須加上新裝置名稱參數。

使用 `zpool replace` 更換故障的磁碟：

    # zpool status
      pool: mypool
     state: DEGRADED
    status: One or more devices could not be opened.  Sufficient replicas exist for
            the pool to continue functioning in a degraded state.
    action: Attach the missing device and online it using 'zpool online'.
       see: http://illumos.org/msg/ZFS-8000-2Q
      scan: none requested
    config:

            NAME                    STATE     READ WRITE CKSUM
            mypool                  DEGRADED     0     0     0
              mirror-0              DEGRADED     0     0     0
                ada0p3              ONLINE       0     0     0
                316502962686821739  UNAVAIL      0     0     0  was /dev/ada1p3

    errors: No known data errors
    # zpool replace mypool 316502962686821739 ada2p3
    # zpool status
      pool: mypool
     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 Mon Jun  2 14:52:21 2014
            641M scanned out of 781M at 49.3M/s, 0h0m to go
            640M resilvered, 82.04% done
    config:

            NAME                        STATE     READ WRITE CKSUM
            mypool                      DEGRADED     0     0     0
              mirror-0                  DEGRADED     0     0     0
                ada0p3                  ONLINE       0     0     0
                replacing-1             UNAVAIL      0     0     0
                  15732067398082357289  UNAVAIL      0     0     0  was /dev/ada1p3/old
                  ada2p3                ONLINE       0     0     0  (resilvering)

    errors: No known data errors
    # zpool status
      pool: mypool
     state: ONLINE
      scan: resilvered 781M in 0h0m with 0 errors on Mon Jun  2 14:52:38 2014
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada2p3  ONLINE       0     0     0

    errors: No known data errors

### 19.3.7. 清潔儲存池

建議儲存池要定期清潔 (Scrub)，最好是每一個月清潔一次。 `scrub` 作業對磁碟操作非常的密集，在執行時會降低磁碟的效能。在排程 `scrub` 時避免在使用高峰的時期，或使用 `vfs.zfs.scrub_delay` 來調整 `scrub` 的相對優先權來避免影響其他的工作。

    # zpool scrub mypool
    # zpool status
      pool: mypool
     state: ONLINE
      scan: scrub in progress since Wed Feb 19 20:52:54 2014
            116G scanned out of 8.60T at 649M/s, 3h48m to go
            0 repaired, 1.32% done
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              raidz2-0  ONLINE       0     0     0
                ada0p3  ONLINE       0     0     0
                ada1p3  ONLINE       0     0     0
                ada2p3  ONLINE       0     0     0
                ada3p3  ONLINE       0     0     0
                ada4p3  ONLINE       0     0     0
                ada5p3  ONLINE       0     0     0

    errors: No known data errors

若發生需要取消清潔作業的事，可以下 `zpool scrub -s `mypool``。

### 19.3.8. 自我修復

校驗碼 (Checksum) 會隨資料區塊一併儲存，這使得檔案系統可以做到自我修復。這個功能可以在校驗碼與儲存池中的另一個裝置不同時自動修復資料。舉例來說，有兩個磁碟做鏡像 (Mirror)，其中一個磁碟機開始失常並無法正常儲存資料，甚至是資料放在長期封存的儲存裝置上，已經很久沒有被存取。傳統的檔案系統需要執行演算法來檢查並修復資料如 fsck(8)，這些指令耗費時間，且在嚴重時需要管理者手動決定要做那一種修復操作。當 ZFS 偵測到資料區塊的校驗碼不對時，它除了把資料交給需要的應用程式外，也會修正在磁碟上錯誤的資料。這件事不需要與系統管理者作任何互動便會在一般的儲存池操作時完成。

接下來的例子會示範自我修復會如何運作。建立一個使用磁碟 `/dev/ada0` 及 `/dev/ada1` 做鏡像的儲存池。

    # zpool create healer mirror /dev/ada0 /dev/ada1
    # zpool status healer
      pool: healer
     state: ONLINE
      scan: none requested
    config:

        NAME        STATE     READ WRITE CKSUM
        healer      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
           ada0     ONLINE       0     0     0
           ada1     ONLINE       0     0     0

    errors: No known data errors
    # zpool list
    NAME     SIZE  ALLOC   FREE   CKPOINT  EXPANDSZ   FRAG   CAP  DEDUP  HEALTH  ALTROOT
    healer   960M  92.5K   960M         -         -     0%    0%  1.00x  ONLINE  -

將部份需要使用自我修復功能來保護的重要資料複製到該儲存池，建立一個儲存池的校驗碼供稍後做比較時使用。

    # cp /some/important/data /healer
    # zfs list
    NAME     SIZE  ALLOC   FREE    CAP  DEDUP  HEALTH  ALTROOT
    healer   960M  67.7M   892M     7%  1.00x  ONLINE  -
    # sha1 /healer > checksum.txt
    # cat checksum.txt
    SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f

寫入隨機的資料到鏡像的第一個磁碟來模擬資料損毀的情況。要避免 ZFS 偵測到錯誤時馬上做修復，接著要將儲存池匯出，待模擬資料損毀之後再匯入。

### 警告:

這是一個危險的操作，會破壞重要的資料。在這裡使用僅為了示範用，不應在儲存池正常運作時嘗試使用，也不應將這個故意損壞資料的例子用在任何其他的檔案系統上，所以請勿使用任何不屬於該儲存池的其他磁碟裝置名稱並確定在執行指令前已對儲存池做正確的備份。

    # zpool export healer
    # dd if=/dev/random of=/dev/ada1 bs=1m count=200
    200+0 records in
    200+0 records out
    209715200 bytes transferred in 62.992162 secs (3329227 bytes/sec)
    # zpool import healer

儲存池的狀態顯示有一個裝置發生了錯誤。注意，應用程式從儲存池讀取的資料中並沒有任何的錯誤資料，ZFS 會自 `ada0` 裝置提供有正確校驗碼的資料。結果裡面 `CKSUM` 欄位含有非零值便是有錯誤校驗碼的裝置。

    # zpool status healer
        pool: healer
       state: ONLINE
      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: http://illumos.org/msg/ZFS-8000-4J
        scan: none requested
      config:

          NAME        STATE     READ WRITE CKSUM
          healer      ONLINE       0     0     0
            mirror-0  ONLINE       0     0     0
             ada0     ONLINE       0     0     0
             ada1     ONLINE       0     0     1

    errors: No known data errors

錯誤已經被偵測到並且由未被影響的 `ada0` 鏡像磁碟上的備援提供資料。可與原來的校驗碼做比較來看儲存池是否已修復為一致。

    # sha1 /healer >> checksum.txt
    # cat checksum.txt
    SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f
    SHA1 (/healer) = 2753eff56d77d9a536ece6694bf0a82740344d1f

儲存池在故意竄改資料前與後的兩個校驗碼仍相符顯示了 ZFS 在校驗碼不同時偵測與自動修正錯誤的能力。注意，這只在當儲存池中有足夠的備援時才可做到，由單一裝置組成的儲存池並沒有自我修復的能力。這也是為什麼在 ZFS 中校驗碼如此重要，任何原因都不該關閉。不需要 fsck(8) 或類似的檔案系統一致性檢查程式便能夠偵測與修正問題，且儲存儲存池在發生問題時仍可正常運作。接著需要做清潔作業來覆蓋在 `ada1` 上的錯誤資料。

    # zpool scrub healer
    # zpool status healer
      pool: healer
     state: ONLINE
    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: http://illumos.org/msg/ZFS-8000-4J
      scan: scrub in progress since Mon Dec 10 12:23:30 2012
            10.4M scanned out of 67.0M at 267K/s, 0h3m to go
            9.63M repaired, 15.56% done
    config:

        NAME        STATE     READ WRITE CKSUM
        healer      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
           ada0     ONLINE       0     0     0
           ada1     ONLINE       0     0   627  (repairing)

    errors: No known data errors

清潔作業會從 `ada0` 讀取資料並重新寫入任何在 `ada1` 上有錯誤校驗碼的資料。這個操作可以由 `zpool status` 的輸出中呈現修復中 `(repairing)` 的項目來辨識。這個作業完成後，儲存池的狀態會更改為：

    # zpool status healer
      pool: healer
     state: ONLINE
    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: http://illumos.org/msg/ZFS-8000-4J
      scan: scrub repaired 66.5M in 0h2m with 0 errors on Mon Dec 10 12:26:25 2012
    config:

        NAME        STATE     READ WRITE CKSUM
        healer      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
           ada0     ONLINE       0     0     0
           ada1     ONLINE       0     0 2.72K

    errors: No known data errors

清潔操作完成便同步了 `ada0` 到 `ada1` 間的所有資料。執行 `zpool clear` 可以清除 (Clear) 儲存池狀態的錯誤訊息。

    # zpool clear healer
    # zpool status healer
      pool: healer
     state: ONLINE
      scan: scrub repaired 66.5M in 0h2m with 0 errors on Mon Dec 10 12:26:25 2012
    config:

        NAME        STATE     READ WRITE CKSUM
        healer      ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
           ada0     ONLINE       0     0     0
           ada1     ONLINE       0     0     0

    errors: No known data errors

儲存池現在恢復完整運作的狀態且清除所有的錯誤了。

### 19.3.9. 擴增儲存池

可用的備援儲存池大小會受到每個 vdev 中容量最小的裝置限制。最小的裝置可以替換成較大的裝置，在更換 (Replace) 或修復 (Resilver) 作業後，儲存池可以成長到該新裝置的可用容量。例如，要做一個 1 TB 磁碟機與一個 2 TB 磁碟機的鏡像，可用的空間會是 1 TB，當 1 TB 磁碟機備更換成另一個 2 TB 的磁碟機時，修復程序會複製既有的資料到新的磁碟機，由於現在兩個裝置都有 2 TB 的容量，所以鏡像的可用空間便會成長到 2 TB。

可以在每個裝置用 `zpool online -e` 來觸發擴充的動作，在擴充完所有裝置後，儲存池便可使用額外的空間。

### 19.3.10. 匯入與匯出儲存池

儲存池在移動到其他系統之前需要做匯出 (Export)，會卸載所有的資料集，然後標記每個裝置為已匯出，為了避免被其他磁碟子系統存取，因此仍會鎖定這些裝置。這個動作讓儲存池可以在支援 ZFS 的其他機器、其他作業系統做匯入 (Import)，甚至是不同的硬體架構 (有一些注意事項，請參考 zpool(8))。當資料集有被開啟的檔案，可使用 `zpool export -f` 來強制匯出儲存池，使用這個指令需要小心，資料集是被強制卸載的，因此有可能造成在該資料集開啟檔案的應用程式發生無法預期的結果。

匯出未使用的儲存池：

    # zpool export mypool

匯入儲存池會自動掛載資料集，若不想自動掛載，可以使用 `zpool import -N`。`zpool import -o` 可以設定在匯入時暫時使用的屬性。`zpool import altroot=` 允許匯入時指定基礎掛載點 (Base mount point) 來替換檔案系統根目錄。若儲存池先前用在不同的系統且不正常匯出，可能會需要使用 `zpool import -f` 來強制匯入。`zpool import -a` 會匯入所有沒有被其他系統使用的儲存池。

列出所有可以匯入的儲存池：

    # zpool import
       pool: mypool
         id: 9930174748043525076
      state: ONLINE
     action: The pool can be imported using its name or numeric identifier.
     config:

            mypool      ONLINE
              ada2p3    ONLINE

使用替代的根目錄匯入儲存池：

    # zpool import -o altroot=/mnt mypool
    # zfs list
    zfs list
    NAME                 USED  AVAIL  REFER  MOUNTPOINT
    mypool               110K  47.0G    31K  /mnt/mypool

### 19.3.11. 升級儲存儲存池

在升級 FreeBSD 之後或儲存池是由其他使用舊版 ZFS 的系統匯入，儲存池可以手動升級到最新版本的 ZFS 來支援新的功能。在升級前請評估儲存池是否還要在舊的系統做匯入，由於升級是一個單向的程序，舊的儲存池可以升級，但有新功能的儲存池無法降級。

升級一個 v28 的儲存以支援功能旗標 (`Feature Flags`)：

    # zpool status
      pool: mypool
     state: ONLINE
    status: The pool is formatted using a legacy on-disk format.  The pool can
            still be used, but some features are unavailable.
    action: Upgrade the pool using 'zpool upgrade'.  Once this is done, the
            pool will no longer be accessible on software that does not support feat
            flags.
      scan: none requested
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
    	    ada0    ONLINE       0     0     0
    	    ada1    ONLINE       0     0     0

    errors: No known data errors
    # zpool upgrade
    This system supports ZFS pool feature flags.

    The following pools are formatted with legacy version numbers and can
    be upgraded to use feature flags.  After being upgraded, these pools
    will no longer be accessible by software that does not support feature
    flags.

    VER  POOL
    ---  ------------
    28   mypool

    Use 'zpool upgrade -v' for a list of available legacy versions.
    Every feature flags pool has all supported features enabled.
    # zpool upgrade mypool
    This system supports ZFS pool feature flags.

    Successfully upgraded 'mypool' from version 28 to feature flags.
    Enabled the following features on 'mypool':
      async_destroy
      empty_bpobj
      lz4_compress
      multi_vdev_crash_dump

ZFS 的新功能在 `zpool upgrade` 尚未完成之前無法使用。可以用 `zpool upgrade -v` 來查看升級後有那些新功能，也同時會列出已經支援那些功能。

升級儲存池支援新版的功能旗標 (Feature flags)：

    # zpool status
      pool: mypool
     state: ONLINE
    status: Some supported features are not enabled on the pool. The pool can
            still be used, but some features are unavailable.
    action: Enable all features using 'zpool upgrade'. Once this is done,
            the pool may no longer be accessible by software that does not support
            the features. See zpool-features(7) for details.
      scan: none requested
    config:

            NAME        STATE     READ WRITE CKSUM
            mypool      ONLINE       0     0     0
              mirror-0  ONLINE       0     0     0
    	    ada0    ONLINE       0     0     0
    	    ada1    ONLINE       0     0     0

    errors: No known data errors
    # zpool upgrade
    This system supports ZFS pool feature flags.

    All pools are formatted using feature flags.

    Some supported features are not enabled on the following pools. Once a
    feature is enabled the pool may become incompatible with software
    that does not support the feature. See zpool-features(7) for details.

    POOL  FEATURE
    ---------------
    zstore
          multi_vdev_crash_dump
          spacemap_histogram
          enabled_txg
          hole_birth
          extensible_dataset
          bookmarks
          filesystem_limits
    # zpool upgrade mypool
    This system supports ZFS pool feature flags.

    Enabled the following features on 'mypool':
      spacemap_histogram
      enabled_txg
      hole_birth
      extensible_dataset
      bookmarks
      filesystem_limits

### 警告:

The boot code on systems that boot from a pool must be updated to support the new pool version. Use `gpart bootcode` on the partition that contains the boot code. There are two types of bootcode available, depending on way the system boots: GPT (the most common option) and EFI (for more modern systems).

For legacy boot using GPT, use the following command:

    # gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1

For systems using EFI to boot, execute the following command:

    # gpart bootcode -p /boot/boot1.efifat -i 1 ada1

Apply the bootcode to all bootable disks in the pool. See gpart(8) for more information.

### 19.3.12. 顯示已記錄的儲存池歷史日誌

修改儲存池的指令會被記錄下來，會記錄的動作包含資料集的建立，屬性更改或更換磁碟。這個歷史記錄用來查看儲存池是如何建立、由誰執行、什麼動作及何時。歷史記錄並非儲存在日誌檔 (Log file)，而是儲存在儲存池。查看這個歷史記錄的指令名稱為 `zpool history`：

    # zpool history
    History for 'tank':
    2013-02-26.23:02:35 zpool create tank mirror /dev/ada0 /dev/ada1
    2013-02-27.18:50:58 zfs set atime=off tank
    2013-02-27.18:51:09 zfs set checksum=fletcher4 tank
    2013-02-27.18:51:18 zfs create tank/backup

輸出結果顯示曾在該儲存池上執行的 `zpool` 與 `zfs` 指令以及時間戳記。只有會修改儲存池或類似的指令會被記錄下來，像是 `zfs list` 這種指令並不會被記錄。當不指定儲存池名稱時，會列出所有儲存池的歷史記錄。

在提供選項 `-i` 或 `-l` 時 `zpool history` 可以顯更多詳細資訊。`-i` 會顯示使用者觸發的事件外，也會顯示內部記錄的 ZFS 事件。

    # zpool history -i
    History for 'tank':
    2013-02-26.23:02:35 [internal pool create txg:5] pool spa 28; zfs spa 28; zpl 5;uts  9.1-RELEASE 901000 amd64
    2013-02-27.18:50:53 [internal property set txg:50] atime=0 dataset = 21
    2013-02-27.18:50:58 zfs set atime=off tank
    2013-02-27.18:51:04 [internal property set txg:53] checksum=7 dataset = 21
    2013-02-27.18:51:09 zfs set checksum=fletcher4 tank
    2013-02-27.18:51:13 [internal create txg:55] dataset = 39
    2013-02-27.18:51:18 zfs create tank/backup

更多詳細的資訊可加上 `-l` 來取得，歷史記錄會以較長的格式顯示，包含的資訊有執行指令的使用者名稱、主機名稱以及更改的項目。

    # zpool history -l
    History for 'tank':
    2013-02-26.23:02:35 zpool create tank mirror /dev/ada0 /dev/ada1 [user 0 (root) on :global]
    2013-02-27.18:50:58 zfs set atime=off tank [user 0 (root) on myzfsbox:global]
    2013-02-27.18:51:09 zfs set checksum=fletcher4 tank [user 0 (root) on myzfsbox:global]
    2013-02-27.18:51:18 zfs create tank/backup [user 0 (root) on myzfsbox:global]

輸出結果顯示 `root` 使用者使用 `/dev/ada0` 及 `/dev/ada1` 建立鏡像的儲存池。主機名稱 `myzfsbox` 在建立完儲存池後也同樣會顯示。由於儲存池可以從一個系統匯出再匯入到另一個系統，因此主機名稱也很重要，這樣一來可以清楚的辦識在其他系統上執行的每一個指令的主機名稱。

兩個 `zpool history` 選項可以合併使用來取得最完整的儲存池詳細資訊。儲存池歷史記錄在追蹤執行什麼動作或要取得除錯所需的輸出結果提供了非常有用的資訊。

### 19.3.13. 監視效能

內建的監視系統可以即時顯示儲存池的 I/O 統計資訊。它會顯示儲存池剩餘的空間與使用的空間，每秒執行了多少讀取與寫入的操作，有多少 I/O 頻寬被使用。預設會監視所有在系統中的儲存池都並顯示出來，可以提供儲存池名稱來只顯示該儲存池的監視資訊。舉一個簡單的例子：

    # zpool iostat
                   capacity     operations    bandwidth
    pool        alloc   free   read  write   read  write
    ----------  -----  -----  -----  -----  -----  -----
    data         288G  1.53T      2     11  11.3K  57.1K

要持續監視 I/O 的活動可以在最後的參數指定一個數字，這個數字代表每次更新資訊所間隔的秒數。在每次經過間隔的時間後會列出新一行的統計資訊，按下 Ctrl+C 可以中止監視。或者在指令列的間隔時間之後再指定一個數字，代表總共要顯示的統計資訊筆數。

使用 `-v` 可以顯示更詳細的 I/O 統計資訊。每個在儲存池中的裝置會以一行統計資訊顯示。這可以幫助了解每一個裝置做了多少讀取與寫入的操作，並可協助確認是否有各別裝置拖慢了整個儲存池的速度。以下範例會顯示有兩個裝置的鏡像儲存池：

    # zpool iostat -v
                                capacity     operations    bandwidth
    pool                     alloc   free   read  write   read  write
    -----------------------  -----  -----  -----  -----  -----  -----
    data                      288G  1.53T      2     12  9.23K  61.5K
      mirror                  288G  1.53T      2     12  9.23K  61.5K
        ada1                     -      -      0      4  5.61K  61.7K
        ada2                     -      -      1      4  5.04K  61.7K
    -----------------------  -----  -----  -----  -----  -----  -----

### 19.3.14. 分割儲存儲存池

由一個或多個鏡像 vdev 所組成的儲存池可以切分開成兩個儲存池。除非有另外指定，否則每個鏡像的最後一個成員會被分離來然用來建立一個含有相同資料的新儲存池。在做這個操作的第一次應先使用 `-n`，會顯示預計會做的操作而不會真的執行，這可以協助確認操作是否與使用者所要的相同。

前一頁 | 上一層 | 下一頁
19.2. 快速入門指南 | 起始頁 | 19.4. `zfs` 管理

本文及其他文件，可由此下載： ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/。

若有 FreeBSD 方面疑問，請先閱讀 FreeBSD 相關文件，如不能解決的話，再洽詢 <questions@FreeBSD.org>。
關於本文件的問題，請洽詢 <doc@FreeBSD.org>。