〇、前言
下面的笔记都是一主一备,或者叫一主一从。
一、名词概念轰炸
1.1.主从延迟(同步延迟)
| 同一个事务,在备库执行完成的时间和主库执行完成的时间之间的差值,也就是“主库执行完一个事务写入binlog” 到 “备库执行完成这个事务” 之间的部分。
二、主从延迟
2.1.如果想查看当前备库延迟了多少秒用什么命令?实现原理是什么?
-
执行show slave status命令的seconds_behind_master可以查看,单位为秒。
-
每个事务binlog中都有一个记录主库写入的时间字段,备库取出正在这个事务的的时间字段与当前系统时间做差值。
⚠️:对于我这种闹事选手可能会说,如果 主备时间不一致怎么办,时间算的准吗?不会,因为备库连接到主库时候会获取主库系统时间,如果时间不一致做差值对比时会扣掉这个差值。如果备库连接主库之后,主库的系统时间修改了,备库同步的时候是否会自动修正?不会修正。
2.2.什么时候会产生主从延迟?
-
主备配置不同(备库机器差或者所有库都放在一个备库上,并且关闭备库的双1模式)。弊端,在于一旦发生主备切换备库性能可能跟不上产生大量的资源争抢导致延迟。
⚠️:备库为什么关闭双1呢?更新请求对 IOPS 的压力,在主库和备库上是无差别的。
-
主备配置一样情况下,从库查询泛滥成灾,耗费大量CPU资源导致主备延迟。解决方案,1)常见方案为一主多从分担查询压力。2)通过大数据方案提供统计类查询。
-
大事务。主库执行时间过久后 [比如N分钟]发到从库,那么就可能造成N分钟的主从延迟。实战举例,1)delete一次性删除太多。2)大表的DDL,因为MDL写锁在退化为读锁前要进行原表的扫描和构建临时文件【⚠️:很消耗 IO 和 CPU 资源】
-
备库的并行复制能力。(下一篇记录,此处一旦主库压力大可能是小时级别延迟)
三、HA策略
3.1.可靠性优先策略步骤是什么?(关键是判断:seconds_behind_master),其中不可用时间在第几步?哪个步骤最耗时?
1)判断备库 B 现在的 seconds_behind_master,如果小于某个值(比如 5 秒)继续下一步,否则持续重试这一步;
2)把主库 A 改成只读状态,即把 readonly 设置为 true;
3)判断备库 B 的 seconds_behind_master 的值,直到这个值变成 0 为止;
4)把备库 B 改成可读写状态,也就是把 readonly 设置为 false;
5)把业务请求切到备库 B。
3.2.可用性优先策略(binlog_format=mixed 和 binlog_format=row)
如强行切B会造成数据不一致的现象。mixed格式新增插入造成的不一致影响行数更多,row对于新纪录的插入会记录新插入的行的所有字段值,所以最后只会有一行不一致。
举例:row格式 VS mixed
![]()
3.3.如何选择高可用还是可用性优先策略?
在满足数据可靠性的前提下,MySQL 高可用系统的可用性,是依赖于主备延迟的。延迟的时间越小,在主库故障的时候,服务恢复需要的时间就越短,可用性就越高。金融业务下,一定是可靠性重要。
3.3.1.实战
当主备延迟为30分钟,这时主库掉电,强行切换备库提供读写会造成主备数据的不一致【如上图】,但是只接切到备库B,保持B只读也不行,因为对用户可能会造成短暂的数据不一致。所以只能等待备库慢慢应用中转日志,在备库应用完中转日志且切换成读写状态之前,数据库是处于不可用的状态。
四、课后题
假设,现在你看到你维护的一个备库,它的延迟监控的图像类似图 6,是一个 45°斜向上的线段,你觉得可能是什么原因导致呢?你又会怎么去确认这个原因呢?
答:备库的同步在这段时间完全被堵住了。一种是大事务(包括大表 DDL、一个事务操作很多行);还有一种情况比较隐蔽,就是备库起了一个长事务,比如begin; select * from t limit 1;然后就不动了。这时候主库对表 t 做了一个加字段操作,即使这个表很小,这个 DDL 在备库应用的时候也会被堵住,也不能看到这个现象。
⚠️:不是主库多线程、从库单线程,备库跟不上主库的更新节奏导致的,这种情况会导致主备延迟,但不会表现为这种标准的呈 45 度的直线。
五、书评
5.1.semi-sync,semi-sync在网络故障超时的情况下会退化成async,这个时候如果刚好主库掉电了,有些binlog还没有传给从库,从库无法判断数据跟主库是否一致,如果强行切换可能会导致丢数据,在金融业务场景下只能"人工智能"来做切换,服务中断时间长。AliSQL采用双通道复制更容易判断主备数据是否一致,如果一致可以自动切换,如果不一致才需要人工恢复数据。--Mark下,不太明白啥意思