relay_log_purge=off会导致中继日志持续累积并撑爆磁盘,因其默认不自动删除,需同时动态设置on并持久化到配置文件,且清理依赖sql线程执行进度,还需配合relay_log_space_limit限制总空间。

relay_log_purge=OFF 会导致磁盘被撑爆
MySQL 中继日志(relay log)默认不会自动删除,除非显式设置 relay_log_purge=ON。如果用在主从复制或 MHA、Orchestrator 等高可用架构中,且从库长期不执行 START SLAVE 或复制卡住,中继日志会持续累积——常见现象是 /var/lib/mysql/relay-bin.000xxx 文件占满磁盘,而 SHOW PROCESSLIST 显示 SQL 线程为 Waiting for relay log to be written 或直接 Slave_SQL_Running: No。
必须在从库上动态+持久化双设置
relay_log_purge 是动态变量,但仅靠 SET GLOBAL relay_log_purge = ON 不够:MySQL 重启后会恢复默认值 ON(注意:5.7+ 默认就是 ON,但某些定制镜像或旧版本可能改过)。真正保险的做法是:
- 确认当前值:
SELECT @@global.relay_log_purge;—— 返回0表示关闭 - 运行时开启:
SET GLOBAL relay_log_purge = ON; - 写入配置文件(如
/etc/my.cnf的[mysqld]段):relay_log_purge = ON - 注意:该参数不能在运行中设为
OFF(会报错ERROR 1238 (HY000): Variable 'relay_log_purge' is a read only variable),只能在启动前配好
清理时机不是“实时”,而是“SQL线程执行完就删”
中继日志清理不是按时间或大小触发的定时任务,而是严格依赖 SQL 线程进度:
- 当 SQL 线程执行完某条 relay log 中的 event 后,MySQL 会立即检查该文件是否已全部执行完毕
- 若已执行完且
relay_log_purge=ON,则立刻unlink()删除该文件(不进回收站) - 所以如果复制延迟大,或者 SQL 线程卡在某个事务(比如大 DML、锁等待),对应 relay log 就一直留着
- 可通过
SHOW SLAVE STATUS\G查看Relay_Log_File和Relay_Master_Log_File,前者是当前正在读的 relay log,后者是主库 binlog 位置;两者差距越大,积压 relay log 越多
别只盯着 relay_log_purge,还要配好 relay_log_space_limit
单靠 relay_log_purge=ON 无法防止突发性积压(比如主库瞬间打满 binlog,从库来不及消费)。这时候需要硬性空间保护:
-
relay_log_space_limit是总 relay log 占用磁盘上限(单位字节),设为0表示不限制(默认值) - 建议设为合理值,例如
relay_log_space_limit = 4294967296(4GB),超出后 SQL 线程会报错停止,并写入 error log:Relay log write failure: The relay log is full - 该参数必须在 MySQL 启动前配置,不支持动态修改
- 搭配使用效果更稳:即使 SQL 线程卡住,也能靠空间限制兜底,避免影响整个实例
Seconds_Behind_Master 和 Slave_SQL_Running_State,而不是只查参数值。











