当前位置: 首页 > 科技观察

MySQL主从复制太慢,怎么办?

时间:2023-03-14 00:47:00 科技观察

Mysql主从同步延迟原因备库延迟的主要原因有以下几种:通常备库所在机器的性能比主库差,备份自然会慢一点。备库读压力大。备用数据库中执行了太多繁重的查询任务。大生意。因为主库必须要等事务执行完,才能写入binlog,再传给备库。使用delete语句一次删除过多的数据,表DDL可能会造成延迟。主库是多线程操作,而从库只有一个线程执行复制。主从同步延迟解决方案解决方法:提高从库物理机的配置,性能差异不要太大。业务持久层实现采用分库架构,mysql服务可并行扩展,分散压力。读写分离是为了分散主库的压力。加入Redis等缓存,减轻mysql的读取压力。为避免大额交易等耗时操作,可将交易内容拆解执行。使用同步并行复制方案MTS并行复制从MySQL5.6开始支持并行复制,解决了之前复制速度慢的问题。协调器是原来的sql_thread,负责读取传输日志和分发事务。实际更新日志的成为工作线程。工作线程数由参数slave_parallel_workers决定。既然是并行,那必然存在数据一致性的问题。如果两个不同的事务同时在不同的作业中执行,顺序也会造成不同的结果。因此,协调器在分发任务时,必须满足以下两个基本要求:不能造成更新覆盖。这就要求更新同一行的两个事务必须分发给同一个worker。同一个事务不能拆分,必须放在同一个worker中。每个版本的多线程复制都遵循这两个基本原则。MySQL5.6版本策略MySQL5.6官方版本支持并行复制,但支持的粒度是数据库并行。在用于确定分发策略的哈希表中,key是数据库名,同一个数据库需要在同一个worker中串行执行,这样就避免了事务之间相互影响的问题。MariaDB策略MariaDB的并行复制策略利用重做日志组提交(groupcommit)优化特性:可以在同一组中提交的事务不得修改同一行。所以可以根据食物的commit—_id进行分组。在实现上,MariaDB是这样做的:一组一起提交的事务commit_id相同,下一组为commit_id+1;commit_id直接写入binlog;传递给备库应用时,将同一个commit_id事务分发给多个worker执行;待本组全部执行完毕后,协调器再去取下一批。MySQL5.7策略MariaDB的多策略在MySQL5.7中得到了优化。因为同时处于prepare状态的事务在备库执行时可以并行执行,此时的redolog已经通过了并行验证,所以备库也可以执行。具体步骤不再赘述,请参考MariaDB策略。MySQL5.7.22的并行复制策略在2018年4月发布的MySQL5.7.22版本(最新的5.7.37)中,MySQL新增了一种并行复制策略,基于WRITESET的并行复制。相应地,增加了一个参数binlog-transaction-dependency-tracking来控制是否开启这个新策略。这个参数有三个可能的值。COMMIT_ORDER是前面介绍的策略,根据prepare和commit的同时进入判断是否可以并行。WRITESET是指对于事务更新涉及的每一行,计算该行的哈希值,形成一个集合writeset。如果两个事务不对同一行进行操作,即它们的writeset不相交,则可以将它们并行化。WRITESET_SESSION是在WRITESET的基础上增加的约束,即同一个线程在主库上连续执行的两个事务,在备库执行时必须保证顺序一致。当然,为了唯一标识,这个哈希值是通过“库名+表名+索引名+值”来计算的。如果一张表除了主键索引之外还有其他唯一索引,那么对于每一个唯一索引,insert语句对应的writeset都会额外增加一个hash值。总结一下,MySQL的并行复制策略主要有三个思路:根据库的级别和粒度并行执行,在用来决定分布策略的哈希表中,key是数据库名。根据行级别,根据id、唯一索引、值、库名计算hash值,分组标记。根据redolog持久化的原理,同一个commitgroup或者同时进入prepare或commit就意味着可以同步执行。