頁斷裂(partial write)與doublewrite技術
from:http://www.cnblogs.com/cchust/p/3961260.html
頁斷裂(partial write)與doublewrite技術
mysql double write (二次寫)是mysql innodb儲存引擎的一個重要特性,本人這兩天翻閱了相關的資料,結合自己已有的知識,說說自己對double write的理解,供各位看官參考。
頁斷裂(partial write)
double write技術innodb為解決頁斷裂(partial write)問題而生,所謂頁斷裂是資料庫當機時(OS重啟,或主機掉電重啟),資料庫頁面只有部分寫入磁碟,導致頁面出現不一致的情況。資料庫,OS和磁碟讀寫的基本單位是塊,也可以稱之為(page size)block size。我們知道資料庫的塊一般為8K,16K;而OS的塊則一般為4K;IO塊則更小,linux核心要求IO block size<=OS block size。磁碟IO除了IO block size,還有一個概念是扇區(IO sector),扇區是磁碟物理操作的基本單位,而IO 塊是磁碟操作的邏輯單位,一個IO塊對應一個或多個扇區,扇區大小一般為512個位元組。所以各個塊大小的關係可以梳理如下:
DB block > OS block >= IO block > 磁碟 sector,而且他們之間保持了整數倍的關係。比如我的系統各個塊的大小如下,DB以mysql為例,OS以linux為例。
DB block size
root@(none) 09:13:02>show variables like 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
OS block size
[1 Single:CHECK: mysql ~ ]
$ getconf PAGESIZE
4096
IO block size
比如檢視sdb1分割槽的IO block size
[root@chuckkkk]# blockdev --getbsz /dev/sdb1
4096
sector size
[root@chuckkkk]# fdisk -l | grep Sector
Sector size (logical/physical): 512 bytes / 512 bytes
從上面的結果可以看到DB page=4*OS page=IO page=8*sector size。
由於任何DB page的寫入,最終都會轉為sector的寫入,如果在寫磁碟的過程中,出現異常重啟,就可能會發生一個DB頁只寫了部分sector到磁碟,進而出現頁斷裂的情況。
頁斷裂與資料庫一致性
前面我們分析了異常重啟一定會導致頁斷裂,而頁斷裂就意味著資料庫頁面不完整,那麼資料庫頁面不完整是否就意味著資料庫不一致呢???我們知道,資料庫異常重啟時,自身有異常恢復機制,我這裡不打算展開講異常恢復機制,因為不同資料庫的異常恢復流程不同。主流資料庫基本原理類似:第一階段重做redo日誌,恢復資料頁和undo頁到異常crash時的狀態;第二階段,根據undo頁的內容,回滾沒有提交事務的修改。透過兩個階段保證了資料庫的一致性。對於mysql而言,在第一階段,若出現頁斷裂問題,則無法透過重做redo日誌恢復,進而導致恢復中斷,資料庫不一致。這裡大家可能會有疑問,資料庫的redo不是記錄了所有的變更,並且是物理的嗎?理論上來說,無論頁面是否斷裂,從上一個檢查點對應的redo位置開始,一直重做redo,頁面自然能恢復到正常狀態。對嗎?講清楚這個問題,先講講重做日誌(redo)格式。
重做日誌(redo)格式
資料庫系統實現日誌主要有三種格式,邏輯日誌(logical logging),物理日誌(physical logging),物理邏輯日誌(physiological logging),而對於redo日誌,則主要採用物理日誌和物理邏輯日誌兩類。邏輯日誌,記錄一個個邏輯操作,不涉及物理儲存位置資訊,比如mysql的binlog;物理日誌,則是記錄一個個具體物理位置的操作,比如在2號表空間,1號檔案,48頁的233這個offset地方寫入了8個位元組的資料,透過(group_id,file_id,page_no,offset)4元組,就能唯一確定資料儲存在磁碟的物理位置;物理邏輯日誌是物理日誌和邏輯日誌的混合,如果一個資料庫操作(DDL,DML,DCL)產生的日誌跨越了多個頁面,那麼會產生多個物理頁面的日誌,但對於每個物理頁面日誌,裡面記錄則是邏輯資訊。這裡我舉一個簡單的INSERT操作來說明幾種日誌形式。
比如innodb表T(c1,c2, key key_c1(c1)),插入記錄row1(1,’abc’)
邏輯日誌:
邏輯物理日誌:
因為表T含有索引key_c1, 一次插入操作至少涉及兩次B樹操作,二次B樹必然涉及至少兩個物理頁面,因此至少有兩條日誌
物理日誌:
由於一次INSERT操作,物理上來說要修改頁頭資訊(如,頁內的記錄數要加1),要修改相鄰記錄裡的連結串列指標,要修改Slot屬性等,因此對應邏輯物理日誌的每一條日誌,都會有N條物理日誌產生。
< group_id,file_id,page_no,offset1, value1>
< group_id,file_id,page_no,offset2, value2>
……
< group_id,file_id,page_no,offsetN, valueN>
因此對於上述一個INSERT操作,會產生一條邏輯日誌,二條邏輯物理日誌,2*N條物理日誌。從上面簡單的分析可以看出,邏輯日誌的日誌量最小,而物理日誌的日誌量最大;物理日誌是純物理的;而邏輯物理日誌則頁間物理,頁內邏輯,所謂physical-to-a-page, logical-within-a-page。
redo格式與資料一致性
回到“發生頁斷裂後,是否會影響資料庫一致性”的問題,發生頁斷裂後,對於利用純物理日誌實現redo的資料庫不受影響,因為每一條redo日誌完全不依賴物理頁的狀態,並且是冪等的(執行一次與N次,結果是一樣的)。另外要說明一點,redo日誌的頁大小一般設計為512個位元組,因此redo日誌頁本身不會發生頁斷裂。而邏輯物理日誌則不行,比如修改頁頭資訊,頁內記錄數加1,slot資訊修改等都依賴於頁面處於一個一致狀態,否則就無法正確重做redo。而mysql正是採用這種日誌型別,所以發生頁面斷裂時,異常恢復就會出現問題,需要藉助於double write技術來輔助處理。
double write處理頁斷裂
doublewrite是Innodb表空間內部分配的一片緩衝區,一般double write包含128個頁,對於pagesize為16k的頁,總共2MB,doublewrite頁與資料頁一樣有物理儲存空間,存在於共享表空間中。Innodb在寫出緩衝區中的資料頁時採用的是一次寫多個頁的方式,這樣多個頁就可以先順序寫入到doublewrite緩衝區,並呼叫fsync()保證這些資料被寫出到磁碟,然後資料頁才被寫出到它們實際的儲存位置並再次呼叫fsync()。故障恢復時Innodb檢查doublewrite緩衝區與資料頁原儲存位置的內容,若doublewrite頁處於頁斷裂狀態,則簡單的丟棄;若資料頁不一致,則會從doublewrite頁還原。由於doublewrite頁落盤與資料頁落盤在不同的時間點,不會出現doublewrite頁和資料頁同時發生斷裂的情況,因此doublewrite技術可以解決頁斷裂問題,進而保證了重做日誌能順利進行,資料庫能恢復到一致的狀態。
oracle如何處理頁斷裂
oracle與mysql一樣,採用的redo日誌也是邏輯物理格式,但沒有doublewrite技術。我一直就想著oracle這麼牛逼的資料庫,一定有它自己的方式來應對這種問題。也許這就是所謂的蠻目崇拜,找了N久資料,中文的英文的,包括諮詢何登成大神,基本能得出一個結論oracle遇到頁斷裂問題,一樣會掛,重啟不來。但是oracle有一個相對簡單的策略來恢復資料庫到一致狀態,備份+歸檔日誌。備份保證了資料頁不發生頁斷裂,加上歸檔日誌增量可以恢復到某個時間點。為什麼不做呢?我想一般使用oracle都會使用DataGuard做容災,主庫發生故障時,備庫會承擔起主庫的責任,然後異常主庫透過備份+歸檔日誌的方式來恢復,雖然不如doublewrite技術快,但也是能恢復出來的。
其他方式解決頁斷裂
前面討論的都是基於一個假設,異常重啟後,一定會導致頁斷裂,其實在底層設施在一定程度上是可以解決這個問題的,比如檔案系統層面,採用ZFS檔案系統,ZFS透過日誌的方式保證了OS頁面的完整性,從底層防止了頁斷裂問題;在磁碟層面,一般RAID卡都會有帶電快取,即使OS異常重啟,快取資料也不會立即丟失,因而也能保證不發生partial write問題。但是我在想,OS的pagesize比DB的pagesize要小,即使能保證OS page不發生頁斷裂,也不能保證DB page 不斷裂,個人感覺不能徹底解決。當然了,如果將DB pagesize設定成和OS pagesize一樣大,就沒問題了。
參考文件
http://blog.csdn.net/oneyearlater/article/details/7720723
http://www.percona.com/blog/2006/08/04/innodb-double-write/
http://blog.itpub.net/22664653/viewspace-1140915/?page=2
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26250550/viewspace-1266097/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Copy-On-Write技術
- 14.6.5 Doublewrite buffer
- 京東首頁前端技術剖析與對比前端
- 牆裂推薦:搜雲庫技術團隊,整理一年的技術乾貨
- (轉)innodb_doublewrite_file
- 不斷提高自己技術水平
- 前端網路診斷技術方案前端
- 缺頁中斷與頁面置換演算法演算法
- MySQL分頁技術總結MySql
- CSDN 技術主題首頁
- Linux--寫時複製(Copy-On-Write,COW)技術簡述Linux
- SAP UI 搜尋分頁技術UI
- MySQL的分頁技術總結MySql
- 掌握ASP分頁技術詳解
- ASP分頁技術原始碼 (轉)原始碼
- python實現基於八方向判斷的斷裂連線Python
- 技術與運營
- 微服務技術棧:流量整形演算法,服務熔斷與降級微服務演算法
- 如何判斷一項技術是否有前途?
- 相關技術連線,不斷新增中...
- Cisco路由器故障診斷技術(轉)路由器
- PHP的分頁處理技術和一些常用的技術PHP
- 頁面靜態化技術演進
- 網頁常見的換膚技術網頁
- Web頁面技術綜述(包括fastm)WebAST
- 理解「業務」與「技術」概念
- Http與HTTP隧道技術HTTP
- 虛擬技術與雲
- ERP與IT技術(轉)
- 【死磕 Java 基礎】 — 談談那個寫時拷貝技術(copy-on-write)Java
- 技術分享 | 調整 max-write-buffer-size 優化 pika 效能10倍的案例優化
- 缺頁中斷
- 演算法與演算法工程師,技術與技術人員演算法工程師
- 資訊系統/技術與計量系統/技術
- NFC技術與RFID技術有哪些異同點?
- 24-PHP+MySQL分頁技術詳解PHPMySql
- 技術分享 | 淺談一下大頁
- AI發展這一年:不斷衍生的技術醜聞與抵制聲潮AI