作者:楊濤濤
資深資料庫專家,專研 MySQL 十餘年。擅長 MySQL、PostgreSQL、MongoDB 等開源資料庫相關的備份恢復、SQL 調優、監控運維、高可用架構設計等。目前任職於愛可生,為各大運營商及銀行金融企業提供 MySQL 相關技術支援、MySQL 相關課程培訓等工作。
本文來源:原創投稿
*愛可生開源社群出品,原創內容未經授權不得隨意使用,轉載請聯絡小編並註明來源。
--
MySQL 8.0 有一個元件叫 component_log_filter_dragnet , 它主要功能就是對 MySQL 的錯誤日誌內容進行定製化過濾與改造,之前有簡單提過,這次來詳細說下如何使用。
使用前,先安裝元件:
INSTALL COMPONENT 'file://component_log_filter_dragnet';
安裝後,設定系統引數log_error_services 來啟用它。
SET global log_error_services = 'log_filter_dragnet; log_sink_internal';
通過系統引數dragnet.log_error_filter_rules 來調整過濾規則,比如對指定錯誤程式碼限流、改造輸出等等。類似對MySQL監控,必須有過濾條件、觸發動作、最終結果等關鍵因素。 過濾條件則類似SQL語句中單個欄位或者多個欄位組合過濾。比如欄位<操作符> 值、NOT EXISTS 欄位、過濾條件組合等。存在三種欄位:分別為核心欄位,可選欄位,使用者自定義欄位。
本篇我們來介紹核心欄位。
核心欄位列表如下:
- time: 時間,比如可以設定在2022年12月1日之前都不允許寫錯誤日誌。
- msg: 錯誤資訊, 由於err_code直接能定位到msg,一般很少用它來判斷,msg可以參與定製內容。
- prio:優先順序,對應的值為ERROR、WARNING、INFORMATION、NOTE幾個值或者任意組合,與設定系統引數log_error_verbosity 效果類似。
- err_code/SQL_state: 具體錯誤程式碼,也即錯誤資訊的KEY。
- err_symbol: 具體錯誤符號,MySQL每個錯誤程式碼都對應一個錯誤符號。具體的err_symbol 資料可以用perror 列印或者從官網錯誤參考頁面查詢:https://dev.mysql.com/doc/mys...
- subsystem: 指定過濾的子系統專案,比如:Server、InnoDB等。
觸發動作有以下四個:
- drop: 刪除錯誤資料。
- throttle: 對內容限流。
- set:定製欄位資料。
- unset: 重置欄位資料。
本篇要改造的錯誤日誌基於如下命令產生:全篇用命令A代替。
[root@ytt-pc ytt]# mysql -utest33333
ERROR 1045 (28000): Access denied for user 'test33333'@'localhost' (using password: NO)
對應的錯誤日誌程式碼:從結果擷取兩個err_code 分別為MY-013360和MY-010926。
2022-03-24T06:03:59.511173Z 50 [Warning] [MY-013360] [Server] Plugin sha256_password reported: ''sha256_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'
2022-03-24T06:03:59.511322Z 50 [Note] [MY-010926] [Server] Access denied for user 'test33333'@'localhost' (using password: NO)
接下來我舉例說明一些常見用法:
欄位time
類似對錶時間欄位進行過濾,可以定義一個等值條件或者取值範圍。例如讓2023-01-01之前的錯誤資料不記入日誌,配合欄位time以及動作drop來實現:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if time <''2023-01-01'' then drop .';
Query OK, 0 rows affected (0.00 sec)
退出執行命令A,只要時間還沒到2023年,錯誤日誌裡就不會記錄任何資料。
欄位prio.
比如可以用欄位prio來遮蔽warning資料,讓其不計入錯誤日誌,實現如下:
ytt-pc:(none):8.0.28>set global dragnet.log_error_filter_rules='if prio==warning then drop .';
Query OK, 0 rows affected (0.00 sec)
退出執行命令A,完了檢視錯誤日誌:日誌裡只保留Note資料,warning資料沒有記入。
2022-03-24T06:05:41.037512Z 52 [Note] [MY-010926] [Server] Access denied for user 'test33333'@'localhost' (using password: NO)
欄位err_code/SQL_state.
err_code 最直接,只要查到錯誤程式碼,根據err_code來過濾即可。比如禁止錯誤程式碼為MY-010926的資料記入日誌,可以直接用err_code=MY-010926來過濾,實現如下:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if err_code==MY-010926 then drop .';
Query OK, 0 rows affected (0.00 sec)
退出執行命令A,完了檢視錯誤日誌:不存在錯誤程式碼為MY-010926的資料。
2022-03-24T06:08:47.771611Z 53 [Warning] [MY-013360] [Server] Plugin sha256_password reported: ''sha256_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'
假設想定製錯誤程式碼,把它們改造成MySQL官網錯誤參考頁面查不到的值,可以配合動作set來實現:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if err_code==MY-010926 or err_code==MY-013360 then set err_code=1234567890 .';
Query OK, 0 rows affected (0.00 sec)
退出執行命令A,完了檢視錯誤日誌:相關錯誤程式碼全部替換為MY-1234567890。
2022-03-24T06:12:37.456522Z 55 [Warning] [MY-1234567890] [Server] Plugin sha256_password reported: ''sha256_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead'
2022-03-24T06:12:37.456676Z 55 [Note] [MY-1234567890] [Server] Access denied for user 'test33333'@'localhost' (using password: NO)
假設想定製錯誤資料,可以在set動作時,更新欄位msg的值,實現如下:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if err_code==MY-010926 or err_code==MY-013360 then set msg=''你來看哦,沒有了哦!!!'' .';
Query OK, 0 rows affected (0.00 sec)
退出執行命令A,完了檢視錯誤日誌:錯誤資料已經被重新定製。
2022-03-24T06:16:05.617758Z 56 [Warning] [MY-013360] [Server] 你來看哦,沒有了哦!!!
2022-03-24T06:16:05.617898Z 56 [Note] [MY-010926] [Server] 你來看哦,沒有了哦!!!
以上err_code也可以直接替換為對應的SQL_state,效果一樣。比如:sql_state='HY000'(這裡是字串)。
欄位err_symbol
之前說過,err_symbol和err_code類似,通過perror列印這兩個錯誤程式碼對應的err_symbol如下:括號裡大寫的兩串字元。
[root@ytt-pc ytt]# perror MY-013360 MY-010926
MySQL error code MY-013360 (ER_SERVER_WARN_DEPRECATED): '%s' is deprecated and will be removed in a future release. Please use %s instead
MySQL error code MY-010926 (ER_ACCESS_DENIED_ERROR_WITH_PASSWORD): Access denied for user '%-.48s'@'%-.64s' (using password: %s)
現在來由err_symbol實現剛才err_code定製的msg資料:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if err_symbol==''ER_SERVER_WARN_DEPRECATED'' or err_symbol==''ER_ACCESS_DENIED_ERROR_WITH_PASSWORD'' then set msg=''你來看哦,沒有了哦!!''.';
Query OK, 0 rows affected (0.00 sec)
欄位subsystem
假設要遮蔽Server級別的錯誤(本篇這兩個錯誤程式碼對應的資料也是Server級別的),實現如下:
ytt-pc:(none):8.0.28>set global dragnet.log_error_filter_rules='if subsystem==''Server'' then drop .';
Query OK, 0 rows affected (0.00 sec)
退出執行命令A,再次檢視錯誤日誌:Server級別的錯誤資料都沒記入日誌。
動作復原命令:unset
unset 可以初始化具體的欄位,比如初始化這兩個錯誤程式碼對應的msg,實現如下:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if err_code==MY-010926 or err_code==MY-013360 then unset msg .';
Query OK, 0 rows affected (0.00 sec)
退出執行命令A,完了檢視錯誤日誌:資料變為“No error message, or error message of non-string type. This is almost certainly a bug!”
2022-03-24T06:24:14.846763Z 59 [ERROR] [MY-013360] [Server] No error message, or error message of non-string type. This is almost certainly a bug!
2022-03-24T06:24:14.846925Z 59 [ERROR] [MY-010926] [Server] No error message, or error message of non-string type. This is almost certainly a bug!
動作限流命令:throttle
假設這兩個錯誤資料在日誌裡只能記錄兩條,實現如下:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if err_code==MY-010926 or err_code==MY-013360 then throttle 2 .';
Query OK, 0 rows affected (0.00 sec)
無論執行多少次命令A,同樣的錯誤資料在日誌裡只記錄兩條。
假設限制這兩個錯誤資料在日誌裡每分鐘記錄2條,實現如下:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if err_code==MY-010926 or err_code==MY-013360 then throttle 2/60 .';
Query OK, 0 rows affected (0.00 sec)
效果為錯誤日誌以分鐘級別記錄這兩條資料。
在條件里加上稍微複雜的判斷條件
假設錯誤程式碼MY-010926 對應的msg被定製為“好的,就這樣!”,錯誤程式碼MY-013360對應的msg被定製為“不錯哦,就這樣吧!”,實現如下:
ytt-pc:ytt:8.0.28>set global dragnet.log_error_filter_rules='if err_code==MY-010926 then set msg=''好的,就這樣!'' elseif err_code==MY-013360 then set msg=''不錯哦,就這樣吧!'' .';
Query OK, 0 rows affected (0.00 sec)
退出執行命令A,完了檢視錯誤日誌:msg 被對應的定製資料分別覆蓋。
2022-03-24T06:32:06.505039Z 60 [Warning] [MY-013360] [Server] 不錯哦,就這樣吧!
2022-03-24T06:32:06.505296Z 60 [Note] [MY-010926] [Server] 好的,就這樣!
由於內容較多,我分成了兩部分,第一部分就到此為止。