logrotate 是 Linux 下管理 MySQL 日志滚动的事实标准,MySQL 仅负责写日志,轮转需依赖系统工具;需先确认日志路径与启用状态,再配置 logrotate 并正确发送 USR1 信号通知 MySQL 切换日志文件。

logrotate 是 Linux 下管理 MySQL 日志滚动的事实标准,不是 MySQL 自己做的——它只管写,轮转得靠系统工具。
确认日志路径和开关状态
别急着配 logrotate,先看 MySQL 实际在往哪写、写了哪些日志:
mysql -u root -p -e "SHOW VARIABLES LIKE 'log_error';"mysql -u root -p -e "SHOW VARIABLES LIKE 'slow_query_log_file';"mysql -u root -p -e "SHOW VARIABLES LIKE 'general_log_file';"
如果返回 Value 为空或为 OFF,说明对应日志没启用,logrotate 配了也白配。必须先在 /etc/my.cnf 的 [mysqld] 段里明确指定路径并开启:
[mysqld] log_error = /var/log/mysql/error.log slow_query_log = ON slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2
改完要 systemctl restart mysql(或 mysqld),部分参数如 log_error 不重启不生效。
配置 /etc/logrotate.d/mysql 文件
这是核心动作。不要直接改全局 /etc/logrotate.conf,用独立配置更安全、易维护:
/var/log/mysql/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 640 mysql adm
sharedscripts
postrotate
if [ -f /var/run/mysqld/mysqld.pid ]; then
kill -USR1 $(cat /var/run/mysqld/mysqld.pid)
fi
endscript
}
关键点解释:
-
daily:每天检查一次,满足条件就轮转;可加size 500M防止单日日志暴增撑爆磁盘 -
create 640 mysql adm:新日志权限必须是mysql可写,adm组可读(Ubuntu/Debian 默认用adm,CentOS 用mysql,注意匹配) -
kill -USR1:通知 MySQL 关闭旧文件句柄、打开新文件。仅对error.log和slow.log有效;general.log若启用,也走这个信号 -
sharedscripts:确保所有匹配的.log文件共用一个postrotate脚本,避免重复发信号
二进制日志(binlog)不能用 logrotate
binlog 是 MySQL 自己管理的,交由 logrotate 强行切割会导致主从中断、PURGE 失效甚至数据不一致:
- 必须在
[mysqld]中用log_bin = /var/log/mysql/mysql-bin(不带后缀!) - 设
max_binlog_size = 100M控制单个文件大小 - 清理策略用 MySQL 原生方式:
expire_logs_days = 7(MySQL 5.7)或binlog_expire_logs_seconds = 604800(MySQL 8.0+) - 手动清理用
PURGE BINARY LOGS BEFORE '2026-02-01 00:00:00';,别删文件
测试和验证不能跳过
配完不验证 = 白配。两个命令必须跑:
-
logrotate -d /etc/logrotate.d/mysql:调试模式,只模拟,不执行,看有没有语法错误、路径是否识别正确 -
logrotate -f /etc/logrotate.d/mysql:强制执行一次,然后立刻检查:
–/var/log/mysql/下是否有error.log.1或slow.log.1.gz
–tail -f /var/log/mysql/error.log是否继续有新内容写入
–ls -l /var/log/mysql/看新文件属主是不是mysql,权限是不是640
最容易被忽略的是 PID 文件路径——有些发行版把 mysqld.pid 放在 /var/lib/mysql/ 或 /run/mysqld/,脚本里写错就收不到信号,日志永远不切换。










