relay_log_purge=off会导致中继日志堆积致磁盘爆满;其控制sql线程执行后是否自动删除relay log,与expire_logs_days无关;启用前需通过show slave status确认relay_master_log_file与relay_log_file已追平,避免数据丢失。

relay_log_purge=OFF 会导致磁盘爆满
MySQL 中继日志(relay log)不自动清理,最直接的后果就是 /var/lib/mysql/ 目录下堆积大量 relay-bin.0000xx 文件,尤其在主从延迟高、网络不稳定或从库停机期间。默认值是 ON,但有些 DBA 为“避免误删”手动设成 OFF,反而埋下隐患。
关键点在于:relay_log_purge 控制的是 SQL 线程执行完一个 relay log 文件后,是否立即删除它;它和 expire_logs_days 无关,后者只管 binlog,不管 relay log。
-
relay_log_purge=ON:SQL 线程读完并执行完某段 relay log 后,立刻释放该文件(前提是 IO 线程没在写它) -
relay_log_purge=OFF:即使已执行完毕,也不会删——必须靠人工PURGE RELAY LOGS或重启 MySQL(重启时若relay_log_purge=ON才会清) - 该变量是动态的,可在线修改:
SET GLOBAL relay_log_purge = ON;
如何安全启用 relay_log_purge 并验证生效
不能只改变量就完事。需确认当前 relay log 是否已被消费完毕,否则开启后可能删掉还没执行的日志,导致从库数据丢失。
先查状态:SHOW SLAVE STATUS\G,重点关注两行:
-
Relay_Log_File:IO 线程当前正在写的 relay log 文件名 -
Relay_Master_Log_File:SQL 线程已执行到的主库 binlog 文件名(对应 relay log 的源头)
只要 Relay_Master_Log_File 和 Relay_Log_File 指向的不是同一个文件(即 SQL 线程已追上),就可以放心开 relay_log_purge。如果差距大,先等同步追平,或用 STOP SLAVE; START SLAVE; 触发一次重载检查。
启用后,观察:ls -lt /var/lib/mysql/relay-bin.*,正常情况下只会剩 1–2 个活跃文件,旧文件很快消失。
my.cnf 里配 relay_log_purge 要注意什么
配置文件中写 relay_log_purge=1 或 relay_log_purge=ON 都可以,但必须放在 [mysqld] 段下,且不能拼错成 relay-log-purge(带横线是错的)。
- 该参数不支持运行时持久化到 my.cnf,必须手动编辑配置文件再重启,否则 MySQL 重启后恢复默认值(取决于版本,5.7+ 默认 ON,但老版本可能 OFF)
- 如果用了
relay_log自定义路径(比如指向 SSD 分区),确保该路径有足够空间且权限正确——relay_log_purge不解决路径问题,只控制删不删 - 搭配
relay_log_recovery=ON更稳妥:崩溃重启后自动重建 relay log,避免因 relay log 损坏+purge 关闭导致同步卡死
PURGE RELAY LOGS 手动清理的适用场景
只有两种情况才需要手动执行:PURGE RELAY LOGS BEFORE '2024-05-01 00:00:00'; 或 PURGE RELAY LOGS TO 'relay-bin.000012';
- 临时关闭了
relay_log_purge,现在要清历史积压(注意:必须确认Relay_Master_Log_File已超过你要删的文件) - 从库已提升为主库(
RESET SLAVE ALL后),但 relay log 还在,需主动清理
别在同步中频繁手动 PURGE——它会锁住 SQL 线程,阻塞复制;也别依赖它替代 relay_log_purge=ON,那是治标不治本。
真正容易被忽略的是:即使开了 relay_log_purge=ON,如果从库长期停止复制(STOP SLAVE),relay log 也不会被删——因为 SQL 线程没运行,就永远不会标记“已执行完毕”。所以监控 Relay_Log_Space 和 Seconds_Behind_Master 比单纯调参数更重要。










