MySQL 的主从复制基于 binlog 实现,其主要过程如下:
图片
- 从服务器在开启主从复制后,将会创建两个线程:I/O 线程与 SQL 线程。
- 从服务器的 I/O 线程会尝试与主服务器建立连接,主服务器中则有一个专门与从服务器的 I/O 线程进行交互的 binlog dump 线程。
- 从服务器的 I/O 线程会向主服务器的 dump 线程指明其接收 binlog 的起始位置。
- 在主服务器的更新过程中,更改记录会被保存到其 binlog 中,依据不同的 binlog 格式,记录的内容可能有所不同。
- 当 dump 线程检测到 binlog 发生变化时,将从指定位置开始读取内容,并由从服务器的 I/O 线程将其拉取过来。
这里需要注意的是,尽管某些资料提到主服务器向从服务器推送数据,实际上,过程是从服务器主动向主服务器拉取的。(https://dev.mysql.com/doc/refman/8.0/en/replication-implementation.html)
拉的模式,从库可以自行管理同步进度和处理延迟。
- 从服务器的 I/O 线程在接收到通知事件后,会将内容保存至 relay log 中。
- 从服务器的 SQL 线程则会不断读取自身的 relay log,将内容解析为具体操作,并将其写入数据表中。
复制方式
MySQL 目前支持多种复制方式,包括全同步复制、异步复制和半同步复制。
异步复制:这是 MySQL 的默认复制方式。在异步复制中,主库在执行完事务后会立即向客户端返回,无需关心从库是否完成该事务的执行。这种方式可能导致问题:当主库发生故障时,尽管事务已执行完毕,但数据可能尚未同步至从库,导致从库在升级为主库时丢失此次事务的变更内容。
全同步复制:在全同步复制模式下,主库在完成事务后,会等待所有从库完成数据复制后,才向客户端反馈。这种方式虽然提高了安全性,但性能较差,尤其在从库数量较多时,整个过程将显得更加漫长。
半同步复制:半同步复制介于全同步与异步之间。当主库执行完事务后,它不会立即反馈给客户端,而是等待至少一个从库完成接收事件后再反馈。在这一方案中,主库会在事务提交的两个阶段完成后,等待从库接收到 binlog 后,再返回成功。
在上面这篇中所绘制的图示中,如果将半同步复制的过程也纳入其中,那么图示将会变为:
图片