MySQL内核大牛解密腾讯数据库关键技术点
本文嘉宾:赖铮,腾讯TEG基础架构部数据库团队专家工程师,负责腾讯TXSQL数据库内核的研发,数据库系统开发老将,专注数据库内核开发十余年,先后就职于达梦、Teradata、北大方正以及MySQL InnoDB存储引擎团队,是达梦数据库内核、方正XML数据库以及InnoDB的GIS支持,加密功能的主要开发者,并获得多项数据库领域的专利。
本文是腾讯TEG基础架构部数据库团队专家工程师赖铮在腾讯云与3306π联合举办的数据库技术沙龙上的演讲实录。
今天分享时长四十分钟左右,详细解释腾讯云数据库内核TXSQL的新功能和特性。主要包括三个部分:
第一个部分是腾讯云CDB介绍,CDB是云数据库服务Cloud DataBase Service的缩写。
第二部分主要介绍CDB新版本的新功能和新优化。
第三部分主要介绍CDB企业级特性。
首先我们介绍一下我们腾讯云的CDB。大家应该都知道腾讯云是国内领先的云服务供应商,像腾讯内部的一些业务,qq、微信之类的一些内部业务就是跑在腾讯云上的,当然不是全部,其他未上云业务后续也会逐步迁移到腾讯云上。
腾讯云上运行的这些数据库服务统一都叫TencentDB也叫CDB。CDB提供了非常完善的数据库服务,能够让用户做一些自主可控的管理,同时针对很多应用做了兼容和优化。腾讯云数据库服务也支持多种数据库引擎。比如我们今天要讲到的MySQL数据库服务,还有Redis、MongoDB等其他数据引擎。现在腾讯云数据库的数据量非常大,就MySQL数据库服务来说早已经超过P级。
接下来,看看我们的现网客户,包括拼多多,蘑菇街,WeBank,微信支付,搜狐畅游等都在使用我们的数据库。而腾讯云数据库服务的核心,也就是刚才介绍的TencentDB或者叫CDB的最主要的核心叫TXSQL也叫TengXunMySQL也叫TencentDB For MySQL。这个数据库的内核是腾讯自己自研的一个MySQL分支,它是基于官方MySQL版本的,它在我们整个腾讯云数据库服务的核心位置。从这个架构图可以看出,首先上层是访问集群 Access clusters,然后中间就是TXSQLInstance cluster 数据库实例集群,下层是存储集群。
接下来讲一下腾讯云数据库内核TXSQL演进的过程,最早的TXSQL是从MySQL5.1开始,因为那时只有有限的资源,所以只做了 Bugfix。而到了之后的TXSQL5.5,除了Bugfix还做了一些 Features needed byOSS。OSS是什么呢?实际上就是我们腾讯云的管控平台或者叫做云操作系统,云操作系统支持或者说管理腾讯云上面的数据库。后来接着到了TXSQL5.6 ,我们做了更多的东西,比如说DBA管理需要的东西,商业化需要的特性,以及针对读写方面的优化等等
现在在腾讯云上提供的最新版本是5.7版本,5.7除了刚才讲的东西,还提供了一些企业级的特性,比如说加密,审计,还有线程池。现在正在研发的是8.0版本。8.0版本我们的团队现在已经基本完成,应该在近期就会发布。8.0版本中我们会加入更多的新特性,而不光是刚才介绍的这些特性。其实8.0大家都应该知道,就官方本身来讲就加入了非常多的特性,比如说数据库字典的优化,对redo log的优化,优化器的重构。8.0可以说算是MySQL近期的里程碑式的版本,所以将来的主流的MySQL数据库服务都会往8.0上迁,我们腾讯的8.0的版本不光是提供官方版本这些特性,还有我们自己的一些特性,我相信大家应该会感兴趣。因为我参与了8.0版本的规划,我想这个版本应该会给大家带来惊喜,敬请期待。
以上我们简单介绍了一下腾讯云整个数据库服务的一些情况,现在讲一下TXSQL最近版本里面提供的新特性。
一、异步删除大表
在TXSQL之前的版本就已经有了这个功能,新版本是对这个功能进行了一些优化。它主要是解决一个什么问题呢,我相信大家都或多或少碰到过这个问题,就是在我们drop database或drop table的时候,当这个表特别大的时候,因为原来的MySQL是直接去删除掉那个IDB文件的,而当这个IDB文件特别大的时候就会产生一个IO尖刺,这个尖刺有的客户是无法接受的,因为可能有些业务会很受影响。为了解决这个问题,我们做了这个异步删除大表的功能。它是怎做的呢?做drop table 、 drop database的时候会把删除文件的工作通过后台线程来做,后台线程每一次会truncate掉128M,然后一直到删除这个IBD文件。
在我们最新的版本里对这个功能的参数支持了动态设置,比如说可以配置临时文件存放的目录,还可以动态打开或关闭这个功能,set global innodb_async_truncate_work_enabled = ON/OFF,新增drop table用异步删除,存量用的还是老的逻辑。
二、CATS事务调度算法
CATS(Contention-Aware Transaction Scheduling) 热点感知事务调度
我们知道MySQL 原来的事务调度是FCFS(First Come First Served)先到先得,就是看谁先来谁先去执行,新的事务调度算法是一个怎么的算法呢?它是根据你当前热点或者叫阻塞的情况来判断究竟应该调用哪个事务。举一个简单的例子:就像有一条公路,大家都往这条公路上走,公路上有摩托车,小汽车,大巴,当发生堵车的时候,我们应该让哪一种车先走,是不是应该先让大巴先走?因为大巴车上人多,当大巴车过去的越多,人就过去的越多,这就是这个算法的基本原理。
如图所示先执行的将会是t1,因为它阻塞的事务个数是四个,而t2只有三个。所以判断是基于阻塞的事务个数,而不是锁的个数,因为会遇到事务拿到了很多行锁,但是这些行锁没有被别人请求的情况,所以它虽然拿了行锁但没有其他事务在等它,也就没必要让它先执行。做MySQL优化有时候还是蛮有意思的,发现一些很简单的优化点就可以做到很大的性能提升。
我们来看一下官方的公布测试效果:
第一个图,随着并发数的增加性能有了近三倍的提升。不过,大家需要注意这个新的事务调度算法并不是万能的,它只能适用某些场景。是哪些场景呢?就是某一部分数据特别热的场景,比如有20张表,每一张都有一千万行数据,相对来讲,它只会去做一些修改相对集中于一张表或者两张表的记录,这种情况下,这种事务算法才会比较有效。TXSQL新版本中,我们增加了一个新的参数,来让用户可以设置事务调度的方法:
innodb_trx_schedule_algorithm={AUTO, FCFS,CATS} 缺省为AUTO
AUTO超过预定设置的值它就会调用这个事务调度算法,现在我们是超过32个线程在等待的时候就会使用这个新的调度算法
三、无主键表复制的优化
不知道大家有没有碰到这种情况,就是发现主备份延迟非常严重,后来一查是因为有一张表没有建立主键,而且没有任何的唯一索引,这种情况就只能怎么办,加主键或者创建唯一索引对不对,这样的话可以明显看到主备延迟在减少,这是为什么,这是因为对于无主键的表,备机做binlog回放的时候会进行全表扫描,当这个表数据量很大的时候,全表扫描的速度就会很慢,自然主备就会延迟的很严重。针对这样的情况,我们提出了一个自己的方案,如果没有建立主键,会自动建立一个隐藏列,并且在这个列上建立一个唯一索引,这样的话我们就可以在做回放的时候,使用上这个唯一索引,来找到需要update的数据,从而减少主备延迟的情况。
我们也有两个参数来进行控制这个功能:
1、参数开关cdb_hidden_key_col,默认为off,无主键表添加隐藏列和隐藏索引功能总开关
2、参数开关cdb_show_ipk_info,默认为off,是否隐藏系统添加的隐藏列,用户可见
cdb_hidden_key_col 缺省的情况是关闭,因为我们正在做一些灰度测试,暂时是关闭的,以后的可能会把它打开,打开后,会对无主键表加上一个隐藏列和索引。
cdb_show_ipk_info这个参数是用户可不可以看到这个隐藏的列和索引,当打开这个参数的时候通过show create table 就可以看到这个隐藏列,还有它的二级索引。
四、GTID复制功能扩展
这个扩展有两个部分:
第一个部分是gtid模式下复制支持 create as select,create/droptemporary table。原来的MySQL官方是不支持这样几种语句在GTID模式下的复制的。有一些客户给我们提了这个需求,所以我们在TXSQL新版本里面提供了这个功能。这个功能也是有相应的设置进行打开:
参数开关cdb_more_gtid_feature_supported,默认为off
当gtid_mode=ON、enforce_gtid_consistency=ON 复制支持如下用法:
create table t2 select * from t;
begin;
create temporary table xx (id int);
insert into xx select *from t2;
insert into t1 select * from xx;
commit;
第二个部分是允许gtid 5.7 同非gtid 5.7建立主从关系,非gtid5.7事务同步到gtid 5.7实例上生成匿名事务,同样有一个参数进行设置:
参数开关cdb_allow_gtid_rep_non,默认为off
注:请在DTS迁移过程中使用,任务完成,请关闭该参数
以上就是我们新版本加入的功能。我们来看下后续版本中我们会加入那些新的功能。
一. 即将加入秒加字段(instant add column)功能
这个功能我相信大家可能会非常感兴趣,因为我们现网用户做的最多的一个DDL操作除了建表就是加字段。加字段的时候,我们会碰到一个什么样的问题?原来在MySQL8.0版本之前的时候,加字段是需要做数据拷贝的,加一个字段表结构变了,需要从原来的旧表copy到另一张表上,需要一条一条插入,尤其是当表的数据量特大的时候就会非常慢。那怎么解决这个问题呢,我们腾讯游戏团体提供了一个解决方案,原来数据就让它留在那里,我们只要给新的数据做一个标记就好了,所以解决方案就是在新的数据上面打标记的方案,就可以避免所有的数据拷贝。这个功能已经被官方合并到8.0了,我们也把这个功能放到TXSQL 5.7版本中了,因为我们觉得这个功能对5.7的用户来说用的非常多,在做加列的时候只需指定一下你的这个算法是instant就能立马完成,在几毫秒的时间完成加字段的操作,只需要修改数据字典的信息,不需要数据拷贝。整个功能我们会在下一个5.7版本中发布。
二. 即将加入修复event定时任务不按时执行的问题
接下来,我们再看一个很有意思的bug fix。这是我们刚刚发现的官方版本的一个bug。不知道大家是否现网在使用event这个功能。我们有一个客户就大量的使用了event。每天晚上大概在十二点的时候会进行一个抽奖的操作,主要是通过设置在某个时间执行MySQL的event来给某些用户发放一些金币。但客户反馈说我明明设置了晚上12点10分这个时间执行这个event,它为什么有时候就不做了呢,有时候会延迟一天,有时候会延迟两天,有时候甚至一直不都执行,这是为什么呢?很奇怪,而且由于他们有很多类似这样的操作都是使用event来做的,所以碰到这种的问题特别频繁。一开始我们也是一头雾水,理论上应该不会啊,我们看过源码,很简单,就是设置一个定时执行的东西,到了那个时间点就会执行。后来经过长时间的追踪,我们发现了问题,原因在于MySQL源码中的小顶堆(Priority Queue)的删除算法是有问题,我们看下面这个图:
初始堆的情况是这个样子的。大家应该都知道小顶堆,最小的数在最上面,也就是在根节点。MySQL的event执行顺序是怎么样的一个算法呢,每一次都去取这个根节点的event来执行,因为这个event是离我时间最近的那个,然后把它取出来等,等到设定的那个时间去执行。取出来一个,然后再把下面一个最近时间的event放到根节点。那我们看我们在做删除一个元素(也就是drop一个event)的时候会发生一些什么样的情况。比方说要删除第一个图中的7,删除7这个动作就会对应MySQL里的drop event这样一个操作。在做删除7这个节点时,会把最后加进去的元素3 放到7的这个位置上,做一个替换,就变成图二的样子。然后再去做排序,从删的地方开始向下做排序,保证3这个节点一定比它下面的节点都要小。但我们发现有一个问题,比如说删除的不是7这个节点,删除的是10这个节点,会发生一种什么情况呢?把3替换到10的位置,就会成为图三的这种情况,按照它原来的算法,它去调整它的子节点,但是因为3是没有子节点的,它就不调整了,然后堆就会变成图三的情况了。大家是不是可以看到,它已经违反了小顶堆的原则,就是父节点永远比子节点小,因为图三中的3是子节点7是父节点,7比这个3要大所以它就错了。在后续排序的过程中就会出现问题,取下一个节点的时候,就会先取7这个节点而不会取这个3节点。这就造成到了执行的时间点不去执行,反而会去执行另外一个节点。非常隐蔽的一个问题,这个问题我们花了很长时间来跟踪,最终才解决了它。
接下来我们讲一些TXSQL内核的企业级特性。
一、TXSQL线程池
大家可能都用过线程池,如果你并发数很多的时候应该要用到线程池,不然的话随着并发数的增加数据库的性能会急速下降。TXSQL也提供线程池的支持,而且TXSQL线程池对线程池做了优化,我们避免了有请求被饿死的情况。让低优先级的用户在等了很长时间后,到达一个预定的值的时候,我们会提升它的优先级,让它先执行。
二、TXSQL审计
审计功能一般情况下大家不会用到,但是当发现问题的时候你就会发现有这样的一个功能该有多好。当你发现我不知道谁把表删掉了或者drop databases的时候,有审计就可以追踪到是谁在什么时候做了一个这样的操作。TXSQL的审计大概的架构图如图:
可能大家会担心打开审计对性能有影响,实际上它对性能的影响非常小,为什么呢?因为我们是把它放在后台,就是有一个Flush thread的后台线程在不停地去刷Auditfile 这样一个文件,把当前的操作记录到一个文件中然后再通过Audit Agent存到一个时序数据库CTSDB里,所以对整个数据库原有的服务影响非常非常小,就我们测试,打开审计和不打开审计只有5%以内的性能损失。
三、TXSQL数据加密
现在,大家越来越注重自己的数据安全了,不管客户数据还是其他数据都不希望被别人拿到。我们的数据加密功能会针对所有的落盘数据,你的ibd文件,只要落盘我们都进行了加密。这个加密是基于官方的TDE(透明数据加密)功能做的。腾讯云的加密基于官方的TDE,集成了腾讯的秘钥管理插件KMS。加密的秘钥是通过KMS Plugin插件来获得的,所以不用担心秘钥被其他人获取。
推荐
江湖召集令
9月27日-11月6日,腾讯云数据库王者挑战赛(点击查看详情) 等你挑战!花几分钟参加比赛免费将☟☟抱回家!
- MacBook/iPhone 11/AirPods
- 25台Kindle
- 8万元腾讯云创业基金
- MySQL之父 Michael Widenius 面对面交流
转发下方海报参与活动可以获得腾讯公仔和腾讯云数据库无门槛代金券,详情请扫描下方图片二维码咨询。
比赛详情&报名入口
请扫下方二维码
疯狂11.11
10月21-31日,腾讯云MySQL低至1.5折起,7元/月;SQL Server全场2折,91元/月,企业新用户及个人新用户可领取千元代金券。