《MySQL資料庫》MySQL ERRORLOG,BINLOG,SLOWLOG日誌詳解
前言
MySQL 經常出現啟動錯誤或者執行錯誤等等,這個時候我們需要查詢error日誌
在資料庫使用中,經常會出現需要恢復資料的情況,MySQL如果需要恢復資料的話需要開啟binlog(二進位制日誌)。
Error Log
錯誤日誌預設設定如下:
1. error log 預設路徑在資料檔案下。
2.error log 預設檔名為主機名.err,例如:iZm5e5v2zi93osbr5z21fvZ.err。
自定義設定檔名和路徑:
開啟MySQL的配置檔案vim /etc/my.cnf 加入如下配置
log_error=/usr/local/mysql/log/mysql.log
Bin Log
1. 配置
mysql 8.0 版本之前,預設不開啟,生成建議開啟。
my.cnf 資料夾下面引數設定。
server_id = 5 ; # 服務編號,5.7必須要。 log_bin=/data/binlog/mysql-bin # binlog 日誌存放目錄+字首,日誌檔名例如:mysql-bin.0001 ,注意目錄需要提前存在。 sync_binlog=1 # binlog 刷寫的策略。1:表示提交只有立即寫入磁碟。 binlog_format=row # binlog的記錄格式為row模式
重啟MySQL之後再對應目錄下可以看到如下日誌:
其中 mysql-bin.index 是日誌索引檔案。
重要:binlog 日誌建議和資料盤分開存放,防止硬碟壞了的情況。
mysql> select @@log_bin_basename; -- 查詢bin_log 存放位置
mysql> select @@log_bin; -- 查詢bin_log 是否開啟 1:開啟
2. 說明
1. binlog 記錄內容
binlog 會記錄下以下操作:
DDL 操作表結構,欄位的語句。 DCL 許可權等一些控制語句。 DML 操作表的語句(insert,update,delete),並且是已經提交的,未提交的不會記錄
DDL 和 DCL 記錄的是你寫了啥就記錄啥。 DML語句記錄方式可以通過引數控制
mysql> select @@binlog_format; -- 5.7 預設ROW, statement:寫啥記啥,ROW:記錄資料頁變化,mixed:混合前兩種記錄
statement : 可讀性高(文字),日誌量少,不夠嚴謹(遇到獲取當前日期的時候,因為語句是故障時執行的,但是後續通過這種方式無法獲取當時的時間點)。
row : 可讀性低(二進位制),日誌量大,嚴謹。
3. bin log 檢視
mysql> show binary logs; -- 查詢mysql存在的binlog日誌檔案
mysql> show master status; -- 查詢現在正在使用binlog 日誌檔案
mysql> show binlog events in 'mysql-bin.000002'; -- 檢視當前被使用的binlog 資訊
mysqlbinlog mysql-bin.000002 -- 使用mysqlbinlog 命令檢視binlog 日誌。
mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000002 -- 該命令可以翻譯binlog 下的DML 操作語句,只能用於檢視。
mysql> flush logs -- 建立新的日誌。後續binlog 就從這個新日誌開始
查詢日誌就可以看到新的日誌:
4. 通過binlog 恢復資料
模擬誤操作的情況:第9步刪除和第13步的drop。
(0) drop database if exists testdb ; (1) create database testdb charset utf8; (2) use testdb; (3) create table t1 (id int); (4) insert into t1 values(1),(2),(3); (5) insert into t1 values(4),(5),(6); (6) commit (7) update t1 set id=30 where id=3; (8) commit; (9) delete from t1 where id=4; (10)commit; (11)insert into t1 values(7),(8),(9); (12)commit; (13)drop database testdb;
我們要恢復第9步刪除和第13步的drop 操作之前的資料
擷取binlog 日誌,找到起點和終點。 我現在要恢復到drop 操作前: 找到開始位置點和結束位置點, 我需要的 383 到 2048 ,下面的語句就是將日誌轉化成語句。
mysqlbinlog --start-position=383 --stop-position=2048 /usr/local/mysql/binlog/mysql-bin.000003 > /usr/local/mysql/bin2.sql
還有一種通過實踐擷取的方式:
mysqlbinlog --start-datetime=200812 21:08:26 --stop-datetime=200912 21:09:09 mysql-bin.000001 mysql-bin.000002 mysql-bin.000003 > /usr/local/mysql/bin2.sql
接下來就是匯入SQL檔案即可,重點因為這是恢復,所以我們不需要他再記錄binlog日誌,故匯入SQL檔案前,先臨時關閉binlog. 操作如下:
mysql> set sql_log_bin = 0; -- 關閉binlog日誌 mysql> source /usr/local/mysql/bin2.sql -- 匯入sql指令碼(通過binlog截取出來的) mysql> set sql_log_bin = 1; -- 開啟binlog日誌
指定資料庫的binlog匯出(-d 資料庫名):
mysqlbinlog -d testdb --start-position=383 --stop-position=2048 /usr/local/mysql/binlog/mysql-bin.000003 > /usr/local/mysql/bin2.sql
binlog實際場景中的運用方式:
binlog 主要是配和備份資料一起恢復資料庫, 先通過備份資料庫恢復到比如一個星期前的資料,然後剩下的資料由binlog恢復。
5. binlog 維護命令
mysql> select @@max_binlog_size;
binlog 不要直接刪除物理檔案:
mysql> select @@expire_logs_days; -- binlog儲存天數,0特殊表示永久儲存。
mysql> purge binary logs to 'mysql-bin.000002'; -- 刪除binlog日誌到mysql-bin.000002,也就是把mysql-bin.000001 刪除。
purge binary logs before now() - interval 3 day; 根據時間刪除,刪除3天前的日誌。
mysql> reset master; -- 全部刪除,操作不建議使用,主從必然會down。
6. binlog(GTID)
GTID(Global Transaction ID) :
mysql> select @@session.gtid_next = 'anonymous'; -- GTID是否開啟,1開啟
GTID 定義
GTID = source_id :transaction_id 例如:7E11FA47-31CA-19E1-9E56-C43AA21293967:29
gtid-mode=on -- 和引數enforce-gtid-consistency一起開啟gtid功能。 enforce-gtid-consistency=true -- 見gtid-mode說明
開啟GTID之後對資料庫的操作會記錄GTID
binlog日誌中也記錄了GTID。
mysql> select @@server_uuid; -- 檢視gtid的uuid
資料檔案目錄下會存在一個檔案:
/usr/local/mysql/mysql-5.7.22-linux-glibc2.12-x86_64/data/auto.cnf 裡面也記錄了server_uuid。
通過案例說明如何使用gtid恢復資料
(1) create database gtiddb charset utf8; (2) use gtiddb ; (3) create table t1 (id int); (4) insert into t1 values(1),(2),(3); (5) insert into t1 values(4),(5),(6); (6) commit (7) update t1 set id=30 where id=3; (8) commit; (9) delete from t1 where id=4; (10)commit; (11)insert into t1 values(7),(8),(9); (12)commit; (13)glush logs; (14)insert into t1 values(10); (15)drop database gtiddb ;
第13步模擬切換日誌, 第15步誤操作。 需要恢復到第14步。
根據(show binlog events in 'mysql-bin.000002';) 找到恢復資料的gtid起點:8993a5f5-2921-11ea-a866-00163e046b75:2 終點:8993a5f5-2921-11ea-a866-00163e046b75:9
下面是擷取命令,我們取2到9 的gtid資料,並且排除7,delete 我們也不要刪除。
mysqlbinlog --include-gtids='8993a5f5-2921-11ea-a866-00163e046b75:2-9' --exclude-gtids='8993a5f5-2921-11ea-a866-00163e046b75:7' mysql-bin.000002 mysql-bin.000003 > /usr/local/mysql/gtid.sql
恢復操作和之前是一樣的
mysql> set sql_log_bin = 0; -- 關閉binlog日誌 mysql> source /usr/local/mysql/gtid.sql; -- 匯入sql指令碼(通過binlog截取出來的) mysql> set sql_log_bin = 1; -- 開啟binlog日誌
上述操作你會發現恢復不了資料,那是為什麼呢?
重點:GTID的冪等性:開啟GTID後,MySQL恢復Binlog時,重複GTID的事務不會再執行。 那要如何處理呢?
擷取日誌的時候過濾掉gtid 需要在擷取命令中加入引數 --skip-gtids。
mysqlbinlog --skip-gtids --include-gtids='8993a5f5-2921-11ea-a866-00163e046b75:2-9' --exclude-gtids='8993a5f5-2921-11ea-a866-00163e046b75:7' mysql-bin.000002 mysql-bin.000003 > /usr/local/mysql/gtid.sql
小結:binlog 重要性不言而喻,後續真正備份恢復中也需要binlog日誌,才能達到真正的恢復如初。
Slow Log
作用:記錄慢SQL語句的日誌,定位低效SQL語句的工具日誌,預設不開啟。
配置:
mysql> select @@slow_query_log; -- 控制慢日誌是否開啟的開關0:不開啟,1:開啟
mysql> select @@slow_query_log_file; -- 慢日誌存放的位置
mysql> select @@long_query_time; --設定時間規則執行多少時間算慢。
mysql> select @@log_queries_not_using_indexes; -- 開啟是否記錄不走索引的語句,0:關,1:開
案例:準備100萬資料量的表。然後執行查詢語句,然後檢視日誌
當你日誌龐大的時候,你會發現vi 看不方便,mysql給我們提供了方便看這個資訊的命令:
mysqldumpslow -s c -t 5 /usr/local/mysql/mysql-5.7.22-linux-glibc2.12-x86_64/data/iZm5e5v2zi93osbr5z21fvZ-slow.log -- c 表示數量,-t 5 顯示前5條。
擴充套件可以實現:更加方便的展示slowlog日誌資訊。
Anemometer基於pt-query-digest將MySQL慢查詢視覺化。
總結
會看MySQL日誌是非常重要的,並且MySQL提供的日誌非常重要,我們需要能夠理解日誌原理,更好為MySQL的資料安全,效能提供幫助。