突然斷電,是否會影響Mysql的執行結果

roc_guo發表於2022-05-02

MySQL採用buffer機制,避免每次讀寫進行磁碟IO,提升效率:

  • 《緩衝池(buffer pool)》
  • 《寫緩衝(change buffer)》
  • 《日誌緩衝(log buffer)》
  • MySQL的buffer一頁的大小是16K,檔案系統一頁的大小是4K,也就是說,MySQL將buffer中一頁資料刷入磁碟,要寫4個檔案系統裡的頁。

    突然斷電,是否會影響Mysql的執行結果突然斷電,是否會影響Mysql的執行結果

    如上圖所示,MySQL裡page=1的頁,物理上對應磁碟上的1+2+3+4四個格。

    那麼,問題來了,這個操作並非原子,如果執行到一半斷電,會不會出現問題呢?

    會,這就是所謂的“頁資料損壞”。

    突然斷電,是否會影響Mysql的執行結果突然斷電,是否會影響Mysql的執行結果

    如上圖所示,MySQL內page=1的頁準備刷入磁碟,才刷了3個檔案系統裡的頁,掉電了,則會出現:重啟後,page=1的頁,物理上對應磁碟上的1+2+3+4四個格,資料完整性被破壞。

    畫外音:redo無法修復這類“頁資料損壞”的異常,修復的前提是“頁資料正確”並且redo日誌正常。

    如何解決這類“頁資料損壞”的問題呢?

    很容易想到的方法是,能有一個“副本”,對原來的頁進行還原,這個儲存“副本”的地方,就是Double Write Buffer。

    Double Write Buffer,但它與傳統的buffer又不同,它分為記憶體和磁碟的兩層架構。

    畫外音:傳統的buffer,大部分是記憶體儲存;而DWB裡的資料,是需要落地的。

    突然斷電,是否會影響Mysql的執行結果突然斷電,是否會影響Mysql的執行結果

    如上圖所示,當有頁資料要刷盤時:

  • 第一步:頁資料先memcopy到DWB的記憶體裡;
  • 第二步:DWB的記憶體裡,會先刷到DWB的磁碟上;
  • 第三步:DWB的記憶體裡,再刷到資料磁碟儲存上;
  • 畫外音:DWB由128個頁構成,容量只有2M。

    步驟2和步驟3要寫2次磁碟,這就是“Double Write”的由來。

    DWB為什麼能解決“頁資料損壞”問題呢?

    假設步驟2掉電,磁碟裡依然是1+2+3+4的完整資料。

    畫外音:只要有頁資料完整,就能透過redo還原資料。

    假如步驟3掉電,DWB裡儲存著完整的資料。

    所以,一定不會出現“頁資料損壞”問題。

    畫外音:寫了2次,總有一個地方的資料是OK的。

    自己實驗了幾十次,仍沒能復現“頁資料損壞”,在網上找了一個“頁資料損壞”時,MySQL重啟過程利用DWB修復頁資料的圖。

    突然斷電,是否會影響Mysql的執行結果突然斷電,是否會影響Mysql的執行結果

    可以看到,啟動過程中:

  • InnoDB檢測到上一次為異常關閉;
  • 嘗試恢復ibd資料,失敗;
  • 從DWB中恢復寫了一半的頁;
  • 能夠透過DWB保證頁資料的完整性,但畢竟DWB要寫兩次磁碟,會不會導致資料庫效能急劇降低呢?

    分析DWB執行的三個步驟:

  • 第一步,頁資料memcopy到DWB的記憶體,速度很快;
  • 第二步,DWB的記憶體fsync刷到DWB的磁碟,屬於順序追加寫,速度也很快;
  • 第三步,刷磁碟,隨機寫,本來就需要進行,不屬於額外操作;
  • 另外,128頁(每頁16K)2M的DWB,會分兩次刷入磁碟,每次最多64頁,即1M的資料,執行也是非常之快的。

    綜上,效能會有所影響,但影響並不大。

    畫外音:

  • write­-ahead-log之所以效能高,就是因為順序追加寫;
  • 有第三方測評,評估約10%效能損失;
  • 更具體的,InnoDB裡有兩個變數可以檢視double write buffer相關的情況:

  • Innodb_dblwr_pages_written:記錄寫入DWB中頁的數量。
  • Innodb_dblwr_writes:記錄DWB寫操作的次數。
  • 可以透過:

show global status like "%dblwr%"

來進行查詢。

突然斷電,是否會影響Mysql的執行結果突然斷電,是否會影響Mysql的執行結果

結尾

MySQL有很強的資料安全性機制:

  • 在異常崩潰時,如果不出現“頁資料損壞”,能夠透過redo恢復資料;
  • 在出現“頁資料損壞”時,能夠透過double write buffer恢復頁資料;
  • double write buffer:

  • 不是一個記憶體buffer,是一個記憶體/磁碟兩層的結構,是InnoDB裡On-Disk架構裡很重要的一部分;
  • 是一個透過寫兩次,保證頁完整性的機制;
  • 知其然,知其所以然。

    思路比結論重要,希望大家有收穫。


    來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69901823/viewspace-2890243/,如需轉載,請註明出處,否則將追究法律責任。

    相關文章