MySQL 更新陳述句執行程序 WAL redolog binlog
WAL
全稱Write-Ahead Logging --- 先寫日志再寫磁盤
當有一條記錄需要更新的時候,InnoDB 引擎就會先把記錄寫到 redo log 里,并更新記憶體,這個時候更新就算完成了,并在適當的時候將該操作記錄更新到磁盤中,
redo log
-
redo log (重做日志)是處于
存盤引擎層的,是InnoDB引擎特有的 -
redo log 存盤的是物理日志 --- 即,“在某個資料頁上改動了什么”
-
redo log是回圈寫,空間是一定的,會用完,
-
InnoDB 引擎的 redo log 的空間是有限的,一組4個檔案,每個檔案1GB,總共4GB,當這塊“臨時記錄板”寫滿后再次從開頭的地方回圈寫入,
-
redo log 的寫入分為兩個步驟 ---
perpare和commit階段 --- ”兩階段提交“
有了redo log,就可以保證即使資料庫發生例外重啟也不會丟失記錄,稱為 crash-safe
binlog
-
binlog (歸檔日志) 處于
server層,是Mysql自帶的日志模塊 -
binlog 是存盤的是邏輯日志 --- 即,“記錄原始陳述句”,因此可用來恢復資料庫 --- 相當于在某個時間的基礎上重新運行了一遍相關陳述句,
-
binlog 是可追加寫入的 --- binlog檔案寫到 一定大小后就會在下一個檔案中繼續寫,而不覆寫之前的檔案,
兩種日志的使用流程
- (執行器)讀取表中需要update的那一行
- (InnoDB)查詢該行資訊是否在記憶體中,若沒有則從磁盤讀取到記憶體,然后都回傳行資料
- (執行器)更改行資料、寫入新行
- (InnoDB)新行更新到記憶體,寫入redo log (此時處于prepare階段)
- (執行器)寫入binlog
- (InnoDB)提交事務 (此時處于commit階段)
使用“兩階段提交”是為了避免恢復時恢復出來的資料庫與原有狀態不一致的現象,
小結一下就是會有一下幾種情況:
- prepare階段crash:資料庫恢復后因為記憶體中的redolog丟失且未寫入binlog,因此事務rollback(就是說該事務的DML會失效)
- binlog階段crash:crash時日志還沒寫入磁盤,啟動時此事務會rollback
- commit階段,未commit成功就crash:此時雖然未完成兩段式提交中的commit,但是mysql資料庫恢復的時候會讀出binlog的xid(prepare階段生成xid),然后告訴InnoDB提交xid的事務,InnoDB提交完之后會回滾其他事務,使得redolog和binlog保持一致,(也就是說有xid的事務就可以恢復)
避免MySQL crash時資料丟失的設定
我們知道發生crash時丟失的肯定都是記憶體中的資料,通過以下設定進行持久化
- redo log 用于保證 crash-safe 能力,將
innodb_flush_log_at_trx_commit = 1--- 每次事務的 redo log 直接持久化到磁盤 sync_binlog = 1--- 每次事務的binlog都持久化到磁盤
恢復與擴容
- 最近的全量備份+到相應時間點的歸檔日志(binlog)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/22851.html
標籤:MySQL
