Mysql的复制主要分为以下几种:
1 异步复制:mysql默认的复制是异步复制,主库在执行完客户端提交的事务后立即将结果返回给客户端,并不关心从库是否已经接受并处理,
这样,如果主库crash掉了,此时主库上已经提交的事务可能并没有传到从库上,此时,如果强行将从库提升为主,可能导致新主库数据不完整。
后果:如果主服务器宕机时可能会导致数据丢失严重。
这里要说说一个参数:sync_binlog=1 它表示在事务提交之前,Mysql都需要先把binlog刷新到磁盘上,这样的话,即使出现数据库主机宕机,系统最多损失prepared状态的事务,
如下是异步复制关系图:
2 semi-sync replication(半同步复制)
异步复制中主库和从库的数据之间难免会存在一定的延迟,这样会有出现一种情况:当在主库上写入一个事务并提交成功,而从库尚未得到主库的binlog日志(为什么没有得到?),主库由于各种原因宕机,导致主库上该事务binlog丢失,此时从库(这是会提升为主库)就会损失这个事务,从而造成主从不一致(修复后的主库会变成从库),因此为了解决这个问题,从Mysql5.5开始,就开始引入半同步复制,半同步为了保证主库上每一个binlog事务都能够被可靠的复制到从库上,主库在每次事务成功提交后,并不及时反馈给前端应用用户,而是等待至少一个从库(rpl_semi_sync_master_wait_for_slave_count)也能接受到binlog事务成功写入中继日志,主库才返回Commit操作给客户端。
也就是说半同步复制保证事务成功提交后,至少有两份日志记录,一份在主库的binlog日志上,另一份在至少一个从库的中继日志relay_log上,从而更进一步保证了数据的完整性。
在传统的半同步复制中,主库写数据到binlog,且执行commit操作后,会一直等待从库的ACK,即从库写入relay log 后,并将数据落盘,返回给主库消息,通知主库可以返回前端
应用操作成功。但是这样会出现一个问题,就是实际上主库已经将该事务Commit到了事务引擎层,应用已经可以看到数据发生了变化,只是等待返回而已,如果此时主库宕机,
有可能从库还没能写入relay log ,就会发生主从库不一致的情况,
后果:1.至少有一个从库收到binlog再返回 2.减少数据丢失风险 3.不能完全避免数据丢失 4.Mysql5.5版本开始支持 loss-less semi-sync replication(增强型半同步)
增强型半同步是对半同步做了微调,即主库写数据到binlog后,就开始等待从库的应答,直到至少一个从库写入relay log 后,并将数据落盘,然后返回给主库消息,
通过主库可以执行commit操作,然后主库开始提交到事务引擎层,应用此时可以看到数据发生了变化。
后果:1.二进制日志先写远程 2 可保证数据完全不丢失 3 mysql5.7版本开始支持
半同步复制模式下,假如传送binlog日志到从库时,从库宕机或者网络延时,导致binlog并没有及时地传送到从库中,此时主库上的事务会等待一段时间,时间长度由参数rpl_semi_sync_master_timeout设置的毫秒数决定,如果binlog在这段时间内都无法成功发送到从库上,则mysql自动调整复制模式为异步模式,事务正常返回提交个客户
半同步复制很大程度上取决于主从库之间的网络情况,往返时延RTT越小决定了从库的实时性越好,通俗地说,主从库之间的网络越快,从库越实时。
配置:
半同步复制搭建需要安装插件:
加载插件 主: INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; 从: INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; 查看是否加载成功: show plugins; 启动: 主: SET GLOBAL rpl_semi_sync_master_enabled = 1; 从: SET GLOBAL rpl_semi_sync_slave_enabled = 1; 重启从库上的IO线程 STOP SLAVE IO_THREAD; START SLAVE IO_THREAD; 查看是否在运行 主: show status like 'Rpl_semi_sync_master_status'; 从: show status like 'Rpl_semi_sync_slave_status';
组复制:之前上面说的不管是异步复制还是半同步复制,他们都不能完全解决数据丢失的问题,首先异步复制不用说,可能有数据丢失的问题,那么增强型半同步呢?其实增强型半同步只是保证了当主库提交事务后,binlog日志可以传到从库并写入relay log日志中,但是对于应用(重放)relay log的过程,从库还是异步进行的,因此,从库最后是否能应用这个事务还看apply过程是不是顺利进行,所以就出现了组复制这种技术来进行的
Mysql组复制是基于传统异步复制和半同步复制的缺陷——数据的一致性问题无法保证,MySQL官方在5.7.17版本正式推出组复制(MySQL Group Replication,简称MGR)
由若干个节点共同组成一个复制组,一个事务的提交,必须经过组内大多数节点(N / 2 + 1)决议并通过,才能得以提交。如上图所示,由3个节点组成一个复制组,Consensus层为一致性协议层,在事务提交过程中,发生组间通讯,由2个节点决议(certify)通过这个事务,事务才能够最终得以提交并响应。
引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。组复制依靠分布式一致性协议(Paxos协议的变体),实现了分布式下数据的最终一致性,提供了真正的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案带来了希望。
一个复制组由若干个节点(数据库实例)组成,组内各个节点维护各自的数据副本(Share Nothing),通过一致性协议实现原子消息和全局有序消息,来实现组内实例数据的一致。
MGR的解决方案目前的一些局限性
1.仅支持InnoDB表,并且每张表一定要有一个主键,用于做write set的冲突检测;
2.必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set
3.COMMIT可能会导致失败,类似于快照事务隔离级别的失败场景
4.目前一个MGR集群最多支持9个节点
5.不支持外键于save point特性,无法做全局间的约束检测与部分部分回滚
6.二进制日志不支持binlog event checksum
MGR方案对数据库的一些要求
1 innodb引擎
在MySQL Group Replication中,事务以乐观形式执行,但是在提交时检查冲突,如果存在冲突,则会在某些实例上回滚事务,保持各个实例的数据一致性,那么,这就需要使用到 事务存储引擎,同事Innodb提供一些额外的功能,可以更好的管理和处理冲突,所以建议业务使用表格使用inndb存储引擎,类似于系统表格mysql.user使用MyISAM引擎的表格,因为极少修改及添加,极少出现冲突情况。
2 主键
每个需要复制的表格都必须定义一个显式主键,注意跟隐式主键区分(使用Innodb引擎的表格,如果没有指定主键,默认选择第一个非空的唯一索引作为主键,如果没有,则自动创建一个6个字节的rowid隐式主键)。这个主键能在冲突发生时启动极其重要的作用,同时,能够有效提高relay log的执行效率。
3 隔离级别
官网建议使用READ COMMITTED级别,除非应用程序依赖于REPLEATABLE READ,RC模式下没有GAP LOCK,比较好支持Innodb本身的冲突检测机制何组复制的内部分布式检测机制一起协同工作。不支持SERIALIZABLE隔离级别。
4 外键
不建议使用级联外键,如果旧库本身有外键,业务上无法去除并且使用的是多主模式,那么,请配置 group_replication_enforce_update_everywhere_check ,强制检查每个组成员的级联检查,避免多主模式下执行级联操作造成的检测不到的冲突
参考文章:https://blog.csdn.net/HD243608836/article/details/110120638