RDS MySQL 8.0启用全新的Lizard事务系统,本文介绍Lizard的详细内容。
背景信息
官方版本MySQL 8.0持续对Redo Log日志系统、Lock System锁系统进行优化,大幅提升了系统性能,但InnoDB存储引擎的事务系统,存在读写互相干扰、XA事务不够稳定等问题。为了更好的提升RDS MySQL数据库的吞吐能力,并支持分布式事务和全局一致性,RDS MySQL 8.0.22(小版本20201231)开始启用全新的事务系统,即Lizard事务系统,Lizard的优势主要体现在如下三个方面:
高并发场景提高性能
官方版本MySQL的InnoDB引擎使用的事务系统是一个全局结构,DML流程中事务状态的变更以及查询过程的读视图(Read View)都要访问全局事务系统,造成严重的读写干扰问题,大大限制了系统的吞吐能力。而Lizard事务系统,在查询过程中不再维护用于实现多版本并发控制(MVCC)的Read View,也就是不再访问事务系统,大幅提高MySQL使用多核CPU的能力,有效提升高并发读写混合场景下的事务吞吐能力。
官方版本MySQL和使用Lizard的RDS MySQL进行SysBench性能测试的结果如下:
- 测试环境
- CPU:96核(Intel(R) Xeon(R) Platinum 8163 主频2.5GHz)
- MySQL配置:
- innodb_buffer_pool_size:50 GB
sync_binlog = 0
,即每次事务提交时,Binlog会写入缓存,但是不会立刻写入磁盘,会由操作系统决定何时写入磁盘。innodb_flush_log_at_trx_commit = 2
,即每次事务提交时,Redo日志会写入缓存,但是不会立刻写入磁盘,每秒会执行一次写入磁盘(flush)操作。
说明sync_binlog = 0
和innodb_flush_log_at_trx_commit = 2
是为了减少了IO子系统的干扰,方便测试高并发场景下Lizard事务系统对多核CPU资源的利用,并且能消除并发争用( Concurrent Contention)。 - 数据量:30 GB(20张表,每张表500万条记录)
- 测试场景1:SysBench OLTP Read_only说明 相比官方版本MySQL,RDS MySQL的QPS最多提高42.2%。
- 测试场景2:SysBench OLTP Read_write说明 相比官方版本MySQL,RDS MySQL的QPS最多提高69.9%。
- 测试场景3:SysBench OLTP Write_only说明 相比官方版本MySQL,RDS MySQL的QPS最多提高48.1%。
综合所有测试结果,使用Lizard事务系统的RDS MySQL能在高并发情况下,消除事务系统的热点,大幅提升系统的吞吐能力。
原生闪回查询
在RDS MySQL数据库日常运维的过程中,可能会遇到误操作或者非预期的数据修改操作,一旦提交就无法Rollback,Lizard事务系统支持原生的闪回查询(Flashback Query),能够指定某个时间点进行一致性查询。
Flashback Query的语法如下:
SELECT ... FROM tablename
AS OF [SCN | TIMESTAMP] expr;
示例
- 初始化数据
mysql> CREATE TABLE tab ( -> id int PRIMARY KEY AUTO_INCREMENT, -> version int, -> gmt_modify timestamp -> ); mysql> INSERT INTO tab VALUES (1, 1, now()),(2, 1, now()); mysql> COMMIT; mysql> SELECT * FROM tab; +----+---------+---------------------+ | id | version | gmt_modify | +----+---------+---------------------+ | 1 | 1 | 2020-12-17 16:40:38 | | 2 | 1 | 2020-12-17 16:40:39 | +----+---------+---------------------+
- 更新数据
mysql> UPDATE tab SET version = version + 1, gmt_modify = now(); mysql> COMMIT; mysql> SELECT * FROM tab; +----+---------+---------------------+ | id | version | gmt_modify | +----+---------+---------------------+ | 1 | 2 | 2020-12-17 16:40:54 | | 2 | 2 | 2020-12-17 16:40:54 | +----+---------+---------------------+
- 使用Flashback Query查询
mysql> SELECT * FROM tab AS OF TIMESTAMP '2020-12-17 16:40:40'; +----+---------+---------------------+ | id | version | gmt_modify | +----+---------+---------------------+ | 1 | 1 | 2020-12-17 16:40:38 | | 2 | 1 | 2020-12-17 16:40:39 | +----+---------+---------------------+ mysql> SELECT * FROM tab AS OF TIMESTAMP '2020-12-17 16:40:55'; +----+---------+---------------------+ | id | version | gmt_modify | +----+---------+---------------------+ | 1 | 2 | 2020-12-17 16:40:54 | | 2 | 2 | 2020-12-17 16:40:54 | +----+---------+---------------------+
说明 如果查询的版本时间点太旧,此时undo记录已经被删除(Truncate),就会报错:ERROR 7546 (HY000): Snapshot too old
。
为了更好的使用Flashback Query,RDS MySQL提供三个参数来管理Flashback Query,说明如下。
类别 | INNODB_UNDO_RETENTION | INNODB_UNDO_SPACE_SUPREMUM_SIZE | INNODB_UNDO_SPACE_RESERVED_SIZE |
---|---|---|---|
描述 | InnoDB存储引擎保留undo记录的最长时间,单位:秒。 保留的越久,Flashback Query能够支持的回档查询越久,但undo表空间所占用的存储空间也会快速上升。 | InnoDB存储引擎保留的undo表空间的最大值,单位:MB。 超过这个值时,会忽略INNODB_UNDO_RETENTION强制清理undo记录。 | InnoDB存储引擎预留的undo表空间大小,单位:MB。 在INNODB_UNDO_RETENTION设置有效(非零)的情况下,将使用这部分空间尽可能的多保留undo记录。 |
命令行格式 | --innodb-undo-retention=# | --innodb-undo-space-supremum-size=# | --innodb-undo-space-reserved-size=# |
参数范围 | 全局参数(Global) | 全局参数(Global) | 全局参数(Global) |
是否动态参数 | 是 | 是 | 是 |
设置变量应用是否提示 | 否 | 否 | 否 |
数据类型 | Integer | Integer | Integer |
默认值 | 0 | 102400 | 0 |
取值范围 | 0~4294967295 | 0~4294967295 | 0~4294967295 |
XA事务和全局一致性
为了完整的支持XA事务和分布式全局一致性,Lizard事务系统支持外部传入全局事务提交号GCN(Global Commit Number),说明如下:
- 事务提交过程中,支持传入GCN提交,即COMMT/XA COMMIT by GCN。
- 语句查询过程中,支持传入GCN查询,提SELECT by GCN。
例如在最简单的分布式结构和场景下,维护一个全局授时服务器(TSO)节点,并购买三个RDS MySQL高可用版实例。

示例命令如下:
- Node 1节点
XA BEGIN $xid; UPDATE account SET balance = balance + 10 WHERE user = '张三'; XA END; XA PREPARE $xid; XA COMMIT $xid $GCN;
- Node 2节点
XA BEGIN $xid UPDATE account SET balance = balance - 10 WHERE user = '李四'; XA END; XA PREPARE $xid; XA COMMIT $xid $GCN;
- 查询语句
- Node 1节点
SELECT * FROM account AS OF GCN $GCN where user ='张三';
- Node 2节点
SELECT * FROM account AS OF GCN $GCN where user ='李四’;
- Node 1节点