relay_log写满磁盘会导致sql线程立即退出、复制彻底中断,必须停sql_thread后清理旧文件并迁移路径;expire_logs_days对relay_log无效,因其仅控制binlog,relay_log依赖relay_log_purge和sql线程推进自动清理。

直接结论:relay_log 写满磁盘不是“延迟高”,是 SQL 线程立刻退出、复制彻底中断——必须停线程 + 迁路径,不能只删文件或调 expire_logs_days。
为什么 expire_logs_days 对 relay_log 完全无效
因为 expire_logs_days 只控制主库的 binlog,而从库的 relay_log 有自己的清理逻辑:它依赖 relay_log_purge=ON(默认开启)和 SQL 线程推进位置来自动删除旧文件。一旦 SQL 线程卡住(比如遇到大事务、DDL 锁、表损坏),relay_log 就停止被 purge,文件持续堆积。更致命的是,默认和 datadir 共用同一分区,主库写入不停 + 从库消费不动 → 磁盘瞬间打满。
错误日志里典型表现:ERROR 1594 (HY000): Relay log read failure 或操作系统级报错:OS error code 28: No space left on device。
紧急止血:手动清理前必须停 SQL_THREAD
不先停线程就删文件,极大概率导致复制错位或启动失败。操作顺序不能错:
-
STOP SLAVE SQL_THREAD;—— 只停 SQL 线程,保留 IO 线程继续拉取 binlog(避免主库新事件丢失) - 查当前正在用的 relay log:
SHOW SLAVE STATUS\G中看Relay_Log_File和Relay_Log_Pos - 进
datadir目录,ls -lt mysql-relay-bin.*排序,只删比Relay_Log_File编号更小的旧文件(例如当前是mysql-relay-bin.000012,可删.000001到.000011) - 绝对不要删
mysql-relay-bin.index,也别碰正在写的那个Relay_Log_File -
START SLAVE SQL_THREAD;后观察Slave_SQL_Running是否恢复为Yes
根治方案:把 relay_log 和 relay_log_index 迁到独立挂载点
这是唯一长期可靠的方式。迁移不是改配置重启那么简单,MySQL 启动时会校验索引文件路径,顺序或权限错一步就会拒绝启动:
-
STOP SLAVE;,确认Seconds_Behind_Master = 0或已追平 - 记下
Relay_Master_Log_File和Exec_Master_Log_Pos(后续验证一致性用) - 新建目录如
/data/relaylog,确保属主为mysql、权限750 - 在
my.cnf的[mysqld]段添加两行:relay_log = /data/relaylog/mysql-relay-bin,relay_log_index = /data/relaylog/mysql-relay-bin.index - 重启
mysqld,启动成功后立刻执行START SLAVE;,再SHOW SLAVE STATUS\G确认两个线程都为Yes
注意:不要手动拷旧 relay_log 文件过去,MySQL 启动时会自动初始化新索引并从正确位置开始写入。
最容易手抖误删的危险文件:别碰 ibdata1 和 ib_logfile*
磁盘满时人容易慌,看到大文件就想删。但 ibdata1 是 InnoDB 共享表空间,删了等于删库;ib_logfile0/ib_logfile1 是 redo log,MySQL 启动时强制校验大小,删了会导致启动失败,报错类似:InnoDB: Error。监控必须单独加一条:df -h 对 relay_log 所在路径做告警,不能只盯 datadir。











