MySQL 常見日志清理策略
前言:
MySQL 數據庫服務器使用多種類型的日志來記錄操作和事件,這對于故障診斷、審計和性能分析非常重要。然而,這些日志文件會隨著時間的推移而不斷增長,可能會占用大量的磁盤空間。因此,定期清理這些日志是必要的,本篇文章我們一起來學習下如何清理 MySQL 中的日志文件。
二進制日志 (Binary Log)
binlog 記錄了數據庫所有的 DDL(數據定義語言)和 DML(數據操作語言)更改操作,一般都是建議開啟 binlog 的,要注意的是 binlog 會占用大量磁盤空間,特別是你的數據庫特別繁忙的情況下。這個時候就要制定清理策略了。
MySQL 5.7 可以通過 expire_logs_days 參數來設置 binlog 刪除時間,在 my.cnf 配置文件中設置 expire_logs_days 參數,指定二進制日志文件的過期天數,過期的日志文件將會自動被刪除。在 MySQL 8.0 中建議使用 binlog_expire_logs_seconds 參數,此參數同樣是控制二進制文件過期時間,單位是秒。binlog 具體要保留多久,可以根據磁盤空間決定,磁盤充足可以多保留,一般建議至少保留 7 天。
除了通過設置參數自動清理外,binlog 還可以使用 PURGE BINARY LOGS 命令來手動執行清理。例如,使用 purge binary logs to 'mysql-bin.000009' 來刪除 mysql-bin.000009 之前的日志文件,或者使用 purge binary logs before '2024-07-15 00:00:00' 來刪除指定時間之前的日志文件。
通用查詢日志 (General Query Log)
MySQL 的 general_log 是記錄所有到達 MySQL 服務器的 SQL 語句的日志。由于它記錄了所有的 SQL 語句,包括連接、查詢、更新等操作,因此其日志量可能增長非常迅速,通常在生產環境中不建議開啟此功能,以免影響性能。如果你的數據庫為了等保評測或者其他原因開啟了 general_log ,那就要及時制定清理策略了。
官方并沒有提供用于清理 general_log 的參數或命令,因此清理 general_log 只能各顯神通了,一般情況下可以通過寫 shell 腳本來執行清理,比如說每天凌晨進行日志切換,刪除幾天前的日志文件。也可以使用 logrotate 功能來配置 general_log 自動輪轉及清理。
錯誤日志 (Error Log)
錯誤日志記錄 MySQL 服務器啟動、關閉及運行時發生的錯誤及警告信息。一般是默認開啟的,不過錯誤日志增長速度很慢,通常不需要頻繁清理,可以手動清理或設置定期任務清理舊的日志文件。錯誤日志保留時間可以更長些。
慢查詢日志 (Slow Query Log)
慢日志主要用于記錄執行時間超過設定閾值的 SQL 查詢。慢查詢日志對于數據庫的性能優化非常重要,因為它可以幫助數據庫管理員和開發者識別和優化那些執行效率低下的查詢。慢日志也是建議開啟的。
通常情況下,我們可以根據系統情況來設置慢 SQL 閾值,比如 1s 或 3s 。慢日志一般情況下增長速度也不是很快,只要持續進行 SQL 優化,慢日志會越來越少的。通常慢日志也不需要頻繁清理,一般我們可以每一周或每一月重命名一次,然后保留幾份這樣來制定清理策略,可以交由 shell 腳本自動執行。
審計日志 (Audit Log)
MySQL 社區版官方并沒有提供審計日志,如果想開啟審計日志,只能借助 MariaDB 或 Percona Server 等其他審計插件。審計日志增長速度也比較快,一般審計插件都提供清理參數,比如說日志文件到達多少 M 自動輪換,保留幾份日志文件等,一定要設置好此類參數,以防占用大量磁盤空間。
中繼日志 (Relay Log)
中繼日志是 MySQL 復制過程中用于存儲從主服務器接收的二進制日志事件的臨時日志文件。這些日志文件由從服務器用來應用來自主服務器的更新。中繼日志只存在于從服務器上,relay log 文件會隨著事件被應用而逐漸增長,因此也需要適當的清理策略來管理這些文件。
MySQL 官方提供了 relay_log_pure 參數,此參數決定了 relay log 文件在被完全應用后是否應該被自動刪除。這個參數有兩個可能的值:ON 和 OFF ,設置為 ON 代表當中繼日志應用完成后會自動刪除,OFF 則不會自動刪除。一般情況下,建議開啟此參數,這樣 relay log 應用完就會被清理掉,不會占用大量磁盤空間。
如果你的從服務器要求關閉 relay_log_pure 參數,例如在 MHA 高可用架構下,為了確保在故障轉移時能夠使用 relay log 進行恢復,通常需要禁用從服務器上的中繼日志自動清理功能。這個時候就要想其他辦法來清理 relay log 了。MHA 提供了一個名為 purge_relay_logs 的 perl 腳本,可通過 purge_relay_logs 腳本配合 cronjob 來完成此清理任務。若 purge_relay_logs 腳本無法使用,那么只能自己寫 shell 腳本了,比如可以定期將 relay_log_pure 設為 ON ,然后執行 flush relay logs 后,再將 relay_log_pure 設為 OFF ,這樣操作下來一般也能實現清理 relay log 。實在不行我們還可以使用 find 命令來找到幾天前的日志文件,然后直接 rm 清理掉,不過用 find 找到后直接 rm 刪除這種方法會導致 relay-log.indx 索引文件中記錄 relay log 與實際存在的不匹配,所以直接 rm 刪除 relay log 后還要記得更新下 relay-log.indx 索引文件。
總結:
本篇文章簡單介紹了 MySQL 中六種常見日志及其清理策略,不同環境可以采用不同的清理策略,本文只是提供一種思路,方法各種各樣,重要的是要根據實際情況制定合理的日志保留策略,并確保不會影響到數據庫的正常運行和備份需求。