主备延迟
主备数据一致的基本步骤是:
1.主库完成事务,写入binlog,T1
2.备库接收主库发过来的binlog,T2
3.备库执行完成该事务,T3
T3-T1即主备延迟,通过参数seconds_behind_master可以查看。
备库在取出binlog时,会计算其记录的写入时间与当前系统时间的差值,这是seconds_behind_master的计算方法。
备库在连接主库时会检查这个差值,如果备库和主库之间的时间有差别,计算seconds_behind_master时会扣掉这个差值。
主备数据一致中,第二步是较快的,所以产生延迟的原因是第三步比第一步慢,也就是备库消费中转日志比主库执行事务并生成binlog慢。
主备延迟的原因
1.备库的机器性能比主库可能要差
因为主库直接与业务相关,而备库没有请求,所以很多人在部署时就会选择让主库的性能好一点,备库差一点没关系
2.备库的压力大
主库提供了写能力,备库就可以用来提供读能力,或者一些分析语句选择在备库上跑。
处理方法就是一主多从提高从库处理能力。
3.大事务
当主库执行一个大事务,假设执行了10分钟才完成,这样主备延迟就至少有10分钟。
预防方法就是尽量不用执行大事务。
因为有主备延迟的存在,所以主备切换时可以选择不同的策略。
双M架构主备切换时的策略
A是主库,B是备库(readonly),请求都发在A上。
此时要进行主备切换,也就是让A变成readonly,让B变成不是readonly,然后请求都发在B上。
1.可靠性原则
如果是可靠性为首要的,也就是数据不能丢失,不能数据不一致,那么就会印象可用性。
首先要等到seconds_behind_master值小于一个值时(如5s)把A设置成readonly,再等到seconds_behind_master=0时也就是主备数据一致时再把B的readonly设置成false,然后让请求都发到B上面。
等到sbm小于一个值再把A设置成readonly是为了后面尽量少等一点。
可以看到从把A设置成readonly到把B设置为非readonly期间这两个库都是readonly的,请求就无法处理。
2.可用性原则
如果以可用性作为最重要的部分,那么就要容忍可能的数据不一致问题。
直接让A变成readonly,然后让B变成非eadonly,将请求发给B。后续B再慢慢执行中转日志
但是如果在binlog的格式是statement或者mixup时,在B执行中转日志前,客户端就发来请求,就会导致数据不一致。因为statement或者mixup记录的是sql语句,如果执行一条insert语句,通常是不会填写主键的,这样就会导致本来应该在主库和备库的同一条数据,变成了主键id不同的两条数据
但是binlog格式是row的话就能直接发现这个数据不一致,因为row格式会记录主库插入这条数据之后的完整数据。