概述
redo log是InnoDB引擎特有的物理日志忠藤。redo log記錄了數(shù)據(jù)被修改后的值褒纲,確保事務(wù)的持久性。
防止在發(fā)生故障的時間點双抽,尚有臟頁未寫入磁盤,在重啟mysql服務(wù)的時候闲礼,根據(jù)redo log進行重做荠诬,從而達到事務(wù)的持久性這一特性。
redo log 物理文件
InnoDB 的 redo log 是固定大小的位仁,
比如可以配置為一組 4 個文件: 0 ~ 3柑贞,每個文件的大小是 1GB。
從頭開始寫到尾后會開始擦除頭部進行循環(huán)寫聂抢。 如圖:
111.png
可以通過配置參數(shù)
innodb_log_files_in_group 日志文件數(shù)量
innodb_log_file_size 文件大小
redo log 寫入包括兩部分:
- 內(nèi)存日志緩沖(redo log buffer)
基于內(nèi)存钧嘶,性能快,但易丟失琳疏。 - 重做日志文件(redo log file)
基于磁盤有决,將文件寫入磁盤進行持久化(由于redo log file是循環(huán)擦除寫闸拿,會導致歷史記錄丟失,這里涉及到二階段提交到binlog進行持久化)书幕。
redo log寫入機制
- 事務(wù)執(zhí)行時是先寫入redo log buffer (必須)
- write 寫到文件系統(tǒng)的 page cache (可選)
- fsync 持久化到磁盤 (可選)
可以通過參數(shù)對redolog寫入策略進行配置:
# 配置文件:mysql.ini
innodb_flush_log_at_trx_commit = 1
設(shè)為0時新荤,表示每次事務(wù)提交時都只是把 redo log 留在 redo log buffer 中 ;(不主動刷到磁盤)
設(shè)為1時,表示每次事務(wù)提交時都將 redo log 直接持久化到磁盤台汇;
設(shè)為2時苛骨,表示每次事務(wù)提交都只是吧redolog寫到page cache
注:InnoDB 后臺線程每1 秒就會把 redo log buffer 中的日志調(diào)用 write 寫到文件系統(tǒng)的 page cache然后調(diào)用 fsync 持久化到磁盤。一個沒有提交的事務(wù)的 redo log苟呐,也是可能已經(jīng)持久化到磁盤的痒芝。
另外兩種場景也會觸發(fā)未提交事務(wù)的redo log 寫入磁盤:
- redo log buffer 占用的空間即將達到 innodb_log_buffer_size 一半時。
注:由于事務(wù)并沒有提交牵素,所以寫盤動作只是 write严衬,未調(diào)用 fsync,也就是只留在了文件系統(tǒng)的 page cache笆呆。 - innodb_flush_log_at_trx_commit = 1 情況下
多事務(wù)并行请琳,當有事務(wù)先提交時,其他事務(wù)還停留在redo log buffer 也會提前觸發(fā)寫磁盤
二階段提交
222.png
階段一:寫入redo log完成時赠幕,階段處于prepare
階段二:binlog 也寫入成功俄精,階段才處于commit
崩潰恢復時的判斷規(guī)則:
- 如果 redo log 里面的事務(wù)是完整的,也就是已經(jīng)有了 commit 標識劣坊,則直接提交;
- 如果 redo log 里面的事務(wù)只有完整的 prepare屈留,則判斷對應(yīng)的事務(wù) binlog 是否存在并完整:
是 提交事務(wù) 局冰, 否 回滾事務(wù)。
redo log 和 binlog 通過共同數(shù)據(jù)字段:XID關(guān)聯(lián)
崩潰恢復時會按順序掃描 redo log:
- 如果碰到既有 prepare灌危、又有 commit 的 redo log康二,就直接提交;
- 如果碰到只有 parepare勇蝙、而沒有 commit 的 redo log沫勿,就拿著 XID 去 binlog 找對應(yīng)的事務(wù)。