TXSQL 数据库内核介绍
\
TXSQL 内核是腾讯云 TencentDB for MySQL 的简称,是腾讯云数据内核团队自研的 MySQL 分支,它是腾讯云上应用最广泛的数据库服务的内核,同时它也是腾讯云及腾讯内部云平台的官方 MySQL 版本。
\
为什么会有 TXSQL 内核?首先 MySQL 是一个应用非常广泛的数据库,所以我们会基于 MySQL 来做一些比较匹配腾讯内外部客户需求的特性。第二个原因,腾讯云目前有几万家用户,实例数超过 10 万规模。如何在这种海量数据,海量用户场景下做好数据库服务,是一个非常大的挑战。我们需要针对不同用户,不同场景,对 MySQL 内核进行有针对性的优化和支持。第三个原因,为了促进整个开源数据库技术发展,我们研发的很多特性都已贡献给官方,并被合入到 MySQL 官方代码中。
\
接下来看一下 TXSQL 内核的演进历程,最早的 TXSQL5.1,这个是 base 在 MySQL 官方 5.1 版本上,我们做了一些简单的 Bug fix,然后到 5.5 到 5.6,我们不光做了适配云平台的工作,还开发了很多支持运维的一些工具,还包括读写优化。再到 5.7 版本,5.7 版本是目前整个腾讯云数据库服务用量最大的一个版本,这个版本里加入了很多企业级特性,例如审计、压缩还有线程池之类的企业级特性。最后到最新的 TXSQL8.0,我们有了列存引擎,还有基于 AEP 新硬件设备的优化等等。同时,在 TXSQL5.7 版本之后我们另外做了一个内核,就是云原生 TDSQL-C 内核,也就是之前被称为 CynosDB 的内核。TDSQL-C 这个内核主要特性是 TDSQL-C 是云原生的数据库,其基本特点是存算分离架构,极致的性能和快速的扩展能力。
\
TXSQL 数据库内核架构与特性
\
接下来主要介绍 TXSQL 内核整体架构和它的代表性特性。从这张图上我们可以简单看到 TXSQL 内核的整体架构。首先客户端进来通过线程池,Server 层访问存储引擎层,在存储引擎层目前支持多种引擎,包括传统的 InnoDB,还包括我们自研的 CStore 列存引擎、RocksDB 存储引擎,还有 MySQL 官方原来内置的 MyISAM 等一些其它存储引擎。下面是高性能 SSD 本地存储磁盘。同时我们还有支持企业级特性的模块,例如审计系统,通过我们自研的,基于官方 API 的审计插件来提供审计服务。还包括透明数据压缩插件,提供数据加密解密的企业级特性。这大概是整体的 TXSQL 内核架构,比较传统的云上 MySQL 数据库服务基本都是这样的架构,
\
接下来介绍 TXSQL 独特的特性。首先是我们的列存引擎,列存引擎主要是为 AP 场景做数据分析的场景服务,列存引擎的数据是按列式存储,查询时无需访问不需要的列,比如说 C1、C2,行存引擎例如 InnoDB 它会把整个行的数据全部取出来,而列式引擎它只会取 C1C2 数据,不需要去访问那些不需要的列数据,大量减少 IO。
\
第二个,列存引擎可以做到高压缩比,因为是按列存储的,比如 Int 数据,就可以进行针对性压缩。但是如果行存,因为是定长,所以对于数据压缩来讲不太适合去做压缩。列存引擎的压缩比平均在 10 比 1,这是一个比较大的压缩比,可以大量减少数据存储的空间。
\
第三个特点是快速加载,我们列存引擎支持 MySQL 标准的 LOAD 语句,通过多核并行加载速度可以达到 InnoDB 和 10 倍。
\
还有一个,从执行引擎来看我们支持了各种查询任意多列组合,单节点可支持百亿行记录的秒级查询。同时还支持多种 JOIN 算法,包括 HASH JOIN。对于整个 AP 场景下复杂查询支持是非常有帮助的。另外在查询优化方面可以用各种形式的稀疏索引过滤数据,维护数据统计信息,支持各聚合类的查询与计算,极大地加速 AP 场景下的查询速度。
\
MySQL 兼容性方面我们全面支持了 MySQL8.0,包括它的一些工具。右边是 CSTORE 在整个内核里的架构情况,包括它的优化器、执行器,CSTORE 内部也内置了一套优化器、执行器,包括运行的加载数据模块,另外还有 BP、索引这些,这就是我们一个服务于 OLAP 场景下的一个列存引擎。
插入 PPT 图片
\
第二个关键特性是我们做的一个基于新硬件的性能优化,面向非易失性存储设备的优化。主要是基于 AEP 硬件。用 PMDK 接口替代传统 POSIX 接口。比如刷 redo 日志和 binlog 日志,这种新存储设备 IO 速度非常快,而且不需要担心数据丢失情况,所以它对于写日志场景 IO 速度提升是非常明显的。另外我们对所有的后台线程进行绑定最近的 CPU,在刷数据、写数据方面能够明显提升它的 IO 速度。
\
在单机场景下我们性能 redolog 的优化,就是写 redo 日志的优化场景性能可以提升 15%。主备场景写 redolog 和写 binlog 都做了优化性能能够提升到 50%以上。在同步场景,如果主机有 redolog 和 binlog 优化,备机有 redolog 和 relaylog 的优化性能可以提升 60%。在强同步场景下性能提升更大。这是基于新硬件的优化,可以极大地提升整体数据库内核性能。
\
第三个是增加的一个非常实用的功能,大家都知道,官方在 MySQL8.0 里已经支持了 instant DDL,可以快速地增加一个字段。实际上这个 patch 也是腾讯内部团队进行研发并贡献给官方的。在腾讯云 TXSQL 内核的 5.7 版本里,我们也支持了这个特性,而且在它的基础上进行了增强。不光是我们可以做到秒加字段 instant add column,还可以秒改字段 modify column 。它的主要思想就是只需要修改数据字典信息,避免数据拷贝。在 MySQL 支持 instant DDL 之前,如果要加一个字段是需要进行数据拷贝的,不管是用 ghost 工具去加字段,还是直接用 MySQL 的 alter table 去加字段,都需要做数据拷贝,相当于建另外一张表再把老表丢掉,这里会涉及到一个大规模的数据拷贝。秒加秒改字段就避免了数据拷贝,它只需修改数据字典就可以了。
\
同时我们优化了清理 AHI 算法,AHI (Adaptive Hash Index)这是一个比较有争议的特性。在大部分场景下 AHI 可以极大提高查询速度,但是它也会带来负面影响,尤其是在做 DDL 时它需要清理 AHI。因为改了数据字典,所以索引 hash index 需要重新 build,重新 build 时它就会清理 AHI 内容,尤其在高并发下会对现有的 workload 产生影响,造成整体性能抖动。我们有针对性地优化了清理算法,避免做 DDL 的同时性能抖动的情况。
\
第四个特性是热点更新,这是一个比较独特的优化。在腾讯云 CDD 的用户有很多是电商用户,电商用户经常会碰到的问题是秒杀,反映到数据库内核层面就是对某一个商品的数量进行减 1、即减库存的操作。同时并发有大量的用户来进行秒杀情况下,相当于并发有很多 Update 语句进来,就会造成阻塞。
大家可以看到在没有优化前,随着并发量上去,64 并发达到一个顶峰,随着并发增加它会快速下降,到 1024 基本上 TPS 会降到 200 以内。我们做优化就是把这些并发 Update 语句进行排队,在数据库的行锁层面进行排队,让它在高并发场景下能够保持相对平稳性能状态。
\
另外,我们知道 MySQL8.0 里支持了并行的 DDL,但是它目前支持程度还是相对简单,比如 create index 它也做了优化,但是 create index 做的优化比较有局限性,只优化了 soft、排序部分,而我们对 create index 的全流程进行了并行的优化。实现了随着并行线程数的增加,可以达到线性的加速比。
\
TDSQL-C 内核介绍
刚才介绍的是 TXSQL 内核,原名 CDB 内核,现在介绍一下 TDSQL-C 内核,TDSQL-C 也就是之前的 CynosDB。它是腾讯云自研新一代企业级云原生分布式数据库,它的主要特点:可靠,数据多副本,共享存储主备数据一致。极致性能,对主备的读写性能进行了全面优化,不同规格做出不同针对性优化。在可用性方面,秒级 RTO,可以做到用户故障无感知。在用传统 MySQL 数据库服务经常会遇见主备延迟情况,而 TDSQL-C 内核可以做到秒级主备延迟,数据极速同步到备机。共享内存、数据恢复、快速预热,这些都是加速性的。
\
同时弹性是云原生数据库非常大的特点,因为架构存算分离,如果 CPU 是密集型的,就可以扩充计算节点。如果是存储密集型的,那么可以随意扩大存储容量。用户可以按照自己需求随意扩展计算性能或存储容量。
\
TDSQL-C 内核架构与特性
\
下面介绍 TDSQL-C 总体架构,左边是传统 MySQL 集群架构,可以看到 Primary 和 Replica 主备间会通过 Binlog 来复制,纯黄色线是 Binlog,通过 Binlog 进行复制。主节点和备节点都需要把 4 种数据刷到磁盘上,包括数据、Binlog、、Redolog、Metadata。最后再把这些放到备份,这是一个传统 MySQL 的集群架构。
\
而 TDSQL-C 架构是通过 Redolog 复制,从主节点把数据传输到复制节点,同时只会刷 Redolog 到存储节点,我们存储节点 TXStore 是多副本存储集群,同时备份会备份到 COS 系统里去,我们不刷数据,不刷数据页面,也不刷 Binlog,只会刷 Redolog,极大减少了 IO。
\
接着看一下 TDSQL-C 关键技术,首先是高可用方面的物理复制,前面介绍 TDSQL-C 复制是通过物理复制,物理复制含义就是只通过 Redolog 来把数据的变化情况进行同步,同步到备机或从机。而传统 Binlog 复制缺点在于它是一个逻辑日志,执行路径很长,复制很慢,数据上逻辑一致,并不是物理一致的,通过日志传过去它还在进行 Binlog 回放。但是 master 和 slave 上的机器从物理上来讲它并不一致。通过 Redolog 复制的好处在于通过 Redolog 复制,而且是存的物理页面修改放在 Redo 再备机回放,这样可以达到两边物理页面相同,省去了解析 Binlog 步骤。这就是为什么它能够实现秒级复制延迟的原因。
\
第二个,我们是如何实现 TDSQL-C 的高可用的。传统高可用方面可能有这些问题:第一个问题是传统 MySQL 如果 Buffer pool 缓冲区大小比较大的情况下初始化会非常慢,可以看到 500G 的 Buffer pool 初始化速度超过 20 秒,也就是重启时花在初始化 Buffer pool 的时间就超过 20 秒,这样当你出现 Crash 就需要很长时间。第二个问题是大事务 Crash recovery 时它需要扫描所有 undo page 来获得表的信息。而构建表锁时间很长,因为一个大事务做 recovery 时间本身就很长,同时这里需要获取表的信息。第三个问题是回滚段,读取 undo page 相关信息,这个构建时间也非常长。第四个问题是 Shutdown 时,如果要关机重启,MySQL 需要清理各种数据结构,这个时间也会非常慢。
\
而 TDSQL-C 解决方法,第一个 Buffer pool 初始化问题,我们通过并行化初始化内存结构。因为它每一个 block 对应的是一个物理页面,每一个 block 的 mutex 初始化通过 lazy 方式来加速它的初始化。可以看到 500G 刚才是 20 多秒,一下降到只有两三秒。这个 patch 已经贡献给官方,官方实际上在 8.0 里已经支持了 Buffer pool 并行化,但还没有支持 lazy 方式。
\
针对第二个问题我们改造了 undo page 格式,在 pag deader 中存储事务涉及表信息,省去了扫描 undo page 获取表信息的时间。
\
第三个问题初始化回滚段,我们并行的去做回滚段初始化,这个 patch 也已经贡献给官方。官方已放到最新的 8.0.26 里。同时针对 shutdown 比较慢的情况,我们支持了快速的 shutdown,跳过没有必要去清理的资源,这样加速了整个 shutdown 的时间。
\
接下来详细介绍 instant modify column,这个是解决什么问题呢?我们线上也经常碰到用户一个需求,有一种很大的表,但是它的 primary key 是自增列,而自增列刚开始的时候估计不足,后来发现 int 类型不够表示,需要把它改成 bigint。而改成 bigint 会出现一个很大问题,需要做 alter table modify column 这样一个操作。当这个数据量很大的情况下,由于需要拷贝数据,这个操作会非常耗时,而且它还会阻塞读写请求,影响非常大。
\
我们在 instant DDL 思想基础上提出了 instant modify column,和 instant DDL 一样,我们会在记录里记录它当前解读版本号,也就是说当前是 int,还是 bigint,通过这个版本号来进行判断。这样我们只需修改数据字典信息,而不去修改数据。老的数据保持 int,比如说原来的 int 是 version1,它还是 int,version2 是 bigint,新插进入的数据都是 bigint,诸如此类。这样可以让整个 alter table modify column 速度缩减到毫秒级,基本不用花时间,因为只是改数据字典,所以非常快。一般的秒原来是 22 秒,现在只需要 0.01 秒。
\
现在这个版本里还会有一些限制条件,这个功能还是需要慢慢完善,我们现在只支持了修改非索引列,没有索引的列。现在我们只是支持了几种数据列类型,比如说 int 到 bigint,char 和 varchar 变长,还包括 binary。
\
那么从需求到发布,TXSQL 内核在 MySQL 的修改中是如何层层把关的?目前 TXSQL 内核开发已经形成了一个比较完善的研发体系,这个体系里包括我们的需求评估、代码方案、设计方案,还包括灰度和最终上线之后的跟踪。这一整套,首先从整个流程上做到了比较完善,从需求来讲现在我们的大部分的需求是来自于用户的需求,例如一些比较实用的特性基本上都是来自于用户在线上碰到的实际问题在转给我们,由我们来进行有针对性的解决。
\
需求到我们这边来会进行一个评估,比如这个功能是不是普适性功能,做了之后是不是能让非常多的用户来进行使用,在根据需求优先级来排开发顺序。后面就是方案评审,以及设计方案的评审。设计方案评审也有比较资深的内核开发团队人员进行评审,现在整个内核研发也有非常多的资深专家,从原来 MySQL 官方团队出来的,还有一些大厂出来的资深开发人员进行评估。
\
开发完成之后会有一些流程,比如 code review 等,再后面就是测试。测试非常重要,现在一个需求的测试可能会包括有针对性的专项功能测试,还包括上线之前的通用测试,包括真实模拟云上环境的一些测试,诸如此类所有全流程的测试。
\
之后是上线之后灰度,我们会邀请一些客户来试用,验证这个功能是不是符合需求。灰度完之后才是真正上线,上线之后还会进行跟踪,如果碰到一些 bug 之类的,会及时响应去进行解决,这就是我们内核研发层层把关的整个过程。
\
那么在保证稳定性性能调优的前提下,TXSQL 未来的主要发展方向是什么?TXSQL 内核现在以稳定性为主,目前我们实例超过 10 万,这么庞大的一个规模实例一旦出现问题后果不堪设想。所以首先要做到稳定性是基石,在保证稳定性的前提下在去进行特性研发和性能优化。
\
未来 TXSQL 主要发展方向还是以三大块:第一大块,保证稳定性,碰到问题要及时解决,。第二个是一些企业级特性研发,如刚才说到 instant ddl 增强,怎样去解决 DBA 和运维当中碰到的比较棘手的问题。第三个是性能优化,怎样去把我们数据库内核性能做得更好,这里包括优化器里各个模块,有优化器,有存储引擎,也有执行部分,甚至如何去运用一些新技术,比如说硬件,诸如此类这些方向,去加速整个 TXSQL 内核。