mysql半同步(semi-sync)源码实现
mysql复制简单介绍了mysql semi-sync的出现的原因,并说明了semi-sync如何保证不丢数据。这篇文章主要侧重于semi-sync的实现,结合源码将semi-sync的实现过程展现给大家。最新的semi-sync源码可以参考官方5.7版本的实现,https://github.com/mysql/mysql-server。
打开semi-sync的正确姿势
默认情况下的mysql复制都是异步复制,mysql通过参数来控制semi-sync开关。具体而言,主库上通过rpl_semi_sync_master_enabled参数控制,备库上通过rpl_semi_sync_slave_enabled参数控制,打开这两个参数后,mysql semi-sync的特性就打开了。注意对于备库而言,为了保证半同步立即生效,需要重启slave的IO线程。另外,还有一个比较重要的参数是rpl_semi_sync_master_timeout,这个参数用于控制master等待semi-slave ack报文的时间,单位是毫秒,默认是10000。master等待超时,则切换为普通的异步复制。
master:
set global rpl_semi_sync_master_enabled=1;
set global rpl_semi_sync_master_timeout=xxx; slave:
stop slave io_thread;
set global rpl_semi_sync_slave_enabled=1;
start slave io_thread;
另外需要注意的是,打开了上述两个参数只说明master-slave已经具备打开semi-sync的基本条件了,但复制是否依照半同步运行,还需要根据Rpl_semi_sync_master_status的状态值确定。因为比如slave较master有很大延迟(超过rpl_semi_sync_master_timeout),那么复制切换为普通复制。对于需要调试代码的童鞋而言,rpl_semi_sync_master_trace_level和rpl_semi_sync_slave_trace_level非常重要,通过设置level取值,可以打印日志记录半同步的详细过程,方便定位问题。
semi-sync的实现
semi-sync说到底也是一种复制,只不过是在普通的复制基础上,添加了一些步骤来实现。因此semi-sync并没有改变复制的基本框架,我们的讨论也从master,slave两方面展开。
1.master(主库)
主库上面主要包含三个部分,(1).负责与slave-io线程对接的binlog dump线程,将binlog发送到slave,(2).主库上写事务的工作线程,(3).收取semi-slave报文的ack_receiver线程。
(1).binlog dump流程
主要执行逻辑在mysql_binlog_send函数中。
1.判断slave是否是semi_slave,调用add_slave将semi-slave加入到ack_receiver线程的监听队列中。判断的逻辑是slave对应的会话上是否设置了参数rpl_semi_sync_slave。
2.根据slave的请求偏移和binlog文件,从指定位点读取binlog
3.根据文件和位点,捞binlog文件中的数据
4.调用updateSyncHeader设置数据包头semi-sync标记
根据实时semi-sync运行状态来确定是否设置(这个状态由ack_receiver线程根据是否及时收到slave-ack报文设置)
5.调用my_net_write发送binlog
6.调用net_flush确认网络包发送出去
如果当前所有产生的binlog已经处理完,需调用wait_for_update_bin_log等待binlog更新。
(2).半同步事务提交流程
mysql5.6以后提交采用组提交方式,主要分为三个阶段,每个阶段有一个队列,增加semi-sync后,又增加了一个semi-sync阶段。
1.flush阶段:
队列能保证写binlog的顺序与innodb-commit的顺序一致。通过队列,可以保证顺序写每个事务的binlog-cache,然后只进行一次write操作(flush_cache_to_file)。flush阶段后,如果sync_binlog不是1,则通知master有新binlog产生;如果sync_binlog为1,则等待sync阶段后,再通知dump线程有新binlog产生。这里我理解是因为如果不为1,则可能没有后续的sync阶段,而操作系统缓存也有binlog数据,所以可以在flush阶段后通知;而对于sync_binlog为1的情况,可以保证主库的binlog先落地,永远比备库多。但如果sync_binlog不为1,比如1000,则主机异常情况下,则可能出现备库的binlog比主库还多的情况。根据sync_binlog的设置,确认是否要跳过sync阶段。
2.sync阶段:
sync_binlog_file
3.semi_sync阶段:
call_after_sync,等待备库应答。调用cond_timewait等待条件变量&COND_binlog_send_,注意这里只是leader线程在等,将leader线程唤醒后,才会结束semi_sync阶段,进而唤醒其它的follower线程。
4.commit阶段:
innodb-commit
waitAfterCommit,等待备库应答。调用cond_timewait等待条件变量&COND_binlog_send_ 。最终我们根据semi-sync复制模式的设置(AFTER_COMMIT,AFTER_SYNC),来确定是第(3)步还是第(4)步进行等待。
(3).接收slave-ack报文流程
这个流程的工作主要在ack_receiver线程中,这个线程的主要作用是监听semi-slave的ack包,确认master-slave链路是否工作在半同步状态,并根据实际运行状态将普通复制与半同步复制进行切换。打开主库rpl_semi_sync_master_enabled参数后,该线程启动,关闭参数后,该线程消亡。
流程如下:
1.遍历semi-slave数组
2.通过select函数监听每个slave是否有网络包过来
3.调用my_net_read读取包数据
4.调用reportReplyPacket处理semi-sync复制状态
若备库已经获取了最新的binlog位点,则唤醒等待的工作线程
5.调用reportReplyBinlog唤醒等待的线程,mysql_cond_broadcast(&COND_binlog_send_);
2.slave(备库)
主要实现在(handle_slave_io)
1.启动io-thread后,调用safe_connect建立与master的连接
2.调用request_dump函数处理请求binlog逻辑
(1).执行命令SET @rpl_semi_sync_slave= 1,设置一个局部变量,通过这个参数标记slave为semi-slave
(2).发送命令COM_BINLOG_DUMP请求日志
循环从master端收取日志,处理日志
{
1.调用read_event,从master端收取日志(如果没有网络包,会阻塞等待)
2.调用slaveReadSyncHeader,确定网络包头是否有semi-sync标记
3.调用queue_event将日志写入relay-log,在这个过程中会过滤自身server-id的日志
4.如果有semi-sync标记,调用slaveReply函数,发送ack报文
}
mysql半同步(semi-sync)源码实现的更多相关文章
- MySQL半同步复制源码解析
今天 DBA 同事问了一个问题,MySQL在半同步复制的场景下,当关闭从节点时使得从节点的数量 < rpl_semi_sync_master_wait_for_slave_count时,show ...
- Mysql半同步复制模式说明及配置示例 - 运维小结
MySQL主从复制包括异步模式.半同步模式.GTID模式以及多源复制模式,默认是异步模式 (如之前详细介绍的mysql主从复制).所谓异步模式指的是MySQL 主服务器上I/O thread 线程将二 ...
- mysql半同步复制问题排查
1.问题背景 默认情况下,线上的mysql复制都是异步复制,因此在极端情况下,主备切换时,会有一定的概率备库比主库数据少,因此切换后,我们会通过工具进行回滚回补,确保数据不丢失.半同步复制则 ...
- 安装MySQL半同步复制
一.简介 从MySQL5.5开始,MySQL以插件的形式支持半同步复制.如何理解半同步呢?首先我们来看看异步,全同步的概念 异步复制(Asynchronous replication) MySQL默认 ...
- MySQL半同步复制搭建
默认情况下,MySQL 5.5/5.6/5.7和MariaDB 10.0/10.1的复制是异步的,异步复制可以提供最佳性能,主库把binlog日志发送给从库,这一动作就结束了,并不会验证从库是否接收完 ...
- mysql半同步复制跟无损半同步区别
mysql半同步复制跟无损半同步复制的区别: 无损复制其实就是对semi sync增加了rpl_semi_sync_master_wait_point参数,来控制半同步模式下主库在返回给会话事务成功之 ...
- MySQL半同步复制
从MySQL5.5开始,MySQL以插件的形式支持半同步复制.如何理解半同步呢?首先我们来看看异步,全同步的概念 异步复制(Asynchronous replication) MySQL默认的复制即是 ...
- MySQL半同步安装以及参数
MySQL半同步安装以及参数 基于MySQL5.5 官档地址: Semisynchronous Replication Administrative Interface https://dev.mys ...
- MySQL 半同步重要状态参数说明
如果配置了MySQL半同步复制,可以在主库查询半同步状态,命令为: SHOW GLOBAL STATUS LIKE '%semi%'; 参数说明 Rpl_semi_sync_master_c ...
- mysql半同步复制实现
mysql半同步复制和异步复制的区别如上述架构图所看到的:在mysql异步复制的情况下.Mysql Master Server将自己的Binary Log通过复制线程传输出去以后,Mysql Mast ...
随机推荐
- ABP源码分析四十一:ZERO的Audit,Setting,Background Job
AuditLog: 继承自Entity<long>的实体类.封装AuditLog的信息. AuditingStore: 实现了IAuditingStore接口,实现了将AuditLog的信 ...
- Oracle数据库自动备份SQL文本:Procedure存储过程,View视图,Function函数,Trigger触发器,Sequence序列号等
功能:备份存储过程,视图,函数触发器,Sequence序列号等准备工作:--1.创建文件夹 :'E:/OracleBackUp/ProcBack';--文本存放的路径--2.执行:create or ...
- Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架
Enterprise Solution 是一套管理软件开发框架,在这个框架基础上开发出一套企业资源计划系统Enterprise Edition. 现将Enterprise Solution开发过程中遇 ...
- Enterprise Solution 生成实体数据访问接口与实现类型 Code Smith 6.5 模板文件下载
数据库表定义为SalesOrder,用LLBL Gen Pro生成的实体定义是SalesOrderEntity,再用Code Smith生成的数据读写接口是ISalesOrderManager,最后是 ...
- nginx+php 在windows下的简单配置安装
开始前的准备 PHP安装包下载:http://windows.php.net/downloads/releases/php-5.5.14-Win32-VC11-x86.zip Nginx 下载地址:h ...
- css权威指南-基本视觉格式化(水平与垂直)
1.基本概念 (1)正常流:是指西方语言文本从左向右,从上向下显示.如果要让一个元素不在正常流中国,唯一的办法 就是使之成为浮动或定位元素. ( ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(9)-MVC与EasyUI结合增删改查
系列目录 文章于2016-12-17日重写 在第八讲中,我们已经做到了怎么样分页.这一讲主要讲增删改查.第六讲的代码已经给出,里面包含了增删改,大家可以下载下来看下. 这讲主要是,制作漂亮的工具栏,虽 ...
- ORA 各种oraclesql错误
ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出 ...
- Windows Live Writer 在线安装失败的解决方法。
这里提供一种解决方法:下载离线安装包,我这个版本是2011的.大家有兴趣的话可以下载一下: http://wl.dlservice.microsoft.com/download/8/3/D/83D75 ...
- 4D卓越团队-两天培训总结
上周末参加了公司组织的领导力培训课程-4D卓越团队(创业型团队领导力训练项目),感觉有一些用,在这里分享一下. 课前游戏 培训老师先带我们做了一个游戏:每一个人,在同时参加培训的人中找到另外的 6 个 ...