正常情况下,只要主库执行更新生成的所有 binlog,都可以传到备库并被正确地执行,备库就能达到跟主库一致的状态,这就是最终一致性。
MySQL 主备切换流程 – 双 M 结构:
主备切换可能是一个主动运维动作,比如软件升级、主库所在机器按计划下线等,也可能是被动操作,比如主库所在机器掉电。
数据同步的有关时间点:
所谓主备延迟,就是同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值,也就是 T3-T1。
可以在备库上执行 show slave status 命令,它的返回结果里面会显示 seconds_behind_master,用于表示当前备库延迟了多少秒
但实际上,更新过程中也会触发大量的读操作。所以,当备库主机上的多个备库都在争抢资源的时候,就可能会导致主备延迟了.
当然,这种部署现在比较少了。因为主备可能发生切换,备库随时可能变成主库,所以主备库选用相同规格的机器,并且做对称部署,是现在比较常见的情况。
由于主库直接影响业务,大家使用起来会比较克制,反而忽视了备库的压力控制。结果就是,备库上的查询耗费了大量的 CPU 资源,影响了同步速度,造成主备延迟。
解决:
出现情况: 主库上必须等事务执行完成才会写入 binlog,再传给备库。所以,如果一个主库上的语句执行 10 分钟,那这个事务很可能就会导致从库延迟 10 分钟。 场景:
由于主备延迟的存在,所以在主备切换的时候,就相应的有不同的策略。
上图双M的结构下,从状态 1 到状态 2 切换的详细过程是这样的:
切换流程一般由专门的HA系统来完成。 切换流程:
可以看到,这个切换流程中是有不可用时间的。因为在步骤 2 之后,主库 A 和备库 B 都处于 readonly 状态,也就是说这时系统处于不可写状态,直到步骤 5 完成后才能恢复。
在这个不可用状态中,比较耗费时间的是步骤 3,可能需要耗费好几秒的时间。这也是为什么需要在步骤 1 先做判断,确保 seconds_behind_master 的值足够小。
试想如果一开始主备延迟就长达 30 分钟,而不先做判断直接切换的话,系统的不可用时间就会长达 30 分钟,这种情况一般业务都是不可接受的。
上述 如果强行把步骤 4、5 调整到最开始执行,也就是说不等主备数据同步,直接把连接切到备库 B,并且让备库 B 可以读写,那么系统几乎就没有不可用时间了。这算一种可用性策略。
可用性存在产生数据不一致的情况: 假如有表:
mysql> CREATE TABLE `t` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`c` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
insert into t(c) values(1),(2),(3);
初始化数据后,主库和备考都是3行数据,然后继续执行下面这两句:
insert into t(c) values(4);
insert into t(c) values(5);
假设主库有大量的数据更新,导致主备延迟达到5秒,在插入一条c=4的时候,发起了主备切换。且 binlog_format=mixed,流程如下:
最后的结果就是,主库 A 和备库 B上出现了两行不一致的数据。可以看到,这个数据不一致,是由可用性优先流程导致的。
采用可靠性优先策略的话,你就必须得等到备库 B 的seconds_behind_master=0 之后,才能切换。但是以数据内容为重,选择可靠性策略好一点。
总结:
①首先,有些部署条件下,备库所在机器的性能要比主库所在的机器性能差,原因多个备库部署在同一台机器上,大量的查询会导致io资源的竞争,解决办法是配置”双1“,redo log和binlog都只write fs page cache②备库的压力大,产生的原因大量的查询操作在备库操作,耗费了大量的cpu,导致同步延迟,解决办法,使用一主多从,多个从减少备的查询压力③大事务,因为如果一个大的事务的dml操作导致执行时间过长,将其事务binlog发送给备库,备库也需执行那么长时间,导致主备延迟,解决办法尽量减少大事务,比如delete操作,使用limit分批删除,可以防止大事务也可以减少锁的范围。 ④大表的ddl,会导致主库将其ddl binlog发送给备库,备库解析中转日志,同步,后续的dml binlog发送过来,需等待ddl的mdl写锁释放,导致主备延迟。
可靠性优先策略,①判断备库 B 现在的 seconds_behind_master如果小于某个值(比如 5 秒)继续下一步,否则持续重试这一步,②把主库 A 改成只读状态,即把 readonly 设置为 true,③判断备库 B 的 seconds_behind_master的值,直到这个值变成 0 为止; 把备库 B 改成可读写也就是把 readonly 设置为 false; 把业务请求切换到备库,个人理解如果发送过来的binlog在中转日志中有多个事务,业务不可用的时间,就是多个事务被运用的总时间。如果非正常情况下,主库掉电,会导致出现的问题,如果备库和主库的延迟时间短,在中转日志运用完成,业务才能正常使用,如果在中转日志还未运用完成,切换为备库会导致之前完成的事务,”数据丢失“,但是在一些业务场景下不可接受。 可用性策略,出现的问题:在双m,且binlog_format=mixed,会导致主备数据不一致,使用使用 row 格式的 binlog 时,数据不一致的问题更容易发现,因为binlog row会记录字段的所有值。
问题:发生主从切换的时候,主有的最新数据没同步到从,会出现这种情况吗,出现了会怎么样? 答:
异常切换有可能的 要根据你的处理策略了,如果不能丢,有几个可选的 1.不切换(等这个库自己恢复起来) 2. 使用semi-sync策略 3. 启动后业务做数据对账(这个一般用得少,成本高)
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有