前言
在MySQL服務器運行過程中,除了會產生各種數據文件外,還會記錄各種日志文件,這些日志文件不僅僅記錄MySQL的數據庫的運行情況、用戶操作、錯誤信息等,還和MySQL服務器的數據息息相關。
MySQL日志文件
MySQL主要有以下幾類日志文件:重做日志(redo log)、回滾日志(undo log)、二進制日志(binlog)、錯誤日志(errorlog)、慢查詢日志(slow query log)、一般查詢日志(general log)、中繼日志(relay log)
Redo Log (重做日志)
redo log也叫做重做日志,是保證事務持久性的重要機制。用于崩潰恢復,防止在發生故障的時間點,尚有臟頁未寫入磁盤,在重啟mysql服務的時候,根據redo log進行重做,從而達到事務的持久性這一特性。
redo log是在事務begin時就開始記錄(并不是事務commit時才記錄,因為整個事務做的操作可能很多,如果在commit的時候才寫redo log,此時一旦發生異常,redo log還沒寫,這就太晚了,無法確保事務的持久性)。
redo log 是物理日志,記錄的是“在某個數據頁上做了什么修改”。另外,redo log是循環寫入固定的文件,而且是順序寫入磁盤的。
在一個事務中,可能會發生多次的數據修改,對應的就是多個數據頁多個偏移量位置的字段變更,也就是說會產生多條redo log,而且因為在同一個事物中,這些redo log,也是不可再分的,也就是說,一個組的redo log在持久化的時候,不能部分成功,部分失敗,否則的話,就會破壞事務的原子性。
另外為了提升性能redo log是按照塊組織在一起,然后寫入到磁盤中的,類似于數據的頁,而且引入了redo log buffer,默認的大小為16MB。buffer中分了很多的block,每個block的大小為512kb,每一個事務產生的所有redo log稱為一個group。
Undo Log (回滾日志)
數據庫事務開始之前,會將要修改的記錄放到Undo日志里,當事務回滾時或者數據庫崩潰時,可以利用UndoLog撤銷未提交事務對數據庫產生的影響。
Undo log的作用:
- 事務回滾 - 原子性:當事務回滾時或者數據庫崩潰時,可以利用Undo Log來進行數據回滾。
- 多個行版本控制(MVCC)- 隔離性:即在InnoDB存儲引擎中MVCC的實現是通過Undo來完成。當用戶讀取一行記錄時,若該記錄已經被其他事務占用,當前事務可以通過Undo讀取之前的行版本信息,以此實現非鎖定讀取。
binary 就是bin log,即二進制日志文件,這個文件記錄了MySQL所有的DML操作。通過binlog日志我們可以做數據恢復,增量備份,主主復制和主從復制等等。
- binlog日志包括兩類文件:
- 二進制日志索引文件(文件名后綴為.index)用于記錄所有的二進制文件。
- 二進制日志文件(文件名后綴為.00000*)記錄數據庫所有的DDL和DML(除了數據查詢語句select)語句事件。
binlog日志
- 查看binlog日志是否開啟:
mysql> show variables like '%log_bin%'; +---------------------------------+----------------------------------+ | Variable_name | Value | +---------------------------------+----------------------------------+ | log_bin | ON | | log_bin_basename | /www/server/data/mysql-bin | | log_bin_index | /www/server/data/mysql-bin.index | | log_bin_trust_function_creators | OFF | | log_bin_use_v1_row_events | OFF | | sql_log_bin | ON | +---------------------------------+----------------------------------+ 6 rows in set (0.00 sec)
啟用binlog,在 my.cnf 配置文件中加入 log-bin 配置,表示啟用binlog,如果沒有給定值,寫成 log-bin=,則默認名稱為主機名。(注:名稱若帶有小數點,則只取第一個小數點前的部分作為名稱)
[mysqld] ## 我配置的文件名為mysql-bin log-bin=mysql-bin
- 查看binlog日志master 狀態:
mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000009 | 80774638 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
上面的查詢結果表示最后(最新)一個binlog日志的編號名稱(mysql-bin.000009),及其最后一個操作事件pos結束點(Position)值
- 查看binlog日志列表
mysql> show master logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000008 | 60794094 | | mysql-bin.000009 | 80774638 | +------------------+-----------+ 2 rows in set (0.00 sec)
表示,當前我的MySQL服務有兩個binlog文件mysql-bin.000008和mysql-bin.000009
Error Log (錯誤日志)
錯誤日志記錄了MySQL 服務器運行過程中所有較為嚴重的警告和錯誤信息,以及MySQL服務器每次啟動和關閉的詳細信息。
在默認情況下,系統記錄錯誤日志的功能是關閉的( 我所使用的 MySQL 5.6 是開啟的 ),錯誤信息被輸出到標準錯誤輸出( stderr )。
- 查看錯誤日志
mysql> show variables like "log_error"; +---------------+-----------------------+ | Variable_name | Value | +---------------+-----------------------+ | log_error | ./VM-16-15-centos.err | +---------------+-----------------------+ 1 row in set (0.00 sec)
根據查詢結果可知,錯誤日志保存在數據目錄下名為VM-16-15-centos.err的文件中。如果查詢結果為stderr,則表示輸出到屏幕,錯誤的信息只會輸出到我們的終端屏幕,并不會記錄在日志中。
- 開啟錯誤日志
在配置文件[mysqld]組添加如下一行配置:
# log_error記錄了錯誤日志所在位置 log_error = /www/server/data/VM-16-15-centos.err
Slow Query Log (慢查詢日志)
慢查詢日志是記錄查詢時長超過指定時間的日志,慢查詢日志主要用來記錄時間較長的查詢語句,通過慢查詢日志可以找出查詢時間較長的、執行效率較低的語句,以便進行優化。
默認情況下,慢查詢日志功能是關閉的。如果不是調優需要,一般不建議啟動該參數,因為開啟慢查詢日志會或多或少帶來一定的性能影響。
- 查看慢查詢日志
mysql> show variables like "%slow_query%"; +---------------------+---------------------------------+ | Variable_name | Value | +---------------------+---------------------------------+ | slow_query_log | ON | | slow_query_log_file | /www/server/data/mysql-slow.log | +---------------------+---------------------------------+ 2 rows in set (0.00 sec)
MySQL通過long_query_time參數來指定慢查詢時間,時間以秒為單位。如果查詢時間超過了這個時間值,這個查詢語句將被記錄到慢查詢日志,如果不設置,默認時間為 10 秒。
mysql> show variables like "%long_query_time%"; +-----------------+----------+ | Variable_name | Value | +-----------------+----------+ | long_query_time | 3.000000 | +-----------------+----------+ 1 row in set (0.00 sec)
- 開啟和關閉慢查詢日志
#開啟慢查詢日志 0關閉 1開啟 SET GLOBAL slow_query_log=1; #修改慢日志記錄SQL的最低閾值時間,單位秒 SET GLOBAL long_query_time=3;
General Log (一般查詢日志)
一般查詢日志會記錄MySQL所有的SQL語句,不管是查詢語句,還是DML語句,還是DDL語句,還是DCL語句,這些語句統統都會被記錄在general log文件中。就連我們連接和斷開MySQL數據庫的這些語句。
MySQL會把它收到的所有SQL語句按照接收的順序依次記錄在general log中。默認情況下一般查詢日志是關閉的(OFF狀態),并且默認保存在數據包目錄中。
- 查看一般查詢日志
mysql> show variables like "%general%"; +------------------+--------------------------------------+ | Variable_name | Value | +------------------+--------------------------------------+ | general_log | OFF | | general_log_file | /www/server/data/VM-16-15-centos.log | +------------------+--------------------------------------+ 2 rows in set (0.01 sec)
genral_log:用于控制是否開啟general log。等于0表示關閉,等于1表示開啟。默認是0。
general_log_file:指定general log日志的保存路徑和文件名,如果不配置這個參數的話,默認會以MySQL服務器的hostname作為general log日志的文件名稱,具體文件為:.log。日志的存放路徑,如果不指定,則默認放在datadir參數所指定的目錄下,也可以在這個參數中指定具體的路徑+名稱
- 開啟一般查詢日志
通用日志有一個默認的保存路徑,和我們的數據庫文件在同一個目錄下,我們只需要開啟即可。
mysql> set @@global.general_log = 1; Query OK, 0 rows affected (0.03 sec)
然后我們在查看一般查詢日志的狀態,就會發現已經是ON。
Relay Log (中繼日志)
一般情況下它在MySQL主從同步讀寫分離集群的從節點才開啟。主節點一般不需要這個日志。
MySQL主從同步
如上圖,master主節點的binlog傳到slave從節點后,被寫到relay log里,它是一個臨時的日志文件,用于存儲從master節點同步過來的binlog日志內容,它里面的內容和master節點的binlog日志里面的內容是一致的。然后slave從節點從這個relaylog日志文件中讀取數據應用到數據庫中,來實現數據的主從復制。
總結
MySQL日志文件是數據庫的重要組成部分,本文介紹的七種日志文件,隨便一種都可以延伸出很多知識點。但是作為MySQL基礎入門文章,我們只對日志文件做簡單的了解,并沒有進行深入的探索,雖然偏理論性知識,但是對使用和學習MySQL非常重要。
結束語
你知道的越多,不知道的就越多。
程序員的修養就是對技術發自內心的欣賞和敬畏!倘若文中表述有誤,還請諒解,并歡迎與我討論,自主思考永遠比被動接受更有效!