mysql错误日志需用logrotate配合mysqladmin flush-logs实现安全轮转,仅配logrotate不通知mysql会导致日志写入已移走文件、磁盘不释放且可能丢记录;必须先查真实log_error路径与权限,postrotate中调用带认证参数的mysqladmin flush-logs,禁用copytruncate和重启,确保create权限匹配mysqld进程用户,并通过lsof和手动触发错误验证生效。

MySQL错误日志不会自动切割,必须靠logrotate配合mysqladmin flush-logs才能安全轮转——只配logrotate不通知MySQL,日志会继续往已移走的文件里写,磁盘空间不释放,还可能丢记录。
确认错误日志路径和当前权限
别凭经验猜路径,先查真实配置:
- 运行
mysql -e "show variables like 'log_error';"看输出的Value字段,比如是/var/log/mysql/error.log - 用
ls -l /var/log/mysql/error.log检查属主和权限,确保mysql用户能读写该路径下的文件 - 如果路径在
/data或/application等非标准位置,logrotate配置里的路径必须完全一致,大小写、斜杠都不能错
logrotate配置必须含postrotate调用mysqladmin flush-logs
这是最关键的一步。不能用copytruncate,也不能重启MySQL服务——前者在MySQL 5.7+上易丢日志,后者会导致连接中断。
-
postrotate块里必须执行mysqladmin flush-logs,不是FLUSH LOGS(那个会刷binlog,没必要) - 命令需带连接参数,如
mysqladmin -uroot -p'xxx' -S /tmp/mysql.sock flush-logs;若用TCP连接,加-h127.0.0.1 -P3306 - 账号只需
RELOAD权限,建议建专用账号:CREATE USER 'flush-logs'@'localhost' IDENTIFIED BY 'pwd'; GRANT RELOAD ON *.* TO 'flush-logs'@'localhost'; - 确保
mysqladmin二进制路径正确,有些环境在/usr/bin/,有些在/usr/local/mysql/bin/
create参数必须匹配MySQL进程的用户和权限
轮转后新建的日志文件,如果权限不对,MySQL启动或重开日志时会写失败,报错Can't open error log file。
- 用
ps aux | grep mysqld看主进程以哪个用户运行(通常是mysql) -
logrotate配置中写create 640 mysql mysql,不能写成root root或漏掉组名 - 如果MySQL跑在容器或systemd下,注意
logrotate执行时的上下文是否能访问socket或有足够权限调用mysqladmin - 加
sharedscripts防止多个匹配路径重复执行postrotate,避免并发冲突
验证是否生效,而不是等磁盘爆掉
配完别干等明天,立刻手动触发并检查效果:
- 运行
logrotate -f /etc/logrotate.d/mysql强制轮转一次 - 看旧文件是否变成
error.log-20260412(或带.gz),新error.log是否为空且属主正确 - 立刻查MySQL进程:用
lsof -p $(pgrep mysqld) | grep error,确认它打开的是新文件的inode号 - 等几秒再故意触发一个错误(比如
mysql -e "SELECT * FROM nonexist;"),看错误是否写进新error.log,而不是旧文件
最容易被忽略的是postrotate脚本里mysqladmin执行失败却没报错——建议在脚本末尾加|| echo "mysqladmin failed at $(date)" >> /var/log/logrotate-mysql.log,留痕排查。











