MySQL日誌概述
MySQL的日誌包含服務日誌(Server Log)和默認存儲引擎InnoDB日誌(InnoDB Log)兩個模塊,細分下去有錯誤日誌(Error Log)、通用查詢日誌(General Query Log)、二進制日誌(Binary Log)、慢查詢日誌(Slow Query Log)、數據定義語句日誌(DDL Log)、重做日誌(Redo Log)、回滾日誌(Undo Log)。其關係圖如下:
這幾種日誌的功能比較好理解:
-
錯誤日誌
記錄了mysqld啓動和關閉的時間、整個從啓動到關閉的運行期間的診斷消息(錯誤、警告、提示)。
-
通用查詢日誌
記錄了客户端斷開和連接時的信息,以及所有客户端發送給mysqld的SQL語句。
-
慢查詢日誌
慢查詢日誌記錄了執行時間超過long_query_time秒並且查詢記錄行數超過min_examined_row_limit行的SQL語句信息。
-
DDL日誌
DDL日誌又稱元數據日誌記錄了數據定義語句產生的會影響表格分區的元數據操作。
下面我們將詳細説明稍微複雜一些的三個日誌。
二進制日誌 Binary Log
二進制日誌的作用
二進制日誌包含了所有數據庫修改的操作,例如創建表、修改表數據。如果沒有配置為row-based模式的話,二進制日誌還會包含可能產生修改的語句,例如不匹配任何行的delete語句。每一條修改數據語句的執行時間也同樣記錄在二進制日誌。
二進制日誌主要是為了:
-
複製
二進制日誌包含了數據庫創建以來所有的修改操作及數據,因此通過在其他服務上重複這些修改,即可實現數據庫的完整複製。
- 數據恢復
一些數據恢復操作需要使用到二進制日誌。備份恢復後,二進制日誌中在備份後記錄的事件將被重新執行。這些事件會將數據庫從備份時間點恢復到最新狀態。
在啓用二進制日誌的情況下運行服務器,性能會略微降低。不過相比於二進制日誌在複製和還原操作方面的優勢,這種性能損失是可以接受的。
由於只會記錄和回讀完整的事務,二進制日誌是完整的,一般不會意外停止。
二進制日誌格式
服務器通過配置--binlog-format有三種格式保存二進制日誌:
- 語句
STATEMENT - 行
ROW - 混合
MIXED
語句格式STATEMENT是通過之間記錄原始的SQL語句,日誌中會保留函數的調用,例如update_time=now()。這樣可能導致數據庫的不一致。
行格式ROW則是將語句細化為對行的影響進行記錄。因此表必須始終存在主鍵來標識行。
混合格式MIXED通過混合STATEMENT和ROW,默認通過STATEMENT進行記錄,但在一些情況下會自動切換到ROW模式下記錄。
日誌記錄格式也可由所使用的存儲引擎設置或限制。這有助於消除在使用不同存儲引擎的源和副本之間複製某些語句時出現的問題。
重做日誌 Redo Log
重做日誌是一種基於磁盤的數據結構,在崩潰恢復期間用於糾正未完成事務寫入的數據。
在正常運行期間,重做日誌會對 SQL 語句或底層 API 調用產生的更改表數據的請求進行編碼。在意外關機前未完成更新數據文件的修改會在初始化期間和接受連接前自動重放。
默認情況下,重做日誌在磁盤上由兩個名為 ib_logfile0 和 ib_logfile1 的文件物理表示。MySQL 以循環方式寫入重做日誌文件。
回滾日誌 Undo Log
回滾日誌是與單個讀寫事務相關的回滾日誌記錄的集合。回滾日誌包含着如何回滾最新的聚類索引記錄的改動。
如果其他事務需要查看原先的數據作為一致性讀操作,則會檢索回滾日誌從而獲取未改動的數據。這樣為其他事務提供快照讀,也被稱為多版本併發控制MVCC。
回滾日誌保存在回滾日誌段內,回滾日誌段包含在回滾段裏面。回滾段則在系統表空間、重做表空間和臨時表空間中。
總結
二進制日誌與備份合作可以保證數據庫恢復到最新的事務提交的時刻。二進制日誌也作用於實現數據庫的高可用,如主備、主從等模式的同步都需要二進制日誌完成。二進制日誌側重於一致性。
重做日誌聚焦於將為提交的事務操作持久化,用於奔潰恢復期間對於未完成的事務的恢復,體現了持久性。
回滾日誌主要是在發生異常時,將已經生效的操作進行回滾,從而保障事務的原子性。
上面分開説明了三個日誌的側重點,然而三者並不是獨立運作的,在絕大部分場景下其實是相互結合發揮作用,如重做日誌和二進制日誌也一同作為二階段提交的重要階段來保障事務的原子性;二進制日誌對已提交事務的持久化是重做日誌運作的基礎。