重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
本篇內容介紹了“Innodb關鍵特性之什么是doublewrite”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
一、經典Partial page write問題
介紹double write之前我們有必要了解partial page write(部分頁失效)問題。
InnoDB的Page Size一般是16KB,其數據校驗也是針對這16KB來計算的,將數據寫入到磁盤是以Page為單位進行操作的。我們知道,由于文件系統對一次大數據頁(例如InnoDB的16KB)大多數情況下不是原子操作,這意味著如果服務器宕機了,可能只做了部分寫入。16K的數據,寫入4K時,發生了系統斷電/os crash ,只有一部分寫是成功的,這種情況下就是partial page write問題。
有經驗的DBA可能會想到,如果發生寫失效,MySQL可以根據redo log進行恢復。這是一個辦法,但是必須清楚地認識到,redo log中記錄的是對頁的物理修改,如偏移量800,寫’aaaa’記錄。如果這個頁本身已經發生了損壞,再對其進行重做是沒有意義的。MySQL在恢復的過程中檢查page的checksum,checksum就是檢查page的最后事務號,發生partial page write問題時,page已經損壞,找不到該page中的事務號。在InnoDB看來,這樣的數據頁是無法通過checksum驗證的,就無法恢復。即時我們強制讓其通過驗證,也無法從崩潰中恢復,因為當前InnoDB存在的一些日志類型,有些是邏輯操作,并不能做到冪等。
為了解決這個問題,InnoDB實現了double write buffer,簡單來說,就是在寫數據頁之前,先把這個數據頁寫到一塊獨立的物理文件位置(ibdata),然后再寫到數據頁。這樣在宕機重啟時,如果出現數據頁損壞,那么在應用redo log之前,需要通過該頁的副本來還原該頁,然后再進行redo log重做,這就是double write。double write技術帶給innodb存儲引擎的是數據頁的可靠性,下面對doublewrite技術進行解析,讓大家充分理解double write是如何做到保障數據頁的可靠性。
二、double write體系結構及工作流程
double write由兩部分組成,一部分是InnoDB內存中的double write buffer,大小為2M,另一部分是物理磁盤上ibdata系統表空間中大小為2MB,共128個連續的Page,既2個分區。其中120個用于批量寫臟,另外8個用于Single Page Flush。做區分的原因是批量刷臟是后臺線程做的,不影響前臺線程。而Single page flush是用戶線程發起的,需要盡快的刷臟并替換出一個空閑頁出來。
對于批量刷臟,每次找到一個可做flush的page,對其持有S lock,然后將該page拷貝到dblwr中,當dblwr滿后者一次批量刷臟結束時,將dblwr中的page全部刷到ibdata中,注意這是同步寫操作;然后再喚醒后臺IO線程去寫數據頁。當后臺IO線程完成寫操作后,會去更新dblwr中的計數以騰出空間,釋放block上的S鎖,完成寫入。
對于Single Page Flush,則做的是同步寫操作,在挑出一個可以刷臟的page后,先加入到dblwr中,刷到ibdata,然后寫到用戶表空間,完成后,會對該用戶表空間做一次fsync操作。
Single Page Flush在buffer pool中free page不夠時觸發,通常由前臺線程發起,由于每次single page flush都會導致一次fsync操作,在大并發負載下,如果大量線程去做flush,很顯然會產生嚴重的性能下降。Percona在5.6版本中做了優化,可以選擇由后臺線程lru manager來做預刷,避免用戶線程陷入其中。
如果發生了極端情況(斷電),InnoDB再次啟動后,發現了一個Page數據已經損壞,那么此時就可以從double write buffer中進行數據恢復了。
double write工作流程如下:
當一系列機制(main函數觸發、checkpoint等)觸發數據緩沖池中的臟頁進行刷新到data file的時候,并不直接寫磁盤,而是會通過memcpy函數將臟頁先復制到內存中的double write buffer,之后通過double write buffer再分兩次、每次1MB順序寫入共享表空間的物理磁盤上。然后馬上調用fsync函數,同步臟頁進磁盤上。由于在這個過程中,double write頁的存儲時連續的,因此寫入磁盤為順序寫,性能很高;完成double write后,再將臟頁寫入實際的各個表空間文件,這時寫入就是離散的了。各模塊協作情況如下圖(第一步應為臟頁產生的redo記錄log buffer,然后log buffer寫入redo log file,為簡化次要步驟直接連線表示):
查看doublewrite工作情況,可以執行命令:
mysql>show status like '%InnoDB_dblwr%' +----------------------------+-----------------+ | Variable_name | Value | +----------------------------+-----------------+ | Innodb_dblwr_pages_written | 216261751 | | Innodb_dblwr_writes | 43307580 | +----------------------------+-----------------+
以上數據顯示,double write一共寫了 61932183個頁,一共寫了15237891次,從這組數據我們可以分析,之前講過在開啟double write后,每次臟頁刷新必須要先寫double write,而double write存在于磁盤上的是兩個連續的區,每個區由連續的頁組成,一般情況下一個區最多有64個頁,所以一次IO寫入應該可以最多寫64個頁。而根據以上我這個系統Innodb_dblwr_pages_written與Innodb_dblwr_writes的比例來看,一次大概在4個頁左右,遠遠還沒到64,所以從這個角度也可以看出,系統寫入壓力并不高。
如果操作系統在將頁寫入磁盤的過程中發送了崩潰,在恢復過程中,InnoDB存儲引擎可以從工序表空間中的double write中找到該頁的副本,將其復制到表空間文件,再應用redo log。下面顯示了一個由double write進行恢復的過程:
090924 11:36:32 mysqld restarted
090924 11:26:33 InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Crash recovery may have faild for some .ibd files!
InnoDB: Restoring possible half-written data pages from the doublewrite.
InnoDB: buffer...
三、double write的缺點
dblwr位于共享表空間上的double write buffer實際上也是一個文件,引入了一次額外寫的開銷,每個數據頁都被要求寫兩次。由于需要大量的fsync操作,所以它會降低MySQL的整體性能,但是并不會降低到原來的50%。這主要是因為:
1) double write是一個連接的存儲空間,所以硬盤在寫數據的時候是順序寫,而不是隨機寫,這樣性能更高。
2) 將數據從double write buffer寫到真正的segment中的時候,系統會自動合并連接空間刷新的方式,每次可以刷新多個pages。
double write默認開啟,參數skip_innodb_doublewrite雖然可以禁止使用double write功能,但還是強烈建議大家使用double write。避免部分寫失效問題,當然,如果你的數據表空間放在本身就提供了部分寫失效防范機制的文件系統上,如ZFS/FusionIO/DirectFS文件系統,在這種情況下,就可以不開啟doublewrite了
四、double write在恢復的時候是如何工作的
如果是寫double write buffer本身失敗,那么這些數據不會被寫到磁盤,InnoDB此時會從磁盤載入原始的數據,然后通過InnoDB的事務日志來計算出正確的數據,重新寫入到double write buffer。
如果double write buffer寫成功的話,但是寫磁盤失敗,InnoDB就不用通過事務日志來計算了,而是直接用buffer的數據再寫一遍。如上圖中顯示,在恢復的時候,InnoDB直接比較頁面的checksum,如果不對的話,Innodb存儲引擎可以從共享表空間的double write中找到該頁的一個最近的副本,將其復制到表空間文件,再應用redo log,就完成了恢復過程。因為有副本所以也不擔心表空間中數據頁是否損壞,但InnoDB的恢復通常需要較長的時間。
“Innodb關鍵特性之什么是doublewrite”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注創新互聯-成都網站建設公司網站,小編將為大家輸出更多高質量的實用文章!