Code前端首页关于Code前端联系我们

简单介绍阅读半同步相关的mysql源码

terry 2年前 (2023-09-30) 阅读数 38 #Mysql
文章标签 Mysql

本文目录:

  • 1、mysql半同步复制适合什么业务场景?
  • 2.mysql异步复制和半同步复制
  • 3、MySQL主从复制原理,异步会怎样?半同步会发生什么?
  • 4、如何查看mysql是否是半同步复制?
  • 5、mysql复制半同步和同步的区别

mysql半同步复制适合哪些业务场景

确保更改操作已写入至少一个磁盘,然后才能继续进行更改操作。也就是说,对于每个连接,最多会因为master崩溃而丢失一个事务。半同步复制不会停止已提交的事务,而只是避免向客户端发送响应,直到该事务写入至少一个 slave 的中继日志。在slave被告知交易已在持久存储中之前,客户的承诺不会被返回。

mysql异步复制和半同步复制

MySQL 5.5之前,MySQL复制是异步操作,主库和从库的数据之间存在一定的延迟。这就造成了一个隐患:当一个事务在主库上写入并提交,而从库还没有收到主库推送的Binlog日志时,主库就宕机了。比如主库可能因为磁盘损坏、内存错误等原因丢失主库上的事务Binlog,此时从库可能会丢失这个事务,从而导致主库丢失Binlog日志。永远不会不一致。

为了解决这个问题,MySQL5.5引入了半同步复制机制。

MySQL 5.5之前的异步复制中,主库执行完Commit操作后,可以在主库写入Binlog日志后返回给客户端,无需等待Binlog日志传输到从库,如图31-7所示。

在半同步复制中,为了保证主库上的每个Binlog事务都能可靠地复制到从库,主库并不会在每个事务提交成功时及时反馈给前端应用用户。当其中一个从库也收到Binlog事务并成功写入中继日志后,主库向客户端返回Commit操作成功。半同步复制保证了一笔事务提交后,至少会有两条日志记录,一条在主库的Binlog日志上,另一条在至少一个从库的Relay日志上,从而进一步保证了完整性的数据。正直。半同步复制的大致流程如图31-8所示。

半同步复制模式下,如果图31-8中的1、2、3任一步骤中主库宕机,则事务未发送成功,从库收不到该事务对应的Binlog日志。因此主从数据是一致的;

如果步骤4中Binlog日志传输到从库时,从库宕机或者网络故障,导致Binlog没有及时传输到从库。此时master数据库上的事务会等待一段时间(时间由rpl_semi_sync_master_timeout参数设置的毫秒数决定)。如果在此时间段内Binlog无法发送到从库,MySQL会自动调整复制为异步模式,事务会正常返回提交结果给客户端。 。

半同步复制很大程度上取决于主从库之间的网络状况。往返时延RTT越小,从库的实时性越好。通俗地说,主从库之间的网络越快,从库的实时性就越强。

半同步模式是作为MySQL5.5的插件实现的。主库和从库使用不同的插件。安装比较简单。在上一节的异步复制环境中,只需安装半同步复制插件即可。

1. 首先判断 MySQL 服务器是否支持动态添加插件:

2. 安装插件

3. 可以看到已安装的插件

4. 安装完成后插件,半同步复制标准关闭,则需要设置参数开启半同步

Master:

Slave:

以上启动方式是在命令行操作,也可以写在配置文件中。

Master:

Slave:

4. 重新启动 Slave 上的 IO 线程

Slave:

如果没有重新启动,默认仍然是异步复制。重启后,slave 将被注册为 master 上并发复制的 slave 角色的一半。此时,master 的 error.log 中会打印如下信息:

Check if semi-sync is running

Master:

Slave:

这两个变量通常用于监控半同步是否运行。主设备和从设备半同步运行。在复印模式下。至此,MySQL半同步复制就完成了~

我们来做个实验,观察半同步状态参数的变化。

1、在主库中插入一条记录,观察变化;

Rpl_semi_sync_master_net_waits 加 1,表示刚刚已经将 post 发送到 Slave,Master 也收到了 Slave 的反馈响应;

2.我们从从机停止mysql,在主机上再次执行插入并检查状态

可以看到,楼主屏蔽了帖子10秒才返回结果。 Rpl_semi_sync_master_status变为OFF,Rpl_semi_sync_master_no_tx增加1,表明本次post与slave不同步。后来重新执行insert,立即返回结果,说明已经降级为异步复制; Rpl_semi_sync_master_no_tx也增加1;

3. 现在重新启动从机,再次检查插入主机后的状态

Rpl_semi_sync_master_status 仍然为 OFF,Rpl_semi_sync_master_no_tx 再次增加 1。注意,重启从库不会自动恢复原来的半同步复制,需要手动操作:

Master SET GLOBAL rpl_semi_sync_master_enabled = 1;

从机设置全局 rpl_semi_sync_slave_enabled = 1;停止从属 IO_THREAD; START SLAVE IO_THREAD;

以上是从机重启后的变化。至于master和slave之间的网络问题,我们可以使用防火墙来模拟。

对于完全同步复制,当主库发送事务时,所有从库节点必须接收、APPLY、发送这些事务,然后主库线程才能继续执行后续操作。这里一个明显的缺点是主数据库完成事务所需的时间延长并且性能降低。

Mysql主从复制原理,异步会怎样?半同步会发生什么

研发同事反映mysql的半同步不同步?一开始并不奇怪,超时之后自然就变成了异步。但binlog同步速度正常后,就会自动同步。但本着严格负责的态度,我立即检查了日志和数据库的半同步状态。

我查看了从库的错误日志,并通过图像中显示的 sem-sync slave net_flush() 响应失败消息进行了更新。 。 。 。 。 。汗,这是哪部的?主库没有日志。

虽然此时主从同步延迟时间正常,维持在0s延迟,但此时的同步状态是异步的。

多么奇怪?

查看代码,半同步slave net_flush()响应失败信息来自函数

ReplSemiSyncSlave::slave回复,函数如下

出现此错误的条件是执行了net_flush(net)函数。没有收到正常返回,报错,所以出现上述错误。该函数的作用是从库中收集数据。将接收到的binlog文件和binlogpos信息发送到主库。

网络有问题吗?即使出现网络抖动的问题,网络恢复后也应该正常。

为什么会出现这个错误信息?主从同步目前正常,但是从半同步变成了异步。

当我重新启动slave时,错误信息很快就出现了。

因为这个函数向主库发送同步的binlog确认信息,即ack信息,请问主库的ack接收线程有问题吗?主库没有错误信息。

在关键时刻,当你自己做不到的时候,尽量寻求帮助。我把错误信息发给了Oracle公司的MySQL开发人员宋先生。宋先生是负责复制模块的开发者,精通复制。他说我可能遇到了MySQL的Bug,让我检查Bug 79865。在这里非常感谢宋老师的热心无偿的帮助。

错误详情链接:

我们看一下使用select()复用io模型的ack_reciver线程的代码:

错误的要点是因为ret= select(max_fd+1, fds、NULL、NULL、电视); select()函数的max_fd+1输入参数有1024的限制,这个限制不能通过改变nproc来突破吗?

(ulimit -n 命令可以更改nproc 参数)。

似乎所有的疑惑都得到了解答,但继续吧。

笔者使用的环境是5.7.15。同时,笔者使用的操作系统是centOS 7。根据上文后半部分Meiji Kimura的描述信息,在centos 6上重现了该错误,但在centOS7上则没有重现该错误。作者使用的是centos 7。

如何判断mysql是否是半同步复制

在讲这个特性之前,我们先来看看MySQL的复制架构的历史。 MySQL 复制分为三种类型: 第一种是定期复制。它易于构建且应用广泛。这种架构从MySQL诞生以来就产生了。表现得非常好,可以说是非常成熟了。但该架构中的数据是异步的,因此存在数据库丢失的风险。另一种类型是mysql集群。它易于设置并且相对稳定。它是MySQL中最可靠的数据保护架构。它也是唯一一个数据完全同步、绝对零丢失的架构。但业绩却远远落后。第三种是半同步复制,其性能和特性介于两者之间。它是从mysql5.5诞生的,是为了妥协上述两种架构的性能、优缺点。 “我们今天讲第三种架构

我们知道,普通复制,即mysql的异步复制,是依靠mysql的二进制日志,也称为二进制日志来进行数据复制的。比如两台机器,一台主机为主,另一台为从机,即slave

1,正常复制是:事务一(t1)写入binlog缓冲区;dump线程通知slave有新事务t1; binlog buffer执行checkpoint;slave的io线程接收到t1并写入自己的relay log;slave的sql线程写入本地数据库,此时master和slave都可以看到这个新事务,即使master挂掉了,slave可以晋升为新主人了......

3.最大的问题是主从事务更新不同步。即使没有网络或其他系统异常,当业务并发时,slave也必须顺序执行母料交易,导致巨大的延迟。

为了弥补以上场景的缺点,mysql从5.5开始引入了半同步。

即master的dump线程通知slave后,添加一个ack,表示是否收到t1标志码。也就是说,dump线程除了发送t1给slave之外,还负责接收slave的ack。如果发生异常,没有收到ack,会自动降级为普通复制,直到异常修复。

我们可以看到半同步的新问题:​ 1.如果出现异常,就会降级为普通复制。那么从机上出现数据不一致的概率会减少,但并没有完全消除。​​​​ 2.主机转储线程承担了更多的工作,这显然会降低整个数据库的性能。 3、MySQL 5.5、5.6使用的after_commit模式下,即如果slave没有收到事务,也就是写入中继日志之前,网络异常或者不稳定,master恰好挂掉此时,系统切换为从机。机,双方的数据会不一致。这样的话,slave的交易数据就会少一个。

随着MySQL 5.7的发布,半同步复制技术升级为全新的无损半同步复制架构,其成熟度、数据一致性和执行效率都得到了显着提升。

MySQL 5.7 提高了数据复制效率 1. 改进了主从一致性,支持事务确认前等待 ACK

新版本的 semi-sync 增加了参数 rpl_semi_sync_master_wait_point 来控制 master 数据库在返回 semi-sync 时会话事务 一种在事务成功之前提交事务的方法。

该参数有两个值:

AFTER_COMMIT(5.6默认值)

master将每个事务写入binlog,发送给slave并刷新到磁盘(中继日志),同时主库提交事务。主站等待slave的反馈来接收中继日志。 Master收到ACK后才向Client返回commit OK结果。

AFTER_SYNC(5.7 默认,但 5.6 中没有模式)

master将每个事务写入binlog,发送给slave并将其刷新到磁盘(中继日志)。 master等待slave的反馈接收来自中继日志的回执,然后提交事务并向客户端返回commit OK结果。即使主数据库崩溃,提交到主数据库的所有事务也保证与slave的中继日志同步。

因此5.7引入了after_sync模式。主要好处是解决after_commit导致的master crash和slave数据不一致的问题。因此,引入after_sync模式后,所有提交的数据都已被复制,故障转移时数据保持一致。性欲将会加强。

2 性能提升支持发送binlog和接收ack的异步

老版本的半同步受到dump线程的限制。原因是转储线程承担两个不同且非常频繁的任务:将 binlog 传输到 slave。还需要等待slave的反馈信息,两项任务是串行的。转储线程必须等待 slave 返回才能传输下一个事件事务。 dump线程成为了提高整个semi-sync性能的瓶颈。在高并发的业务场景下,这样的机制会影响数据库整体的TPS。

图片:没有ACK接收线程

为了解决上述问题,在5.7版本的semisync框架中,创建了一个独立的ack收集器线程。专门为接收slave的反馈而设计。这样就存在两个关于master的线程独立工作,可以向slave发送binlog,同时接收slave的反馈。

图片:使用ACK接收线程3,性能改进检查主库收到的成功slave写事务反馈的数量。主库接受 ,并为更改高可用性架构提供灵活性。

如图,当count值为2时,master必须等待两次slave的ack

4 性能提升

binlog互斥锁的改进

旧版本在body提交binlog中半同步复制写入session和dump读取binlog的线程的操作,会给binlog加上互斥锁,导致binlog的读写被序列化,引发并发问题。

MySQL 5.7对binlog锁做了以下两个方面的优化

1。删除了 binlog

2 上转储线程的互斥锁。增加了安全裕度,保证binlog的读取安全

5性能改进组提交

5.7引入了一个新变量slave-parallel-type,其可配置值为:

DATABASE(5.7之前默认值) )、基于库的并行复制方法; LOGICAL_CLOCK(5.7中新值),基于组提交的并行复制方式;

MySQL 5.6版本也支持所谓的并行复制,但并行性只是基于DATABASE,即基于库。在用户的MySQL数据库实例中拥有多个DATABASE确实可以帮助提高从属复制的速度。如果用户实例只有一个数据库,则无法实现并行播放,性能甚至可能比原来的单线程还差。不同之处。

MySQL 5.7增加了一种新的并行模式:同时进入COMMIT阶段的事务被分配相同的序列号。这些具有相同序列号的事务可以在备库中同时执行。

MySQL 5.7实现了真正的并行复制。造成这种情况的主要原因是slave服务器的播放与主机一致,即在主服务器上如何并行执行,在slave上进行并行播放。对基于库的并行复制不再有限制,对二进制日志格式也没有特殊要求(对基于库的并行复制也没有要求)。

所以以下序列中可以并发的序列是(第一个数字是last_commited,下一个数字是sequence number):

trx1 1…..2trx2 1……….3trx3 1………… ………………4trx4 2 ………………………….5TRX5 3 …………………………………………………… ……………………………………………………………………………………………………………………………………。 .8

备库并行规则:当事务分布式时,其last_commited序列号小于当前正在执行的事务的最小序列号,则允许执行。

因此

a) trx1执行完毕,last_commit2可以同时执行,trx2和trx3可以继续部署执行

b) trx1执行完成后,可以执行last_commit 3,可以部署trx4

c) trx2执行完成后,可以执行last_commit 4,可以部署trx5、trx6

d) trx3、trx4、trx5完成后,可以执行last_commit 7,可以部署trx7

综上

我们认为MySQL 5.7版本已经优化了Loss-Less半同步复制技术,它具有显着提高成熟度和执行效率。我们建议在使用MySQL 5.7作为生产环境时,可以使用半同步技术作为数据复制方案,实现高可用和读写分离。

请点击进入图片说明

MySQL复制半同步与同步的区别

异步复制

MySQL默认的复制是异步的。主库执行完客户端发送的事务后会立即返回结果给客户端,并不关心从库是否收到。并且处理一下,就会出现问题,主要是如果崩溃了,此时master提交的事务无法传输到slave上。如果此时强行将slave提升为master,可能会导致新master上的数据不完整。

全同步复制

是指当主库完成一个事务时,所有从库都已经完成了该事务才返回给客户端。因为必须等待所有从库完成事务才返回,所以完全同步复制的性能必然会受到严重影响。

半同步复制

在异步复制和全同步复制之间,主库在提交客户端发送的事务后并不立即返回给客户端,而是等待至少一个从库接收并写入在将其返回给客户端之前先记录到中继日志。与异步复制相比,半同步复制提高了数据安全性,但也会造成一定程度的延迟。这一延迟至少是一个 TCP/IP 往返时间。因此,半同步复制最适合在低延迟网络中使用。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

热门