说说MySQL复制是咋回事,基本原理那些东西大概了解一下
- 问答
- 2026-01-19 00:37:38
- 2
(主要依据MySQL官方文档、高性能MySQL、MySQL技术内幕等资料综合整理)
MySQL复制,说白了就是让一台MySQL服务器(称为从库)自动地去同步另一台MySQL服务器(称为主库)上的数据,你可以把它想象成是一个不停工作的“抄写员”,主库那边每写一笔新账目,这个抄写员就赶紧把这笔账一模一样地抄到自己这边的小本本上,这样做的目的很简单,通常是为了做数据备份、提高系统的读能力,或者当主库出问题时能有个备用的顶上去。
核心角色:主与从
这个过程里有两个关键角色:
- 主库:就是那个原始的数据源,负责处理应用程序发来的所有写操作(比如增、删、改数据),它就像公司的总经理,所有重要的决策和变更都由它发出。
- 从库:是那个复制数据的一方,它主动去主库那里获取数据变动的信息,然后在自己身上重新执行一遍,从而保持数据和主库一致,它就像总经理的秘书,把总经理的每一个指令都记录下来并执行。
一台主库可以同时给很多台从库同步数据,反过来,一台从库一般情况下只能从一台主库同步数据(现在也有更复杂的多源复制,但那是后话了)。
复制的基本工作流程:三步走
MySQL的复制过程,本质上就是三个步骤的循环往复,这被概括为“三步复制模型”。
第一步:主库记录变更(写二进制日志) 当主库执行完一条会改变数据的SQL语句后(比如UPDATE、INSERT),它并不会直接通知从库,而是会把这个改动事件(Event)按照顺序写到一个特殊的日志文件里,这个文件就叫二进制日志,你可以把这个二进制日志想象成主库的“操作流水账”,里面详细记录了谁在什么时候做了什么改动,这是整个复制机制的基石。

第二步:从库获取日志(拉取日志事件) 从库上有一个专门的线程,叫做I/O线程,这个线程会主动跑到主库那里去,就像一个勤快的通讯员,它会对主库说:“嗨,老大,我上次抄到你流水账的第100条了,之后还有新的变动吗?”主库就会把从第100条之后新产生的二进制日志事件发送给这个I/O线程,I/O线程拿到这些新事件后,并不会立即执行,而是先把它们原封不动地保存到从库本地的另一个日志文件里,这个文件叫做中继日志,中继日志可以看作是主库二进制日志在从库的一个临时“快递中转站”。
第三步:从库执行变更(重放日志事件)
从库上还有另一个专门的线程,叫做SQL线程,这个线程的工作就是不停地检查本地的中继日志,一旦发现中继日志里有了新的内容(也就是I/O线程刚“快递”过来的那些事件),它就会立刻从中继日志里读取这些事件,然后按照事件记录的顺序,在从库的数据库上重新执行一遍对应的SQL语句,比如主库执行了一个INSERT INTO users VALUES (1, '张三'),那么SQL线程就在从库上也执行一遍一模一样的INSERT语句,这样,从库的数据就和主库保持一致了。
简单总结一下这个流水线:主库写Binlog -> 从库I/O线程拉取Binlog并存为Relay Log -> 从库SQL线程读取Relay Log并执行,这三个步骤持续不断地进行,就实现了数据的实时同步。
复制的关键点:异步机制
需要了解的是,MySQL默认的复制模式是异步的,这是什么意思呢?就是说,主库在写完二进制日志之后,就会认为这个事务已经提交成功了,然后就可以直接响应客户端的请求,它并不会等待从库是否已经成功接收并执行了这个事件。

这就像总经理下达一个指令后,就继续去忙别的事情了,他不会一直站在秘书旁边等着看她把指令抄完并执行完毕,这样做的好处是主库的性能非常高,不受从库速度快慢的影响,但带来的风险是,如果主库和从库之间的网络突然出现问题,或者从库压力太大处理慢了,就可能出现数据不一致的情况——主库的数据已经更新了,但从库的数据还没来得及更新,这种延迟我们称之为“复制延迟”。
复制格式的演变:记录什么内容?
在复制过程中,主库到底把“什么信息”写入二进制日志,再传给从库呢?这个问题很重要,MySQL在这方面也经历了演变。
- 基于语句的复制:最早的方式是,主库直接把执行的原始SQL语句(比如
UPDATE table SET name='abc')记录到二进制日志里,从库拿到后就直接执行这条SQL,这种方式日志量小,但有个大问题:如果SQL语句里包含不确定的函数,比如NOW()(获取当前时间)或者RAND()(随机数),在主库和从库上执行的结果可能不一样,导致数据不一致。 - 基于行的复制:后来更推荐的方式是,主库不再记录SQL语句本身,而是记录这条语句导致具体哪一行数据发生了怎样的变化,它不会记录
UPDATE table SET name='abc',而是记录“将第5行数据的name字段值从‘aaa’改成了‘abc’”,这种方式更精确,能避免不确定函数带来的问题,但缺点是如果一次更新了成千上万行,日志量会非常大。 - 混合模式复制:这是MySQL默认采用的智能方式,它通常使用基于语句的复制,但当它检测到某条语句可能引发不一致(比如使用了
UUID()函数)时,会自动切换为基于行的复制,兼有两种方式的优点。
复制有什么用?
了解了原理,就知道它为什么有用了:
- 数据备份与灾难恢复:最经典的用法,你可以用一台从库作为主库的“热备胎”,定期对从库进行备份,这样不会影响主库的性能,一旦主库磁盘损坏,可以很快地将从库提升为新的主库继续服务。
- 读写分离,提升性能:在网站应用中,读请求往往远大于写请求,我们可以让主库只负责处理写操作,而让多台从库来分担大量的读查询(比如报表生成、用户查询等),这样通过增加便宜的从库,就能有效地扩展整个数据库系统的读能力。
- 数据分析:可以给从库挂上一些复杂的分析查询,这些查询可能会跑很长时间并消耗大量资源,如果在主库上执行会影响正常业务,在从库上执行就完全没有问题。
MySQL复制是一个设计巧妙且非常实用的功能,它通过日志传递和重放这一相对简单的逻辑,实现了数据的冗余和服务的扩展,是构建高可用、高性能MySQL架构的基石,虽然现在有了更高级的组复制、InnoDB Cluster等技术,但其底层思想仍然离不开这个经典的“主从复制”模型。
本文由召安青于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/83351.html
