定时清理MySQL慢查询日志优化数据库
为什么要定期清理慢查询日志
MySQL 的慢查询日志记录了执行时间超过 long_query_time 的 SQL 语句。
如果数据库运行时间较长,慢查询日志文件会持续膨胀,不仅占用磁盘空间,还可能影响 MySQL 本身的 I/O 性能。定时清理慢查询日志 是数据库日常优化中一个容易被忽视但非常实用的操作。
本文会从零开始,教你通过 Linux 的 cron 定时任务自动完成清理,整个过程不需要装额外软件,纯命令行操作。
环境准备
在执行清理之前,你需要确认两件事:
- MySQL 慢查询日志已开启,知道日志文件存放位置。
- 你的服务器是 Linux 系统(CentOS / Ubuntu / Debian 通用),并且有 root 或 sudo 权限。
可以通过以下命令查看慢查询日志状态和文件路径:
mysql -u root -p -e "SHOW VARIABLES LIKE 'slow_query_log%';"
重点关注 slow_query_log_file 的值,比如 /var/lib/mysql/server-slow.log。
如果未开启,可以临时开启(生产环境请按需设置):
mysql -u root -p -e "SET GLOBAL slow_query_log = ON;"
不过建议直接在 MySQL 配置文件 /etc/my.cnf 中永久开启:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/server-slow.log
long_query_time = 2
修改后重启 MySQL 使配置生效。
编写清理脚本
我们使用 重命名+重建日志 的方式,而不是直接删除文件。
这样可以避免 MySQL 失去文件句柄导致无法继续写入,也是官方推荐的做法。
创建一个脚本文件 /usr/local/bin/clean_slowlog.sh:
#!/bin/bash
# 定时清理MySQL慢查询日志脚本
# 使用时请将以下路径替换为你的实际慢查询日志文件路径
SLOW_LOG="/var/lib/mysql/server-slow.log"
BACKUP_DIR="/var/log/mysql/slow_backup"
# 创建备份目录(如果不存在)
mkdir -p $BACKUP_DIR
# 1. 将当前日志重命名,加上时间戳
mv $SLOW_LOG ${SLOW_LOG}.$(date +%Y%m%d%H%M%S)
# 2. 通知MySQL重新打开日志文件
mysql -u root -pYOUR_ROOT_PASSWORD -e "FLUSH SLOW LOGS;" 2>/dev/null
# 3. 将备份的旧日志移动到备份目录(可选)
mv ${SLOW_LOG}.* $BACKUP_DIR/ 2>/dev/null
# 4. 保留最近7天的备份,删除更早的
find $BACKUP_DIR -name "server-slow.log.*" -type f -mtime +7 -delete
注意:-pYOUR_ROOT_PASSWORD 这里直接写密码不安全,建议使用 ~/.my.cnf 文件存放凭据。
创建一个 /root/.my.cnf:
[client]
user=root
password=你的数据库密码
然后修改脚本中的 mysql 命令为不带密码输入:
mysql -e "FLUSH SLOW LOGS;"
确保 .my.cnf 权限为 600:chmod 600 /root/.my.cnf。
为脚本添加执行权限:
chmod +x /usr/local/bin/clean_slowlog.sh
设置定时任务
使用 crontab -e 编辑定时任务。
假设我们希望在每天凌晨 3 点执行一次清理:
0 3 * * * /usr/local/bin/clean_slowlog.sh
保存退出。
可以通过 crontab -l 查看是否添加成功。
避坑提醒:
- cron 默认使用 sh 而不是 bash,如果你的脚本开头是
#!/bin/bash,最好在 cron 任务中指定:
0 3 * * * /bin/bash /usr/local/bin/clean_slowlog.sh
- cron 的环境变量和交互式终端不一样,如果脚本中依赖 mysql 命令,建议在脚本开头设置
PATH:PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,或者使用绝对路径/usr/bin/mysql。 - 测试脚本是否可独立运行:直接执行
/usr/local/bin/clean_slowlog.sh,观察有无报错,并检查慢查询日志是否重新生成。
效果验证与高频问题解答
如何验证清理成功?
- 查看慢查询日志文件是否被重命名:检查
/var/lib/mysql/下是否有带时间戳的旧文件,并且server-slow.log已重新生成(大小很小)。 - 检查备份目录
/var/log/mysql/slow_backup/下是否有归档文件。 - 运行
tail -f /var/lib/mysql/server-slow.log,确认 MySQL 仍在正常写入。
常见问题
Q1:执行脚本后 MySQL 不再记录慢查询?
通常是因为 FLUSH SLOW LOGS 失败。最常见原因是 MySQL 的 root 密码或 .my.cnf 配置不正确。可以尝试手动执行 mysqladmin flush-logs(需要 mysqladmin 命令)。
Q2:日志文件权限导致无法写入?
如果 MySQL 用户是 mysql,脚本生成的新日志文件所有者可能是 root,导致无法写入。解决办法:在 FLUSH 之前确保新文件权限正确。可以在脚本中加入 touch $SLOW_LOG && chown mysql:mysql $SLOW_LOG。
Q3:cron 没有执行
先检查 cron 服务是否运行:systemctl status crond(CentOS)或 service cron status(Ubuntu)。检查邮件(mail 命令)查看 cron 执行输出。另外确认脚本路径是绝对路径。
延伸建议
如果你觉得脚本管理繁琐,也可以考虑使用 logrotate 工具来管理 MySQL 慢查询日志。
但通过 cron 脚本方式更灵活,适合初学者理解原理。
未来如果需要更精细的控制(比如按大小或按天保留多少份),可在脚本中调整 mtime 参数。
总之,定时清理MySQL慢查询日志优化数据库 这个操作成本极低,但能有效避免日志文件吃满磁盘、影响数据库性能。
建议你根据本文步骤在你的服务器上实践一遍,再根据实际环境微调备份周期和保留天数。