relay_log_purge=on必须开启但不足够,sql线程卡死后purge机制彻底失效,需结合relay_log_space_limit硬限制、路径隔离及stop slave后手动purge等措施协同防护。

relay_log_purge=ON 是必须开的,但光开它远远不够——磁盘爆满往往发生在 SQL 线程卡死之后,此时 purge 机制完全失效。
确认 relay_log_purge 是否真正在生效
很多人以为 SET GLOBAL relay_log_purge = ON 就万事大吉,其实不是。这个变量是动态的,但 MySQL 重启后会按配置文件里的值恢复。如果 my.cnf 里没写,或者写成了 relay_log_purge = OFF,重启后就又关了。
- 查当前运行值:
SELECT @@global.relay_log_purge;—— 返回 0 表示已关闭 - 临时开启:
SET GLOBAL relay_log_purge = ON; - 持久化必须加到
[mysqld]段:relay_log_purge = ON(注意:不能在运行中设为 OFF,会报错ERROR 1238 (HY000): Variable 'relay_log_purge' is a read only variable) - 检查
SHOW SLAVE STATUS\G中的Relay_Log_File和Exec_Master_Log_Pos是否持续前进;如果长期卡在同一个文件+位置,说明 purge 根本没机会触发
relay_log_space_limit 是防爆盘的最后一道闸
relay_log_purge 是“执行完就删”,但删得再快也赶不上 SQL 线程卡住时 IO 线程狂写的速度。这时候靠 relay_log_space_limit 做硬性截断——它限制的是所有 relay log 占用的总字节数,超限后 SQL 线程直接报错停止,避免磁盘被写满。
- 默认值是 0(不限制),生产环境必须设一个合理上限,例如:
relay_log_space_limit = 4294967296(4GB) - 该参数需写入
my.cnf并重启生效,不支持动态修改 - 超限后错误日志会出现:
Relay log write failure: The relay log is full,这是明确信号,必须立刻排查 SQL 线程为何卡住 - 不要设太小(比如 512MB),否则可能频繁触发中断;也不要设太大(比如 20GB),起不到保护作用
别把 relay log 和 datadir 放一起
默认 relay log 跟数据文件共用 datadir 分区,一旦中继日志失控,ibdata1、ib_logfile、表空间全跟着遭殃。最稳妥的做法是物理隔离。
- 在
my.cnf中显式指定路径:relay_log = /data/relaylog/mysql-relay-bin,并确保该目录独立挂载、有足够空间 - 同时配好索引文件:
relay_log_index = /data/relaylog/mysql-relay-bin.index - 目录权限必须和
mysql用户一致,且 SELinux/AppArmor 不拦截写入(常见坑:改路径后 MySQL 启不动,日志报Can't create/write to file) - 路径写错一个字符(比如多一个斜杠或漏写文件名前缀),MySQL 启动会失败,不会 fallback 到默认值
PURGE RELAY LOGS 不是万能的,卡死时它会直接报错
很多人想用 PURGE RELAY LOGS TO 'mysql-relay-bin.000042'; 手动清理,但它有个硬前提:SQL 线程必须正常运行且未卡死。一旦 Slave_SQL_Running: No,这条命令会立刻返回 ERROR 1981 (HY000): Cannot purge when relay log is active。
- 真正安全的手动清理顺序只能是:
STOP SLAVE SQL_THREAD;→ 查Relay_Log_File→rm掉编号更小的旧文件(不能删当前正在读的)→START SLAVE SQL_THREAD; - 切记:
FLUSH LOGS对 relay log 完全无效,它只影响 binlog 和 error log -
RESET SLAVE会清空所有 relay log 并重置坐标,但会丢失当前Master_Log_File和Master_Log_Pos,仅适用于确认已完全追平且可接受重同步的场景 -
expire_logs_days对 relay log 完全无影响,它只管主库的 binlog
最常被忽略的一点:relay log 的清理时机不是定时或轮转,而是严格绑定 SQL 线程执行进度。只要线程一卡,无论 relay_log_purge 开没开,文件就停在那里不删——所以日常监控不能只看参数,必须盯紧 Slave_SQL_Running 和 Seconds_Behind_Master 的真实性。











