淺析MySQL日志體系
引言
在數(shù)據(jù)庫中,日志文件記錄了數(shù)據(jù)庫運行的各方面信息,對于數(shù)據(jù)庫的正常運行起著重要作用。在MySQL數(shù)據(jù)庫中,主要包括了Redolog日志、Undolog日志、Binlog日志、Relaylog日志、GeneralQuery Log日志、SlowQuery Log日志以及Errorlog日志。這些日志共同構(gòu)成了MySQL數(shù)據(jù)庫的日志體系,在本文中會逐一對這些日志的作用進行介紹。
一、事務日志
MySQL InnoDB 引擎中,事務日志主要由兩個部分組成,分別是Redolog和Undolog。其中Redolog也稱為重做日志,用于保證事務的原子性和持久性,在崩潰恢復期間糾正不完整事務寫入的數(shù)據(jù)。而Undolog主要是記錄數(shù)據(jù)改動的前映像信息,用來實現(xiàn)事務回滾和MVCC功能。
1.1、Redo log 的基本概念
Redo日志主要包含了兩部分:
1)Redo Log Buffer(日志緩沖區(qū)),是位于內(nèi)存中的一塊區(qū)域,主要用于緩存要寫入磁盤日志文件中的數(shù)據(jù)。
2)Redo Log File,位于磁盤上,持久化Log Buffer中的日志數(shù)據(jù)。建庫后,默認會創(chuàng)建名為ib_logfile0和ib_logfile1的兩個文件。
為了保證日志的持久性,InnoDB存儲引擎通過ForceLog at commit機制實現(xiàn),即當事務提交時,必須先將該事務的所有日志寫入到重做日志中。在InnoDB的默認設置下(innodb_flush_method),每次將RedoLog Buffer中日志更新到磁盤中的日志文件時,先將重做日志緩沖寫入到文件系統(tǒng)緩存,然后調(diào)用一次操作系統(tǒng)的fsync操作寫入Redolog file,其過程如下圖所示。
圖 1 log buffer到log file寫入過程
針對為了保證嚴格遵守ACID特性和磁盤IO性能取舍的問題,在MySQLInnoDB引擎中還有一個參數(shù)innodb_flush_log_at_trx_commit,用來控制Logbuffer中的日志刷新到磁盤的策略,其策略如下:
1)當設置為1時(default),事務每次提交時都會將Log buffer中的日志寫入操作系統(tǒng)緩存并調(diào)用fsync寫入到Redo log file中。這樣可以保證每一個事務日志不丟失。
2)當設置為0時,并不會在事務提交時一并將Log buffer中的日志 fsync到Redo log file中,而是根據(jù)innodb_flush_log_at_timeout(default=1) 參數(shù)設置的固定時間頻率(s),定期將log buffer日志持久化到Redo log file。這樣就有可能會在異常宕機時,意外丟失一部分redo 日志,造成了部分事務日志丟失。
3)當設置為2時,會在事務提交時將Log buffer中的日志寫入到Redo log file,但僅寫入文件系統(tǒng)的緩存中,不進行fsync操作。這樣也不能完全保證一個事務中所有日志的完整性,如果當系統(tǒng)宕機,也可能會造成沒有fsync到磁盤中的日志丟失。
1.2 Undo log 的基本概念
Undo log是與單個讀寫事務關聯(lián)的undo日志記錄的集合,undolog記錄包含關于如何撤消事務對聚簇索引記錄的最新更改的信息。Undolog存放在數(shù)據(jù)庫內(nèi)部的一個特殊段(segment)中,稱為undosegment,位于共享表空間內(nèi)。
Undolog 在數(shù)據(jù)庫中主要實現(xiàn)了兩個功能分別是事務的回滾和MVCC。
二、Binlog
Binlog(二進制日志)是MySQLServer層維護的一種二進制日志,主要記錄了數(shù)據(jù)庫中所有的DDL操作和DML操作,但Binlog中不會記錄SELECT和SHOW這類查詢語句,Binlog語句是以”事務”的形式保存在磁盤中。
2.1主要作用
1)復制:在MySQL源端開啟Binlog,并向從端發(fā)送源端生成的binlog,再由從端回放日志實現(xiàn)與源端數(shù)據(jù)一致。
2)數(shù)據(jù)恢復:通過Binlog日志實現(xiàn)指定時間點的數(shù)據(jù)恢復。
2.2 Binlog日志的格式
在my.cnf文件中設置log_bin=/DIRECTORY_NAME/file_name參數(shù),開啟。
Binlog日志主要有三種格式,可以在my.cnf文件中通過–binlog_format參數(shù)進行設置。
1)STATEMENT
基于SQL語句模式,日志中記錄是執(zhí)行語句和上下文環(huán)境。該模式下生成的日志量較少所以減少了對磁盤IO的影響,提高了性能。
2)ROW
基于行的模式,會將每一行的變化都記錄到日志中,相較于statement格式,其日志內(nèi)容要大很多,對磁盤IO影響較大,但是由于記錄了每行數(shù)據(jù)修改的細節(jié),因此不會發(fā)生某些特定情況下從庫無法復制的情況發(fā)生。
3)MIXED
混合模式,即混合了Statement和Row兩種日志格式,是MySQL默認的日志格式。在混合模式下,MySQL會默認使用基于SQL語句的日志記錄模式(Statement),但是在一些特殊的場景下會自動切換到基于行的日志記錄模式。
三、Relay log
Relay log(中繼日志)是在MySQL主從復制時產(chǎn)生的日志,在MySQL的主從復制主要涉及到三個線程:
1) Log dump線程:向從庫的IO線程傳輸主庫的Binlog日志
2) IO線程:向主庫請求Binlog日志,并將Binlog日志寫入到本地的relay log中。
3) SQL線程:讀取Relay log日志,將其解析為SQL語句并逐一執(zhí)行。
圖2
從圖2中可以看出,從庫的IO線程接收到主庫的logdump線程傳遞的Binlog日志后,會將其寫入到本地的一個日志中,這個日志就是Relaylog。在文件目錄中,一般由多個host_name-relay-bin.nnnnnn 的日志文件和host_name-relay-bin.index索引文件組成,其中日志文件記錄的是事務中修改數(shù)據(jù)的信息,索引文件記錄的是使用過的日志文件信息。
Relaylog日志的格式與Binlog的一致,但是相較于Binlog多了master.info和relay-log.info兩個日志(默認存儲于數(shù)據(jù)文件目錄中)。master.info主要記錄上一次讀取到master同步過來的binlog的位置,從節(jié)點的連接信息和主節(jié)點信息,以及連接master和啟動復制必須的所有信息。relay-log.info主要記錄了從節(jié)點文件復制的進度,下一個事件從什么位置開始,由sql線程負責更新。
四、General Query Log
General QueryLog(通用查詢?nèi)罩?記錄了用戶的所有操作,包括啟動和關閉MySQL服務、增刪改語句和查詢語句,需要注意查詢?nèi)罩驹赽inlog中是不記錄的。默認情況下,該日志是關閉狀態(tài)。
相關參數(shù)如下:
general_log = [0|1] --0關閉,1開啟
log-output = [TABLE|FILE|NONE] --設置日志輸出對象
general_log_file = [FILENAME] --設置輸出日志名稱
五、Slow Query Log
Slow QueryLog(慢速查詢?nèi)罩?由SQL語句組成,記錄了所有執(zhí)行時間超過參數(shù)log_query_time(秒)且掃描的記錄數(shù)不小于min_examined_row_limit的所有SQL語句的日志,慢查詢?nèi)罩局饕糜诓檎覉?zhí)行時間較長的語句。
默認情況下,管理語句和不使用索引的查詢語句是不會記錄在slowquery log中,不過可以通過設置參數(shù)log_slow_admin_statements和log_queries_not_using_indexes對這兩類語句進行監(jiān)控。在MySQL中,管理語句被定義為ALTER TABLE,ANALYZETABLE, CHECK TABLE, CREATE INDEX, DROP INDEX, OPTIMIZE TABLE和REPAIRTABLE。
如果從文本日志中搜索一些慢查詢的語句,會非常消耗時間,MySQL推薦使用mysqldumpslow工具對慢查詢?nèi)罩具M行分類匯總。
相關參數(shù)如下:
long_query_time = 10 --默認是10s,最小值是0
slow_query_log[={0|1}] --也可以是布爾值(ON|OFF),默認是0,日志關閉。
slow_query_log_file=file_name --指定慢查詢?nèi)罩疚募Q,默認host_name-slow.log
log-output = [TABLE|FILE|NONE] –設置日志輸出對象
六、Error log
ErrorLog(錯誤日志)包含mysqld啟動和關閉時間的記錄,以及診斷消息,如服務器啟動和關閉期間以及服務器運行時發(fā)生的錯誤、警告和注意事項。當數(shù)據(jù)庫出現(xiàn)故障導致無法運行時,可以通過查看該日志進行問題分析。
相關參數(shù)如下:
log-error [=file_name] --設置日志名稱
總結(jié)
MySQL數(shù)據(jù)庫的日志系統(tǒng)是一個較為龐大的體系,本文中僅僅是針對一些常見的日志做了簡要的介紹,在使用和參數(shù)設置中還有非常多的細節(jié),大家也可以參考官方文檔進行詳細的學習。