MySQL數據庫日誌介紹
第1章 binlog日誌
1.1 binlog日誌介紹
MySQL的binlog日誌作用是用來記錄mysql內部增刪改等對mysql數據庫有更新的內容的記錄(對數據庫的改動),對數據庫查詢的語句如show,select開頭的語句,不會被binlog日誌記錄。binlog日誌只要用於數據庫的增量恢復,以及主從複製。
mysql數據目錄下的如下文件就是mysql的binlog日誌:
[root@test3 ~]# ll /data/3306/ total 88 -rw-rw---- 1 mysql mysql 703 Feb 3 14:21 mysql-bin.000001 #<==binlog日誌文件 -rw-rw---- 1 mysql mysql 126 Feb 3 14:23 mysql-bin.000002 -rw-rw---- 1 mysql mysql 126 Feb 3 14:24 mysql-bin.000003 -rw-rw---- 1 mysql mysql 479 Feb 3 14:36 mysql-bin.000004 -rw-rw---- 1 mysql mysql 477 Feb 3 14:39 mysql-bin.000005 -rw-rw---- 1 mysql mysql 18699 Feb 4 03:05 mysql-bin.000006 -rw-rw---- 1 mysql mysql 150 Feb 4 03:05 mysql-bin.000007 -rw-rw---- 1 mysql mysql 13334 Feb 4 04:08 mysql-bin.000008
1.2 binlog日誌功能的開啓
需要在配置文件my.cnf中打開log-bin功能,纔會生成對應的binlog日誌文件
[root@localhost 3306]# grep "log-bin" /data/3306/my.cnf [mysqld] log-bin = /data/3306/mysql-bin #<==在mysqld配置裏面添加log-bin功能
查看bin-log功能開啓狀況:
mysql> show variables like '%log_bin%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | log_bin | ON | #<==記錄binlog開關 | log_bin_trust_function_creators | OFF | | sql_log_bin | ON | #<==臨時不記錄binlog開關 +---------------------------------+-------+ 3 rows in set (0.00 sec)
臨時不記錄bin-log:
mysql> set session sql_log_bin = OFF;
1.3 binlog日誌的三種模式
1.3.1 Row Level
日誌中會記錄成每一行數據被修改的形式,然後在slave端再對相同的數據進行修改。
優點:在row level模式下,bin-log中可以不記錄執行的sql語句的上下文相關的信息,僅僅只需要記錄哪一條記錄被修改了,修改成什麼樣了。所以row level的日誌內容會非常清楚的記錄下每一行數據修改的細節,非常容易理解。而且不會出現某些特定情況下的存儲過程或function,以及trigger的調用和觸發無法被正確複製的問題。
缺點:row level下,所有的執行語句當記錄到日誌中的時候,都將以每行記錄的修改來記錄,這樣可能會產生大量的日誌內容,比如有一條這樣的update語句:update product set owner_member_id=‘b’ where owner_member_id=’a’,執行了之後,日誌中記錄的不是這條update語句所對應的事件(MySQL以事件的形式來記錄bin-log日誌),而是這條語句所更新的每一條記錄的變化情況,這樣就記錄成很多條記錄被更新的時間。自然,bin-log日誌的量就會很大。尤其是當執行alter table之類的語句的時候,產生的日誌量是驚人的,因爲MySQL對於alter table之類的表結構變更語句的處理方式是整個表的每一條記錄都需要變動,實際上就是重建了整個表,那麼該表的每一條記錄都會被記錄到日誌中。
1.3.2 Statement Level
每一條會修改數據的sql都會記錄到master的bin-log中。slave在複製的時候sql進程會解析成和原來master端執行過程相同的sql來再次執行。
優點:statement level下的優點首先就是解決了row level下的缺點,不要需要記錄每一行數據的變化,減少bin-log日誌量,節約IO,提高性能。因爲它只需要記錄在master上所執行的語句細節,以及執行語句時候的上下文信息。
缺點:由於他是記錄的執行語句,所以,爲了讓這些語句在slave端也能正確執行,那麼它還必須記錄每條語句在執行時候的一些相關信息,也就是上下文信息,以保證所有語句在slave端被執行的時候能夠得到和在master端執行時候相同的結果。另外就是,由於MySQL發展很快,很多新功能不斷的加入,使MySQL的複製遇到了不小的挑戰。自然複製的時候涉及到的內容越複雜,bug也就越容易出現。在statement level下,目前已經發現的就有不少情況會照成MySQL的複製出現問題,主要是修改數據的時候使用了某些特定的函數或者功能的時候會出現,比如sleep()函數在有些版本中就不能正確複製;在存儲過程中使用了last_insert_id()函數,就可能會使slave和master上得到不一致的id等等。由於row level是基於每一行來記錄的變化,所以不會出現類似的問題。
1.3.3 Mixed
實際上就是前兩種模式的結合。在Mixed模式下,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日誌形式,也就是在statement和Row之間選擇一種。新版本中的statement level還是和以前一樣,僅僅記錄執行的語句。而新版本的MySQL中對row level模式也做了優化,並不是所有的修改都會以row level來記錄,像遇到表結構變更的時候就會以statement模式來記錄,如果sql語句確實就是update或者delete等修改數據的語句,那麼還是會記錄所有行的變更。
1.3.4 如何選擇使用binlog的模式
1、互聯網公司,使用MySQL的功能相對少(存儲過程、觸發器、函數)
選擇默認的語句模式,statement Level模式
2、如果用到MySQL的特殊功能(存儲過程、觸發器、函數)則選擇Mixed模式。
3、公司如果用到使用MySQL的特殊功能(存儲過程、觸發器、函數),數據最大化一致,此時最好行模式。
1.3.5 如何設置binlog的模式
mysql> show global variables like '%binlog_format%'; +---------------+-----------+ | Variable_name | Value | +---------------+-----------+ | binlog_format | STATEMENT | +---------------+-----------+ 1 row in set (0.00 sec)
q 在配置文件裏面修改
[mysqld] log-bin=mysql-bin #binlog_format="STATEMENT" #binlog_format="ROW" binlog_format="MIXED"
q 直接修改
SET GLOBAL binlog_format = 'STATEMENT' SET GLOBAL binlog_format = 'ROW' SET GLOBAL binlog_format = 'MIXED'
1.4 binlog文件解析工具mysqlbinlog
默認情況下,binlog是二進制格式的,不能使用查看文本工具的命令查看,例如:cat,vi,find等
1.4.1 解析整個log-bin文件
[root@test3 3306]# mysqlbinlog mysql-bin.000001
1.4.2 解析指定的數據庫
q -d 只解析對應的數據庫
使用-d參數,能夠解析出對應log-bin文件裏面的數據庫,如下所示:
[root@test3 3306]# mysqlbinlog -d oldboy mysql-bin.000001
q -r 數據導出到指定文件
將解析的結果存入另一個sql文件:
[root@test3 3306]# mysqlbinlog -d oldboy mysql-bin.000001 -r oldboy.sql
mysqlbinlog工具分庫導出binlog,如果使用-d參數,那更新數據時,必須有use database,才能分出指定庫的binlog,例如:''
use oldboy; insert into student values(1,'oldboy ')
下面的寫法就不行:
insert into oldboy.student values(2, 'oldboy' )
1.4.3 按照位置截取
mysqlbinlog mysqlbin.000001 --start-position=365 --stop-position=456 -r pos.sql
指定開始位置,不指定結束位置:
mysqlbinlog mysqlbin.000001 --start-position=365 -r pos.sql
指定結束位置,不指定開始位置:
mysqlbinlog mysqlbin.000001 --stop-position=456 -r pos.sql
1.4.4 按照時間截取
mysqlbinlog mysql-bin000020 --start-datatime='2017-10-16 17:14:15' --stop-datetime='2017-10-16 18:14:15' -r time.sql
指定開始時間,不指定結束時間:
mysqlbinlog mysql-bin000020 --start-datatime='2017-10-16 17:14:15' -r time.sql
指定結束時間,不指定開始時間:
mysqlbinlog mysql-bin000020 --stop-datetime='2017-10-16 18:14:15' -r time.sql
1.4.5 mysqlbinlog命令小結
1、該命令作用是把binlog解析爲sql語句(包含位置和時間點)
2、-d參數根據指定庫拆分binlog(拆分單表binlog可以通過SQL關鍵字過濾)
3、通過位置參數截取部分binlog:--start-position=265 --stop-position=345,精確定位取部分內容。
4、通過時間參數截取部分binlog:--start-datetime= 180203 14:21:56 --stop-datetime= 180203 14:21:56,模糊取內容
5、-r文件名,相當於重定向”>”
6、解析ROW級別binlog日誌的方法
mysqlbinlog --base64-output=decode-rows -v mysql-bin.000016
mysqlbinlog --base64-output=”decode-rows” --verbose mysql-bin.000004
第2章 錯誤日誌error log
2.1 error log日誌介紹
MySQL的錯誤日誌(error log)記錄MySQL服務進程mysqld在啓動/關閉或運行過程中遇到的錯誤信息。
2.2 error log日誌功能的開啓
在配置文件中調整參數:
[root@test3 3306]# grep log-error my.cnf [mysqld] log-error = /data/3306/mysql_3306.err #<==在mysqld配置裏面添加log-error功能
在啓動命令里加入:
mysqld_safe --defaults-file=/data/3306/my.cnf --log-error=/data/3306/mysql_3306.err &
查看error log:
mysql> show variables like '%log_error%'; +---------------+---------------------------+ | Variable_name | Value | +---------------+---------------------------+ | log_error | /data/3306/mysql_3306.err | +---------------+---------------------------+ 1 row in set (0.00 sec)
第3章 普通查詢日誌
3.1 general query log日誌介紹
普通查詢日誌(general query log):記錄客戶端連接信息和執行的SQL語句信息;
3.2 general query log日誌功能的卡其
在配置文件中調整參數:
[root@test3 3306]# grep general_log my.cnf [mysqld] general_log = on general_log_file = /data/3306/data/MySQL.log #<==在mysqld配置裏面添加general_log功能
第4章 慢查詢日誌
4.1 slow query log介紹
慢查詢日誌(slow query log):記錄執行時間超出指定值(long_query_time)的SQL語句。
4.2 slow query log日誌功能的開啓
long_query_time = 1 log-slow-queries = /data/3306/slow.log log_queries_not_using_indexes
慢查詢日誌的設置,對於數據庫的SQL的優化非常重要。
4.3 切割慢查詢日誌
將慢查詢日誌按天切割,腳本如下:
[root@test3 scripts]# cat cut_slow_log.sh #/bin/bash cd /data/3306/ &&\ /bin/mv slow.log.$(date +%F) &&\ mysqladmin -uroot -p123456 -S /data/3306/mysql.sock flush-log
設置切割日誌文件的定時任務:
[root@test3 scripts]# tail -2 /var/spool/cron/root #cut mysql slow log 00 00 * * * /bin/sh /server/scripts/cut_slow_log.sh &>/dev/null