首页 > 数据库 >mysql主从复制模式

mysql主从复制模式

时间:2022-10-30 17:45:05浏览次数:44  
标签:主从复制 同步 Slave 事务 模式 复制 mysql 从库 GTID

转自:https://www.cnblogs.com/jimoer/p/14673646.html,https://juejin.cn/post/6844903921677238285

1.模式

1.1 异步复制

MySQL的默认复制模式,主要是指MySQL的主服务器上的I/O线程,将数据写到binlong中就直接返回给客户端数据更新成功,不考虑数据是否传输到从服务器,以及是否写入到relaylog中。

风险:一旦数据只写到了主库的binlog中还没来得急同步到从库时,主库挂了,从库就就会被强行提升为主库,就会造成数据的丢失。但高效。

1.2 半同步复制

  • 同步模式:当主库执行完客户端提交的事务后,需要等到所有从库也都执行完这一事务后,才返回给客户端执行成功。因为要等到所有从库都执行完,执行过程中会被阻塞,等待返回结果,所以性能上会有很严重的影响。
  • 半同步复制模式:主库在执行完客户端提交的事务后,要等待至少一个从库接收到binlog并将数据写入到relay log中才返回给客户端成功结果。半同步复制模式,比异步模式提高了数据的可用性,但是也产生了一定的性能延迟,最少要一个TCP/IP连接的往返时间。所以,半同步复制最好在低延时的网络中使用。

在master的dump线程去通知从库时,增加了一个ACK机制,也就是会确认从库是否收到事务的标志码,master的dump线程不但要发送binlog到从库,还有负责接收slave的ACK。当出现异常时,Slave没有ACK事务,出现等待超时的情况,那么将自动降级为异步复制,直到异常修复后再自动变为半同步复制。

风险

事务在主库提交完后等待从库ACK的过程中,如果Master宕机了,这个时候就会有两种情况的问题:

  • 事务还没发送到Slave上:若事务还没发送Slave上,客户端在收到失败结果后,会重新提交事务,因为重新提交的事务是在新的Master上执行的,所以会执行成功,后面若是之前的Master恢复后,会以Slave的身份加入到集群中,这个时候,之前的事务就会被执行两次,第一次是之前此台机器作为Master的时候执行的,第二次是做为Slave后从主库中同步过来的。【为什么客户端收到失败结果后会重新提交事务?事务不是已经提交了吗,只不过没有等到ACK。】
  • 事务已经同步到Slave上:因为事务已经同步到Slave了,所以当客户端收到失败结果后,再次提交事务,你那么此事务就会再当前Slave机器上执行两次。

改进:

MySQL从5.7版本开始,增加了一种新的半同步方式。新的半同步方式的执行过程是将“Storage Commit”这一步移动到了“Write Slave dump”后面。这样保证了只有Slave的事务ACK后,才提交主库事务。【就是之前先提交commit再同步,现在是先保证同步了再commit】。MySQL从5.7.2版本开始,默认的半同步复制方式就是AFTER_SYNC方式,但这种同步方式可能会存在slave多数据的情况。

2.3 GTID

在传统的复制里面,当发生故障,需要主从切换,需要找到 Binlog 和 位点信息【???什么意思?】,恢复完成数据之后将主节点指向新的主节点。在原来基于日志的复制中,从库需要告知主库要从哪个偏移量进行增量同步, 如果指定错误会造成数据的遗漏,从而造成数据的不一致。

从5.6版本开始推出了GTID复制模式,只需要知道主节点的 IP、端口以及账号密码就行,因为复制是自动的,自我寻找复制位置。全局事务ID (global transaction identifier):

GTID = UUID + TransactionId
  1. UUID:单个MySQL实例的唯一标识,在第一次启动MySQL实例时会自动生成一个server_uuid,并会持久化到文件;
  2. TransactionId:事务标识,在每台 MySQL 服务器上都是从 1 开始自增长的序列。这样保证了GTID在一组复制中,全局唯一

优点:

基于GTID在一组主从复制集群中的唯一性,从而保证了每个GTID的事务只在一个MySQL上执行一次。通过全局的事务 ID 确定从库要执行的事务的方式代替了以前需要用 Binlog 和 位点确定从库要执行的事务的方式

GTID 在每次事务提交时自动生成,在实际的更新事务记录之前将 GTID 写入到 Binlog。

流程:

  1. master更新数据时,在事务前生产GTID,一同记录到binlog中。
  2. slave端的i/o线程,将变更的binlog写入到relay log中。
  3. sql线程从relay log中获取GTID,然后对比Slave端的binlog是否有记录。
  4. 如果有记录,说明该GTID的事务已经执行,slave会忽略该GTID。
  5. 如果没有记录,Slave会从relay log中执行该GTID事务,并记录到binlog。
  6. 在解析过程中,判断是否有主键,如果没有主键就使用二级索引,再没有二级索引就扫描全表。

缺点:

  1. 首先不支持非事务的存储引擎;
  2. 不支持create table ... select 语句复制(主库直接报错);(原理: 会生成两个sql, 一个是DDL创建表SQL, 一个是insert into 插入数据的sql; 由于DDL会导致自动提交, 所以这个sql至少需要两个GTID, 但是GTID模式下, 只能给这个sql生成一个GTID);
  3. 在一个事务里面混合使用引擎,如 Innodb(支持事务)、MyISAM(不支持事务), 造成多个 GTIDs 和同一个事务相关联出错;
  4. 在一个MySQL复制群组中,要求全部开启GTID或关闭GTID。

 

标签:主从复制,同步,Slave,事务,模式,复制,mysql,从库,GTID
From: https://www.cnblogs.com/BlueBlueSea/p/16841773.html

相关文章