MySQL半同步(四)流程和相关参数

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: MySQL半同步(四)流程和相关参数

源码版本5.7.29

本文作为新书《深入理解MySQL主从原理》的补充部分,供大家参考,如有误请见谅。

屏幕快照 2021-11-19 下午2.47.17.png

数据结构和流程参考:

此处不再单独列出

一、半同步的总体流程图

image.png

查看大图请移步 https://www.jianshu.com/p/5ebf4f4c1cf8

二、半同步中几个重要的状态值(主库)

半同步插件是否注册:半同步插件注册状态

ReplSemiSyncMaster::init_done_                                                                                                                                                                                                                                                                                               
 /* True when initObject has been called */                                                                                                                                                                                                                                                                                  

半同步插件是否启用:半同步开启状态

ReplSemiSyncMaster::master_enabled_

/ semi-sync is enabled on the master /
getMasterEnabled用于获取变量
set_master_enabled设置变量

完全取决于参数rpl_semi_sync_master_enabled

是否使用半同步(异步):半同步复制方式

ReplSemiSyncMaster::state_                                                                                                                                                                                                                                                                                                   
/ whether semi-sync is switched /

本状态非常重要,决定了是否是半同步复制方式,在函数ReplSemiSyncMaster::commitTrx中会完全依赖这个状态决定是否进行用户线程事务的等待,也是Rpl_semi_sync_master_status信息的来源。

三、相关参数(主库)

研究的参数包括

| rpl_semi_sync_master_enabled              | ON         |                                                                                                                                                                                                                                                                   
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
rpl_semi_sync_master_enabled

默认为false

生效点:

  • 插件初始化初始化生效,参考第一节初始化函数ReplSemiSyncMaster::initObject
  • Ack_receiver线程初始化生效,参考第一节初始化函数Ack_receiver::init
  • 参数动态生效,参考函数fix_rpl_semi_sync_master_enabled

fix_rpl_semi_sync_master_enabled函数会动态转换为半同步开启状态,并且开启Ack_receiver线程,当然根据参数rpl_semi_sync_master_wait_for_slave_countrpl_semi_sync_master_wait_no_slave

的设置,考虑是否使用同步复制方式,并且本参数会设置到 ReplSemiSyncMaster::master_enabled_ 全局变量。如果是关闭则会转化为异步复制switch_off(),并且做一些清理操作,比如active_tranxs_。

rpl_semi_sync_master_timeout

默认为10000毫秒,即10秒

生效点:

  • 等待需要的ack反馈的事务超时,生效函数为ReplSemiSyncMaster::commitTrx,如果超时那么切换为异步复制,调用switch_off函数
  • 插件初始化生效
  • 参数动态生效,参考函数fix_rpl_semi_sync_master_timeout设置方式就是赋值给ReplSemiSyncMaster::wait_timeout_
rpl_semi_sync_master_wait_for_slave_count

默认为on

本参数可以和参数rpl_semi_sync_master_wait_no_slave共同作用共同决定半同步复制还是异步复制,这里先说rpl_semi_sync_master_wait_no_slave设置on的情况

生效点:

  • 初始化Ack_recevier线程的AckContainer的元素个数,调用函数setWaitSlaveCount
  • 等待需要的ack反馈的事务超时,会通过AckContainer遍历找到最小的ack反馈点,参考repl_semi_report_binlog_sync函数
  • 动态参数修改fix_rpl_semi_sync_master_wait_for_slave_count,这里也会重新设置AckContainer的元素个数,调用函数setWaitSlaveCount

因此和rpl_semi_sync_master_timeout参数配合,可以决定收到多少个半同步从库的ack后进行反馈。

rpl_semi_sync_master_wait_no_slave

默认为on

如果为on则遵守如上rpl_semi_sync_master_wait_for_slave_count的说明,这里重点说一下它设置为false有什么作用,如果其设置为false那么会有如下影响

生效点:

  • 每次有半连接从库退出的时候,dump线程退出之前会通过回调函数repl_semi_binlog_dump_end,调入ReplSemiSyncMaster::remove_slave函数进行判断rpl_semi_sync_master_clients(现有存在的半同步从库数量)是否小于了rpl_semi_sync_master_wait_for_slave_count的个数,如果小于了则直接切换为异步复制方式。而不需要等到无ack反馈才进行切换。
  • 如果设置半同步开启状态,需要进行判断是否rpl_semi_sync_master_clients(现有存在的半同步从库数量)是否小于了pl_semi_sync_master_wait_for_slave_count的个数,如果小于则不开启同步复制。参考函数ReplSemiSyncMaster::enableMaster
  • 动态参数修改fix_rpl_semi_sync_master_wait_no_slave,根据rpl_semi_sync_master_clients(现有存在的半同步从库数量)是否为0来决定是否开启半同步复制方式,但是这里有一个疑问判断条件为rpl_semi_sync_master_clients==0。

因此本参数设置为false,设置rpl_semi_sync_master_timeout为一个很大的值,也不能保证主从一定是半同步复制。

rpl_semi_sync_master_trace_level

默认为32

我们在前面已经多次说过,如果这个参数设置16,将会有大量的半同步日志输出。这里不做描述

rpl_semi_sync_master_wait_point

默认为AFTER_SYNC,这个参数也是在前面说过了,这里不做详细描述。

生效点:

  • 主要位于回调函数repl_semi_report_commit和repl_semi_report_binlog_sync中,用于确认是在commit队列处理之前进行用户的ack反馈还是commit队列处理之后进行ack反馈。

四、重点统计值(主库)

主要研究的统计值包含

| Rpl_semi_sync_master_clients               | 0     |                                                                                                                                                                                                                                                                       
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | OFF |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
Rpl_semi_sync_master_clients:当前处于半同步复制的从库个数
  • 增加:repl_semi_binlog_dump_start回调函数调用ReplSemiSyncMaster::add_slave,及dump线程启动时刻
  • 减少:repl_semi_binlog_dump_end回调函数调用ReplSemiSyncMaster::remove_slave,及dump线程退出时刻
Rpl_semi_sync_master_no_times:关闭半同步复制方式的次数

内部为rpl_semi_sync_master_off_times

  • 增加:ReplSemiSyncMaster::switch_off函数
Rpl_semi_sync_master_no_tx:没有在半同步复制方式状态下,事务commit队列处理的次数(after_sync)/事务处理的次数(after_commit)

内部为rpl_semi_sync_master_no_transactions。

  • 增加:用户线程repl_semi_report_commit/repl_semi_report_binlog_sync调用ReplSemiSyncMaster::commitTrx函数的末尾
Rpl_semi_sync_master_yes_tx:半同步复制方式状态下,事务commit队列处理的次数(after_sync)/事务处理的次数(after_commit)

内部为rpl_semi_sync_master_yes_transactions。

  • 增加:同上
Rpl_semi_sync_master_status:内部表示就是ReplSemiSyncMaster::state_,也就是当前主库状态是否处于半同步复制方式下。

参考ReplSemiSyncMaster::setExportStats函数

  • 更改就是ReplSemiSyncMaster::switch_off函数。
Rpl_semi_sync_master_wait_sessions:主要用于表示当前处于堵塞的session数量。
  • 增加:用户线程repl_semi_report_commit/repl_semi_report_binlog_sync调用ReplSemiSyncMaster::commitTrx函数,进入等待前
  • 减少:用户线程repl_semi_report_commit/repl_semi_report_binlog_sync调用ReplSemiSyncMaster::commitTrx函数,退出等待后但是需要注意的能够进入这个函数的是commit的leader线程,因此实际堵塞的会话数量可能是远远大于这个数字。
Rpl_semi_sync_master_tx_wait_time:主要用于表示由于等待ack反馈而等待的时间,单位微秒(百万分之1秒)

内部表示为rpl_semi_sync_master_trx_wait_time。

  • 增加:用户线程repl_semi_report_commit/repl_semi_report_binlog_sync调用ReplSemiSyncMaster::commitTrx函数,等待ack之后(未超时)
Rpl_semi_sync_master_tx_waits:同上,表示次数
  • 增加:用户线程repl_semi_report_commit/repl_semi_report_binlog_sync调用ReplSemiSyncMaster::commitTrx函数,等待ack之后(未超时)
rpl_semi_sync_master_wait_pos_backtraverse:降低wait_file_name_/wait_file_pos_的次数
  • 增加:用户线程repl_semi_report_commit/repl_semi_report_binlog_sync调用ReplSemiSyncMaster::commitTrx函数。

五、从库参数和统计值

从库的参数和统计值很简单,和主库不同开启rpl_semi_sync_slave_enabled参数,不会动态让从库的Rpl_semi_sync_slave_status生效,启用半同步复制方式

参数rpl_semi_sync_slave_enabled:用于表示是否从库开启了半同步状态

生效点为

  • ReplSemiSyncSlave::initObject初始化的时候
  • fix_rpl_semi_sync_slave_enabled动态修改,但是需要注意这里的动态修改并不影响统计值Rpl_semi_sync_slave_status
状态值Rpl_semi_sync_slave_status:用于表示从库是否是半同步复制方式

无法动态开启这点和主库不同,并且此状态不会由于主库问题在运行期间改变,因此不能做判断半同步复制方式的根据,应该在主库判断。

改变:

  • dump线程启动时刻根据,rpl_semi_sync_slave_enabled参数和主库是否安装半同步插件来共同判定是否开启。
  • dump线程关闭时刻。

下面是一个测试(主库未安装半同步插件)

mysql> show variables like '%semi%slave_enabled';                                                                                                                                                                                                                                                                            
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
+-----------------------------+-------+
1 row in set (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected (0.02 sec)

mysql> show status like '%Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF |
+----------------------------+-------+

可以看到Rpl_semi_sync_slave_status并未启动。

下面是另外一个测试

mysql> show slave status \G;                                                                                                                                                                                                                                                                                                 
1. row **
Slave_IO_State: Reconnecting after a failed master event read
Master_Host: 192.168.1.63
Master_User: repsem
Master_Port: 3325
Connect_Retry: 60
Master_Log_File: log_bin.000004
Read_Master_Log_Pos: 194
Relay_Log_File: relaylog.000020
Relay_Log_Pos: 363
Relay_Master_Log_File: log_bin.000004
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes

ERROR:
No query specified

mysql> show status like '%Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.02 sec)

可以看到即便IO线程已经处于重连状态,Rpl_semi_sync_slave_status依旧为on。

六、运行状态下主库半同步状态切换时刻

  • 我们熟知的超过参数rpl_semi_sync_master_timeout的设置
    调用为


ReplSemiSyncMaster::commitTrx                                                                                                                                                                                                                                                                                                
->switch_off
  • 如果参数rpl_semi_sync_master_wait_no_slave设置false,那么当dump线程退出之前会判断是否小于rpl_semi_sync_master_wait_for_slave_count的设置,小于切换为异步
    调用为
repl_semi_binlog_dump_end                                                                                                                                                                                                                                                                                                    
->ReplSemiSyncMaster::remove_slave
->switch_off
  • 如果Ack_recevier线程发现反馈ack的半同步从库数量满足rpl_semi_sync_master_wait_for_slave_count的设置,尝试使用半同步复制方式
    调用为
ReplSemiSyncMaster::reportReplyPacket                                                                                                                                                                                                                                                                                        
->handleAck
->ReplSemiSyncMaster::reportReplyBinlog
->try_switch_on
  • 设置参数rpl_semi_sync_master_enabled参数的时候,会尝试使用半同步复制模式,参考上文
  • 设置参数rpl_semi_sync_master_wait_no_slave参数的时候,会尝试改变半同步复制模式,参考上文

全文完。

Enjoy MySQL :)



            </div>
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
canal 关系型数据库 MySQL
cancal 同步mysql数据到es中
cancal 同步mysql数据到es中
43 1
|
1月前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化复杂查询,使用临时表简化数据库查询流程(13)
轻松入门MySQL:优化复杂查询,使用临时表简化数据库查询流程(13)
|
2月前
|
关系型数据库 MySQL
elasticsearch对比mysql以及使用工具同步mysql数据全量增量
elasticsearch对比mysql以及使用工具同步mysql数据全量增量
26 0
|
2月前
|
关系型数据库 MySQL API
Flink CDC产品常见问题之mysql整库同步到starrock时任务挂掉如何解决
Flink CDC(Change Data Capture)是一个基于Apache Flink的实时数据变更捕获库,用于实现数据库的实时同步和变更流的处理;在本汇总中,我们组织了关于Flink CDC产品在实践中用户经常提出的问题及其解答,目的是辅助用户更好地理解和应用这一技术,优化实时数据处理流程。
|
2月前
|
SQL DataWorks 关系型数据库
DataWorks常见问题之dataworks同步Rds任务失败如何解决
DataWorks是阿里云提供的一站式大数据开发与管理平台,支持数据集成、数据开发、数据治理等功能;在本汇总中,我们梳理了DataWorks产品在使用过程中经常遇到的问题及解答,以助用户在数据处理和分析工作中提高效率,降低难度。
|
12天前
|
运维 DataWorks 关系型数据库
DataWorks产品使用合集之DataWorks还有就是对于mysql中的表已经存在数据了,第一次全量后面增量同步的步骤如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
28 2
|
12天前
|
DataWorks 关系型数据库 MySQL
DataWorks产品使用合集之在DataWorks中,要实现MySQL数据源的增量同步如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
37 2
|
1月前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
3天前
|
存储 缓存 关系型数据库
MySQL结构流程,看这一篇就够了!
MySQL结构流程,看这一篇就够了!
|
10天前
|
关系型数据库 MySQL Linux
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)
【MySQL-10】数据库函数-案例演示【字符串/数值/日期/流程控制函数】(代码演示&可cv代码)