MySQL 5.7 重要记事
2018-05-30 18:11:53 阿炯

本站赞助商链接,请多关照。 半同步复制技术介绍


复制架构衍生史

在谈这个特性之前,我们先来看看MySQL的复制架构衍生史。MySQL的复制分为四种:

普通的replication,异步同步。 搭建简单,使用非常广泛,从mysql诞生之初,就产生了这种架构,性能非常好,可谓非常成熟。 但是这种架构数据是异步的,所以有丢失数据库的风险。

semi-sync replication,半同步。性能,功能都介于异步和全同步中间。从mysql5.5开始诞生,目的是为了折中上述两种架构的性能以及优缺点。

sync replication,全同步。目前官方5.7基于Group replication的全同步技术处在labs版本,离正式集成已经不远。全同步技术带来了更多的数据一致性保障。相信是未来同步技术一个重要方向,值得期待。

mysql cluster,基于NDB引擎,搭建也简单,本身也比较稳定,是mysql里面对数据保护最靠谱的架构,也是目前唯一一个数据完全同步的架构,数据零丢失。不过对业务比较挑剔,限制也较多。


半同步复制

在此谈论第二种架构。我们知道,普通的replication,即mysql的异步复制,依靠mysql二进制日志也即binary log进行数据复制。比如两台机器,一台主机(master),另外一台是从机(slave)。

正常的复制为:事务一(t1)写入binlog buffer;dumper 线程通知slave有新的事务t1;binlog buffer 进行checkpoint;slave的io线程接收到t1并写入到自己的的relay log;slave的sql线程写入到本地数据库。 这时,master和slave都能看到这条新的事务,即使master挂了,slave可以提升为新的master。

异常的复制为:事务一(t1)写入binlog buffer;dumper 线程通知slave有新的事务t1;binlog buffer 进行checkpoint;slave因为网络不稳定,一直没有收到t1;master 挂掉,slave提升为新的master,t1丢失。

很大的问题是:主机和从机事务更新的不同步,就算是没有网络或者其他系统的异常,当业务并发上来时,slave因为要顺序执行master批量事务,导致很大的延迟。

为了弥补以上几种场景的不足,mysql从5.5开始推出了半同步。即在master的dumper线程通知slave后,增加了一个ack,即是否成功收到t1的标志码。也就是dumper线程除了发送t1到slave,还承担了接收slave的ack工作。如果出现异常,没有收到ack,那么将自动降级为普通的复制,直到异常修复。 我们可以看到半同步带来的新问题:

    如果异常发生,会降级为普通的复制。 那么从机出现数据不一致的几率会减少,并不是完全消失。
    主机dumper线程承担的工作变多了,这样显然会降低整个数据库的性能。
    在MySQL 5.5和5.6使用after_commit的模式下, 即如果slave 没有收到事务,也就是还没有写入到relay log 之前,网络出现异常或者不稳定,此时刚好master挂了,系统切换到从机,两边的数据就会出现不一致。 在此情况下,slave会少一个事务的数据。


随着MySQL 5.7版本的发布,半同步复制技术升级为全新的Loss-less Semi-Synchronous Replication架构,其成熟度、数据一致性与执行效率得到显著的提升。

MySQL 5.7 数据复制效率的改进

主从一致性加强, 支持在事务commit前等待ACK。新版本的semi sync 增加了rpl_semi_sync_master_wait_point参数, 来控制半同步模式下主库在返回给会话事务成功之前提交事务的方式。 该参数有两个值:

AFTER_COMMIT(5.6默认值)master将每个事务写入binlog ,传递到slave 刷新到磁盘(relay log),同时主库提交事务。master等待slave 反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。



AFTER_SYNC(5.7默认值,但5.6中无此模式)master 将每个事务写入binlog , 传递到slave 刷新到磁盘(relay log)。master等待slave 反馈接收到relay log的ack之后,再提交事务并且返回commit OK结果给客户端。 即使主库crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中。因此5.7引入了after_sync模式,带来的主要收益是解决after_commit导致的master crash主从间数据不一致问题,因此在引入after_sync模式后,所有提交的数据已经都被复制,故障切换时数据一致性将得到提升。



性能提升, 支持发送binlog和接受ack的异步化

旧版本的semi sync 受限于dump thread ,原因是dump thread 承担了两份不同且又十分频繁的任务:传送binlog 给slave ,还需要等待slave反馈信息,而且这两个任务是串行的,dump thread 必须等待 slave 返回之后才会传送下一个 events 事务。dump thread 已然成为整个半同步提高性能的瓶颈。在高并发业务场景下,这样的机制会影响数据库整体的TPS 。



为了解决上述问题,在5.7版本的semi sync 框架中,独立出一个 ack collector thread ,专门用于接收slave 的反馈信息。这样master 上有两个线程独立工作,可以同时发送binlog 到slave ,和接收slave的反馈。



性能提升, 控制主库接收slave 写事务成功反馈数量

MySQL 5.7 新增了rpl_semi_sync_master_wait_slave_count参数,可以用来控制主库接受多少个slave写事务成功反馈,给高可用架构切换提供了灵活性。如图所示,当count值为2时,master需等待两个slave的ack。



性能提升, Binlog 互斥锁改进

旧版本半同步复制在主提交binlog的写会话和dump thread读binlog的操作都会对binlog添加互斥锁,导致binlog文件的读写是串行化的,存在并发度的问题。



MySQL 5.7 对binlog lock进行了以下两方面优化: 1. 移除了dump thread对binlog的互斥锁 2. 加入了安全边际保证binlog的读安全



性能提升, 组提交

MySQL 5.7 引入了新的变量slave-parallel-type,其可以配置的值有:1. DATABASE(5.7之前默认值),基于库的并行复制方式; 2. LOGICAL_CLOCK (5.7新增值),基于组提交的并行复制方式;MySQL 5.6版本也支持所谓的并行复制,但是其并行只是基于DATABASE的,也就是基于库的。如果用户的MySQL数据库实例中存在多个DATABASE ,对于从机复制的速度的确可以有比较大的帮助,如果用户实例仅有一个库,那么就无法实现并行回放,甚至性能会比原来的单线程更差。

MySQL5.7中增加了一种新的并行模式:为同时进入COMMIT阶段的事务分配相同的序列号,这些拥有相同序列号的事务在备库是可以并发执行的。MySQL 5.7真正实现的并行复制,这其中最为主要的原因就是slave服务器的回放与主机是一致的即master服务器上是怎么并行执行的slave上就怎样进行并行回放。不再有库的并行复制限制,对于二进制日志格式也无特殊的要求(基于库的并行复制也没有要求)。因此下面的序列中可以并发的序列为(其中前面一个数字为last_committed ,后面一个数字为sequence_number):

trx1 1…..2
trx2 1………….3
trx3 1…………………….4
trx4        2……………………….5
trx5               3…………………………..6
trx6                     3………………………………7
trx7                            6………………………………..8

备库并行规则:当分发一个事务时,其last_committed 序列号比当前正在执行的事务的最小sequence_number要小时,则允许执行。因此: 1. trx1执行,last_commit<2的可并发,trx2, trx3可继续分发执行 2. trx1执行完成后,last_commit < 3的可以执行, trx4可分发 3. trx2执行完成后,last_commit < 4的可以执行, trx5, trx6可分发 4. trx3、trx4、trx5完成后,last_commit < 7的可以执行,trx7可分发

综述

我们认为MySQL 5.7版对半同步复制技术的优化,使得其成熟度和执行效率都得到了质的提高。我们建议在使用MySQL 5.7作为生产环境的部署时,可以使用半同步技术作为高可用与读写分离方案的数据复制方案。

本文转自:MySQL 5.7 深度解析: 半同步复制技术,感谢原作者。

MySQL5.7 停服

2023年9月,信通院下属的云计算开源产业联盟发布了一个关于 MySQL 数据库开源生态的研究报告《开源数据库生态发展研究报告 - MySQL 开源数据库》,其中提到了在 10 月份 MySQL 社区将会发生一件大事 --MySQL 5.7 将会于 2023 年 10 月 21 日结束服务期(EOL)。MySQL 目前已经成为中国用户使用最广泛的开源数据库,其中 5.7 版本的用户的比重又是最高的,因此 MySQL 5.7 EOL 事件会影响到很多 MySQL 用户。

根据报告中的统计数字,MySQL 5.7 用户占比在国内高达 47%。届时这些用户将会面临选择,如何应对 EOL 事件。实际上 2020 年的时候就有一些机构提醒用户,MySQL 5.7 按照生命周期将于 2023 年到达服务期限,当时这件事还在 MySQL 社区和 DBA 圈子里引发过一些关于开源项目安全性的讨论。3 年后,这个狼来了的问题,终于正式要面对我们了。实际上数据库 EOL 的问题并不是在 MySQL 5.7 上第一次出现,Oracle 用户都很清楚每个版本 EOL 的时间表。只不过 Oracle 官方依然会对付费用户提供延长期服务,还会在数年时间里继续为这些用户发布安全补丁包,因此 EOL 的 Oracle 版本依然可以通过各种渠道找到安全补丁包。而作为开源数据库的 MySQL,EOL 就意味着开源社区不再提供安全与功能方面的补丁升级了。

面对 MySQL 5.7 EOL 这个事件,percona 官方宣布了付费支持的计划,在 EOL 之后的三年内,percona 会为需要服务的客户提供收费服务支持。不过支持的力度如何,是否承诺对安全问题发布补丁不得而知。MariaDB 一贯的对 MySQL 持有敌意,他们希望 MySQL 5.7 用户不要升级 MySQL 8 了,而是通过 11 条简单的命令迁移到 MariaDB 上去。除此之外,一些云厂商也纷纷提出了解决方案。云厂商则纷纷发布了延长服务的声明,微软 Azure 将会在 MySQL 5.7 EOL 之后,为其公有云用户提供延长的服务,由 Azure 官方提供支持,最晚到 2025 年。类似情况,亚马逊也将为其公有云用户提供一年期的支持。不论是亚马逊还是微软,当延长服务期结束后,MySQL 5.7 用户将必须强制升级到 MySQL 8 或者迁移到其他数据库上。

面对这个问题,国内的 MySQL 生态的数据库厂商也纷纷给出了自己的迁移方案,希望吸引这部分用户到自己的产品上来。和一些 MySQL 5.7 用户做了一些交流,根据他们反馈的情况,以及业内对此问题的应对措施,再结合报告中反馈的四种情况,我总结了一下,大致有六种应对措施。

第一条路径:直接升级到 8.0
做出此选择的 MySQL5.7 用户占比较高,此类用户对此问题早已了解,并且在半年前就已经开始应对工作。MySQL 5.7 升级到 8.0 不仅仅是更换一个数据库版本而已,因为 8.0 与 5.7 在技术上有较大的差异,CBO 优化器与 SQL 引擎都有一定的不同,因此数据库升级后应用需要做全面的测试,对于不够兼容的部分代码做一定的修改才能确保顺利迁移。因此采用第一种路径的用户,需要做一定的提前准备。

第二条路径:直接迁 移到 MySQL 兼容的国产数据库
有一部分客户考虑到信创的问题,原本就已经计划对数据库进行国产化替代,准备一次性到位。如果用国产数据库替代,那么可以选择的路径也很多,很多国产数据库产品就是 MySQL 生态产品,比如腾讯 TDSQL、万里 GreatSQL、中兴通讯 GoldenDB、Oceanbase、阿里 PolarDB-x 等。如果不需要使用存储过程,还可以考虑 TiDB。很多国产数据库也有 MySQL 兼容模式,虽然不能完全兼容 MySQL,应用做少量的修改也可以迁移过去。达梦、人大金仓、GaussDB 等数据库都有 MySQL 兼容模式。直接迁移到国产数据库的优点是从根本上完成数据库国产化替代,不过缺点也很明显,一方面是迁移需要一定的资金,也需要一定的时间,另外一方面是国产数据库许可证采购的总体成本不低。

第三条路径:迁移到其他 MySQL 生态的开源产品
比如 MariaDB 和国内的 GreatSQL。 向 MariaDB 迁移的用户主要考虑的是摆脱 Oracle 生态,选择一个相对更加安全的开源项目,不过 MariaDB 社区是否足够安全,也是仁者见仁智者见智。GreatSQL 是 Percona Server 的一个开源分支,也基于 GPLv2 协议,代码托管在国内的 gitee 上。在保持与 Percona Server 兼容的基础上,会更快速地修复漏洞,保障用户的数据安全。随后 GreatSQL 开源社区将会在官网上开设一个 MySQL5.7 停服专区,帮助 MySQL 5.7 的用户解决一些停服带来的问题,为某些暂时无法升级的用户提供支撑。随着软件供应链安全方面的需求的不断加强,国内开源项目分支的发展将会迎来高速发展。这条路径的迁移成本较低,缺点是用户目前对国内的开源分支的认可度还存在一定问题。

第四条路径:对于公有云用户,依托云平台再多撑一两年,在一两年中再选择方向。公有云厂商还会对 MySQL 5.7 提供一定时间的延长支持。公有云用户先观望一年再选择稳妥的技术路线的比例是比较高的。这条路线获得了一定时间的缓冲区,以便于做出更为科学的决策,不过仅仅是过渡期的临时做法。

第五条路径:换门
从 MySQL 直接更换数据库种类,转投另外一个开源数据库 PG 阵营。和摄影界换门一样,采取这条路径是要下大决心的。因为以往的应用都要修改,数据都要迁移,以往积累的应用开发与运维经验也都要放弃。

第六条路径:不变应万变
数据库都是在内部使用的,因此把网络的安全边界扎牢,哪怕有安全漏洞,也不升级,不改变,等到应用系统升级的时候再考虑升级或者更换数据库。选择这条路线的用户比例不低,这条路径成本最低,不过要承担一定的安全风险。采用这条路线的用户把安全依托在网络安全和边界安全上,通过扎紧篱笆来防止安全事故。

最后要表达的观点是,EOL 是很多产品都会面临的事件,无需过度担心。不过数据库产品的 EOL 影响面更广一些,处理起来也更麻烦一些,特别是 MySQL 5.7,对于一些复杂一些的系统,直接升级到 8.0 还是需要做一些验证工作的。作为一个核心的数据资产承载体,没有安全补丁处于裸奔状态的数据库也是一个比较大的隐患。从软件供应链安全上看,商用数据库 Oracle 在代码上的安全性要高于 MySQL 这样的开源数据库,再加上 Oracle 延长期服务依然在出安全补丁,用户也可以通过一些特殊渠道获得安全补丁。因此相对于 Oracle 数据库的版本 EOL,MySQL 的 EOL 问题更受企业级用户的重视。面对即将到来的 MySQL 5.7 EOL,IT 部门的领导和 DBA 哪怕没有做什么动作,多思考一下也是好的。