今天主要说说MySQL的异步复制、全同步复制和半同步复制。目前我们的生产库实际使用的是异步复制,后面会讲到切换到半同步复制。一、MYSQLReplication架构的推导历史2000年,MySQL3.23.15版本引入了Replication。复制作为一种准实时同步方法被广泛使用。Replicaton此时的实现涉及到两个线程,一个在Master,一个在Slave。Slave的I/O和SQL函数作为一个线程,从Master那里拿到event后直接申请,不需要relaylog。这样读取事件的速度就会被Slave的重放速度拖慢。当master和backup有较大的延迟时,大量的二进制日志不会备份到Slave。2002年MySQL4.0.2版本将Slave端的事件读取和执行分离成两个线程(IO线程和SQL线程),同时引入了relaylog。IO线程读取事件并写入中继日志,SQL线程从中继日志中读取事件并执行。这样即使SQL线程执行缓慢,Master的二进制日志也会尽可能同步到Slave。当Master宕机切换到Slave时,不会有大量数据丢失。在2010年的MySQL5.5之前,一直使用这种异步复制的方式。主库的事务执行不控制备库的同步进度。如果备库落后,主库不幸崩溃,就会造成数据丢失。因此,在MySQL5.5中,顺理成章地引入了半同步复制。主库需要保证至少有一个从库在响应客户端提交的事务之前接收和写入中继日志。2016年,MySQL在5.7.17引入了一项全新的技术,叫做InnoDBGroupReplication。目前MySQL5.7.17官方基于Group复制的全同步技术已经问世,全同步技术带来了更多的数据一致性保障。下图对应了MySQL复制的几种类型,即异步、半同步、全同步二、异步复制(Asynchronousreplication)1、从逻辑上讲,MySQL默认的复制是异步的。主库执行完客户端提交的事务后,会立即将结果返回给客户端,它并不关心从库是否接收并处理了,所以会出现问题,主要是crash丢了,master已经提交的transaction此时可能还没有传输到slave库,如果此时强行将slave提升为master,可能会导致新master上的数据不完整。2、技术上,主库将事务Binlog事件写入Binlog文件。此时主库只会通知Dump线程发送这些新的Binlog,然后主库会继续处理提交操作,但这些此时并不能保证。Binlog传递给任意一个从库节点。3、示意图(1)在Slave服务器上执行sartslave命令,打开主从复制开关,开始主从复制。(2)此时Slave服务器的IO线程会通过master上的授权复制用户权限请求连接到master服务器,并请求执行指定位置的binlog日志文件(日志文件名和location是配置主从复制服务的时候。(3)Master服务器收到Slave服务器IO线程的请求后,负责复制的IO线程会根据IO线程请求的信息批量读取Slave服务器的,获取指定binlog日志文件指定位置后的binlog日志信息,然后返回给Slave端的IO线程,返回的信息除了binlog日志内容外,还包括IO线程记录在Master服务器端,返回的信息中,除了binlog中下一个指定的更新位置。(4)当Slave服务器的IO线程获取到Master服务器上的IO线程发送的日志内容、日志文件、位置点时,会将binlog日志内容写入到Master服务器的RelayLog(中继日志)文件中Slave端依次(Mysql-relay-bin.xxx),并在master-info文件中记录新的binlog文件名和位置,以便master服务器告诉master服务器从指定文件中读取新的binlog日志以及开始读取新的binlog日志内容的位置(5)Slave服务器端的SQL线程会实时检测本地RelayLog中IO线程的新日志内容,然后解析RelayLOG文件中的内容及时转化为SQL语句,并在自己的Slave上按照SQL语句在服务器上解析位置的顺序执行应用的SQL语句,并记录当前应用中继登录的文件名和位置中继日志信息。三、完全同步复制(Fullysynchronousreplication)1.逻辑上是指主库执行完一个事务后,所有从库执行完事务再返回给客户端。因为需要等待所有从库都执行完事务才返回,全同步复制的性能必然会受到严重影响。2、技术上,主库提交交易后,所有从库节点都必须接收、APPLY并提交这些交易,然后主库线程才能继续做后续操作。但缺点是主库完成一个事务的时间会延长,性能会降低。三、示意图四、半同步复制(Semisynchronousreplication)1、从逻辑上讲,它是介于全同步复制和全异步复制之间的一种类型。主库只需要等待至少一个从节点接收并FlushBinlogtoRelayLog文件就足够了,主库不需要等待所有从库都反馈给主库。同时,这里只是一个收到的反馈,并不是一个已经完全完成并提交的反馈,这样可以节省很多时间。2.在异步复制和全同步复制之间的技术上,主库在执行完客户端提交的事务后不会立即返回客户端,而是等待至少一个从库接收并写入relaylog后才返回客户。与异步复制相比,半同步复制提高了数据的安全性,但也会造成一定程度的延迟,至少是一个TCP/IP往返时间。因此,半同步复制最适用于低延迟网络。3、示意图中master将每笔事务写入binlog(sync_binlog=1),传递给slave并刷新到磁盘(sync_relay=1),同时master库提交事务(犯罪)。master等待slave反馈收到relaylog,master收到ACK后才向client反馈commitOK结果。总之,mysql主从模式默认是异步复制,而MySQLCluster是同步复制。只要设置成对应的模式,就是使用对应的同步策略。从MySQL5.5开始,MySQL以插件的形式支持半同步复制。其实说明半同步复制是一种更好的方式,兼顾同步和性能问题。
