【翻譯】ZFS - Ondiskformat 第一章 虛擬設備(vdevs),Vdev Label以及Boot Block

(翻譯 ZFS On-Disk Specification》, 因爲是2006年給出的文檔,與當前ZFS系統確定有不少的不一樣,可是也是一份至關有幫助的ZFS學習文檔)

1.1 擬設備

ZFS存儲池是由一個虛擬設備集合構成的。這裏面一共有兩種虛擬設備:物理虛擬設備(physical virtual devices,也稱爲葉虛擬設備,leaf vdevs),以及邏輯虛擬設備(logical virtual devices,也稱爲內部虛擬設備,interior vdevs)。物理設備是一個可寫的塊設備(好比一個磁盤);邏輯設備在概念上的一組物理設備。數組

Vdev是經過一個以物理設備爲葉子節點的樹來管理的。每個pool都有一個被稱爲「root vdev」的設備做爲這棵樹的根。root節點的全部直接子節點(不管是邏輯的仍是物理的)都被稱爲top-level vdevs。下圖顯示了一個由兩個Mirror構成的pool的虛擬設備樹。第一個Mirror(標籤爲M1)有兩個磁盤,分別經過「vdev A」「vdev B」來表示;一樣的,第二個Mirror(標籤爲M2)也有兩個磁盤,分別經過「vdev C」「vdev D」來表示。虛擬設備ABCD都是物理虛擬設備。「M1」「M2」都是邏輯虛擬設備,因爲M1M2都是root的直接子節點,因此都是「top-level vdevs」

vdev tree
佈局

 

1.2 虛擬設備標籤(Vdev Label

Pool中的每個物理虛擬設備都包含一個256K的結構體——vdev_label。這個Label描述了這個設備以及同一top-level vdev下的其餘全部虛擬設備的信息。例如:對於虛擬設備C,它的vdev label中包含虛擬設備CD以及M2的信息。vdev label的詳細信息在下一節中詳細描述。學習

使用vdev label有兩個目的:它提供訪問pool中信息的入口;另外它還被用於驗證pool的完整新和可用性。爲了保證vdev label老是合法可用的,咱們使用冗餘和特殊的更新方式。冗餘:pool中的每一個物理虛擬設備都有4個相同的Label,同一個設備上的4份是徹底相同的,不一樣設備則是不一樣的。更新:Label的更新過程當中,使用兩階段的事務來更新,這樣確保虛擬設備上至少有一個合法的Label。下面詳細介紹一下Label的冗餘和更新技術。ui

1.2.1 Label<span "="">冗餘

pool中的每一個物理虛擬設備都有4份相同的Label,在更新過程當中,這4Label每個均可以用來訪問、驗證pool中的數據。當一個設備被添加到pool中時,ZFS在設備的最前面放兩個Label,最後面也放兩個Label。下圖顯示四個Label的分佈,N表示設備的總大小,L0L1爲前兩個LabelL2L3爲後兩個Labelspa

Label - 4

<span "="">考慮到通常狀況下設備的損壞都是一個連續的段,因此要將Label放在兩個不一樣的地方。翻譯

1.2.2 <span "="">兩階段的事務性更新

Label<span "="">的位置是在設備加入pool時就設定好了,所以Label的更新並不能像ZFS對待其餘數據那樣採用Copy-On-Write技術,也就是說,對Label的更新是直接覆蓋原有的數據。可是在寫任何數據的過程當中都有可能發生錯誤,爲了保證ZFS任什麼時候候老是有一個合法的LabelLabel的更新過程被分爲兩個階段。第一階段更新偶數的LabelL0L2),若是在這一階段中任什麼時候刻發生了錯誤,奇數LabelL1L3)仍然是合法的。在L0L2更新結束以後,第二階段則是更新L1L3code

1.3 vdev技術細節

vdev label的信息被分紅了4部分:8K的空閒空間(Blank Space),8Kboot header信息,112Kname-value鍵值對以及128K1K大小的uberblock結構數組。下圖顯示了L0的擴展視圖。對象

Label - detail

1.3.1 <span "="">空閒空間

ZFS支持使用VTOCVolume Table of Content)和EFI兩種方式來描述磁盤佈局。EFI標籤並非Slice的一部分(它有本身的保留空間),VTOC標籤必須被寫在Slice0的前8K空間內,因此爲了支持VTOC標籤,vdev_label的前8K空間被保留下來防止重寫了VTOC標籤。遞歸

1.3.2 Boot Block Header

保留,之後使用。事務

1.3.3 Name-Value Pair List

後面的112KB存儲描述這個設備以及其關聯設備的鍵值對。關聯設備即:同一個top level vdev下的設備。好比下圖中的灰色圓內部的ABM1三個設備。

related-vdev

<span "="">全部的鍵值對都使用XDR encoded nvlists存儲。關於更多的XDR encoding或是nvlists請參見 libnvpair(3LIB)nvlist_free(3NVPAIR)man手冊。如下的鍵值對都被包含在這112K的部份內。

屬性

名稱

描述

Version

version

DATA_TYPE_UINT64

版本號

Name

name

DATA_TYPE_STRING

當前vdev所屬的pool名稱

State

state

DATA_TYPE_UINT64

當前pool的狀態,pool全部狀態有:

POOL_STATE_ACTIVE      0

POOL_STATE_EXPORTED    1

POOL_STATE_DESTROYED   2

Transaction

txg

DATA_TYPE_UINT64

將這個Label寫入磁盤的事務組號

Pool Guid

pool_guid

DATA_TYPE_UINT64

pool的全局惟一標識符

Top Guid

top_guid

DATA_TYPE_UINT64

top_vdev的全局惟一標識符

Guid

guid

DATA_TYPE_UINT64

當前vdev的全局惟一標識符

Vdev Tree

vdev_tree

DATA_TYPE_NVLIST

vdev_tree使用遞歸的方式來描述。下文詳細描述

 

vdev_tree遞歸地描述與當前vdev相關的vdev的信息。

nvlist-vdev-tree

每一個vdev_tree都包含如下信息:

名稱

描述

type

DATA_TYPE_STRING

代表vdev的類有如下幾種類型:

disk      葉設備:塊設備存儲

file       葉設備:文件存儲

mirror    內部設備:mirror

raidz     內部設備:raidz

replacing 內部設備:ZFS在設備替換時使用

root      內部設備:vdev tree的根設備

id

DATA_TYPE_UINT64

當前vdev在父節點孩子中的序號

guid

DATA_TYPE_UINT64

當前樹的全局惟一標識符

path

DATA_TYPE_STRING

設備路徑(僅用於葉虛擬設備)

devid

DATA_TYPE_STRING

vdev_tree的設備ID,僅用於disk類型的虛擬設備

metaslab_

arrary

DATA_TYPE_UINT64

由對象號構成的數組。數組中的每一個元素(ma[i]metaslab對應的空間圖的對象號

metaslab_

shift

DATA_TYPE_UINT64

log2metaslab大小)

ashift

DATA_TYPE_UINT64

log2(當前top level vdev的最小可分配單元,block大小)

children

DATA_TYPE_NVLIST_ARRARY

子節點的vdev_tree

 

1.3.4 uberblock

nvlist以後就是uberblock的數組。uberblock是訪問pool中數據的入口。任意時刻,只有一個uberblock處於激活狀態,全部uberblock中事務組編號最高且經過SHA-256 checksum驗證合法的uberblock爲激活的uberblock,它相似於UFS文件系統中的超級塊。

爲了可以持續訪問激活的uberblock,激活的uberblock永遠不會被覆蓋。全部對uberblock的修改都是經過寫入uberblock數組中的另一個元素來完成的。在寫入新的uberblock時,事務組編號以及時間戳都是在同一個原子性的操做中完成。Uberblock經過循環的方式寫入。

下圖顯示兩個uberblock

uberblock

uberblock技術細節

uberblock按照機器的字節模式存儲。

ub_magic

用於表示該設備包含ZFS數據。ub_magic的值爲0x00bab10c(oo-ba-bloc)

ub_version

版本號,與前文中鍵值對的版本號意義相同。

ub_txg

ZFS中全部的寫操做都是經過事務組來完成的。每一個事務組都有一個對應的事務組編號。ub_txg用來表示寫入這個uberblock的事務組編號。ub_txg必須大於等於前面鍵值對中的txg編號。

ub_guid_sum

用來檢驗pool中全部設備的可用性。當pool被打開後,ZFS遍歷pool中全部的葉虛擬設備計算這些GUID的和,而後與ub_guid_sum進行比較,來驗證pool中磁盤的可用性。

ub_timestamp

當前uberblock寫入的時間戳(197011日至今的秒數)

ub_rootbp

這是一個blkptr結構體,包含了MOS的位置。MOSblkptr將在後文中詳細描述。

1.4 Boot Block

L0L1以後有一個3.5M的保留空間。

boot block

相關文章
相關標籤/搜索