mysql数据库的复制架构与主从同步机制

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

MySQL 主从同步不是自动“实时一致”的管道,而是一套基于二进制日志(

binlog
)的异步/半同步复制机制;主库写入后,从库需拉取、重放日志才能追上——这意味着延迟、不一致窗口和潜在的数据断裂风险。

主从复制依赖 binlog 格式与执行模式

主库必须开启

binlog
,且格式直接影响从库重放行为和一致性保障能力:

STATEMENT
:记录 SQL 语句本身;在含
NOW()
UUID()
、用户变量等非确定性函数时,从库执行结果可能与主库不同
ROW
:记录每行数据变更前后的镜像;安全但体积大,尤其批量更新时
binlog
膨胀明显
MIXED
:默认混合模式,对非确定性语句自动切到
ROW
;但无法完全规避判断盲区,生产环境建议显式设为
ROW

确认当前格式:

SHOW VARIABLES LIKE 'binlog_format';
修改需在主库配置文件中设置
binlog_format = ROW
并重启(或动态生效,取决于 MySQL 版本)。

从库 IO 线程与 SQL 线程分工明确,各自可能中断

复制由两个独立线程协作完成,故障点也分离:

IO_THREAD
:连接主库,拉取
binlog
事件并写入本地
relay log
;中断常见于网络超时、主库权限不足(如复制用户无
REPLICATION SLAVE
权限)、主库
binlog
被清理(
expire_logs_days
过小)
SQL_THREAD
:读取
relay log
,逐条重放;中断多因语句冲突(如从库有同名表但结构不同)、DDL 与 DML 并发导致锁等待、或遇到
STOP SLAVE
后未手动恢复

检查状态用:

SHOW SLAVE STATUS\G
重点看
Slave_IO_Running
Slave_SQL_Running
是否均为
Yes
,以及
Seconds_Behind_Master
是否持续增长。

GTID 模式能简化故障恢复,但要求全集群统一启用

传统基于文件名+位置(

File
/
Position
)的复制,在主库切换或从库异常后需要人工计算偏移量;
GTID
(Global Transaction Identifier)为每个事务分配唯一 ID,使从库可自动定位并跳过已执行事务:

启用前需确保所有节点
gtid_mode = ON
enforce_gtid_consistency = ON
从库执行
CHANGE MASTER TO ... GTID_SET = ...
时,若
GTID_EXECUTED
不匹配,会报错
ERROR 1236 (HY000)
,此时需用
SET GLOBAL gtid_purged = '...'
手动补全(仅当确认缺失事务已丢失时才可操作)
GTID 下
RESET SLAVE
会清空
gtid_executed
,务必搭配
RESET SLAVE ALL
避免后续启动失败

查看当前 GTID 状态:

SELECT @@global.gtid_mode, @@global.gtid_executed;

半同步复制不能消除延迟,只约束主库提交行为

启用

rpl_semi_sync_master_enabled
后,主库
COMMIT
将阻塞直到至少一个从库确认收到
binlog
(而非执行完成),这能防止主库宕机后丢失已提交事务,但:

仍不保证从库已重放,
Seconds_Behind_Master
可能很大
若所有半同步从库失联,主库会自动退化为异步模式(由
rpl_semi_sync_master_timeout
控制超时时间)
性能敏感场景下,超时值设太小易频繁降级,设太大则拖慢主库响应

启用后验证:

SELECT plugin_name, plugin_status FROM information_schema.plugins WHERE plugin_name LIKE '%semi%';

真正难处理的是主库崩溃后如何选新主——GTID + MHA 或 Orchestrator 可自动完成,但切换过程中的脑裂、从库数据不完整、应用连接未及时刷新等问题,远比配置复制参数更消耗运维精力。

相关推荐