mysql主从复制中的binlog和relaylog有什么作用_日志机制解析

来源:这里教程网 时间:2026-02-28 20:49:42 作者:

binlog 是主库的“操作录像带”,必须开启才能复制

主库不写

binlog
,从库就完全收不到任何变更——这是主从复制的硬性前提。它不是可选功能,而是整个复制链路的源头。MySQL 默认关闭
binlog
,必须显式配置
log-bin=binlog
(文件名可自定义)并重启生效。常见错误是只改了配置但忘了重启 mysqld,结果
SHOW VARIABLES LIKE 'log_bin';
仍返回
OFF
,同步必然失败。

另外,

binlog_format
推荐设为
ROW
:它记录每一行数据的实际变化,避免
STATEMENT
模式下因函数(如
NOW()
UUID()
)或非确定性语句导致主从数据不一致。虽然日志体积变大,但数据一致性有保障,生产环境几乎无例外。

relaylog 是从库的“本地待办清单”,由 IO 线程写入

从库的

IO_THREAD
连上主库后,会持续拉取
binlog
内容,并原样写入本地的
relay-log
文件(如
relay-bin.000001
),这个过程不解析、不执行,只是搬运。关键点在于:
relay-log
不是永久存储,而是中转站——一旦
SQL_THREAD
执行完某段日志,对应内容就会被自动清理(除非手动配置
relay_log_purge=OFF
)。

常见误操作是直接删

relay-log
文件。这会导致
SQL_THREAD
找不到执行位置而报错
Could not parse relay log event entry
。正确做法是用
RESET SLAVE
(清空所有中继日志 + 重置复制坐标)或
RESET SLAVE ALL
(额外清除
master.info
等元数据)。

两个日志的生命周期和角色完全不同

binlog
在主库上长期保留(受
expire_logs_days
控制),既用于复制,也用于备份恢复(
mysqlbinlog
回放);而
relay-log
只存在于从库,纯属复制中间产物,生命周期由 SQL 线程推进进度决定。

它们还分属不同线程管理:

binlog
由主库的
Binlog Dump Thread
向外推送;
relay-log
由从库的
IO_THREAD
接收写入,再由
SQL_THREAD
读取执行。如果
SHOW SLAVE STATUS\G
中看到
Seconds_Behind_Master
持续增长,大概率是
SQL_THREAD
执行慢(比如大事务、锁争用),而不是网络或
IO_THREAD
问题。

查日志时别搞混命令和路径

看主库

binlog
:用
mysqlbinlog /var/lib/mysql/binlog.000001
(路径以
datadir
log_bin
配置为准);

看从库

relay-log
:同样用
mysqlbinlog /var/lib/mysql/relay-bin.000001
,但要注意文件名前缀由
relay_log
参数定义,默认是
relay-bin

查当前坐标:主库用

SHOW MASTER STATUS;
,从库用
SHOW SLAVE STATUS\G
中的
Relay_Master_Log_File
Exec_Master_Log_Pos
—— 这俩才是实际已执行到主库 binlog 的位置,不是
Relay_Log_File
Relay_Log_Pos
(那是中继日志自身偏移)。

最容易忽略的是:

relay-log
的索引文件(如
relay-bin.index
)必须和日志文件保持一致,否则启动时可能找不到最新文件,导致复制中断。这个文件不能手动编辑,全靠 MySQL 自动维护。

相关推荐