最近被问道,关于建设一个MySQL的集群的方案,当时真的是不太清楚,在底下简单的了解了一下,今天分享一下主库(Master)和从库(Slave)之间的数据同步方式。
下图是MySQL的复制演示图:
上图可以简单的总结为三步:
- 主库将更改记录保存到二进制日志文件中
- 从库将主库上的日志复制到自己的中继日志中
- 从库读取中继日志并将日志中记录的事件重放(更新)到自己的数据库之中。
第一步:将更改记录保存到日志文件
在准备提交事务完成数据更新之前,主库会将数据更新事件记录到二进制日志文件中,二进制日志文件的记录顺序是按事务提交的顺序而非SQL语句执行的顺序。
只有在日志记录完成之后,存储引擎才对数据进行更新。
第二步:从库将主库上的日志复制到自己的中继日志中
从库在将主库中的日志文件复制到自己的中继日志中前,会开启一个I/O线程,I/O线程用来与主库之间建立数据连接,同时,主库中会开启一个二进制转储线程,二进制转储线程用来监控主库中二进制日志文件中的事件,当二进制日志文件中有新的事件发生,即当二进制日志中发生更改后,二进制转储线程会将更改的内容发送到从库,I/O线程接受发送的内容,并保存到中继日志中。当主库中没有事件发生时,二进制转储线程会自动进入休眠状态,当二进制日志文件有新的事件发生时,其又会被重新唤醒。
第三步:从库读取中继日志并将日志中记录的事件重放(更新)到自己的数据库之中
从库在启动I/O线程的同时,还会启动一个SQL线程,SQL线程用于将中继日志中的内容更新到数据库中,从而保证主从库之间的数据一致性。
同时,我们也可以设置,跳过中继日志文件这个过程,当二进制转储线程将文件内容发送过来的时候,I/O线程接受到以后,直接交付给SQL线程,这样做的优点是尽可能的减小了主从库之间的内容差异,从而对于实时性要求比较高的业务比较有利。但同时,其缺点也是显而易见的,比如主从库的业务都特别繁忙,从库除了要处理来自外部的请求任务之外,还需要及时的将主库传送来的事件更新到自己的数据库中,这样就使从库更加的繁忙。对于实时性要求不是那么高的业务,我们可以在从库业务繁忙时,将事件暂时的保存到中继文件中,待到业务少的时候,再一点点的将事件更新的数据库中。