唯一安全清理方式是purge binary logs;确认可删需三步:show binary logs查已关闭文件、show slave status核对relay_master_log_file确保不删从库未读文件、select检查无活跃binlog dump连接。

PURGE BINARY LOGS 是唯一安全的清理方式,直接 rm -f 会导致主从断裂或 MySQL 崩溃。
怎么确认哪些 binlog 真的能删
MySQL 只清理「已关闭」且「未被从库读取」的日志,SHOW BINARY LOGS 输出的文件才可能被删;SHOW MASTER STATUS 返回的 File 字段是当前正在写的日志,它和它之前的文件都不能删。
- 执行
SHOW BINARY LOGS,检查每行的File_size:为 0 的文件通常已被关闭,但不等于可删 - 查从库位置:
SHOW SLAVE STATUS\G中的Relay_Master_Log_File,确保你要删的文件编号或时间点早于它 - 查是否有活跃 dump 连接:
SELECT * FROM performance_schema.threads WHERE TYPE = 'FOREGROUND' AND PROCESSLIST_COMMAND = 'Binlog Dump',有就别删
PURGE BINARY LOGS TO 和 BEFORE 到底怎么选
TO 按文件名字典序删(不含目标文件),BEFORE 按事件时间戳删(含等于该时间的所有文件),两者逻辑完全不同,混用会误删。
-
PURGE BINARY LOGS TO 'mysql-bin.000123':删掉所有字典序小于mysql-bin.000123的文件,比如mysql-bin.000122、mysql-bin.000099都会被删,但mysql-bin.000123保留 -
PURGE BINARY LOGS BEFORE '2024-05-01 00:00:00':删掉所有第一个事件时间早于该时间戳的文件,哪怕某个日志里只有一条事件在范围内,整个文件也删 - 注意时区:
BEFORE使用 MySQL 服务器系统时区,不是你本地终端时区 —— 容易差一整天
自动清理为什么没生效
expire_logs_days 在 MySQL 8.0.11+ 已弃用,且它本身不“定时运行”,必须靠 FLUSH LOGS 触发清理逻辑,否则配置再久也没用。
- 查当前策略:
SELECT @@binlog_expire_logs_seconds(推荐)或SHOW VARIABLES LIKE 'expire_logs_days' - 设新值:
SET GLOBAL binlog_expire_logs_seconds = 604800(7 天),同时建议SET GLOBAL expire_logs_days = 0避免冲突 - 立即触发清理:
FLUSH LOGS—— 它会滚动新 binlog 并清理过期旧文件 - 生产环境建议加 crontab:
0 2 * * * mysql -e "FLUSH LOGS",每天凌晨跑一次
错误日志和慢查询日志怎么轮转
这类日志不走 MySQL 内部机制,不能用 PURGE,得靠系统工具管理,否则容易堆积失控。
- 先查路径:
SHOW VARIABLES LIKE 'general_log_file'、SHOW VARIABLES LIKE 'slow_query_log_file' - 用
logrotate配置轮转(如/etc/logrotate.d/mysql):/var/log/mysql/mysql-slow.log { daily rotate 7 missingok compress delaycompress postrotate mysql -e "FLUSH SLOW LOGS;" endscript } - 禁用非必要日志更治本:
SET GLOBAL slow_query_log = OFF或SET GLOBAL general_log = OFF,重启后生效
最容易被忽略的是 GTID 模式下从库未拉取完就 purge,或者 BEFORE 时间写错时区导致多删一天——务必以 SHOW SLAVE STATUS 和 SHOW BINARY LOGS 为准,别信本地 ls 列出的文件名。











