26 | MySQL主从延迟分析以及HA保障(柯南版的中篇)

〇、前言

下面的笔记都是一主一备,或者叫一主一从。

一、前置背景

上一篇中讲到主从延迟场景对于从库的影响一般是分钟级别的,备库恢复之后都可以追上来,但是第四点如果备库执行日志的速度低于主库生成日志的速度,可能会导致小时级别的延迟。

--这篇是个重点,来到了面试可以装逼的环节。PS:在大神面前估计装不了。

二、主备库并行复制能力

2.1.主库上并发度受什么影响?备库上日志的执行是单线程还是多线程的?

  • 在主库上,影响并发度的原因就是各种锁了。由于 InnoDB 引擎支持行锁,除了所有并发事务都在更新同一行(热点行)这种极端场景外【顾名思义秒杀场景】,它对业务并发度支持很友好。

  • 在官方的 5.6 版本之前,MySQL 只支持单线程复制,由此在主库并发高、TPS 高时就会出现备库sql thread线程更新数据 (DATA) 的严重延迟。

2.2.sql thread的多线程复制原理是怎么样的?

1)大致图解如下

⭐️说明:coordinator 就是原来的 sql_thread, 不过现在它不再直接更新数据了负责读取中转日志分发事务真正更新日志的,变成了 worker 线程。而 work 线程的个数,就是由参数 slave_parallel_workers 决定的。

⚠️:经验把这个slave_parallel_workers值设置为 8~16 之间最好(32 核物理机的情况),毕竟备库还有可能要提供读查询,不能把 CPU 都吃光了

2)所以,coordinator 在分发的时候,需要满足以下这两个基本要求:

  • 不能造成更新覆盖。这就要求更新同一行的两个事务,必须被分发到同一个 worker 中。

  • 同一个事务不能被拆开,必须放到同一个 worker 中。  |  PS:这里是指事务迟早要commit,但是两个worker是两个线程,没办法约好“同时提交”,这样就有可能出现一个先提交一个后提交。虽然最终的结果是主备一致的,但如果表 a 执行完成的瞬间,备库上有一个查询,就会看到这个事务“更新了一半的结果”,破坏了事务逻辑的隔离性。

2.3.如果自己实现并行复制策略应该怎么做?有什么优缺点?

   分为两种策略:

  • 1)按表并行复制,每个 worker 线程对应一个 hash 表,用于保存当前正在这个 worker 的“执行队列”里的事务所涉及的表。hash 表的 key 是“库名. 表名”,value 是一个数字,表示队列中有多少个事务修改这个表。例如,worker中有db1.t1 : 4 和 db2.t2 : 1。缺点并行度低,热点行问题就变成了单线程。

        2)按行并行复制,如果两个事务没有更新相同的行,它们在备库上可以并行执行。显然,这个模式要求 binlog 格式必须是 row。hash表的key是“库名.表名.主键.唯一键名字.唯一键值”。缺点:耗IO和内存。

2.4.MySQL5.6并行复制策略是怎么做的?

  • 按照库维度进行并行。

2.5.MariaDB的并行复制策略依据是什么?分为那四步?好处是什么?缺点是什么?

  • 利用了组提交的特性。

  • 1)在一组里一起提交的事务有一个相同的commit_id,下一组就是 commit_id+1。2)commit_id直接写到binlog里面。3)相同commit_id的事务分发到多个worker。4)这一组全部执行完之后,coordinator再去取下一批。

  • 模拟了主库的并行模式,而不是分析binlog拆解到worker上。

  • 在备库上执行的时候,要等第一组事务完全执行完成后,第二组事务才能开始执行,这样系统的吞吐量就不够。

2.5.1.那组提交有什么特性呢? 

   1)能够在同一组里提交的事务一定不会修改同一行。PS:怎么保证的这点?不知道那怎么保证修改同一行的事务执行顺序呢?答:如果修改同一行commit的时候就会被锁住,等待锁的事务会等待不会进入commit状态。

   2)主库上可以并行执行的事务,备库上也一定是可以并行执行的。

2.6.MySQL5.7的并行复制策略是那两种分别怎么做的?LOGICAL_CLOCK具体方式什么?该方式具有什么优化策略?

  • 由参数 slave-parallel-type 来控制并行复制策略:配置为 DATABASE,表示使用 MySQL 5.6 版本的按库并行策略;配置为 LOGICAL_CLOCK,表示的就是类似 MariaDB 的策略。

  • 设置为 LOGICAL_LOCK 则会采用基于GroupCommit的并行回放,同一个Group内的事务将会在Slave上并行回放。MySQL 5.7 版本在产生 Binlog 日志时会有两个特殊的值记录在Binlog Event中, last_committed 和 sequence_number , 其中 last_committed 指的是该事务提交时,上一个事务提交的编号,sequence_number 是事务提交的序列号,在一个Binlog文件内单调递增。如果两个事务的 last_committed 值一致,这两个事务就是在一个组内提交的。

  • “所有处于 commit”状态的事务可以并行。事务处于 commit 状态,表示已经通过了锁冲突的检验了。优化策略:在两阶段提交过程中,只要保证到达了redo log prepare阶段,就表示事务已经通过锁冲突的检验了。所以,就可以通过设置binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count参数来拉长 binlog 从 write 到 fsync 的时间,从而增加prepare阶段的事务。

2.7.MySQL5.7.22的并行复制策略是怎么做的,每个参数值的具体作用是什么?

  • 新增了一个参数 binlog-transaction-dependency-tracking

    COMMIT_ORDER,表示的就是前面介绍的,根据同时进入 prepare 和 commit 来判断是否可以并行的策略。

    WRITESET,表示的是对于事务涉及更新的每一行,计算出这一行的 hash 值,组成集合 writeset。如果两个事务没有操作相同的行,也就是说它们的 writeset 没有交集,就可以并行。hash 值是通过“库名 + 表名 + 索引名 + 值”计算出来的

    WRITESET_SESSION,是在 WRITESET 的基础上多了一个约束,即在主库上同一个线程先后执行的两个事务,在备库执行的时候,要保证相同的先后顺序。

 

三、疑问点

  • group commit分为几步,每一步做什么?

四、课后题

假设一个 MySQL 5.7.22 版本的主库,单线程插入了很多数据,过了 3 个小时后,我们要给这个主库搭建一个相同版本的备库。这时候,你为了更快地让备库追上主库,要开并行复制。在 binlog-transaction-dependency-tracking 参数的 COMMIT_ORDER、WRITESET 和 WRITE_SESSION 这三个取值中,你会选择哪一个呢?

⭐️:由于主库是单线程压力模式,所以每个事务的 commit_id 都不同,那么设置为 COMMIT_ORDER 模式的话,从库也只能单线程执行。同样地,由于 WRITESET_SESSION 模式要求在备库应用日志的时候,同一个线程的日志必须与主库上执行的先后顺序相同,也会导致主库单线程压力模式下退化成单线程复制。

五、评论区

⚠️:并行策略,当同一组中有3个事务,它们都对同一行同一字段值进行更改,而它们的commit_id相同,可以在从库并行执行,那么3者的先后顺序是怎么保证不影响该行该字段的最终结果与主库一致?

--大部分人都会有这个问题

答:对同一行的修改,第一个拿到行锁的事务还没提交前,另外两个会被行锁堵住的,这两个进入不了commit状态。所以这三个的commit_id不会相同的

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL主从延迟问题是数据库运维中经常遇到的问题之一,通常会引起应用程序性能下降或者数据不一致的问题。下面我们来介绍一下如何排查MySQL主从延迟问题。 1. 确认主从复制的状态 首先需要确认主从复制的状态。可以通过以下命令查看: ``` SHOW SLAVE STATUS \G; ``` 在输出结果中,需要关注以下几个参数: - Slave_IO_Running:表示Slave I/O线程是否正在运行,如果为YES,则正常运行,否则需要检查错误日志; - Slave_SQL_Running:表示Slave SQL线程是否正在运行,如果为YES,则正常运行,否则需要检查错误日志; - Seconds_Behind_Master:表示从库落后主库的时间,如果为0,则表示主从同步正常。 2. 确认网络延迟 如果主从复制状态正常,但是Seconds_Behind_Master不为0,那么需要确认网络延迟是否存在。可以通过在主库和从库上分别执行以下命令进行测试: 在主库执行: ``` SELECT NOW(); ``` 在从库执行: ``` SELECT NOW(); ``` 比较两个输出结果的时间差,即可得到主从复制的网络延迟时间。如果网络延迟较大,可以考虑优化网络连接或者将主从库部署在同一地域内。 3. 检查主从库配置 如果网络延迟不存在,那么需要检查主从库的配置是否正确。可以比较主从库的以下参数是否一致: - server_id:表示服务器的ID,主从库必须不同; - log_bin:表示二进制日志文件名称,主库必须开启二进制日志; - binlog_format:表示二进制日志格式,主库必须开启ROW格式; - replicate_do_db:表示从库需要复制的数据库,如果设置了该参数,则只复制该数据库; - replicate_ignore_db:表示从库忽略复制的数据库,如果设置了该参数,则不复制该数据库。 4. 检查主从库版本 如果主从库配置正确,但是主从延迟问题依然存在,那么需要检查主从库的版本是否一致。主从库的版本必须一致,否则会出现主从延迟的问题。 5. 总结 通过以上步骤,可以排查MySQL主从延迟问题。在实际运维过程中,还可以通过监控工具对主从库的状态进行实时监控,及时发现主从延迟问题,并进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值