在FreeBSD 使用Advanced Format 硬碟建立 ZFS
Advanced Format HDD in ZFS
由於現在的新購入的硬碟幾乎都是Advanced Format 的硬碟, 這種硬碟1 sector = 4096 bytes. (傳統的硬碟是 1 sector = 512 bytes) , 若讓新硬碟模擬傳統硬碟的方式來操作, 這會讓硬碟的效率及壽命都大打折扣.
目前大部份的作業系統, 如Windows, MAC OSX, Linux…都已經支援了Advanced Format 硬碟. 但是偏偏我的File Server 是FreeBSD, 且File system 是採用ZFS.
目前的ZFS 中最小的存取單元是可以由使用者來決定的. 其利用一個參數叫做ashift 來決定最小的存取單位. 而ashift default value = 9, 即最小的存取單位是 2 ^ 9 = 512 bytes. 剛好符合傳統的硬碟1 sector 的size.
若要讓ZFS 支援Advanced Format HDD 的方法就是將ashift 值改為12 (2 ^ 12 = 4096 bytes). 注意! ashift 的值是在建立zpool 時後自動檢查device 時決定, 而且一旦決定好之後, 不能被修改了.
問題來了, 當我們建立zpool 時, 使用如下的指令
#zpool create fspool raidz /dev/ada0 /dev/ada1 /dev/ada2
zpool 會檢查/dev/ada0, /dev/ada1, /dev/ada2 並將ashift 設為9, 那就不符合我們的期待了.
所以我們必須改用另一個作法來建立zpool
首先用gnop 對於硬碟 ada0 ~ ada2 建立sector 為4k 的虛擬 GEMO classes.
#gnop create -S 4096 /dev/ada0
#gnop create -S 4096 /dev/ada1
#gnop create -S 4096 /dev/ada2
這時會產生/dev/ada0.nop, /dev/ada1.nop 及/dev/ada2.nop
然後使用ada0.nop, ada1.nop ada2.nop 建立zpool
#zpool create fspool raidz /dev/ada0.nop /dev/ada1.nop /dev/ada2.nop
這時fspool 的ashift 值應該是12了
#zdb fspool | grep ashift
ashift: 12
然後將fspool 匯出, 刪除/dev/ada0.nop /dev/ada1.nop /dev/ada2.nop, 然後再匯入fspool
#zpool export fspool
#gnop destroy /dev/ada0.nop
#gnop destroy /dev/ada1.nop
#gnop destroy /dev/ada2.nop
#zpool import fspool
zpool 在建立時, 會以device 中最大的sector size 來當作ashift 的設定值, 所以上例中, 應該只要一個HDD 的GEMO 為4K 就可以了, 可以不需要全部都設成4K.