relay_log_purge=on不是定时清理,仅当sql线程执行完且io线程轮转时才“顺手删”,需stop slave+purge+start slave三步手动清理,并配relay_log_space_limit防磁盘爆满。

relay_log_purge=ON 是自动清理的开关,但不是“定时删除”
MySQL 不会像 expire_logs_days 那样按时间自动删 relay log。所谓“自动”,仅指当 relay_log_purge=ON(默认值)时,SQL 线程每执行完一个 event 后,会检查当前 relay log 文件是否已全部应用完毕、且无其他线程引用——满足才标记为“可删”。真删动作要等 IO 线程写入新文件触发轮转后才发生。
常见误解是“开了就立刻清”,实际现象往往是:Relay_Log_File 指向 relay-bin.000015,但磁盘里还堆着 .000001 到 .000014 —— 因为 SQL 线程没跑完、或 IO 线程没切新文件,根本没走到删除逻辑。
- SQL 线程卡在锁等待、大事务回放慢 → 旧文件一直挂着
- STOP SLAVE 后没再 START → IO 线程停写,永不轮转,永不清理
-
relay_log_recovery=ON时,最老的一个 relay log 强制保留,用于崩溃恢复
为什么 relay_log_purge=ON 还不删?关键看两个线程状态
自动清理生效需同时满足:SQL 线程已执行完某文件所有 event + IO 线程已写入新 relay log 文件。缺一不可。
查状态用:SHOW SLAVE STATUS\G,重点关注:
-
Slave_IO_Running: Yes→ IO 线程活跃,能写新 relay log -
Slave_SQL_Running: Yes→ SQL 线程没卡死 -
Relay_Master_Log_File和Exec_Master_Log_Pos是否已越过待删文件对应主库 binlog 位置 -
Seconds_Behind_Master接近 0,说明积压小,清理机会多
如果 Slave_SQL_Running_State 显示 Waiting for table metadata lock 或长时间 Reading event from the relay log,清理就停摆。
PURGE RELAY LOGS 才是真正可控的清理手段
relay_log_purge=ON 只管“顺手删”,不保证及时性;手动 PURGE RELAY LOGS 才能强制回收已确认无用的日志。
安全操作必须分三步:
- 先
STOP SLAVE:冻结 IO/SQL 线程,避免删到一半被覆盖 - 再
PURGE RELAY LOGS TO 'mysql-relay-bin.000027':删编号小于目标的所有文件(注意:不是删这个文件本身) - 最后
START SLAVE:恢复复制
⚠️ 错误做法:rm -f relay-bin.* 会破坏 relay-log.info 或 mysql.slave_relay_log_info 表,导致复制启动失败;PURGE RELAY LOGS BEFORE '2026-06-10' 语法无效,MySQL 不支持时间条件。
relay_log_space_limit 是防止磁盘爆掉的最后一道防线
单靠 relay_log_purge=ON 无法应对突发积压(比如主库瞬间打满 binlog)。这时需要硬限流:
在配置文件中设:relay_log_space_limit = 4294967296(即 4GB),超出后 SQL 线程报错停止,并写入 error log:Relay log write failure: The relay log is full。
注意:relay_log_space_limit 是总空间上限,单位字节;设为 0 表示不限制(默认值),生产环境务必设合理值。
真正容易被忽略的是:即使 relay_log_purge=ON,MySQL 至少保留当前正在读的 + 下一个待读的两个 relay log 文件——这是防止切换时丢事件的保护机制,不是 bug。











