MySQL通过 3个线程来完成主从库间的数据复制:其中Binlog Dump线程跑在主库上, I/O线程和SQL线程跑在从库上。当在从库上启动复制(START SLAVE)时,首先创建 I/O线程连接主库,主库随后创建Binlog Dump线程读取数据库事件并发送给 I/O线程,I/O线程获取到事件数据后更新到从库的中继日志Relay Log中去,之后从库上的SQL线程读取中继日志Relay Log中更新的数据库事件并应用.

MySQL 的复制是主库主动推送日志到从库去的,是属于“推”日志的方式来做同步

同样地,在从库上通过SHOW PROCESSLIST可以看到 I/O线程和SQL线程,I/O线程等待主库上的Binlog Dump线程发送事件并更新到中继日志Relay Log,SQL线程读取中继日志Relay Log并应用变更到数据库.

从MySQL的复制流程可以了解到MySQL的复制是异步的。从库上的数据和主库存在一定的延时。

二进制日志文件(Binlog)会把 MySQL 中的所有数据修改操作以二进制的形式记录到日志文件中,包括Create、Drop、Insert、Update、Delete操作等,但二进制日志文件(Binlog)不会记录Select操作,因为Select操作并不修改数据.

中继日志文件Relay Log的文件格式、内容和二进制日志文件Binlog一样,唯一的区别在于从库上的SQL线程在执行完当前中继日志文件Relay Log中的事件之后,SQL线程会自动删除当前中继日志文件Relay Log,避免从库上的中继日志文件Relay Log占用过多的磁盘空间。

为了保证从库Crash重启之后,从库的I/O线程和SQL线程仍然能够知道从哪里开始复制,从库上默认还会创建两个日志文件master.info和relay-log.info用来保存复制的进度。这两个文件在磁盘上以文件形式分别记录了从库的 I/O 线程当前读取主库二进制日志 Binlog 的进度和SQL线程应用中继日志Relay Log的进度。

在MySQL 5.5之前的异步复制时,主库执行完 Commit 提交操作后,在主库写入 Binlog 日志后即可成功返回客户端,无需等待Binlog日志传送给从库.

而半同步复制时,为了保证主库上的每一个 Binlog 事务都能够被可靠的复制到从库上,主库在每次事务成功提交时,并不及时反馈给前端应用用户,而是等待其中一个从库也接收到 Binlog事务并成功写入中继日志后,主库才返回Commit操作成功给客户端。半同步复制保证了事务成功提交后,至少有两份日志记录,一份在主库的 Binlog 日志上,另一份在至少一个从库的中继日志Relay Log上,从而更进一步保证了数据的完整性。