本文介绍标准版形态下Lizard事务系统的相关概念。
使用限制
引擎版本需要选择兼容MySQL 8.0。
工作原理
关系型数据库的MVCC机制,依赖数据的提交版本来决定其可见性,所以,Lizard单机事务系统,引入了SCN (System Commit Number)来表达事务的提交顺序,并设计了事务槽(Transaction Slot)来持久化事务的提交版本号即SCN,其架构图如下:
写事务:
事务启动时,申请事务槽Transaction Slot,地址记为UBA。
事务过程中,对修改的记录填入 (SCN=NULL, UBA) 两个字段。
事务提交时,获取提交号SCN,并回填到事务槽上,并完结事务状态,返回客户提交完成。
读事务:
查询启动时,启动事务视图Vision,即从SCN生成器上获取当前SCN,作为查询的Vision。
查询进行时,根据行记录的UBA地址找到对应的事务槽,获知事务的状态以及提交号。
根据记录SCN和视图SCN进行数字大小比较,就可以判断可见性。
SCN事务性能优化
相比于MySQL开源的InnoDB事务系统,Lizard SCN事务系统带来了巨大的优势:
解绑对全局结构的访问依赖,读写冲突得到大幅缓解。
视图升级为Vision,只有一个SCN数字,不再有活跃事务ID 数组,易于传播。
支持自定义的FlashBack查询。
但同时也引入了一些代价,因为事务提交只修改了事务槽,行记录上的 SCN 一直为 NULL 值,所以,每次的可见性比较,都需要根据 UBA 地址访问事务槽来确定真实的提交版本号 SCN。为了减轻事务槽的多次重复访问,我们在Lizard SCN 事务系统上引入了Cleanout,一共分为两类,Commit Cleanout和Delayed Cleanout。
Commit Cleanout
事务在修改过程中,收集部分记录,在事务提交后,根据提交的SCN,回填部分收集的记录,因为需要尽量保证提交的速度不受影响,仅仅根据当前记录数和系统的负载能力,回填少量的记录,并快速提交返回客户。
Delayed Cleanout
查询过程中,再根据UBA地址回查事务槽SCN,判断其事务状态以及提交版本号之后,如果事务已经提交,就尝试帮助进行行记录的Cleanout,我们称之为Delayed Cleanout,以便下次查询的时候,直接访问行记录SCN进行可见性判断,减轻事务槽的访问。
Transaction Slot复用
由于事务槽不能无限扩展,为了避免空间膨胀,采用Reusing方案。事务槽会持续地保存到一个free_list链表上,在分配的时候,优先从free list中获取进行复用。
频繁地访问free_list链表以及从free_list链表上摘取,需要访问多个数据页,这带来了巨大的开销。为了避免访问多个数据页,事务槽page会被先放入cache快表中,下次获取时直接从cache快表上获取,这大大降低了读多个数据页带来的开销。
SCN事务系统性能表现
虽然Cleanout带来了部分的代价,但由于分担到了查询过程中,并且没有集中的热点争抢存在,在测试结果上,相比于MySQL开源的InnoDB事务系统,Lizard SCN事务系统整体的吞吐能力大幅提升。
QPS | TPS | 95% Latency (ms) | |
Lizard | 636086.81 | 31804.34 | 16.07 |
MySQL-8032 | 487578.78 | 24378.94 | 34.33 |
MySQL-8018 | 311399.84 | 15577.15 | 41.23 |
以上数据测试环境为Intel 8269CY 104C,数据量为1600万,场景为Sysbench Read Write 512并发。
相比于MySQL-8032,Lizard SCN事务系统性能提升30%,延时降低53%。