MySQL 特性:Double Write

1.什麼是double write
  首先要明白double write這個特性是針對誰的,日誌or髒數據?
  明白的是髒數據,是內存中修改後的數據頁,這些數據頁修改後和磁盤上存儲的原數據不一致了,稱爲髒數據。爲了數據的持久性,這些髒數據須要刷新到磁盤上,使修改永久的保存,而double write就產生在將髒數據刷盤的過程當中。刷盤是一份髒數據寫到共享表空間,一份寫到真正的數據文件永久的保存。寫了兩次髒數據,就叫double wriete。
 
2.爲何要有double write
  不少人疑問,爲啥寫兩次,刷一次數據文件保存數據不就好了,寫共享表空間是啥意思嘛。共享表空間是在ibdbata文件中劃出2M連續的空間,專門給double write刷髒頁用的,說白了就是磁盤上2M連續空間。
  MySQL的數據頁默認是16k,對數據頁的校驗也是按16k計算的。而操做系統的數據頁默認是2k或者4k,IO操做是按系統頁爲單位就行讀寫的。這就可能出現一種狀況,數據庫對一個16k的數據頁修改後,操做系統開始進行寫磁盤,每次寫4k,結果剛寫完第一個4k,數據庫掛了。這時候系統一臉懵逼的看着掛掉的數據庫,呆呆的說了句‘這事不怨我’。這時候數據庫重啓時,校驗數據頁,發現有數據頁不完整,就起不來了,即便經過歪門邪道使數據庫起來,也會有一頁的數據丟失。
  爲了解決這個問題,double write就應運而生了,爲安全而來。簡單來講,修改後的髒頁放到double write buffer區,這個區佔用2M內存空間,buffer空間滿或其餘條件觸發,使double write buffer存的髒頁先寫到共享表空間,以後在寫入數據文件。這個時候若是寫了不完整的頁,能夠用共享表空間中完整的頁加以覆蓋,數據頁完整了,數據庫也就能夠拉起了,以後的各類恢復就看redo log的了。提到redo log了,有人可能又會懵逼,不完整的數據頁用redo log恢復唄,搞個double write畫蛇添足嗎。這時候不得不介紹一下redo log的記錄日誌格式了——redo log是按數據塊的方式記錄日誌的,差很少相似於髒頁直接放到redo log中,但又不徹底相同,否則redo log得多佔空間啊。它是根據偏移量來記錄修改了,好比test數據文件的第1025個數據塊的100字節的偏移位置,數據修改成了‘new data’。一個16k的數據塊不可能哪兒哪兒都修改,有可能僅僅修改裏面的一個字節,而redo log的工做做風就是:修改哪兒記錄哪兒。這樣,數據頁不完整了,找redo log沒用。
 
3.double write工做流程
  論double write的工做流程,廢話很少說,請直接看圖:先產生髒頁,產生髒頁的過程當中會寫redo log,這是第一步。髒頁有了,也就循序漸進了。
4.如何利用double write進行恢復
數據恢復有三種狀況:
4.1 髒數據寫磁盤成功
  這種狀況是最多見的,髒頁刷磁盤99.9%都會成功,可是即便有0.1失敗可能也要作處理,否則數據丟了,數據庫就不安全了,沒有公司願意每天提心吊膽的抱着個定時炸彈。刷盤成功,找檢查點,redo log前滾、回滾就好了。
4.2 共享表空間寫失敗
  若是是寫共享表空間失敗,那麼這些數據不會被寫到數據文件,數據庫會認爲此次刷盤從沒發生過,MySQL此時會從磁盤載入原始的數據,而後找檢查點,redo log前滾、回滾就好了。
4.3 髒數據刷數據文件失敗
  寫共享表空間成功,可是寫數據文件失敗,在恢復的時候,MySQL直接比較頁面的checksum,若是不對的話,直接從共享表空間的double write中找到該頁的一個最近的副本,將其複製到表空間文件,再應用redo log,就完成了恢復過程。由於有副本因此也不擔憂表空間中數據頁是否損壞。
 
5.double write缺陷及改進過程
  太長了,之後再說。

原文出處:https://www.cnblogs.com/nandi001/p/11662992.htmlhtml

相關文章
相關標籤/搜索