1、第 33 卷第 2 期2023年6月Vol.33 No.2Jun.2023湖 南 工 程 学 院 学 报(自 然 科 学 版)Journal of Hunan Institute of Engineering(Natural Science Edition)收稿日期:2023-04-28作者简介:吴振海(2002-),男,研究方向:应用数学.通信作者:何格新(1974-),男,高级工程师,研究方向:数据库国产化.吴振海1,何格新2(1.东南大学 数学学院,南京 211189;2.尚选(深圳)软件技术有限公司,深圳 518028)摘要:Mysql半同步复制技术在高性能的数据管理中被广泛采用,但它
2、在可靠性方面却存在不足.本文对半同步复制技术进行优化,提出了一种快速全同步复制技术,通过对半同步数据复制过程中的事务流程设置、线程资源合理应用、批量日志应用等技术手段,在保证数据可靠性的基础上降低复制过程中的性能损失,实现了快速的全同步复制.测试结果表明,快速全同步复制技术可以在性能、可靠性和一致性方面做到很好的均衡,有效提高了Mysql存储集群的业务承载能力.关键词:Mysql;异步复制;半同步复制;全同步复制中图分类号:TP311.131文献标识码:A文章编号:1671-119X(2023)02-0038-07Mysql快速全同步复制技术的设计和应用0 引言数据复制是将主机节点服务器上的数
3、据及其变更应用到一个或多个备机节点服务器里,达到主机节点和备机节点数据相同的目的.复制功能是实现数据库系统高可用性、可扩展性、灾难恢复能力、备份等功能的基础,在分布式数据库多副本读写、读写分离、备份容灾等场景应用非常广泛.根据复制技术的发生时机及复制后果,Mysql复制技术可分为异步复制、同步复制、半同步复制三种1.异步复制是Mysql 原生支持的复制技术,主机节点将事务信息写入Binlog文件中时,主机节点会通过 Binlog dump 线程给备机节点发送这些新的Binlog变化,并不等待从库的响应继而提交事务并写入Binlog,所以异步复制不能保证这些事务变化的Binlog数据可靠传输并应
4、用到任何备机节点,从而有数据丢失的可能性1.在 2010 年发布的 Mysql 5.5 版本中,引入了半同步复制,半同步复制解决了异步复制存在的数据可靠性问题,主机节点需要等待至少一个备机节点收到且成功把日志写入Relay log文件,客户端才可收到复制完成的确认消息,从而进入事务的下一个阶段.与异步复制相比,半同步复制在提交成功返回时已知数据至少存在于两个位置,从而提高了数据完整性2.但半同步复制依然存在数据丢失的可能性,在半同步复制中,如果出现异常,在没有任何从库反馈确认消息的情况下,会导致事务等待超时,这种情况下主库将退化为异步复制,直到至少有一个半同步从库恢复正常后,主库才恢复半同步复
5、制.为 提 高 数 据 的 可 靠 性,在 2016 年 发 布 的Mysql 5.7.17版本中引入了一个全新的技术,称之为InnoDB Group Replication,也就是全同步复制.在全同步复制中,当主库执行完一个事务,必须等所有的从库都执行了该事务才返回给客户端,这样就可以完全保证数据在所有节点都被成功复制.但因需等待所有从库执行完该事务才能返回,全同步复制的主机节点完成一个事务的时间会被拉长,导致性能急剧降低1.采用何种复制技术,往往需要在性能、可靠性、一致性三个方面做好均衡.异步复制性能最优,但可靠性差.同步复制可靠性和数据一致性高,但性能表DOI:10.15987/ki.h
6、gbjbz.2023.02.005第2期现最差.半同步复制性能接近异步复制(经测试,半同步复制相对异步复制有10%左右的性能损失,而全同步复制的性能损失超过20%),也可以提供较高的可靠性,但在网络异常等故障的情况下,半同步复制会退化为异步复制,可靠性也无法得到保障.在实际应用中,数据库同步既要求具有全同步复制的数据可靠性,又要求能有接近异步复制的性能.为此,本文设计了快速全同步复制技术,它通过直接在Mysql的事务处理流程中设置断点来处理数据复制,并且应用线程池技术降低系统资源的占用及采用批量提交等技术手段,解决了Mysql现有复制技术的主要问题,达到降低复制带来的性能损失以及在任何情况下保
7、证数据不丢失的目的.1 快速全同步复制技术原理1.1 快速全同步复制快速全同步复制是Mysql存储集群主机节点和备机节点通过Binlog进行复制的一种技术,通过数据复制期间线程资源的重复利用及批量确认等优化手段,在保证主机节点变更日志已经传输到备机节点的基础上,快速响应数据库客户的请求和响应.快速全同步复制技术的架构如图 1 所示,具体运行步骤如下:图1 快速全同步复制技术架构图第一步:主机节点(Master)接收到客户程序的提交请求,在完成本地提交后将数据变更日志通过Binlog Dump 线程发往备机节点(Slave),此时并不给客户程序反馈请求操作成功的消息.第二步:备机节点接收到 n
8、个 Binlog 变更日志后,IO 线程将变更日志写入备机节点的 Relay Log完成后,将写入成功的确认消息(ACK)发回到主机节点的ACK 消息队列(ACK Wait Queue)线程池.第三步:主机节点的Wait线程池收到备机节点的确认消息后,反馈给客户程序,本次请求的处理结束.1.2 快速全同步复制的特点Mysql半同步复制5.6版本和5.7版本的基本原理如图2所示3.Mysql 5.6半同步Mysql 5.7增强半同步图2 Mysql半同步复制架构图吴振海,等:Mysql快速全同步复制技术的设计和应用392023年湖南工程学院学报(自然科学版)Mysql5.6 的半同步是after
9、 commit机制的复制,用户事务在主机节点完成提交之后,用户线程直到等到备机节点确认消息(ACK)后才反馈给客户程序事务成功.Mysql5.7 及以后的增强半同步是 aftersync 的复制机制,用户事务在主机节点提交完成之前,用户线程直到等到备机节点确认消息(ACK)后才完成提交并反馈给客户程序事务成功.这两种不同机制的差别导致了主机节点上不同事务间数据一致性的差别,在性能上和可靠性上没有根本的改变4.1.2.1 线程复用无论是 5.6 版本的半同步复制还是 5.7 版本及以后的增强半同步复制,在用户会话等待备机节点确认消息(Wait ACK)期间,用户会话始终占用一个线程,直到该事务完
10、成才退出.在一个负载高的系统,大量用户会话在等待 ACK 期间将占用大量的线程资源而影响性能.而快速全同步复制利用了线程池技术,每个事务 Commit(包括 DDL、AUTOCOMMIT STMT、COMMIT、XA PREPARE、XA COMMIT 等)在完成所有提交过程后,将 Wait ACK 数据包发送到客户端之前等待备机节点确认.在等待完整 WaitACK时,由于使用了线程池,事务或其会话不占用任何操作系统线程,数据库的工作线程将继续处理来自其他连接的其他请求,这种机制避免了资源浪费,从而使性能明显得到提升.1.2.2 数据可靠性保证在半同步复制中,如果数据复制发生异常(备机节点不可
11、以用或者数据复制所用的网络发生异常)的情况下,主机节点会暂停(Mysql 默认 10 s 左右)对应用的响应,复制方式将降为异步复制.直到数据复制恢复正常,将恢复为半同步复制.当复制方式降为异步复制时,数据可靠性就无法保障,这在某些业务场景是不允许的.而快速全同步复制,在默认情况下是不可以降级为异步复制的(只在特殊情况下方可通过参数配置支持降级),从而保证数据在任何情况下都不会丢失.下面从两个不同场景进行分析,当出现异常的情况时,快速全同步复制如何处理这种异常.场景一:主机节点到备机节点的网络异常.在这种情况下,数据本身虽然没有丢失,但考虑到可靠性要求,数据至少有一个或 N 个副本.因此,在这
12、种异常期间,所有用户的数据都可以在主机节点提交,但客户程序不能获取到数据库事务完成的消息.因此,应用程序需要处理这种异常以保障高可靠性.在分布式数据库中,通常会有一个HA 的组件来自动做切换或其他的操作,如果网路长时间不恢复,将触发主机节点切换的行为.主机节点一旦切换到其他的服务器上(原来的备机节点),之前没有获得确认的事务将在新的主机节点重新提交,而在原来旧的备机节点上已提交的事务也将被回退.在这种情况下,数据不会丢失且始终有N个副本,也不会出现重复提交.场景二:多个备机节点故障.在快速全同步复制中,可以定义至少有1个或N个数据副本,当可用数据副本的数量低于设定的值,用户的请求将不能获得提交
13、确认,直到故障的副本备机节点被修复.1.2.3 批量写入快速全同步复制在性能上的优化还包括批量Relay Log 写入和组提交.批量Relay Log写入是指备机节点可以根据参数配置,在接收到一定数量的Binlog 之后才写入 Relay Log,然后将 ACK 消息批量反馈到主机节点的应用程序.这在一定程度上提高了备机节点的写入效率,并使复制性能得到明显提升.2 快速全同步复制的功能实现Mysql过去的半同步复制和全同步复制技术是通过插件的方式实现,而快速全同步复制技术为了提高复制性能及实现高可靠性,直接在Mysql的事务处理流程里设置断点及增加相应函数,通过在事务处理过程中,增加等待备机节
14、点的 ACK 消息等一系列流程后才完成事务来实现快速全同步.本文设计的快速全同步复制技术具体应用在 Sharding-sphere的Sharding-proxy分库分表解决方案场景上,具体的应用方案如下.在如图 3 所示的架构中,应用程序通过 Shard-ing-Proxy 访问存储集群里的数据,Sharding-Proxy40第2期复制 SQL 语句的路由下发 SQL 到对应的存储集群.在每个存储集群里,通过快速全同步技术实现高可用性5,HA manager 负责集群监测和角色管理(如主从切换).快速全同步技术定义了一系列的数据库参数和状态变量,用于控制和展示快速全同步技术的运行,主机节点和
15、备机节点的实现原理及过程如下.图3 分库分表数据库集群架构图2.1 主机节点快速全同步复制采用了 after-commit 的同步模式.在处理用户会话的工作线程完成事务T提交或prepare(XA prepare)且还未向客户端确认成功(即发送OK包)之前,主节点检查事务T的binlog是否已经收到足够数量的备机ACK.通过主机节点设置参数数据库参数 Fullsync_consistency_level,定义了主节点需要让每个事务等待多少个备机的 ACK,如果是0就不等待任何ACK;如果大于0则等待定义数量备机的ACK.在数据库集群中,数据库管理员根据集群节点数量为每个 Master 节点设置
16、合理的 Fullsync_consis-tency_level.通常的设定方法是对于一个2*n+1个节点的存储节点,设置Fullsync_consistency_level=n,从而在同时有n个节点消失的情况下,集群仍然可以正常写入.也可以支持其他策略,比如要求所有备机全部确认等.若释放条件满足,则工作线程直接返回成功状态给客户端,且完成本次请求处理,否则工作线程就把会话对象放到Fullsync ACK等待队列,然后去处理其他连接中收到的请求.主节点收到 ACK 后会对等待队列中的会话做释放条件检查,满足释放条件的会话会被释放,也就是返回成功状态给客户端.在等待备机ACK的过程中,用户会话并不占用工作线程.如超时(Fullsync_timeout)未收到足够的ACK来释放一个等待的会话时,Mysql存储集群有如下两种策略(由全局变量disable_fullsync_on_slave_ack_timeout来控制):(1)如果 disable_fullsync_on_slave_ack_timeout=1,那么 fullsync 会自动退化为异步,这样后续等待的事务将不再做 fullsy