全面解读:腾讯 CDB 内核特性与优化实践

简怀兵,腾讯云数据库高级工程师,负责腾讯云 CDB 内核及基础设施建设,从事 MySQL 内核开发工做 8 年,具备丰富的优化经验;在分布式存储等领域有丰富经验。node

TxSQL,是腾讯 CDB(Cloud Database 云数据库)的内核,由开源的数据库 MySQL 分支发展而来。数据库

本文会从四个方面来对 TxSQL(腾讯CDB内核)进行解读,分别是:后端

  • TxSQL 的发展历程
  • TxSQL 的特性功能
  • TxSQL 的深度优化
  • TxSQL 的演进计划

1、TxSQL 的发展历程

TxSQL 最先是用于腾讯的内部业务,像腾讯游戏当中使用的数据库。安全

而后受业务驱动,被用于互联网金融支付业务。支付业务对数据库提出了更高的要求,尤为是在性能和稳定性方面。服务器

再后来,运营推进其发展,针对外部需求加上更多功能。你们比较熟悉的可能就是 RDS(腾讯云)。网络

因此基本上 TxSQL 的发展历程就是首先从内部业务到互联网金融,再到如今 RDS 上蓬勃发展的趋势。这三个业务的维护慢慢驱动造成了一个腾讯内部本身维护的数据库分支 —— TxSQL。架构

2、TxSQL 的特性功能

TxSQL 的特性功能有不少,在此仅列出一些你们可能比较感兴趣或者是对开发者及其余公司来讲会有一些借鉴性的功能。并发

① 分布式锁服务app

TxSQL 这个内核分支当中有提供一个分布式的锁服务。这个锁服务是用来作什么的呢?运维

首先它提供了一个和链接无关的锁服务,能够经过完整的和 MySQL 兼容的协议来使用这个锁服务。它和如今的一些分布式锁服务不同,好比说 zp(ZooKeeper)。不同的地方在于:

第一是它能够实现让你的锁和你的数据在一块儿;第二是能够用原生的彻底兼容 MySQL 的协议来使用这个锁服务。因此它提供的实际上是两个不同的东西。            

好比说有时要部署一个 MySQL,须要一个比较高可用的集群,同时还要去作一些后期的维护,有了分布式的锁服务之后,不须要作额外的应用,只须要在 RDS 里面操做,后面所用的高可用、运维等一些东西都已经包含在 MySQL 这个运维的体系当中了。

② 超级 root 帐号

这个功能比较有意思。拿 MySQL 来讲,在公有云上申请了 MySQL 实例时,后端会负责作主从复制、备份,可是作这些工做都须要有一个 MySQL 帐号。假如如今已经申请了一个数据库实例,但有时候因为误操做或其它缘由,会把一个不属于本身的业务账号删掉,由此会影响网站后端作备份这些功能。

TxSQL 提供的这个 root 帐号,实际上是 MySQL 的虚拟帐号。即使把 MySQL 的系统表 delete 之后,也不会有任何影响,后端的业务仍是能够链接上来,继续运营、运维。

③ OSC(Online Schema Change)

所谓 OSC,就是 Online Schema Change。用过数据库的人都知道,尤为是互联网业务,变化很泛,业务需求在变,产品形态也在变。此时就有对数据库的表结构、规范结构进行增长、删除和字段类型修改的操做的需求。若是在原生 MySQL 中实行这样的操做,会比较麻烦并且有风险。这个功能能够经过改变内部的表结构来与原生的进行支持,而且能够在线修改。

④ 带租约的工做模式

在一些对移植性要求比较高的数据库的应用场景下,为了防止在同一个拓扑结构下会有多个 master 或者是有多个读写的状况,能够经过带租约的工做模式,把每个 MySQL 的实例定位到一个具体的 multi mode 当中,就是说如今是只读、可读写仍是说查询相似这样的一些区分。

带租约的工做模式,便是能够经过外围的一些空 paper 让租约在整个拓扑范围内,让每个节点达到一个惟一肯定的状态。

⑤ Binlog 限速插件

在 MySQL 的主从之间,通常原生的是经过获取 node 来访问主从复制,但这样就会有一个问题,就是在主从之间(也就是 master 和 slave 之间)新建了一个实例,若是中断时间比较长,而你的网络刚开始恢复的时候,它会瞬间把你主从之间的带宽给打满,这可能会影响到其余一些正常的业务逻辑。

为了不相似这样的问题,TxSQL提供了一个限速插件。这个插件在主从同步的时候,能够设置阈值。所以即使在这种状况下,也能够保证为业务应用预留必定的带宽。

⑥ Super Read Only

第六个就是 Super Read Only。在 MySQL 发布 5.5 以前,也有 Read Only 这样的一个功能,但为了保证访问数据严格的一致性,又开发了 Super Read Only 的功能,无论是 root 帐号仍是其余的普通用户帐号,经过开启这个功能均可以保证数据在预期的时候去写,不会出现不预期的写。

⑦ 预留 super 链接

这里指的是预留 super 链接的权限。比方说,当你开发了一个 app,可这个 app 有 bug,它会一直去链接 MySQL,可是每个 MySQL 实例都是有链接次数限制的,因此有可能会由于这个程序的 bug,致使设置的 GET 链接数被占满了。这种状况下,不管是 DBA 仍是运维,都没办法链接上来作一些其余的应急措施。

所以,TxSQL 提供了这样的一个功能,会为预留的 super 帐号提供一些额外的链接,这些链接不能够配置,所以即使是你的 app 有 bug 或是其余紧急状况下,也能够保证这个运维的链接是始终均可以连上的。

⑧ 安全 Reset Master

在一般状况下,好比主从复制正在进行时,外面 master 也正在进行一个 Reset Master 的操做,这可能会致使有些 Binlog 会被删除,下次再来建主从的时候就会致使有一些 node 还没同步过去就已经被删除,所以会出现建不上主从复制的状况。

TxSQL 会在 Reset Master 前,确保如今是没有主从链接。若是必定要作这个动做,而如今又有主从链接,会先把主从复制上的拓扑停掉。

⑨ 数据强同步

数据强同步的封装最先是在 MySQL 5.5 上,5.5 以前都是经过异步的方式。所谓的异步就是指 master 和 slave 之间不主从复制,比方说如今有一个 app 已经在 master 上,你提交了一个事务或一条数据,这时候把 master 的大小切到 slave 上,你会发现刚才提交的事务有可能已经查询不到。

为了防止这种状况,在 5.6 和 5.7 已经提供了半同步的功能,半同步和强同步的差异就是半同步第一次在某些比较特殊的场景仍是保护不了数据同步的一致性,第二就是它会设置一个 time out 的值,第三个就是性能方面的问题,原生的话可能性能不足。

针对一些应用对数据的一致性要求很是高,TxSQL 在 MySQL 原生半同步的基础上进行了深度优化,确保一个事务在主库上提交以前必定已经复制到至少一个备库上,确保主库宕机时数据的一致性。

⑩ 在线 GTID 升级

MySQL 5.6 已经提供了 GTID 这样的一些特性,可是这个版本中从 非 GTID 的版本到 GTID 版本是没有办法比较简单在线升级的。因此为了确保能够在线平滑升级,有作一些工做。

最后还有两个特性功能,第一个是须要在某些场景下过滤其中一些功能,这就须要把一些 MyISAM 的表转换成 InnoDB 的表,第二个是把系统库里面的一些需求隐藏掉。

功能这部分就讲完了,这里列的 12 个特性功能,都是在最多见的使用场景当中对你们比较有意义的一些功能。

3、TxSQL 的深度优化

① 主从复制全链路优化

这个会在后面做为一个点单独来说,好比说在主从复制中、优化过程当中,还有不少其余环节中作了哪些优化,有什么效果。

② ReadView 优化

第二个是 ReadView 的优化,在最新的 MySQL 5.7.14 版本中,MySQL 官方已经有这个优化。

③ Redo Log Buffer 锁拆分

简单讲就是之前会有一把大锁去共享这个 Redo Log Buffer、去读写字段,而后都会频繁竞争这把锁,这就会致使在大并发的量下产生较大的性能开销。

④ Logical Clock(MTS)

 Logical Clock,就是 MTS(multi-threaded slave)。传统的官方 MySQL 版本是 slave 去回放,master 同步 Binlog 过来的时候,都是单线程的模式,到 5.6 之后就变成了并行。

TxSQL上作了一些正式的优化,按临界事务提交的这个区间,只有不一样的事务没有的状况下去竞争或者在同一个资源上的时候竞争,至关于把它的粒度拆分到最细。

⑤ Thread Pool

有关 Thread Pool 的功能,在 MySQL 中,通常状况下是产生一个链接就会去建一个线程,该线程用 node 链接,这个可能跟早期的 Apache 同样。

⑥ Redo Group Commit

Redo Group Commit,简单的理解就是由于 TxSQL 是 IO 密集型的服务器,对于服务器,最致命的东西就是 IO、磁盘,使用传统的机械硬盘又须要转磁头以定位到扇区,而这些东西的开销都很大,所以这个功能就是为了减小磁盘寻道和寻址的开销。

接下来从三个维度去介绍 TxSQL 所作的改进,分别是高性能、强一致和工程化。

1. 主要改进 - 高性能

在 MySQL 内核复制的 4 个主要环节优化:

  • Binlog 读写锁拆分
  • 网络传输 Binlog 串行变并行
  • 写 RelayLog IO 合并和解锁
  • 事务回放串行变并行(MTS)

1) 高性能 - Binlog 读写锁拆分

MySQL 5.6 存在的问题:

  • 对 Binlog 的读写都要互斥,高并发(尤为是有多个 Slave)时,是影响性能的关键之一;

TxSQL 的优化:

  • 将读写分离开来,多个写入的线程仍是在锁保护下串行执行,每个写入线程写入完成后更新当前 Binlog 的长度信息,多个 Dump 线程以 Binlog 文件的长度信息为读取边界,多个 Dump 线程之间并行执行。以这种方式来让复制拓扑中的 Dump 线程发送得更快!

2) 高性能 - 传输 Binlog 串行变并行

MySQL 5.6 存在的问题:

  • 未收到上一个 Binlog Event 的 ACK 以前,不能发送下一个 Binlog Event;
  • 每一个事务须要一个 RTT,不能有效利用主从 DB 之间的带宽,尤为是跨园区条件下;

TxSQL 的优化:

  • 将发送和 ACK 回应的接收独立到不一样的线程中,因为发送和接收都是基于 TCP 流的传输,因此时序性是有保障的;这样发送线程能够在未收 ACK 以前继续发送,接受线程收到 ACK 后唤醒等待的线程执行相应的任务。

3) 高性能 - 写 RelayLog 时 IO 合并和解锁

MySQL 5.6/5.7 存在的问题:

  • IO 线程和 SQL 线程竞争 RelayLog 的锁
  • 以 Binlog Event 为单位写文件,产生大量小 IO
  • 写 Masterinfo 文件产生额外文件 IO
  • 频繁动态内存分配和释放

TxSQL 的优化:

  • 使用读写边界解除 IO 线程和 SQL 线程之间的锁竞争
  • 合并小 IO 到事务级别
  • 使用 GTID 规避 Masterinfo 文件写 IO
  • 内存复用

4) 高性能 - 事务回放串行变并行(MTS)

MySQL 5.6 存在的问题:

  • 事务按 Database 级别并行,并发粒度大,效率低

TxSQL 的优化:

  • 在 Master 上提交无冲突的事务,均可以并行回放

2. 主要改进 - 强一致

优化 MySQL 内核半同步复制为强同步:

  • Master 提交事务前保证至少有一个 Slave 已经收到日志
  • HA 单独处理临界事务

存在问题:

  • Master 在本地完成事务提交后再同步 Binlog,致使幻读

1 )强一致 - 事务不丢失和消除幻读

MySQL 5.6 存在的问题:

  • 主 DB 先提交事务再发送给 Slave, 在发送过程当中 Crash 时,主 DB 可见的事务在从 DB 不可见

TxSQL 的优化:

2) 强一致 - 临界事务处理

HA 存在的问题:

  • Master 写 Binlog 成功,但 Binlog 同步时进程 Crash;
  • Master 进程恢复时,会产生多余的事务

TxSQL 的优化:

  • Truncate 临界事务的 Binlog 信息

 

3. 主要改进 - 工程化

1) 工程化 - 低侵入

  • 业务痛点老应用迁移成本高、风险大、没法享受新技术红利
  • TxSQL 的方案彻底兼容 MySQL 5.1-5.7 的复制中间件

2 )工程化 - 健康诊断和审计

业务痛点:

  • 访问安全:IP、账号、对象、越权操做记录、不活跃账号
  • SQL安全:注入、宽松条件的修改\删除、低效SQL

TxSQL的方案:

  • 对访问和SQL相关安全事件进行记录
  • 对异常事件进行拦截或者预警
  • 提供SQL级别耗时统计

3 )工程化 - 兼容

业务痛点:    

  • 不一样业务使用不一样分支的 MySQL,迁移难
  • 不一样业务使用不一样版本的 MySQL,升级难

TxSQL 的方案:

  • 支持主流 MySQL 分支
  • 支持在线升级
  • 支持业务的持续集成

4、TxSQL 的演进计划

首先是实现用户使用的基本功能,而后在此基础上进行深度优化,也就是上面提到的那些。未来,会针对架构进行优化。

相关文章
相关标签/搜索