Relay_Log_Space 增大表明从库 SQL 线程追不上 IO 线程,常见于主库大事务、从库性能弱、锁表或级联复制;应通过 PURGE RELAY LOGS 安全清理,禁用 relay_log_purge 会增加磁盘爆满风险。

为什么 SHOW SLAVE STATUS 里 Relay_Log_Space 越来越大?
这不是磁盘快满了的信号,而是从库 SQL 线程追不上 IO 线程的明确表现——中继日志写得快、读得慢,积压自然产生。常见原因包括:主库突发大事务(如单条 UPDATE 影响百万行)、从库硬件性能弱于主库、SQL 线程被锁表或长事务阻塞、或者开启了 log_slave_updates 后又做了级联复制,导致自身也生成 binlog 并加重 I/O 压力。
- 别直接删
relay-log文件——MySQL 依赖relay-log.info(或mysql.slave_relay_log_info表)记录当前读到哪条,手动删会彻底断复制 -
Relay_Log_Space是所有 relay log 文件总大小,不等于“没用的日志”,只要Relay_Master_Log_File和Exec_Master_Log_Pos还在往前走,说明还在正常消费 - 真正危险的是
Seconds_Behind_Master持续增长 +Relay_Log_Space不下降,这时得先查 SQL 线程卡在哪(看Slave_SQL_Running_State)
如何安全清理已执行完的 relay log?
MySQL 提供了原生机制,不需要手动干预文件系统。核心是让 SQL 线程确认“这段日志真跑完了”,然后由 PURGE RELAY LOGS 或自动策略回收。
- 最稳妥方式:
PURGE RELAY LOGS BEFORE '2024-05-20 00:00:00';—— 只删早于该时间点且已被执行的日志;注意时间必须是 MySQL 服务器时区,不是系统时区 - 更常用的是按文件名清理:
PURGE RELAY LOGS TO 'mysqld-relay-bin.000123';—— 删除编号小于000123的所有 relay log(含000122及之前) - 加
MASTER_LOG_FILE条件可避免误删:例如PURGE RELAY LOGS TO 'mysqld-relay-bin.000123' AND MASTER_LOG_FILE = 'binlog.000456';,确保只清理对应主库 binlog 范围内的 relay log - 启用自动清理:在配置文件设
relay_log_purge = ON(默认就是 ON),再配relay_log_recovery = ON(崩溃后自动重建 relay log info)
relay_log_purge=OFF 有什么实际影响?
关掉自动清理不是“更安全”,而是把风险转移给了 DBA——你得自己盯空间、定期 purge,否则磁盘迟早爆。它唯一合理场景是:需要临时保留 relay log 做逻辑回放分析(比如审计某条语句怎么执行的),但这种需求极少,且应配合监控和明确清理计划。
- 即使
relay_log_purge=ON,MySQL 也不会立刻删刚执行完的文件——它至少保留当前正在读的 + 下一个待读的两个文件,防止切换时出错 - 如果发现
Relay_Log_Space居高不下但Seconds_Behind_Master=0,大概率是 SQL 线程空闲但 relay log 文件还没轮到被 purge(比如刚重启过),等几分钟或手动PURGE一次即可 - 某些云厂商 RDS 默认禁用
PURGE权限,此时只能靠后台定时任务或联系支持,不能假设命令一定可用
误删 relay log 后还能恢复复制吗?
能,但代价高。只要主库 binlog 还在,就能重搭从库——本质是丢掉 relay log,重新拉一遍。关键不是“能不能”,而是“值不值得”。
- 如果只是删了几个旧文件,但
Relay_Master_Log_File和Exec_Master_Log_Pos对应的主库 binlog 还存在,执行CHANGE MASTER TO ... MASTER_LOG_FILE='xxx', MASTER_LOG_POS=yyy;再START SLAVE;就能续上 - 如果删的是当前正在读的文件(比如
Relay_Log_File显示为mysqld-relay-bin.000123,你却删了它),SQL 线程会报错Could not parse relay log event entry,此时必须跳过或重拉 - 最省事但最重的操作:
RESET SLAVE ALL;清空所有复制元数据,然后重新CHANGE MASTER TO—— 这相当于从头开始同步,适合积压严重且主库压力可控的场景
真正难处理的不是删文件本身,而是删完才发现主库 binlog 已过期(expire_logs_days 太小),这时候只能停写、导出主库全量再恢复,整个链路中断时间不可控。










