前言
说到主从,我相信大家在 MySQL 这一节面试经常被问到MySQL 的主从复制原理
,而且大家背得滚瓜烂熟。但是在主从复制的过程中,是如何进程数据同步的,又涉及到了哪些线程呢?这些线程又是充当的什么角色呢?
首先,MySQL 有如下几种复制模式:
- 主从复制模式:A - - > B
- 主主复制模式:A < - - > B
- 链式复制模式:A - - > B - - > C
- 环形复制模式:A - - > B - - > C - - > A
生产环境中一般建议部署为主从模式
,这也是比较稳健的一种 MySQL 复制方式,如果想实现一定程度上的高可用,可选择使用主主模式,但是主主模式必须确保任何一个时刻都只有一个数据库是 Active 状态(即读写状态),另一个数据库作为备用,否则就要解决自增键/主键
的冲突问题。
一、主从同步原理
简单的主从复制基本原理如下:
- 主库将更新写入二进制文件,并维护文件的一个索引来跟踪日志循环;
- 从库复制主库的二进制日志事件到本地的中继日志(relay log);
- 从库重放中继日志实现与主库的数据同步。
这里不进行深入的源码分析,有兴趣的自行查阅官方文档。
二、主从同步分析
MySQL 使用 3 个线程来实现同步(复制)功能,一个线程在主库上,另两个线程在从库上。
当从库执行 start slave
指令时,从库将创建一个 I/O 线程,该线程用于连接主库并让主库发送记录在其二进制日志(主库二进制日志)中的语句。此时,主库会创建一个线程将其二进制日志的内容发送到从库,如下图,就是其创建的线程,有两个线程,是因为我的 MySQL 复制是双主双从架构(关于如何部署双主,可看看我前面的博文《基于 Docker 的 MySQL GTID 主从复制与测试》),下图是在某个一个主库上查询的,因此它有两个从库,所有就会生成两个 Binlog Dump 线程,该线程会发送更新的二进制内容到从库,并等待新的二进制日志更新,有更新就会推送。
show processlist\G
然后从库的 I/O 线程读取主库 Binlog Dump 线程发送的内容并将读取的数据存储到从库的中继日志文件中,最后从库的 SQL 线程会将中继日志中的事件重演并最终落盘。I/O 线程与 SQL 线程位于从库上,如下图:
而且要确保这两个线程均处于 Yes
状态,才能实现主从复制。
以上就是 MySQL 主从复制过程涉及到的三个线程!