应通过MySQL内部命令清理旧日志:binlog用PURGE BINARY LOGS TO 'xxx',relay log需先确认SQL线程状态及Relay_Master_Log_File,error log须FLUSH ERROR LOGS后删除,直接rm会导致空间不释放且日志丢失。

mysql_upgrade 执行后残留的旧日志文件怎么删
执行 mysql_upgrade 后,MySQL 不会自动清理升级前生成的旧日志(比如 mysql-bin.000001、mysqld-relay-bin.000002),尤其在启用了 binlog 或 relay log 的主从环境中,这些文件可能持续占满磁盘。直接删文件会破坏复制或导致启动失败——必须通过 MySQL 内部命令触发清理。
- 先确认当前正在使用的日志:执行
SHOW MASTER STATUS查看File字段值(如mysql-bin.000042),所有小于该编号的 binlog 才可安全清理 - 用
PURGE BINARY LOGS TO 'mysql-bin.000042'删除指定文件及之前全部 binlog;不要写成PURGE BINARY LOGS BEFORE '2024-01-01 00:00:00',时间判断依赖系统时钟和日志事件时间戳,容易误删 - 如果启用了 GTID,
PURGE仍有效,但需确保gtid_purged不被截断——执行前检查SELECT @@global.gtid_purged,若返回为空或明显落后于SELECT * FROM mysql.gtid_executed,说明已有日志被删但 GTID 记录未同步,此时禁止 PURGE
relay-log 清理不生效?可能是 sql_slave_skip_counter 干扰了 purge 逻辑
从库上执行 PURGE RELAY LOGS 失败或没效果,常见原因是 SQL 线程卡住、或手动设置过 sql_slave_skip_counter 导致 relay log 位置与实际执行状态脱节。MySQL 在清理 relay log 前会校验 Relay_Log_File 和 Relay_Log_Pos 是否指向可安全删除的位置。
- 运行
SHOW SLAVE STATUS\G,重点看Relay_Master_Log_File和Exec_Master_Log_Pos,它们共同定义了已应用的 relay log 范围;PURGE RELAY LOGS BEFORE 'xxx'中的文件名必须严格小于Relay_Master_Log_File - 若
Seconds_Behind_Master非零且持续增长,说明 SQL 线程滞后,此时强制 PURGE 可能丢数据;应先解决复制延迟,再清理 - 临时跳过错误后未重置
sql_slave_skip_counter(设为 0),会导致 MySQL 误判已执行位置,建议跳过错误后立即执行SET GLOBAL sql_slave_skip_counter = 0
my.cnf 里 expire_logs_days 设置了但日志还在
expire_logs_days 是 MySQL 自动清理 binlog 的开关,但它只在服务器启动时或日志切换时触发检查,不是实时守护进程。如果你改完配置没重启 mysqld,或长期没产生新 binlog(比如业务停了几天),旧日志就一直留着。
- 确认变量是否生效:连接后执行
SELECT @@global.expire_logs_days,返回值应是你配置的数字(如 7);若为 0,说明配置未加载或被动态覆盖 - 该参数只影响
binlog,不影响error log、slow query log或general log;这些需靠外部轮转(logrotate)或 MySQL 8.0+ 的log_error_services配置 - MySQL 8.0.26+ 支持
binlog_expire_logs_seconds(精度秒级),优先级高于expire_logs_days;若两者都设,后者会被忽略
rm -f *.log 直接删 error log 会出什么问题
MySQL 的 error.log 默认由 mysqld 自己打开并持续写入,Linux 下用 rm -f 删除后,文件 inode 虽消失,但 mysqld 进程仍持有 fd 指向原文件,继续往已被删除的文件写——磁盘空间不会释放,且日志内容不可见,排查故障时会以为“没日志”。
- 正确做法是:先执行
FLUSH ERROR LOGS(MySQL 5.7.19+)或FLUSH LOGS(通用),让 mysqld 关闭旧 fd 并新建日志文件 - 若版本太老不支持
FLUSH ERROR LOGS,可用kill -USR1 $(pgrep mysqld)(仅 Linux),触发日志 reopen;注意不是 SIGTERM - 生产环境建议用 logrotate 配合
create+delaycompress+postrotate中调用mysql -e "FLUSH ERROR LOGS",避免日志中断
清理日志最危险的不是删错文件,而是删完才发现复制链路断了、GTID 对不上、或者 error log 实际还在往 deleted 文件里写。每次操作前,务必用 SHOW BINARY LOGS 或 SHOW RELAYLOG EVENTS 确认边界,别信配置文件里的注释,也别信上次运维留下的 README。


















