腾讯云CDB的核弹头:TXSQL的研发、实践和未来
TXSQL内核版本拥有更高的性能、更强的稳定性,同时提供Oracle MySQL企业级版本才拥有的特性,对内支持集团内部业务的发展,对外提供强有力的竟争力,大大提升了腾讯云在业界的影响力,赢得了客户的信任与口碑,积极的推动了腾讯云的快速发展。
5月11日,国内数据库技术盛会——2017第八届中国数据库技术大会(DTCC2017)拉开帷幕。本届大会以“数据驱动 价值发现”为主题,吸引5000多名IT数据库人群、大数据从业人员、广大互联网人士。腾讯高级工程师、腾讯云布道师张青林进行了题为《腾讯云CDB的核弹头——TXSQL》主题演讲。
嘉宾介绍:张青林,腾讯云布道师、MySQL架构师,隶属腾讯TEG-基础架构部-数据库内核研发团队,专注于MySQL内核研发&相关架构工作,有着服务多个10W级QPS客户的数据库优化及稳定性维护经验。
在本次主题演讲中,张青林主要从概览、内核研发、云上实践、未来发展方向四个方面介绍了Tencent MySQL(TXSQL)在腾讯云发展过程中遇到的各种问题,以及在解决这些问题的过程中TXSQL内核所做的一系列优化,包括read_view优化、Lock_log拆分、分布式token锁、Redo log锁拆分、Binlog限速等功能,从功能、性能和稳定性上对TXSQL进行深入的解析。
TXSQL概览
什么是TXSQL?为什么有TXSQL?
TXSQL是Tencent MySQL的简称,是TEG基础架构部CDB(Cloud DataBase)团队在近十年发展过程中衍生出来的一个对MySQL内核源码深度定制、对官方MySQL版本进行二次开发的项目。其主要目的是在保证线上稳定性的同时,满足业务对数据库的各种需求。
TXSQL的服务对象是公司内部用户和腾讯云上小至数G大至数百T的外部客户。TXSQL是支撑这些业务平稳运行的关键基石,促进开源数据库技术发展。
图1
TXSQL内核研发
TXSQL read view优化
read view又称读视图,用于存储事务创建时的活跃事务集合。当事务创建时,线程会对trx_sys上全局锁,然后遍历当前活跃事务列表,将当前活跃事务的ID存储在数组中的同时,记录最大事务low_limit_id&最小事务 high_limit_id&最小序列化事务low_limit_no。
当事务执行时,凡是大于low_limit_id的数据对于事务是不可见的,凡是事务小于high_limit_id的数据都是可见的,事务ID是read_view数组中的某一个时也是不可见的;Purge thread在执行Purge操作时,凡是小于low_limit_no的数据,都是可以被Purge的,read view是MySQL MVCC实现的基础。
Redo log优化背景
据介绍,MySQL有两种很重要的Log,分别为redo log&binlog,前者是保证事务原子性操作所产生的日志,后者是主备数据同步所产生的同步日志。其中binlog在ordered_commit时进行group commit,而redo log则是在事务提交的时候分别调用trx_prepare使redo log落地,导致log_sys->mutex竟争较为严重。
从crash recovery的逻辑来看,只要redo log早于binlog落地,就不会有数据问题,因此在ordered_commit的第一阶段时,TXSQL会收集各种引擎的最大redo log LSN,然后将小于该LSN的redo log落盘,从而提升写性能。更详细的分析与测试,可以参考bug#73202。
图2
TXSQL redo log双缓冲区
MySQL redo log是一个顺序写的单缓冲区,log_sys->mutex锁资源竟争激烈,在事务落盘的过程中对LSN相关的读、写都被阻塞,为了解决 log_sys->mutex的锁竟争问题,引入双缓冲区机制&w_mutex锁,在flush redo log 的过程中释放log_sys->mutex,继续持有log_sys->w_mutex,从而阻塞写,不阻塞LSN相关的读操作,flush完成后释放w_mutex;从而提升并发性,提升性能。
图3
TXSQL性能数据对比
读性能数据对比
写性能数据对比
读写混合数据对比
TXSQL功能开发
在TXSQL并行复制方面,MySQL并行复制存在的问题:在实际的应用环境中,实例中往往只有一个 Database,导致 relay log 中的事务大部分会分到同一个 worker 线程中,造成备库的性能低下,当主库的性能超过备库的单线程执行的性能时,就会出现延迟,对只读实例产生影响。
TXSQL并行复制存在的优化
为了解决上述问题,TXSQL 添加了另外一种分发方式,即基于表粒度的分发,为了实现基于表粒度的分发,TXSQL 对于不同的实现,进行了不同的处理:
当binlog_row_format= ROW 时, 调用 get_slave_worker 直接进行分发;
当 binlog_row_format= statement 时,则需要对语句先进行调用 mysql_parse 对语句进行解析,然后再做分发。
TXSQL强同步支持
原生 semi-sync 存在着以下问题:
semi-sync 在时间超过 rpl_semi_sync_master_timeout 会退化为异步;
采用 select 进行监听,当句柄值大于 1024 时则会出现异常,详情可参考 bug#79865;
在 after commit 后等待 ACK 容易出现幻读的问题;
TXSQL 强同步支持:
优化半同步,增加ack线程,收发并行化;
修正select时fd超过1024导致异常的bug,改为poll;
在半同步基础上实现强同步,一直hold住直到收到ack;
修改同步方式时,唤醒正在等待的用户线程,继续等待或者退出;
增加一些状态,用于展示当前等待的情况(正在等待的binlog位点,已等待时间);
对于主多 binlog 备少 binlog 的情况进行特殊的处理,以保证双写的情况不会发生;
TXSQL云上实践
XX游戏数据库优化案例
问题现象:性能不能满足业务要求,游戏业务逻辑 TPS 不达标;在压力达到一定程度时,CPU 不能充分利用,idle 较高;性能抖动较为明显; thread running 过高,系统负载较高;系统 IO 压力较小,IO 没有问题;
问题排查:
pt-pmp & pstack & mysql 命令进行问题排查,发现以下问题:
1.应用在执行SQL语句的过程中,table_cache_manager 中的锁冲突比较严重; 2.MySQL Server 层中的 MDL_lock 冲突比较重; 3.实例开启了 Performance_schema 功能; 4.事务锁 trx_sys->mutx 冲突较高;
调优过程:
根据已经查找出来的问题,调整相应参数与版本并重启,效果如下图所示:
1.table_open_cache_instances= 32 2.metadata_locks_hash_instances= 32 3.performance_schema= OFF 4.其它
TXSQL未来发展方向
最后,张青林针对今天的演讲做了精简的总结,列出的数据库问题如下:在压力达到一定程度时,CPU 不能充分利用,idle 较高; 性能抖动明显; 并发过大引起的 thread running 过高,系统负载较高; IO 问题引起的性能抖动; 锁问题导致的性能抖动; 压力不够大或者压力不均匀; 优化器问题引起的执行计划出错; SQL 语句引起的异常; 参数配置的不合理; 内核 Bug; 网络问题。
在未来的发展过程中TXSQL仍然会以用户为导向从以下方面不断的进行改进:批量计算;执行计划缓存;XA 三阶段支持;基于binlog的深度优化;Innodb的持续优化;引入oracle企业级特性。