一、事務日誌介紹
參照mysql5.5的中文說明;
Innodb的事務日誌是指Redo log,簡稱Log,保存在日誌文件ib_logfile*裏面。Innodb還有另一個日誌Undo log,但Undo log是存放在共享表空間裏面的(ibdata*文件)。mysql
因爲Log和Checkpoint緊密相關,所以將這兩部分合在一塊兒分析。linux
名詞解釋:LSN(log serial number),日誌序列號,Innodb的日誌序列號是一個64位的整型
1.1log的寫入機制:sql
LSN實際上對應日誌文件的偏移量,新的LSN=舊的LSN + 寫入的日誌大小。舉例以下:安全
LSN=1G,日誌文件大小總共爲600M,本次寫入512字節,則實際寫入操做爲:async
l 求出偏移量:因爲LSN數值遠大於日誌文件大小,所以經過取餘方式,獲得偏移量爲400M;日誌
l 寫入日誌:找到偏移400M的位置,寫入512字節日誌內容,下一個事務的LSN就是1000000512;
1.2Checkpoint寫入
Innodb實現了Fuzzy Checkpoint的機制,每次取到最老的髒頁,而後確保此髒頁對應的LSN以前的LSN都已經寫入日誌文件,再將此髒頁的LSN做爲Checkpoint點記錄到日誌文件,意思就是「此LSN以前的LSN對應的日誌和數據都已經寫入磁盤文件」。恢復數據文件的時候,Innodb掃描日誌文件,當發現LSN小於Checkpoint對應的LSN,就認爲恢復已經完成。
Checkpoint寫入的位置在日誌文件開頭固定的偏移量處,即每次寫Checkpoint都覆蓋以前的Checkpoint信息。
1.3管理機制
因爲Checkpoint和日誌緊密相關,將日誌和Checkpoint一塊兒說明,詳細的實現機制以下
如上圖所示,Innodb的一條事務日誌共經歷4個階段:事務
l 建立階段:事務建立一條日誌;it
l 日誌刷盤:日誌寫入到磁盤上的日誌文件;innodb
l 數據刷盤:日誌對應的髒頁數據寫入到磁盤上的數據文件;ast
l 寫CKP:日誌被看成Checkpoint寫入日誌文件;
對應這4個階段,系統記錄了4個日誌相關的信息,用於其它各類處理使用:
l Log sequence number(LSN1):當前系統LSN最大值,新的事務日誌LSN將在此基礎上生成(LSN1+新日誌的大小);
l Log flushed up to(LSN2):當前已經寫入日誌文件的LSN;
l Oldest modified data log(LSN3):當前最舊的髒頁數據對應的LSN,寫Checkpoint的時候直接將此LSN寫入到日誌文件;
l Last checkpoint at(LSN4):當前已經寫入Checkpoint的LSN;
對於系統來講,以上4個LSN是遞減的,即: LSN1>=LSN2>=LSN3>=LSN4.建立日誌的LSN最大,寫入checkpoint的lsn是最小的;
show engine innodb status \G;
---
LOG
---
Log sequence number 16953660229
Log flushed up to 16953660229
Last checkpoint at 16953652205
1.4保護機制
Innodb的數據並非實時寫盤的,爲了不宕機時數據丟失,保證數據的ACID屬性,Innodb至少要保證數據對應的日誌不能丟失。對於不一樣的狀況,Innodb採起不一樣的對策:
宕機致使日誌丟失
Innodb有日誌刷盤機制,能夠經過innodb_flush_log_at_trx_commit參數進行控制;
日誌覆蓋致使日誌丟失
Innodb日誌文件大小是固定的,寫入的時候經過取餘來計算偏移量,這樣存在兩個LSN寫入到同一位置的可能,後面寫的把前面寫得就覆蓋了,以「寫入機制」章節的樣例爲例,LSN=100000000和LSN=1600000000兩個日誌的偏移量是相同的了。這種狀況下,爲了保證數據一致性,必需要求LSN=1000000000對應的髒頁數據都已經刷到磁盤中,也就是要求Last checkpoint對應的LSN必定要大於1000000000,不然覆蓋後日志也沒有了,數據也沒有刷盤,一旦宕機,數據就丟失了。
爲了解決第二種狀況致使數據丟失的問題,Innodb實現了一套日誌保護機制,詳細實現以下:
上圖中,直線表明日誌空間(Log cap,約等於日誌文件總大小*0.8,0.8是一個安全係數),Ckp age和Buf age是兩個浮動的點,Buf async、Buf sync、Ckp async、Ckp sync是幾個固定的點。各個概念的含義以下:
當事務執行速度大於髒頁刷盤速度時,Ckp age和Buf age會逐步增加,當達到async點的時候,強制進行髒頁刷盤或者寫Checkpoint,若是這樣作仍是趕不上事務執行的速度,則爲了不數據丟失,到達sync點的時候,會阻塞其它全部的事務,專門進行髒頁刷盤或者寫Checkpoint。 所以從理論上來講,只要事務執行速度大於髒頁刷盤速度,最終都會觸發日誌保護機制,進而將事務阻塞,致使MySQL操做掛起。 因爲寫Checkpoint自己的操做相比寫髒頁要簡單,耗費時間也要少得多,且Ckp sync點在Buf sync點以後,所以絕大部分的阻塞都是阻塞在了Buf sync點,這也是當事務阻塞的時候,IO很高的緣由,由於這個時候在不斷的刷髒頁數據到磁盤。例如以下截圖的日誌顯示了不少事務阻塞在了Buf sync點: 參考資料:linux公社謀篇文章