1、为什么需要主从同步

选择主从之前你可以考虑使用索引、优化SQL的方式来提高并发访问效率;其次是考虑使用Redis缓存,提高读取的速率;最后才是考虑使用主从架构,进行读写分离。

a、主从同步可以读写分离,我们可以通过主从复制的方式来进行数据同步,然后通过读写分离来提高数据库的并发能力。

简单来说就是同一份数据被放到了多个数据库中,其中一个数据库是Master,其余的多个数据库是Slave从库。当主库进行更新的时候,会自动将数据复制到从库中,而我们在客户端读取数据的时候,会从从库中进行读取,也就是采用读写分离的方式。同时,我们还能对服务器进行负载均衡,让不同的读请求按照策略均衡地分配到不同地服务器上,让读请求更加顺畅。读取顺畅另一个原因就是减少减少表锁的影响,比如我们在主库上加锁的时候,不会影响从库进行select读取。

b、数据备份,我们通过主从复制将主库上的数据复制到从库上,相当于是一种热备份,也就是在主库正常运行的情况下进行的备份,不会影响到服务。

c、高可用,当主库宕机的时候,可以切换到从服务器上,保证服务的正常运行。(99.999%)

2、主从同步的原理

提到主从同步的原理,我们久需要了解在数据库中的一个重要日志文件,那就是Binlog二进制日志,它记录了对数据库进行的更新操作。实际上主从同步的原理就是基于Binlog进行数据同步的。在主从复制的过程中,会基于三个线程来操作,一个主线程,两个从线程。

二进制日志转储线程(Binlog dump thread)是一个主线程。当从库线程连接的时候,主库可以将二进制日志发送给从库,当主库读取数据的时候,会在Binlog上加锁,读取完成后,再将锁释放掉。

从库I/O线程会连接到主库,向主库发送请求更新Binlog。这时从库的I/O线程就可以读取到主库的二进制日志转储线程发送的Binlog更新部分,并且拷贝到本地形成中继日志(Relay log)

从库SQL线程会读取从库中的中继日志,并且执行日志中的事件,从而将从库中的数据与主库保持一致。

数据库同步会连着索引一起同步吗 数据库同步问题_数据

所以你能看到的主从同步内容就是二进制日志(Binlog),它虽然叫二进制日志,实际上存储的是一个又一个事件(Event),这些事件分别对应着数据库的更新操作,比如insert,update,delete等。另外不是所有版本的Mysql都默认开启了二进制日志。

进行主从同步的内容是二进制日志,它是一个文件,在进行网络传输的过程中就一定会存在延迟,这样就有可能造成用户在丛库上读取的内容不是最新的数据,也就是主库与从库数据不一致的问题。

3、如何解决主从同步数据不一致的问题

可以想到,如果我们要操作的数据都存储在同一个数据库中,那么对数据进行更新的时候,可以对记录加写锁,这样在读取的时候就不会发生数据不一致的情况,但这时候从库的作用就是备份,并不能起到读写分离的作用。

数据库同步会连着索引一起同步吗 数据库同步问题_mysql_02

a、异步复制

异步复制是客户端提交commit之后不需要等待从库返回任何结果,而是直接将结果返回给客户端,这样做的好处就是不会影响主库写效率,但可能出现主库宕机,而Binlog还没有同步到从库的情况,也就是主库和从库数据不一致的情况,这时候再从从库里选择一个作为主库,那么新的主库可能缺少原来主库已提交的事务,所以这种复制模式的数据一致性最弱。

数据库同步会连着索引一起同步吗 数据库同步问题_sql_03

b、半同步复制

Mysql5.5之后开始支持半同步复制的方式。原理是在客户端提交commit之后不直接将结果返回客户端,而是等待至少有一个从库接收到了Binlog,并且写入到了中继日志中,再返回给客户端。这样做的好处就是提高了数据的一致性,相比于异步复制来说,至少增加了一个网络的延迟,降低了主库写的效率。

在Mysql5.7版本中还增加了rpl_semi_sync_master_wait_for_slave_count参数,我们可以对应答的从库数量进行设置,默认为1,也就是说只要有一个从库进行了响应,就可以返回给客户端,如果将这个参数调大,可以提高数据一致性的强度,但是也会增加主库等待从库响应的时间。

注意:半同步复制只是提高了数据的一致性,并不能保证主从数据完全一致

数据库同步会连着索引一起同步吗 数据库同步问题_数据库_04

c、组复制

组复制技术简称MGR(Mysql Group Replication)是在Mysql5.7.17版本中推出的一种新的数据复制技术,这种技术是基于Paxos协议的状态机复制。

首先,我们将多个节点共同组成一个复制组,在执行读写(RW)事务的时候,需要通过一致性协议层(Consensus层)的同意,也就是读写事务想要进行提交,必须经过组里“大多数人”(对应Node节点)的同意,大多数是过半节点(N/2+1),这样才可以进行提交,而不是原发起方一方说了算。而针对只读(RO)事务则不需要经过组内同意,直接commit即可。

在一个复制组内有多个节点组成,它们各自维护了自己的数据副本,并且在一致性协议层实现了原子消息和全局有序消息,从而保证组内数据的一致性。

数据库同步会连着索引一起同步吗 数据库同步问题_mysql_05

总结

数据库同步会连着索引一起同步吗 数据库同步问题_mysql_06