一、阿里云RDSMySQL(AliSQL)
AliSQL是MySQL的分支,阿里在这个分支上做了很多深度的定制,以充分挖掘MySQL的潜力。AliSQL支撑了阿里集团电商业务十余年,其稳定性、安全性和高性能是经过了极其严苛实践检验的。除此之外,AliSQL做了很多实用性的功能,以提高MySQL的易用性和使用效率。下图是AliSQL上重要的功能的列表。
二、RDS定制化功能介绍
1.实用性:SQLOutline在线固化SQL执行计划
我们使用MySQL的时候时常会碰到一种情况,即业务跑着的时候有个SQL执行会变慢,分析之后发现是这个SQL执行计划发生了变化。这种变化有很多原因,比如bug或是版本升级了等等。
MySQL就提供了hint功能,它可以使我们在SQL语句里增加一些提示,以保证SQL在生成执行计划的时候是按照提示来工作的。但这只是比较理想化的状态,实际情况中这样是很不方便的,因为业务已经在线上运行了,这个时候即使能够改变业务的SQL,也需要一个很漫长的时间和过程。
为了解决这个问题,就有了SQLOutline的功能。这个功能不需要改变应用的SQL语句,只需要在server端告诉RDS碰到哪种类型的特定的SQL,可以给它定制一个hint,然后按照用户指定的方式执行。
2.实用性:PerformanceAgent可诊断、可度量
我们在实例的监控上也做了大量的工作,从而可以很容易的分析数据库中的一些问题。首先就是实例级别的统计信息,它包括了操作系统层面、server层和InnoDB等共计55个指标。然后把它放到一个Performance表中,每秒钟进行一次统计。通过这些统计的信息可以分析系统出现问题的原因。
3.实用性:PerformanceInsight可诊断、可度量
这个是对象级别性能度量的指标,包括表和索引。这些统计可以支持业务数据模型的优化和变更。
还有语句级别的统计信息。MySQL本身具有语句级别统计信息,但是它的统计信息不够丰富,因此在这个基础上我们又增加了更多实用性的统计信息,比如CPU的使用时间,加锁消耗的时间等。
MySQL里用了大量的Mutex来保证多线程之间的数据访问,我们加了对于Mutex加锁时消耗时间的统计,方便对数据库热点的分析。
这些统计信息提供了更充分的数据依据,帮助我们做快速的问题定位。
4.稳定性:BufferPool优化
在稳定性方面,我们也做了大量的工作。首先是BufferPool的优化。
云上用户会有临时变配的需求。举个例子,在业务高峰时,若希望实例临时规格变大,过了高峰之后再把规格降下来。MySQL是支持线上的resize,但是它的稳定性不够好。在做Onlineresize对性能的影响还是比较大的。AliSQL针对这个做了优化后,可以看到下图蓝色线条是动态变配的波动曲线,稳定性好很多。
5.稳定性:ConcurrencyControl并发控制
用户常常会碰到几个SQL过来一下子就把实例的CPU打满的情况,或者是内存耗光等类似的情况。ConcurrencyControl并发控制这个功能,可以让用户根据实际使用情况,对SQL限制执行个数,以提高实例整体运行的稳定性。
6.安全性:TDE支持国密SM4
企业级用户对于安全性的要求越来越高,对于各种各样的加密、密码强度、生命周期等要求也越来越多。AliSQL在安全这块做了更全面的支持,比如对于加密来讲,除了支持TDE这种AES的加密算法,还支持国密加密算法SM4,对于有涉密要求的用户可以用SM4的加密算法来保证数据的安全性。
7.安全性:RecycleBin防止误删除
当用户在做删除表或是Truncate表的时候,使用这个回收站功能,并不会把数据文件直接删除掉,而是会把这些表放到一个回收站里,这样就避免了用户在误删之后数据丢失的风险,误删除后还能通过回收站把删除的数据快速找回。
8.安全性:FlashbackQuery
不仅是表级的误删除,当我们对某一些数据更新的范围错误了之后,使用Flashback机制,可以恢复到更新前的历史版本。同时,用户还可以自定义查询某个时间戳的某个数据。
所以FlashbackQuery对误操作删除恢复或是回档需求是很有效的方法。
9.高性能:BinlogInRedo
对比原生MySQL,AliSQL的性能提升很多。首先介绍的是BinlogInRedo功能。众所周知,在MySQL里面,事务提交的时候需要持久化两次,因为要执行两阶段的事务提交过程。这里面做了一个改进,即可以把Binlog写到Redo里面,这样的话就只需要持久化一次Redolog,Binlog可以异步刷盘。
通过这种方式,用户事务在提交的时候就只需要一次刷盘动作,因此时延会降低,吞吐量会增大。
上图是基于两个BinloginRedo版本的测试结果。通过左侧第二个版本的数据,我们发现性能会提高很多。对于Updatenonindex来讲,可以有大概38%的性能提升。对于writeonly来讲,也可以达到25%的性能提升。
10.高性能:FastQueryCache
AliSQL针对QueryCache在并发控制、内存管理和缓存机制等等做了大量的优化。
优化之后,它的性能提升非常明显。在pointselect的场景下,性能提升甚至可以达到%以上。通过测试发现,在rewrite模式命中率比较低的情况下,几乎没有任何性能损失。所以用户在读比较多的场景就可以把QueryCache打开,可以保持稳定高效的状态。
11.高性能:DDLOptimization
围绕DDL我们做了大量优化。
用户在使用DDL的时候会发现,如果表特别大需要做rebuild或更新数据等操作的时候,效率非常低。主要是因为DDL利用BufferPool的模型是效率低下的模型。优化之后,对于rebuild表的这种操作效率会高很多,对于其他SQL语句的影响也会降低很多。
下图是针对CreateIndex和OptimizeTable的测试,可以看到优化之后,操作都会有10倍以上的性能提升。
三、XACrashSafe介绍
1.XACrashSafe背景
抛开XACrashSafe本身,MySQL本身也有CrashSafe机制。为什么会需要这样的机制呢,因为在MySQL里,同时包括Binlog和数据两个部分,可以理解为存了两份一模一样的数据。为了保证这两份数据的一致性,MySQLCrashSafe实现了两阶段提交机制。为了保证Binlog和数据的一致性,任何用户的事务都会被转化成为两阶段的事务,首先就是进行prepare,然后再写Binlog并持久化,最后做事务的提交。所以在这两个阶段的提交过程中,Prepare、刷Redo、写Binlog和刷Binlog的执行顺序是保持不变的。
如何保证CrashSafe呢?这要看它恢复的处理过程。在实际的事务执行过程中,只要是Binlog有这个事务,一定是Prepare的状态。那么利用这个原则,在MySQLCrash重启的时候,它会取出所有已经prepare的事务,把它们的XID取出来,扫描最后一个Binlog文件,然后确认XID所对应的事务是否已经存储到Binlog里了。如果已经存储过了,就直接提交即可;如果还没有存储,就回滚掉。通过这个CrashRecovery机制后,Binlog里的数据就和引擎里面的数据保持一致了。
对于普通用户事务可以用两阶段来保证CrashSafe,那么对于用户的XA事务怎么处理呢?
在Binlog里会把这个事务分为独立的两部分,当用户执行XAPrepare的时候,会写Binlog文件,然后把这个Prepare状态执行到引擎里,这是完全独立的。用户在XACommit里,可以在任何时间执行,当用户在执行XACommit之后会被再记录一次Binlog,所以这两者是完全脱离的。
对于普通的用户事务,执行过程只记录一次Binlog,而且整个事务是一个基本的单元存在Binlog中的;对于XA事务,这就是分开的。而且它整个过程是先写Binlog,然后才去把状态持久化到引擎中,做引擎的prepare。对于MySQL来讲,不能保证外部XA事务数据和Binlog的一致性。
也就是说当写完Binlog,还没有在引擎中执行prepare和