mysql主从怎么确保数据一致_Mysql-如何保证主从数据一致

要知道,Mysql 的主从使用的是 binlog 那样简单的 日志传输方式,来完成从库对主库的复制,虽然提高了效率,但是主库和从库之间并没有 raft 那样的协议来保证 主从一致。

有时候主库宕机,但是 binlog 还没有发出去,如果直接将从库切换为主库,那么将会主备不一致。

并且从库是单纯告诉主库,需要从主库的 binlog 的哪个偏移量开始 ,让主库发送 binlog 过来,所以很有可能因为偏移量不正确,导致从库得到的 binlog 是以前获得过的,导致重复的插入或者删除,使得从库因为错误终止运行。

Mysql 5.6 引入了 GTID ,启动这个模式:启动参数 + gtid_mode=on和enforce_gtid_consistency=on

Global Transaction ID , 可以唯一表示 一个集群中的事务(前提是这些集群中的机器的id 要相互不同),格式是 server_id : gno (数据库实例 id : 事务 id)

前者用来标识机器,后者用来在一台机器中唯一标识事务。

数据库会维护 一个 GTID 的集合,标识所有该数据库实例执行过的事务

于是有一种新的模式,从库把自己的 GTID 集合发送给 主库,主库检查 从库的 GTID 集合 和 自己 GTID 集合的差集,这个差集就是 主库需要给从库的 数据。

倘若从库要求的 GTID 集合在 主库上没有,那么可能是 主库删除了对应的 binlog,主库会报错(但是如果是从库自己在 成为从库前 执行了一些事务,这些事务的 GTID 也会被发给主库吗?如果发的话不就必然报错?)(其实可以 在从库上使用命令 : set global gtid_purged = '24024e52-bd95-11e4-9c6d-926853670d0b:1 - N';       来告诉从库,哪些binlog 已经被 purge 了,不要再发给主库了,不要再向主库索要了 ,注意上面的 gno 是 1 - N 这种格式 ,只有事务提交了,才能使 gno + 1)

一般的 gtid 是递增的,gtid_next=automatic 可以设置递增。

也可以自己设置 set gtid_next='aaaaaaaa-cccc-dddd-eeee-ffffffffffff:10';

这样的话,被设置的机器 若执行下一个事务,这个事务 使用的 gtid 就是上面手工设置的 gtid。

假如有 互为 主从的 两个库 A B ,现在的写请求都是打到 A 上的,假如要加索引,又不想影响A 上的效率

1.先 停掉 B 向 A 发送 binlog

2.在 从库 B 上,加索引,假设这条 加索引的 DDL 的 GID 是 B:X

3.在 主库 A 上,设置 gid_next = A:X , 并且执行一个空事务(在设置 gid_next = A:X 到执行空事务期间,可不可能有其他的事务抢占,哦,好像就算被抢了也无所谓,反正我们要做的只是让这个gid 对应的 DDL 不被执行)

4. A 重新认 B 为 主库,会发送 A 的 GID 集合(这期间没有停止 A 向 B 发送 binlog,所以 B 的 gid 集合应该和 A 一致,所以不会报错),A 从 B 那里获取 B 的 gid 集合,因为之前已经执行过那条 DDL 语句对应事务的 gtid 代表的假事务,所以不会执行 这条 DDL。

把写请求打到 库 B 上,并且再来一次刚才的过程,只不过这次反过来,B 是之前的 A ,A 是之前的 B。

5. 最后 A 和 B 上 都有了 索引。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值