ROW: redirect on write 。 寫時重定向。
如下圖所示,左邊是我們的文件。上邊是inode,下邊是block,里邊都是123且是指向關系。然后我們對它拍一個快照snap01,snap01中也有索引123,且指向block中對應的數據。這些步驟和COW是一模一樣的。不同的是,COW會生成一個COW區域用來存放和原block不同的數據,但是ROW不會。ROW會在底層生成一個.img形式的磁盤文件,我們稱這個文件為ROW差分卷。差分就是區別的意思,這里的差分就是指和左邊block的區別。原磁盤底層(左邊block)也是一個.img形式的磁盤文件(雖然是.img形式結尾,但是這個文件是磁盤文件),當我們拍了一次快照之后,原來的磁盤文件(左邊底層block)就直接變成了只讀。那這個時候如果我們改變數據會發生什么情況呢?
刪除:假設我們刪除inode中的3,差分卷會怎么做呢?和COW一樣,因為snap01中的索引和block中的數據依然是一一指向關系,所以這個時候差分卷什么都不會做。維持原樣。
修改:假設我們的數據發生變化,差分卷會怎么做呢?比如我們把inode中的3改成5。因為之前的block在拍快照之后變成了只讀文件,所以沒辦法寫入數據。當inode中的3改成5之后,它會直接把本該寫入block中的5寫入row差分卷中,然后修改inode中5的指向直接指到差分卷中。
新增:假設新增數據,會怎么辦呢?假設我們新增了數據678,因為原block是只讀的,所以678也是直接寫到了差分卷中。然后修改inode中678的指向直接指到差分卷中。
如果我們接着拍了第二個快照,會發生什么呢?如下圖所示,假如我們拍了snap02,那么它就會產生第二個row差分卷,重要的是第一個差分卷就變成了只讀,所以只要有新的差分卷生成,之前的差分卷就會變成已讀。當有數據寫入時,會直接寫入到新的差分卷中。snap02中的索引也會一一指向block和第一個差分卷中的數據。所以如果我們連續的拍快照,最后就會形成一個快照鏈,因為每一個row差分卷都是有用的,快照鏈如下圖所示。
這就是寫時重定向ROW,所謂重定向就是在寫入數據的時候直接把他寫入到了差分卷中。
最后我們總結一下ROW和COW的區別:
cow拍快照后,如果對數據進行修改和新增,不僅會影響原磁盤中的block,也會影響cow區域。
row拍快照后,如果對數據進行修改和新增,只會影響最后一次快照對應的row差分卷。
實驗:
我們做個實驗來看一下ROW的底層到底是什么樣的。
如下圖所示,我們查看我們虛擬機的磁盤信息,發現它就是一個.img文件,這就對應了我們上邊說的磁盤block也是一個.img文件。我們可以看到它的大小是40G,這就是我們創建虛擬機時划分給它的磁盤大小。但是它的實際使用量只用了11G。然后我們給這個虛擬機拍一個快照,我們可以看到這時候多了一個.img文件出來,這就是快照生成的ROW差分卷,我們可以看到這時候它的大小只有9M,因為這時候還沒有數據寫入。
這個時候我們在虛擬機中寫入一些數據,我們可以看到差分卷的大小變成了136M,這就是我們前邊說的ROW快照模式下,原先的磁盤會變成只讀,有數據寫入時只會寫入ROW差分卷中。
這個時候我們在拍一次快照,我們可以看到又多了一個新的img文件出來,這就是我們說的每拍一個快照,就會生成一個新的row差分卷。
然后我們在往磁盤中寫入數據,我們會發現原先的差分卷大小沒有發生變化,而新的差分卷變成了103M。這就是我們說的新的差分卷生成之后,之前的差分卷也都會變成只讀。新的數據只會寫入到最新的差分卷。
那么這個時候如果我們刪除第二個快照會發生什么呢?我們可以看到第二個快照對應的差分卷已經沒有了。第一個差分卷的大小從221M變成了274M,這就意味着他把第二個差分卷中的數據合並到了第一個差分卷中。這就是ROW快照合並。這時候再有數據寫入的話,它會直接寫入到第一個差分卷中。以此類推,假如我們再把第一個快照刪了,那么第一個差分卷中的數據也會合並到原磁盤中。