天天看點

為什麼有了binlog還要有redo log

為什麼有了binlog還要有redo log?

  1. binlog會記錄所有與MySQL資料庫有關的日志記錄,包括InnoDB, MyISAM,Heap等其他存儲引起的日志。而redo log隻記錄innodb引擎本身的日志。
  2. binlog記錄的是關于一個事務的具體操作内容,即該日志是邏輯日志。而redolog記錄的是關于每個頁的更改的實體情況。
  3. 寫入時間不同。binlog僅在事務送出前送出,隻寫磁盤一次,不論這個事務有多大。而redolog在事務進行過程中會不停的寫入。

它們分工是不同的。binlog用來做資料歸檔,但不具備崩潰恢複的能力,也就是說如果系統突然崩潰,重新開機後可能會有部分資料丢失。

innodb将所有對頁面的修改操作寫入一個專門的檔案,并在資料庫啟動時從此檔案進行恢複操作。

redolog擴充:

每個innodb引擎至少有1個重做日志檔案組(group),每個檔案組下面至少有2個重做日志檔案。為了提高可靠性,可以設定多個組,放到不同的磁盤中。在日志組中每個重做日志檔案大小一緻,并以循環寫入的方式運作。先寫入檔案1,寫滿後寫入檔案2,2寫滿再切換到1.

寫入redolog不是直接寫磁盤,而是先寫入一個重做日志緩沖(redo log buffer),然後按一定的條件寫入。

所謂的條件:

  1. 主線程每秒重新整理
  2. 其實是基于配置的:

    參數:innodb_flush_log_at_trx_commit

    值:0、1、2 (0-表示事務送出的時候,不主動将事務的重做日志寫入磁盤,而是等待主線程重新整理;1- 事務送出,将重做日志刷入磁盤,并伴有fsync調用;2- 将重做日志異步寫入磁盤,即寫入到檔案系統的緩存中。是以并不能完全保重寫入到磁盤)

    為了保證事務的持久性,應該将innodb_flush_log_at_trx_commit設定為1。

其他影響redolog的參數

  • innodb_log_file_size 指定每個重做日志檔案大小
  • innodb_log_files_in_group 指定了日志檔案組中重做日志檔案的數量,預設為2;
  • innodb_mirrored_log_groups 指定了日志鏡像檔案組的數量,預設為1,表示隻有一個日志檔案組,沒有鏡像。若磁盤本身有高可用方案,可不開啟鏡像。
  • innodb_log_group_home_dir 指定了日志檔案組所在路徑,預設為./ 表示在MYSQL資料目錄下。

binlog擴充:

binnlog記錄資料庫執行更改的操作。預設關閉,需要手動開啟。

影響binlog的參數

  • max_binlog_size: 單個二進制日志檔案的最大值,如果超過這個值,産生新的二進制檔案,字尾名+1;
  • binlog_cache_size: 當資料庫使用支援事務的存儲引擎(例如innodb),所有未送出的二進制日志會被記錄到緩存中,等待事務送出時直接寫到檔案中。這個緩沖區大小是由binlog_cache_size決定的。如果事務記錄大于緩沖區大小(預設32k),會寫入到臨時檔案,影響效率。

判斷binlog_cache_size是否合适:

mysql> show global status like 'binlog_cache%'

Binlog_cache_disk_use	0
Binlog_cache_use	1
           

如上,Binlog_cache_disk_use為0,使用臨時檔案次數為0,這個緩沖區夠大,不需要增加。

預設binlog不是每次寫的時候都同步磁盤(緩沖寫),當系統當機時,可能會有一部分資料沒寫入binlog中。參數sync_binlog = [N] 表示寫入緩沖多少次就同步到磁盤。N=1表示同步寫。不會用到作業系統的緩沖。

如果将sync_binlog設定為1,在一個事務發出commit之前,binlog被寫入磁盤,這時候當機,事務沒有送出。下次啟動的時候,這個事務沒有送出,應該復原,但是binlog被寫入磁盤了,就不能復原。将innodb_support_xa設定為1可以解決這個問題。能確定binlog和redolog檔案的同步。

姜承堯·MySQL技術内幕InnoDB存儲引擎·機械工業出版社

繼續閱讀