阿里云RDS深度定制-XA Crash Safe

简介: 近几年,随着分布式数据库系统的兴起,特别是基于MySQL分布式数据库系统,会用到XA来保证全局事务的一致性。众所周知,MySQL对XA事务的支持是比较弱的,存在很多问题。为了满足分布式数据库系统对XA事务的要求,阿里做了大量的工作。 本篇内容将从两部分介绍,第一部分介绍在AliSQL分支上做的一些实用功能;第二部分介绍XA Crash Safe问题的根源和在5.7和8.0版本上的实现原理。

一、阿里云RDS MySQL(AliSQL)

AliSQL是MySQL的分支,阿里在这个分支上做了很多深度的定制,以充分挖掘MySQL的潜力。AliSQL支撑了阿里集团电商业务十余年,其稳定性、安全性和高性能是经过了极其严苛实践检验的。除此之外,AliSQL做了很多实用性的功能,以提高MySQL的易用性和使用效率。下图是AliSQL上重要的功能的列表。

image001.png

二、RDS定制化功能介绍

1. 实用性:SQL Outline 在线固化SQL执行计划

我们使用MySQL的时候时常会碰到一种情况,即业务跑着的时候有个SQL执行会变慢,分析之后发现是这个SQL执行计划发生了变化。这种变化有很多原因,比如bug或是版本升级了等等。

MySQL就提供了hint功能,它可以使我们在SQL语句里增加一些提示,以保证SQL在生成执行计划的时候是按照提示来工作的。但这只是比较理想化的状态,实际情况中这样是很不方便的,因为业务已经在线上运行了,这个时候即使能够改变业务的SQL,也需要一个很漫长的时间和过程。

为了解决这个问题,就有了SQL Outline的功能。这个功能不需要改变应用的SQL语句,只需要在server端告诉RDS碰到哪种类型的特定的SQL,可以给它定制一个hint,然后按照用户指定的方式执行。

2. 实用性:Performance Agent可诊断、可度量

我们在实例的监控上也做了大量的工作,从而可以很容易的分析数据库中的一些问题。首先就是实例级别的统计信息,它包括了操作系统层面、server层和InnoDB等共计55个指标。然后把它放到一个Performance表中,每秒钟进行一次统计。通过这些统计的信息可以分析系统出现问题的原因。

3. 实用性:Performance Insight可诊断、可度量

这个是对象级别性能度量的指标,包括表和索引。这些统计可以支持业务数据模型的优化和变更。

image002.png

还有语句级别的统计信息。MySQL本身具有语句级别统计信息,但是它的统计信息不够丰富,因此在这个基础上我们又增加了更多实用性的统计信息,比如CPU的使用时间,加锁消耗的时间等。

image004.png

MySQL里用了大量的Mutex来保证多线程之间的数据访问,我们加了对于Mutex加锁时消耗时间的统计,方便对数据库热点的分析。

这些统计信息提供了更充分的数据依据,帮助我们做快速的问题定位。

4. 稳定性:Buffer Pool优化

在稳定性方面,我们也做了大量的工作。首先是Buffer Pool的优化。

云上用户会有临时变配的需求。举个例子,在业务高峰时,若希望实例临时规格变大,过了高峰之后再把规格降下来。MySQL是支持线上的resize,但是它的稳定性不够好。在做Online resize对性能的影响还是比较大的。AliSQL针对这个做了优化后,可以看到下图蓝色线条是动态变配的波动曲线,稳定性好很多。

image005.png

5. 稳定性:Concurrency Control 并发控制

用户常常会碰到几个SQL过来一下子就把实例的CPU打满的情况,或者是内存耗光等类似的情况。Concurrency Control并发控制这个功能,可以让用户根据实际使用情况,对SQL限制执行个数,以提高实例整体运行的稳定性。

image006.png

6. 安全性:TDE支持国密SM4

企业级用户对于安全性的要求越来越高,对于各种各样的加密、密码强度、生命周期等要求也越来越多。AliSQL在安全这块做了更全面的支持,比如对于加密来讲,除了支持TDE这种AES的加密算法,还支持国密加密算法SM4,对于有涉密要求的用户可以用SM4的加密算法来保证数据的安全性。

7. 安全性:Recycle Bin防止误删除

当用户在做删除表或是Truncate表的时候,使用这个回收站功能,并不会把数据文件直接删除掉,而是会把这些表放到一个回收站里,这样就避免了用户在误删之后数据丢失的风险,误删除后还能通过回收站把删除的数据快速找回。

8. 安全性:Flashback Query

不仅是表级的误删除,当我们对某一些数据更新的范围错误了之后,使用Flashback机制,可以恢复到更新前的历史版本。同时,用户还可以自定义查询某个时间戳的某个数据。

所以Flashback Query对误操作删除恢复或是回档需求是很有效的方法。

9. 高性能:Binlog In Redo

对比原生MySQL,AliSQL的性能提升很多。首先介绍的是Binlog In Redo功能。众所周知,在MySQL里面,事务提交的时候需要持久化两次,因为要执行两阶段的事务提交过程。这里面做了一个改进,即可以把Binlog写到Redo里面,这样的话就只需要持久化一次Redolog,Binlog可以异步刷盘。

通过这种方式,用户事务在提交的时候就只需要一次刷盘动作,因此时延会降低,吞吐量会增大。

image007.png

上图是基于两个Binlog in Redo版本的测试结果。通过左侧第二个版本的数据,我们发现性能会提高很多。对于Update non index来讲,可以有大概38%的性能提升。对于write only来讲,也可以达到25%的性能提升。

10. 高性能:Fast Query Cache

AliSQL针对Query Cache在并发控制、内存管理和缓存机制等等做了大量的优化。

优化之后,它的性能提升非常明显。在point select的场景下,性能提升甚至可以达到100%以上。通过测试发现,在rewrite模式命中率比较低的情况下,几乎没有任何性能损失。所以用户在读比较多的场景就可以把Query Cache打开,可以保持稳定高效的状态。

11. 高性能:DDL Optimization

围绕DDL我们做了大量优化。

用户在使用DDL的时候会发现,如果表特别大需要做rebuild或更新数据等操作的时候,效率非常低。主要是因为DDL利用Buffer Pool的模型是效率低下的模型。优化之后,对于rebuild表的这种操作效率会高很多,对于其他SQL语句的影响也会降低很多。

下图是针对Create Index和Optimize Table的测试,可以看到优化之后,操作都会有10倍以上的性能提升。

image008.png

三、XA Crash Safe 介绍

1. XA Crash Safe背景

抛开XA Crash Safe本身,MySQL本身也有Crash Safe机制。为什么会需要这样的机制呢,因为在MySQL里,同时包括Binlog和数据两个部分,可以理解为存了两份一模一样的数据。为了保证这两份数据的一致性,MySQL Crash Safe实现了两阶段提交机制。为了保证Binlog和数据的一致性,任何用户的事务都会被转化成为两阶段的事务,首先就是进行prepare,然后再写Binlog并持久化,最后做事务的提交。所以在这两个阶段的提交过程中,Prepare、刷Redo、写Binlog和刷Binlog的执行顺序是保持不变的。

如何保证Crash Safe呢?这要看它恢复的处理过程。在实际的事务执行过程中,只要是Binlog有这个事务,一定是Prepare的状态。那么利用这个原则,在MySQL Crash重启的时候,它会取出所有已经prepare的事务,把它们的XID取出来,扫描最后一个Binlog文件,然后确认XID所对应的事务是否已经存储到Binlog里了。如果已经存储过了,就直接提交即可;如果还没有存储,就回滚掉。通过这个Crash Recovery机制后,Binlog里的数据就和引擎里面的数据保持一致了。

对于普通用户事务可以用两阶段来保证Crash Safe,那么对于用户的XA事务怎么处理呢?

在Binlog里会把这个事务分为独立的两部分,当用户执行XA Prepare的时候,会写Binlog文件,然后把这个Prepare状态执行到引擎里,这是完全独立的。用户在XA Commit里,可以在任何时间执行,当用户在执行XA Commit之后会被再记录一次Binlog,所以这两者是完全脱离的。

对于普通的用户事务,执行过程只记录一次Binlog,而且整个事务是一个基本的单元存在Binlog中的;对于XA事务,这就是分开的。而且它整个过程是先写Binlog,然后才去把状态持久化到引擎中,做引擎的prepare。对于MySQL来讲,不能保证外部XA事务数据和Binlog的一致性。

也就是说当写完Binlog,还没有在引擎中执行prepare和commit,这个时候就Crash了,那么它起来之后就变成,Binlog里有事务记录,而在引擎里却丢失了,也许只以prepare的状态停留在那里,这就没有被提交。

2. XA Crash Safe:基于MySQL 5.7的修复

1)调整执行顺序

为了更好的支持分布式数据库系统,在MySQL 5.7的时候,阿里就做过对于XA Crash Safe的修复。这个修复是把执行顺序做了颠倒,即先执行引擎的Prepare,再写Binlog,这样它就跟普通事务的过程一样了。在Prepare之后做Crash,如果用户的XA事务做了Prepare之后没有记Binlog,那么数据就会被回滚掉。但是由于XA事务跟普通事务不太一样,需要更多处理来支持回滚,而且它也不是一个完善的方案。因为用户具有多样性,比如用户执行了一个事务但是并没有记Binlog,这个时候就没法区分是否记录了Binlog。另外,XA事务的Prepare和Commit是分开的,当用户将Prepare事务记录到很久以前的Binlog里了,也不能区分用户是否记录了Binlog。

这种情况下就需要一个解决方案,即在做Binlog rotation时候,要把所有Prepare事务的XID记录到Binlog中。这样我们就可以通过最后一个Binlog去了解所有Prepare状态的XID,然后就可以通过Rollback的方式保持Binlog和数据的一致性。

2)调整Recovery逻辑

Commit执行了另外一种逻辑,即先执行Binlog,在执行后发现事务是Prepare状态,且在Binlog中记录了Commit或Rollback,那么执行Commit或Rollback。

这就是MySQL 5.7上XA Crash Safe的修复的过程。

3. XA Crash Safe:MySQL 8.0 Gtid和事务的一致性

MySQL 8.0采用了另外一种方法。介绍这个方法之前,首先介绍下MySQL 8.0 Gtid和事务的一致性。在MySQL8.0.17的时候,引入克隆功能,这个功能可以把Gtid记到事务的undo里。记到Undo里的过程也很简单,在Prepare的时候还是先记Binlog,然后引擎里做事务Prepare的时候,去监测这个事务是否有Gtid。如果有,在修改事务状态时会连通Gtid一起写到Undo里。如果Crash之后,Prepare丢了,那么Gtid一定也是不存在的,反之亦然。在Commit的时候也同理。这样做,克隆的时候用户使用起来就会非常简单。

但是Rollback是个特例,尤其是对于XA事务来说。Rollback也会记录一个Gtid。Rollback在引擎里的做法是,把事务状态改成active之后就会自然回滚,所以在active的时候它也会记一个Gtid,所以XA Rollback会记录Binlog也会产生Gtid。整个操作也是原子的。

Gtid最终会持久化到Gtid_executed表里。之所以要做汇总是因为Undo本身需要Purge,否则会越来越大,而且检索效率也非常低。所以虽然在Prepare后会放进Undo里,但是实际上最后都会汇总到Gti_executed表中,然后会有一个单独的Gtid Flush的线程,它会周期性的把Gtid list里的Gtid写到Gtid_executd表中。写到表后,只需要持续化整个表后,undo就可以丢掉了,这样始终会有一个完整的Gtid集合。

image009.png

对于外部XA事务会记录两个Gtid,一个是Prepare的时候,一个是Commit的时候。最初实现这个功能的时候,只会记录一个Gtid,也就是说在commit的时候会把prepare的给覆盖了。这就要求,在Commit之前需要把Prepare的Gtid持久化到Gtid executed表里,效率非常低。后来官方优化成将两个Gtid分别存在两个位置,这就大大提高了效率。

经过以上的优化之后,我们可以看到Gtid和事务数据之间的关系,是Gtid Executed表中的Gtid代表了InnoDB中已经执行了的事务的Gtid。这两者之间是原子对应的关系。

通过这样的对应关系,我们可以在系统启动的时候做Apply Binlog这样的操作,来保证外部XA事务的Crash Safe。

image010.png

根据Gtid Executed表中的Gtid就可以知道哪些事务在引擎里存在,然后通重放Binlog里的事务将引擎里的数据补齐。通过这样的方式,不需要修改过添加Binlog Event,原来的recover过程也不需要变化。只需要在recover之后,检查Gtid Executed的表,然后对比Binlog。将缺少的事务重新Apply一下就可以了,这样就可以保证XA事务的Crash Safe。

原文链接
本文为阿里云原创内容,未经允许不得转载。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/512213.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java集合表_java集合类散列表

哈希表是种数据结构,它可以提供快速的插入操作和查找操作。第一次接触哈希表时,它的优点多得让人难以置信。不论哈希表中有多少数据,插入和删除(有时包括侧除)只需要接近常量的时间即0(1)的时间级。实际上,这只需要几条机器指令。…

庖丁解牛|图解 MySQL 8.0 优化器查询转换篇

简介: 本篇介绍子查询、分析表和JOIN的复杂转换过程 一 背景和架构 在《庖丁解牛-图解MySQL 8.0优化器查询解析篇》一文中我们重点介绍了MySQL最新版本8.0.25关于SQL基本元素表、列、函数、聚合、分组、排序等元素的解析、设置和转换过程,本篇我们继续…

Java 底层知识:什么是 “桥接方法” ?

作者 | 小志来源 | 程序员小灰导语笔者在最近的日常工作中,因业务需要,研究 Java 字节码层面的知识。具体是,需要根据类字节码,获取特定方法名的方法入参,此方法名在源码中只有一个。但是在实际使用中发现:…

ACMMM2021|在多模态训练中融入“知识+图谱”:方法及电商应用实践

简介: 随着人工智能技术的不断发展,知识图谱作为人工智能领域的知识支柱,以其强大的知识表示和推理能力受到学术界和产业界的广泛关注。近年来,知识图谱在语义搜索、问答、知识管理等领域得到了广泛的应用。 作者 | 朱渝珊 来源 |…

带你体验云原生场景下 Serverless 应用编程模型

简介: 阿里云 Knative 基于 ASK 之上,在完全兼容社区 Knaitve 的同时对 FC、ECI 工作负载进行统一应用编排,支持事件驱动、自动弹性,为您提供统一的 Serverless 应用编程模型。 背景 阿里云 Serverless Kubernetes(A…

CSO全球网络安全大会来了,权威奖项征集中

全球网络安全顶级峰会——IDC 2022 全球CSO网络安全大会(以下简称大会)将于2022年6月首次落地中国。本届大会以“聚力数据安全 赋能企业现代化”为主题,由Foundry(IDG)/IDC联合上海市信息安全行业协会共同举办&#xf…

stream of java_Java 8 新特性-Stream更优雅的处理集合入门

Java 8 新特性之——Stream一. 简单介绍Stream是Java 8提出了的一种新的对集合对象功能的增强。它集合Lambda表达式,对集合提供了一些非常便利,高效的操作,使得代码具有非常高的可读性,优雅性!!举个例子来说…

MySQL深潜|剖析Performance Schema内存管理

简介: 本文主要是通过对PFS引擎的内存管理源码的阅读,解读PFS内存分配及释放原理,深入剖析其中存在的一些问题,以及一些改进思路。 一 引言 MySQL Performance schema(PFS)是MySQL提供的强大的性能监控诊断工具,提供…

敲地鼠java_Java实现的打地鼠小游戏完整示例【附源码下载】

本文实例讲述了Java实现的打地鼠小游戏。分享给大家供大家参考,具体如下:这里涉及到java线程和GUI的相关知识,一个简单的java小游戏打地鼠,有兴趣的朋友可以优化一下。先来看看运行效果:具体代码:Mouse.jav…

深入理解 Docker 网络原理

作者 | 渡、来源 | CSDN博客Docker网络原理容器是相对独立的环境,相当于一个小型的Linux系统,外界无法直接访问,那他是怎么做的呢,这里我们先了解下Linux veth pair。1. Linux veth pairveth pair是成对出现的一种虚拟网络设备接口…

全网首发|阿里资深技术专家数仓调优经验分享(上)

简介: 本篇文章总结了AnalyticDB表的设计的最佳经验、数据写入的最佳经验、高效查询的最佳实践,以及一些常见的问题。 随着云原生数据仓库AnalyticDB for MySQL(下文统一简称:AnalyticDB)在阿里集团各个业务线、社会上…

重大技术突破首次发布!十问解密云栖大会!

简介: 2021年10月19日,杭州,云栖大会正式开幕。大会上,阿里巴巴正式发布自研云芯片倚天710,这是阿里云推进“一云多芯”策略的重要一步,也是阿里第一颗为云而生的CPU芯片,将在阿里云数据中心部署…

Redis 缓存击穿(失效)、缓存穿透、缓存雪崩怎么解决?

作者 | 码哥来源 | 码哥字节原始数据存储在 DB 中(如 MySQL、Hbase 等),但 DB 的读写性能低、延迟高。比如 MySQL 在 4 核 8G 上的 TPS 5000,QPS 10000 左右,读写平均耗时 10~100 ms。用 Redis 作为缓存系统正好可以…

在 Kubernetes 集群中使用 MetalLB 作为 Load Balancer(上)

作者 | Addo Zhang来源 | 云原生指北TL;DR网络方面的知识又多又杂,很多又是系统内核的部分。原本自己不是做网络方面的,系统内核知识也薄弱。但恰恰是这些陌生的内容满满的诱惑,加上现在的工作跟网络关联更多了,逮住机…

Java程序员情人节_盘点程序员情人节的表白,前端程序员最浪漫,后端不服来战...

今天是 2 月 14 日情人节,我看公众号后台有好多人在回复关键字:情人节表白代码。我想,我作为大家的校长,必须给大家送一波福利代码啊!我是真没想到,竟然很多程序员都想用代码表白,还整的挺浪漫的&#xff0…

GRPC: 如何实现分布式日志跟踪?

简介: 本文将介绍如何在 gRPC 分布式场景中,实现 API 的日志跟踪。 介绍 本文将介绍如何在 gRPC 分布式场景中,实现 API 的日志追踪。 什么是 API 日志追踪? 一个 API 请求会跨多个微服务,我们希望通过一个唯一的 ID…

一文搞懂物联网Modbus通讯协议

简介: 一般来说,常见的物联网通讯协议众多,如蓝牙、Zigbee、WiFi、ModBus、PROFINET、EtherCAT、蜂窝等。而在众多的物联网通讯协议中,Modbus是当前非常流行的一种通讯协议。它一种串行通信协议,是Modicon公司于1979年…

快看世界技术VP安尝思:从漫画到视频,如何用技术赋能创作

供稿 | 快看世界 2月25日,在火山引擎举办的视频云科技原力峰会上,快看世界技术VP安尝思受邀参加,并发表主题为《如何搭建轻量高效的视频技术体系》的演讲。 安尝思表示,快看视频内容的革命性变化来自于漫剧的推出,在过…

2021云栖大会丨阿里云发布第四代神龙架构,提供业界首个大规模弹性RDMA加速能力

简介: 10月20日,2021年杭州栖大云会上,阿里云发布第四代神龙架构,升级至全新的eRMDA网络架构,是业界首个大规模弹性RDMA加速能力。 10月20日,2021年杭州栖大云会上,阿里云发布第四代神龙架构。…

Rambus推出面向下一代数据中心的PCIe 6.0控制器

新闻摘要: 将先进的人工智能/机器学习、存储和网络应用的性能提升至64 GT/s优化了功耗、面积和延迟,全方位实现PCIe 6.0特性集成IDE引擎提供最先进的数据安全Rambus PCIe 6.0控制器框图 作为业界领先的芯片和IP核供应商,致力于使数据传输更…