1. 程式人生 > >MySQL重做日誌相關

MySQL重做日誌相關

 

 

Ⅰ、事務的實現

這裡我們先丟擲答案,通過答案再展開分析

特性 實現
A(原子性) redo
C(一致性) undo
I(隔離性) lock
D(永續性) redo/undo

本節針對redo展開分析

Ⅱ、redo詳解

2.1 redo log buffer

  • redo就是我們常說的重做日誌,用來實現永續性
  • mysql目錄下兩個ib_logfile檔案,就是重做日誌檔案,在ssd場景下至少設定為4G
  • redo log裡面記錄的是每個page修改操作的物理邏輯日誌(不是完全的二進位制的差異值,比如一個sql修改了一千萬行,一千萬個page被修改了,那記錄的是1000w page的變化,而不是sql語句)

redo由redo log buffer和redo log file組成,重做日誌先寫入一塊記憶體,再定期重新整理到磁碟

先看下redo log buffer

它由很多個log block組成,每個log block 512個位元組,不需要doublewrite

innodb_log_buffer_size    8M即可,不需要太大,一秒鐘寫滿8M不太可能

redo log刷盤的條件

①master thread    每秒從記憶體刷到磁碟
  5.6版本後,增加innodb_flush_log_at_timeout引數,可以設定重新整理間隔,預設為1,調大一點可減少io,提升效能,但不建議

②redo log buffer  使用大於1/2也會刷 ③事務提交時進行重新整理,即使上面兩個條件不滿足(事務永續性的要求) innodb_flush_log_at_trx_commit={0|1|2},預設為1,事務提交時將redo log buffer寫到磁碟(即使上面兩個條件不滿足,這樣crash了就還可以通過redo恢復),只有是1的時候innodb才能真正達到永續性的標準 事務對page做了修改,提交的時候並不需要保證贓頁刷到磁碟,只需要保證將對應修改的日誌刷過去就可以了 0表示交給master thread每秒重新整理,事務提交不將redo log buffer刷到磁碟,最多會丟失1s的事務 2表示事務提交時僅將redo log buffer寫到作業系統快取,所以mysql重啟,只要作業系統沒重啟,那資料還是在的額

2.2 redo log file

先弄個圖看看redo buffer刷盤吧

每個ib_logfile都分為很多個512bits的塊,最前頭2k是留出來寫checkpoint的,通過對比兩個cp可知哪個是最新的,cp1和cp2輪詢寫確保cp不會壞掉,一個壞了也沒事,即使用小的cp頂多就是恢復的時候多一點時間,沒有oracle的歸檔

優點: 這樣做的好處是不需要歸檔,少了IO操作
缺點: 如果redo_log_file太小則可能需要等待,因為當要覆蓋log_file中的log_block時,如果該log_block中的髒頁還沒有進行重新整理的話,則需要等待這個髒頁進行重新整理
所以需要把redo log file設定的儘可能的大

redo日誌分類

物理日誌:記錄整個page的變化(diff)

邏輯日誌:Like SQL語句

物理邏輯日誌:根據page進行記錄,內容邏輯

redo log file與redo log buffer內容一致

+---------------+----------+---------+---------------+
| redo_log_type | space no | page no | redo log body |
+---------------+----------+---------+---------------+
#  redo log 型別 表空間號 頁號 redo log 內容 MLOG_REC_INSERT +------+--------+------+---------+------------+-------+---------+-----------+----------+ | type | space | page | cur_rec | len & | info | origin | mis_match | rec body | | | no | no | _offset | extra_info | _bits | _offset | _index | | +------+--------+------+---------+------------+-------+---------+-----------+----------+ MLOG_REC_DELETE +------+----------+---------+--------+ | type | space no | page no | offset | +------+----------+---------+--------+ rec body根據page的變化來記錄,而不是根據操作SQL來記錄,所以偏物理日誌 因為還記錄了redo log body,一個具體操作,所以又叫邏輯 每種不同型別的redo log的內在格式可能長得不一樣

相關引數

innodb_log_file_size 單個redo檔案大小(推薦8G,官方推薦等於bp)
  之前不建議調大因為有bug,如果調大,恢復速度會很慢O(N^2) 5.5版本的redo檔案總大小(num * size)最大隻能4G 5.6之後限制未512G,調大後唯一的問題就是恢復的內容變多了 5.6之後,正常關閉MySQL,然後調整該值,會自動調整檔案大小 innodb_log_files_in_group innodb_log_group_home_dir 和資料檔案分開,選擇更快的磁碟
  分類:  MySQL

Ⅰ、事務的實現

這裡我們先丟擲答案,通過答案再展開分析

特性 實現
A(原子性) redo
C(一致性) undo
I(隔離性) lock
D(永續性) redo/undo

本節針對redo展開分析

Ⅱ、redo詳解

2.1 redo log buffer

  • redo就是我們常說的重做日誌,用來實現永續性
  • mysql目錄下兩個ib_logfile檔案,就是重做日誌檔案,在ssd場景下至少設定為4G
  • redo log裡面記錄的是每個page修改操作的物理邏輯日誌(不是完全的二進位制的差異值,比如一個sql修改了一千萬行,一千萬個page被修改了,那記錄的是1000w page的變化,而不是sql語句)

redo由redo log buffer和redo log file組成,重做日誌先寫入一塊記憶體,再定期重新整理到磁碟

先看下redo log buffer

它由很多個log block組成,每個log block 512個位元組,不需要doublewrite

innodb_log_buffer_size    8M即可,不需要太大,一秒鐘寫滿8M不太可能

redo log刷盤的條件

①master thread    每秒從記憶體刷到磁碟
  5.6版本後,增加innodb_flush_log_at_timeout引數,可以設定重新整理間隔,預設為1,調大一點可減少io,提升效能,但不建議

②redo log buffer  使用大於1/2也會刷 ③事務提交時進行重新整理,即使上面兩個條件不滿足(事務永續性的要求) innodb_flush_log_at_trx_commit={0|1|2},預設為1,事務提交時將redo log buffer寫到磁碟(即使上面兩個條件不滿足,這樣crash了就還可以通過redo恢復),只有是1的時候innodb才能真正達到永續性的標準 事務對page做了修改,提交的時候並不需要保證贓頁刷到磁碟,只需要保證將對應修改的日誌刷過去就可以了 0表示交給master thread每秒重新整理,事務提交不將redo log buffer刷到磁碟,最多會丟失1s的事務 2表示事務提交時僅將redo log buffer寫到作業系統快取,所以mysql重啟,只要作業系統沒重啟,那資料還是在的額

2.2 redo log file

先弄個圖看看redo buffer刷盤吧

每個ib_logfile都分為很多個512bits的塊,最前頭2k是留出來寫checkpoint的,通過對比兩個cp可知哪個是最新的,cp1和cp2輪詢寫確保cp不會壞掉,一個壞了也沒事,即使用小的cp頂多就是恢復的時候多一點時間,沒有oracle的歸檔

優點: 這樣做的好處是不需要歸檔,少了IO操作
缺點: 如果redo_log_file太小則可能需要等待,因為當要覆蓋log_file中的log_block時,如果該log_block中的髒頁還沒有進行重新整理的話,則需要等待這個髒頁進行重新整理
所以需要把redo log file設定的儘可能的大

redo日誌分類

物理日誌:記錄整個page的變化(diff)

邏輯日誌:Like SQL語句

物理邏輯日誌:根據page進行記錄,內容邏輯

redo log file與redo log buffer內容一致

+---------------+----------+---------+---------------+
| redo_log_type | space no | page no | redo log body |
+---------------+----------+---------+---------------+
#  redo log 型別 表空間號 頁號 redo log 內容 MLOG_REC_INSERT +------+--------+------+---------+------------+-------+---------+-----------+----------+ | type | space | page | cur_rec | len & | info | origin | mis_match | rec body | | | no | no | _offset | extra_info | _bits | _offset | _index | | +------+--------+------+---------+------------+-------+---------+-----------+----------+ MLOG_REC_DELETE +------+----------+---------+--------+ | type | space no | page no | offset | +------+----------+---------+--------+ rec body根據page的變化來記錄,而不是根據操作SQL來記錄,所以偏物理日誌 因為還記錄了redo log body,一個具體操作,所以又叫邏輯 每種不同型別的redo log的內在格式可能長得不一樣

相關引數

innodb_log_file_size 單個redo檔案大小(推薦8G,官方推薦等於bp)
  之前不建議調大因為有bug,如果調大,恢復速度會很慢O(N^2) 5.5版本的redo檔案總大小(num * size)最大隻能4G 5.6之後限制未512G,調大後唯一的問題就是恢復的內容變多了 5.6之後,正常關閉MySQL,然後調整該值,會自動調整檔案大小 innodb_log_files_in_group innodb_log_group_home_dir 和資料檔案分開,選擇更快的磁碟