@
redo log(物理日志\重做日志)
redo log
是InnoDB存儲引擎層的日志,又稱重做日志文件,是物理日志。redo log
記錄數據修改后新數據的備份、冗雜的undo log
、未提交的事務和回滾的事務,數據緩存到內存中,只是在事務提交前將redo log
持久化到磁盤
redo log
可以保證即使數據庫發生異常重啟,之前提交的記錄都不會丟失,保證了事務的持久性。當有一條記錄需要更新的時候,InnoDB引擎就會先把記錄寫到
redo log
中,並更新內存。之后,InnoDB引擎會在適當的時候,將這個操作更新到磁盤中,這個更新是在系統比較空閑的時候做,他的關鍵點是先寫日志,再寫磁盤。
redo log
日志大小是固定的,若空間滿了以后會回到頭部停止更新,先加載一些數據到磁盤讓出文件空間,之后繼續寫入
物理日志:因為
mysql
數據最終是保存在數據頁中的,物理日志記錄的就是數據頁變更。
為了保證Redo Log能夠有比較好的IO性能,InnoDB 的 Redo Log的設計有以下幾個特點:
-
盡量保持
Redo Log
存儲在一段連續的空間上。因此在系統第一次啟動時就會將日志文件的空間完全分配。以順序追加的方式記錄Redo Log,通過順序IO來改善性能。 -
redo log包括兩部分:一是內存中的日志緩沖(redo log buffer),該部分日志是易失性的;二是磁盤上的重做日志文件(redo log file),該部分日志是持久的。日志並不是直接寫入文件的,而是先寫入日志緩沖,當需要將日志刷新到磁盤時(如事務提交),將許多日志一起寫入磁盤.
-
並發的事務共享
Redo Log
的存儲空間,它們的Redo Log
按語句的執行順序,依次交替的記錄在一起,以減少日志占用的空間。所以,當一個事務將Redo Log寫入磁盤時,也會將其他未提交的事務的日志寫入磁盤。 -
Redo Log
上只進行順序追加的操作,當一個事務需要回滾時,它的Redo Log
記錄也不會從Redo Log
中刪除掉。
注意:
一般在事務提交之前會將redo log
持久化到磁盤中,以此來保證持久性
binlog(邏輯日志/歸檔日志)
binlog
是屬於MySQL Server層面的,又稱為歸檔日志,屬於邏輯日志,是以二進制的形式記錄的是這個語句的原始邏輯,依靠binlog
是沒有CrashSafe
能力的
邏輯日志:可以簡單理解為記錄的就是sql語句。
binlog
主要使用場景:主從復制
,數據恢復
主從復制:在Master
端開啟binlog
,然后將binlog
發送到各個Slave
端,Slave
端重放binlog
從而達到主從數據一致。
數據庫恢復方法
系統會定期整庫備份,binlog會記錄所有的邏輯操作,當需要恢復到指定的某一時刻時:
- 首先,找到最近的一次全量備份
- 然后,從備份時間開始,將binlog依次取出來,一直重放到指定的時刻
為什么 redo log 具有 crash-safe 的能力,而 binlog 沒有?
CrashSafe
指MySQL服務器宕機重啟后,能夠保證:
- 所有已經提交的事務的數據仍然存在。
- 所有沒有提交的事務的數據自動回滾。
當數據庫 crash(崩潰) 后,想要恢復未刷盤但已經寫入 redo log
和 binlog
的數據到內存時,binlog
是無法恢復的。雖然 binlog
擁有全量的日志,但沒有一個標志讓 innoDB 判斷哪些數據已經刷盤,哪些數據還沒有。
但 redo log
不一樣,只要刷入磁盤的數據,都會從 redo log
中抹掉,數據庫重啟后,直接把 redo log
中的數據都恢復至內存就可以了。這就是為什么 redo log
具有crash-safe
的能力,而binlog
不具備。
redo log 和 binlog的區別:
- redo log是InnoDB特有的日志,binlog 所有引擎都可以使用
- redo log是物理日志,記錄的是該數據頁更新的內容;
binlog
是邏輯日志,記錄的是這個更新語句的原始邏輯 - redo log是循環寫的,空間固定會用完。binlog是可以追加寫的,當binlog寫到一定大小會切換到下一個,並不會覆蓋以前的日志
- binlog可以作為恢復數據使用,主從復制搭建,redo log作為異常宕機或者介質故障后的數據恢復使用。
update語句執行流程
首先進行sql查詢語句的執行流程,如需 update ID = 2 ,先找到這一行,執行以下流程:

為什么update語句 要有兩階段提交?
這是為了讓兩份日志之間的邏輯一致。
當執行update語句時,數據修改完更新到內存,先寫redo log
並設置redo log
為准備階段,再寫binlog
,寫完binlog
設置為redo log
為結束階段。兩個中間有一個寫入差錯,那么該操作都是失敗,即redo log
發現只有准備階段沒有結束,那么會將該條事務進行回滾。
假如不采用兩階段提交機制的話那么會有什么影響呢?
(1)先寫redo log
:當寫完redo log設備斷電,binlog
沒有記錄,那么數據庫剛剛啟動之后通過redo log
可以恢復到斷電前的狀態,但是由於binlog
沒有寫入,當從某個節點進行恢復時(或者創建一個備份庫),那么binlog沒用這條記錄,恢復出來的數據庫是有錯誤的。
(2)先寫binlog
:當寫完binlog
設備斷電,redo log
沒有記錄,還沒有寫入磁盤,那么數據庫重新啟動之后通過redo log
恢復並沒有這條數據,而當從某個時間點進行恢復(或者創建一個備份庫)時,binlog
有相關數據,所以會導致數據不統一。
Undolog(回滾日志/重做日志)
Undo Log 是為了實現事務的原子性,事務中執行失敗,進行回滾,在MySQL數據庫 InnoDB
存儲引擎中,還用Undo Log
來實現多版本並發控制(簡稱:MVCC
)。由引擎層的InnoDB引擎實現,是邏輯日志,記錄數據修改被修改前的值。
原理:
Undo Log的原理很簡單,為了滿足事務的原子性,在操作任何數據之前,首先將數據備份到Undo Log。然后進行數據的修改。如果出現了錯誤或者用戶執行了ROLLBACK語句,系統可以利用Undo Log中的備份將數據恢復到事務開始之前的狀態。
回滾時機?
- 用戶調用 rollback 主動回滾
- 事務出錯
- 輔助 redo log 實現事務持久性
undo log 的清除
當事務提交的時候,innodb
不會立即刪除undo log
,因為后續還可能會用到undo log
,如隔離級別為repeatable read
時,事務讀取的都是開啟事務時的最新提交行版本,只要該事務不結束,該行版本就不能刪除,即undo log不能刪除。
但是在事務提交的時候,會將該事務對應的undo log
放入到刪除列表中,未來通過purge來刪除。並且提交事務時,還會判斷undo log
分配的頁是否可以重用,如果可以重用,則會分配給后面來的事務,避免為每個獨立的事務分配獨立的undo log
頁而浪費存儲空間和性能。
undo log
主要分為兩種:
- insert undo log
代表事務在 insert 新記錄時產生的undo log
, 只在事務回滾時需要,並且在事務提交后可以被立即丟棄。 - update undo log
事務在進行 update 或 delete 時產生的undo log
; 不僅在事務回滾時需要,在快照讀時也需要;所以不能隨便刪除,只有在快速讀或事務回滾不涉及該日志時,對應的日志才會被 purge 線程統一清除
purge
從前面的分析可以看出,為了實現 InnoDB 的 MVCC 機制,更新或者刪除操作都只是設置一下老記錄的 deleted_bit ,並不真正將過時的記錄刪除。
為了節省磁盤空間,InnoDB 有專門的 purge 線程來清理 deleted_bit 為 true 的記錄。為了不影響 MVCC 的正常工作,purge 線程自己也維護了一個read view(這個 read view 相當於系統中最老活躍事務的 read view );如果某個記錄的 deleted_bit 為 true ,並且 DB_TRX_ID 相對於 purge 線程的 read view 可見,那么這條記錄一定是可以被安全清除的。
undo log+redo log保證持久性
除了可以保證事務的原子性,Undo Log也可以用來輔助完成事務的持久化,如數據庫異常之后的恢復機制。
因為未提交的事務和回滾了的事務也會記錄在Redo Log
,因此在進行恢復時,這些事務要進行特殊的的處理。有2種不同的恢復策略:
A. 進行恢復時,只重做已經提交了的事務。
B. 進行恢復時,重做所有事務包括未提交的事務和回滾了的事務。然后通過Undo Log回滾那些未提交的事務。
MySQL數據庫InnoDB存儲引擎使用了B策略,InnoDB
存儲引擎中的恢復機制有幾個特點:
-
Undo Log回滾那些未提交的事務,被回滾了的事務在恢復時先
redo
再undo
,也不會破壞數據的一致性 -
必須要在寫
Redo Log
之前將對應的Undo Log
寫入磁盤。為了降低復雜度,InnoDB將Undo Log
看作數據,因此記錄Undo Log
的操作也會記錄到redo log
中。這樣undo log就可以象數據一樣緩存起來,而不用在redo log
之前寫入磁盤了。
參考:
極客時間 mysql45講
https://www.qiancheng.me/post/coding/mysql-001
說說MySQL中的Redo log Undo log都在干啥 - 蘇家小蘿卜 - 博客園 (cnblogs.com)