慢查询日志是MySQL用于记录执行时间超过指定阈值的SQL语句的日志文件,是数据库性能优化和问题排查的核心依据。但长期运行的MySQL实例会产生大量慢查询日志,如果不及时管理,会导致磁盘空间被占满,同时过大的日志文件也会降低分析效率。合理的管理、自动归档和清理慢查询日志,是数据库运维的必要工作。

慢查询日志基础配置
首先确认慢查询日志是否开启,以及相关的配置参数,这是后续管理操作的基础。可以通过以下SQL语句查看当前配置:
-- 查看慢查询日志是否开启 SHOW VARIABLES LIKE 'slow_query_log'; -- 查看慢查询日志文件路径 SHOW VARIABLES LIKE 'slow_query_log_file'; -- 查看慢查询时间阈值(单位:秒) SHOW VARIABLES LIKE 'long_query_time'; -- 查看是否记录未使用索引的查询 SHOW VARIABLES LIKE 'log_queries_not_using_indexes';
如果需要开启慢查询日志,可以执行以下配置语句,永久生效需要将配置写入MySQL的配置文件my.cnf或my.ini中:
-- 临时开启慢查询日志 SET GLOBAL slow_query_log = 'ON'; -- 设置慢查询时间阈值为2秒,执行超过2秒的查询会被记录 SET GLOBAL long_query_time = 2; -- 设置慢查询日志文件路径,需要保证MySQL进程有写入权限 SET GLOBAL slow_query_log_file = '/var/lib/mysql/slow.log';
手动管理慢查询日志
在日志量不大的场景下,可以手动进行日志的归档和清理,操作相对简单直接。
手动归档慢查询日志
手动归档的核心思路是将当前的慢查询日志内容备份到其他文件,然后清空当前日志,避免直接删除日志文件导致MySQL无法继续写入。操作步骤如下:
- 第一步:备份当前慢查询日志,将日志内容复制到归档文件,归档文件可以按照日期命名,方便后续查找
- 第二步:清空当前慢查询日志,MySQL提供了专门的命令来刷新日志,不需要手动删除文件
对应的操作命令如下,在服务器命令行执行:
# 备份慢查询日志到带日期的归档文件 cp /var/lib/mysql/slow.log /var/lib/mysql/archive/slow_$(date +%Y%m%d).log # 执行MySQL日志刷新命令,清空当前慢查询日志 mysql -u root -p -e "FLUSH SLOW LOGS;"
手动清理慢查询日志
手动清理一般是删除过期的归档日志,比如保留最近30天的归档文件,删除更早的文件:
# 删除30天前的慢查询归档日志 find /var/lib/mysql/archive/ -name "slow_*.log" -mtime +30 -delete
自动归档与清理方案
手动操作效率低且容易遗漏,生产环境通常需要配置自动归档和清理机制,这里提供两种常用方案。
方案一:基于Shell脚本+Crontab实现
编写Shell脚本完成日志归档和过期清理,然后通过Crontab设置定时执行,适合所有MySQL版本。
首先创建归档清理脚本/opt/mysql_slow_archive.sh:
#!/bin/bash # MySQL慢查询日志自动归档清理脚本 # 配置参数 SLOW_LOG_PATH="/var/lib/mysql/slow.log" # 慢查询日志路径 ARCHIVE_DIR="/var/lib/mysql/archive" # 归档目录 MYSQL_USER="root" # MySQL用户名 MYSQL_PASS="your_password" # MySQL密码 KEEP_DAYS=30 # 保留归档日志的天数 # 创建归档目录(如果不存在) mkdir -p $ARCHIVE_DIR # 生成归档文件名,带日期 ARCHIVE_FILE="$ARCHIVE_DIR/slow_$(date +%Y%m%d).log" # 备份当前慢查询日志 cp $SLOW_LOG_PATH $ARCHIVE_FILE # 刷新慢查询日志,清空当前日志 mysql -u$MYSQL_USER -p$MYSQL_PASS -e "FLUSH SLOW LOGS;" # 删除过期的归档日志 find $ARCHIVE_DIR -name "slow_*.log" -mtime +$KEEP_DAYS -delete echo "慢查询日志归档清理完成,归档文件:$ARCHIVE_FILE"
给脚本添加执行权限,然后配置Crontab定时任务,比如每天凌晨2点执行:
# 添加执行权限 chmod +x /opt/mysql_slow_archive.sh # 编辑crontab任务 crontab -e # 添加以下内容,每天凌晨2点执行脚本 0 2 * * * /opt/mysql_slow_archive.sh >> /var/log/mysql_slow_archive.log 2>&1
方案二:基于MySQL事件调度器实现
如果MySQL版本支持事件调度器,可以在数据库内部创建事件,定期执行归档清理逻辑,不需要依赖外部脚本。
首先开启MySQL事件调度器:
-- 查看事件调度器是否开启 SHOW VARIABLES LIKE 'event_scheduler'; -- 开启事件调度器 SET GLOBAL event_scheduler = ON;
创建存储过程,用于执行日志归档和清理逻辑:
DELIMITER //
CREATE PROCEDURE archive_slow_log()
BEGIN
DECLARE archive_path VARCHAR(255);
-- 生成归档文件路径,这里需要结合服务器文件系统操作,实际场景中可以配合外部脚本
-- 也可以通过修改日志文件路径的方式实现归档,先关闭慢查询日志,重命名文件,再重新开启
SET @old_log_path = @@slow_query_log_file;
-- 关闭慢查询日志
SET GLOBAL slow_query_log = 'OFF';
-- 重命名当前日志文件为归档文件,日期作为后缀
SET @archive_file = CONCAT('/var/lib/mysql/archive/slow_', DATE_FORMAT(NOW(), '%Y%m%d'), '.log');
SET @rename_cmd = CONCAT('RENAME FILE ''', @old_log_path, ''' TO ''', @archive_file, '''');
-- 执行重命名命令(需要MySQL有对应权限,部分版本可能需要通过系统变量配合)
PREPARE stmt FROM @rename_cmd;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 重新设置慢查询日志路径为原路径,开启慢查询日志
SET GLOBAL slow_query_log_file = @old_log_path;
SET GLOBAL slow_query_log = 'ON';
-- 清理30天前的归档日志,这里需要配合系统层面的清理,或者记录归档日志信息到表中再清理
END //
DELIMITER ;
创建定时事件,每天凌晨2点执行该存储过程:
CREATE EVENT IF NOT EXISTS ev_archive_slow_log ON SCHEDULE EVERY 1 DAY STARTS '2024-01-01 02:00:00' DO CALL archive_slow_log();
注意事项
- 操作慢查询日志文件时,要确保MySQL进程对日志目录和归档目录有读写权限,避免出现权限不足导致操作失败
- 清空慢查询日志时,不要直接删除
slow_query_log_file对应的文件,否则MySQL可能无法继续写入日志,优先使用FLUSH SLOW LOGS命令 - 自动归档清理脚本中,MySQL密码如果明文存储存在安全风险,可以使用配置文件存储密码,或者在crontab中通过环境变量传递
- 归档的慢查询日志建议定期备份到其他存储位置,避免本地磁盘故障导致日志丢失,影响后续问题排查
通过以上方法,就可以实现对MySQL慢查询日志的规范管理,自动完成归档和清理工作,既保留了对历史慢查询的分析能力,又避免了日志文件膨胀带来的磁盘和性能问题。
MySQL慢查询日志自动归档日志清理slow_query_log修改时间:2026-07-17 05:30:32