X-Engine引擎使用须知

RDS MySQL提供阿里云自研的X-Engine存储引擎,支持事务并且可以大幅降低磁盘空间占用。

产品介绍

X-Engine是阿里云数据库产品事业部自研的联机事务处理OLTP(On-Line Transaction Processing)数据库存储引擎。作为自研数据库PolarDB的存储引擎之一,已经广泛应用在阿里集团内部诸多业务系统中,包括交易历史库、钉钉历史库等核心应用,大幅缩减了业务成本,同时也作为双十一大促的关键数据库技术,挺过了数百倍平时流量的冲击。

X-Engine是适用于大规模电子商务交易处理的优化存储引擎,X-Engine团队撰写的论文 《X-Engine: An Optimized Storage Engine for Large-scale E-Commerce Transaction Processing》,详细讲述了X-Engine在数据库存储引擎领域所做的原创性工作,2019年被SIGMOD'19 Industrial Track接收。

与传统的InnoDB引擎不同,X-Engine使用分层存储架构(LSM-Tree)。分层存储有两个比较显著的优点:

  • 需要索引的热点数据集更小,写入性能更高。

  • 底层持久化的数据页是只读的,数据页采用紧凑存储格式,同时默认进行压缩,存储成本更低。

除了LSM-Tree架构自身的优势之外,X-Engine在工程实现上也进行了大量的创新,主要包含如下几个方面:

  • 利用先天性的优势,持续优化写入性能,X-Engine相比同为LSM-tree架构的Rocksdb,有超过10倍的性能提升。

  • 在存储层引入数据复用技术等,优化Compaction的性能,降低传统LSM-tree架构中Compaction动作对系统资源的冲击,保持系统性能平稳。

  • 支持在同一实例中混合部署SSD/HDD等不同IO能力的存储设备, 利用天然分层结构的特点,结合不同存储硬件的IO读写性能,智能地进行数据的冷热分离存储,在不降低性能的前提下,降低综合成本。

  • 引入多个层级Cache,同时结合Cach回填和预取机制,利用精细化访问机制和缓存技术,弥补传统LSM-tree引擎的读性能短板。

通过以上多方面的工程优化,X-Engine成为传统InnoDB引擎的一个替代选项,既支持事务,同时又能够显著的降低业务存储成本(依据数据特征,存储空间可降低至10%~50%),特别适合数据容量巨大,同时又要保证一定事务读写性能的业务。

说明

关于X-Engine引擎适用的业务场景请参见X-Engine最佳实践

前提条件

实例为RDS MySQL 8.0高可用系列或基础系列。

购买RDS实例(X-Engine)

如果您需要使用X-Engine引擎,请在购买RDS实例时,基础资源页面选择实例类型为MySQL 8.0,然后在实例配置页面选择存储引擎为X-Engine(高压缩率)。其他参数说明请参见快速创建RDS MySQL实例

说明

创建X-Engine表

如果创建实例时设置了默认引擎为X-Engine,则建表时默认引擎就是X-Engine。您可以通过如下命令查看默认引擎:

show variables like '%default_storage_engine%';

查看默认引擎

当默认引擎是X-Engine时,建表语句无需指定存储引擎。

创建表

表创建成功后,后续使用方法与InnoDB一样,数据会存储在X-Engine引擎。

说明

实例上仍然可以创建InnoDB引擎的表,尤其是使用DTS迁移数据时,可能会出现迁移的表引擎仍然为InnoDB。解决方案请参见引擎转换方案二

使用限制

  • 与InnoDB引擎共存时的资源分配限制

    使用X-Engine引擎时,95%的内存会提供给X-Engine引擎用做写入缓存和BlockCache以加速读写速度,留给InnoDB Buffer Pool的内存非常少,所以在X-Engine引擎的实例中尽量避免使用InnoDB引擎表存储太多数据,否则会因为缓存命中率低而导致性能大幅降低。建议使用RDS MySQL 8.0时,所有的表都使用相同的引擎(X-Engine或InnoDB),避免两种引擎混用。

  • 引擎功能限制

    X-Engine在引擎功能上有一些限制,其中部分功能尚在开发中。其他未列出的部分,默认其功能特性与InnoDB引擎相同。

    分类

    功能

    X-Engine引擎

    备注

    SQL功能

    外键

    不支持

    -

    临时表

    不支持

    -

    分区表(partition)

    不支持(所有partition相关创建及增删改查操作均不支持)

    -

    Generated Column

    不支持

    -

    Handler API

    不支持

    -

    列属性

    最大列长度

    (longblob/longtext/json)

    32MB

    -

    GIS地理数据类型

    所有GIS相关数据类型均不支持(包含geometry、point、linestring、polygon、multipoint、multilinestring、multipolygon、geometrycollection)

    -

    索引

    哈希索引

    不支持

    -

    空间索引

    不支持(所有fulltext索引相关的创建,使用均不支持)

    -

    事务

    事务隔离级别

    2个隔离级别:

    • 读已提交(RC)

    • 可重复读(RR)

    -

    最大事务

    32MB

    更大事务的支持在开发中

    Savepoint

    不支持

    -

    XA事务

    不支持

    功能开发中

    锁粒度

    • 支持表级别锁

    • 支持行级别锁

    • 不支持GAP锁

    -

    Skip Locked

    Lock Nowait

    不支持

    -

    字符集支持

    非索引列支持的字符格式

    非索引列支持所有的字符集(校对规则)

    -

    索引列支持的字符格式

    • latin1(latin1_bin)

    • gbk(gbk_chinese_ci、gbk_bin)

    • utf8(utf8_general_ci、utf8_bin)

    • utf8mb4(utf8mb4_0900_ai_ci、utf8mb4_general_ci、utf8mb4_bin)

    -

    主从复制

    Binlog格式

    stmt/row/mixed

    说明

    默认为row,采用stmt/mixed在特定并发场景可能存在数据安全性问题。

    -

  • 大事务功能限制

    X-Engine目前不支持大事务。当一个事务修改的行数特别多时,X-Engine会使用commit in middle功能。例如用户在一个事务中修改的行数超过10000行,X-Engine会在内部把该事务提交,并且重新开启一个事务继续服务当前用户开启的事务。但是commit in middle并不能遵循严格意义上的ACID,您在使用过程中需要注意。以下举例说明:

    • 用户开启一个事务插入大量数据,在插入的过程中,由于先提交了一部分数据,其它请求就可以访问到插入的数据。

    • 用户开启一个事务修改大量数据,回滚的时候,已经执行了commit in middle的事务无法回滚。

      drop table t1;
      create table t1(c1 int primary key , c2 int)ENGINE=xengine;
      begin;
      call insert_data(12000); //插入12000行数据,触发commit in middle,前10000行数据已经提交。
      rollback;// 回滚只能把最后2000条数据回滚。
      select count(*) from t1; // 这里仍然能够查询到10000条数据。
      +----------+
      | count(*) |
      +----------+
      |    10000 |
      +----------+
      1 row in set (0.00 sec)
    • 用户开启一个事务删除或者修改大量数据时,会遗漏掉本事务修改的行。

      drop table t1;
      create table t1(c1 int primary key , c2 int)ENGINE=xengine;
      call insert_data(10000);
      begin;
      insert into t1 values(10001,10001), (10002,10002);
      delete from t1 where c1 >= 0;// delete操作触发commit in middle,导致delete操作没有读到本事务插入的行。
      commit;
      select * from t1;
      +-------+-------+
      | c1    | c2    |
      +-------+-------+
      | 10001 | 10001 |
      | 10002 | 10002 |
      +-------+-------+
      2 rows in set (0.00 sec)

参数说明

说明

快速创建RDS MySQL实例时,可以选择X-Engine为默认存储引擎,也可以根据下表的参数说明调整参数模板以便适应自身业务。

类别

参数

说明

备注

性能

xengine_arena_block_size

memtable向操作系统/jemalloc的外部内存管理系统申请新内存分配的单位。

启动后只读

xengine_batch_group_max_group_size

事务流水线最大分组数。

启动后只读

xengine_batch_group_max_leader_wait_time_us

事务流水线最大等待时间。

启动后只读

xengine_batch_group_slot_array_size

事务流水线最大batch大小。

启动后只读

内存

xengine_block_cache_size

读block缓存的大小。

不可修改

xengine_row_cache_size

行缓存的大小。

不可修改

xengine_write_buffer_size

单Memtable的最大大小。

不可修改

xengine_block_size

磁盘上数据block大小。

初始化后只读

启动后只读

xengine_db_write_buffer_size

所有subtable的Active Memtable的总计大小限制。

不可修改

xengine_db_total_write_buffer_size

所有subtable的Active Memtable/Immutable memtable的总大小限制。

不可修改

xengine_scan_add_blocks_limit

每个请求在范围扫描时,可以加到BlockCache中的Block数目。

不可修改

compaction

xengine_flush_delete_percent_trigger

当Memtable中记录数超过此数目时,则xengine_flush_delete_record_trigger参数生效。

不可修改

xengine_max_row_locks

单SQL请求中,最大可以锁定的行数。

不可修改

xengine_lock_wait_timeout

锁等待超时时间。

不可修改

运行状态指标

下表为X-Engine的运行状态指标。

指标名

含义

xengine_rows_deleted

删除行数。

xengine_rows_inserted

写入行数。

xengine_rows_read

读取行数。

xengine_rows_updated

更新行数。

xengine_system_rows_deleted

对引擎为X-Engine的系统表的删除次数。

xengine_system_rows_inserted

对引擎为X-Engine的系统表的插入次数。

xengine_system_rows_read

对引擎为X-Engine的系统表的读取次数。

xengine_system_rows_updated

对引擎为X-Engine的系统表的更新次数。

xengine_block_cache_add

向Block Cache添加次数。

xengine_block_cache_data_hit

读数据Block命中Cache次数。

xengine_block_cache_data_miss

读数据Block时Miss次数。

xengine_block_cache_filter_hit

Filter Block的命中次数。

xengine_block_cache_filter_miss

Filter Block的miss次数。

xengine_block_cache_hit

Block Cache的整体命中次数(data_hit + index_hit)。

xengine_block_cache_index_hit

索引Block命中次数。

xengine_block_cache_index_miss

索引Block miss次数。

xengine_block_cache_miss

Block Cache整体Miss次数(data_miss + index_miss)。

xengine_block_cachecompressed_miss

压缩的Block Cache Miss次数。

xengine_bytes_read

读物理磁盘的字节数。

xengine_bytes_written

写入物理磁盘的字节数。

xengine_memtable_hit

Memtable命中次数。

xengine_memtable_miss

Memtable Miss次数。

xengine_number_block_not_compressed

未压缩的Block数目。

xengine_number_keys_read

Key的读取次数。

xengine_number_keys_updated

Key的更新次数。

xengine_number_keys_written

Key的写入次数。

xengine_number_superversion_acquires

Superversion引用的申请次数统计。

xengine_number_superversion_cleanups

Superversion的清理次数。当一个Superversion无人再引用时则被清理。

xengine_number_superversion_releases

Superversion的引用释放次数,当一个Superversion的引用次数为0时则被清理。

xengine_snapshot_conflict_errors

在RR隔离级别下,因为Snapshot版本冲突而报错的次数。

xengine_wal_bytes

Redo落盘字节数。

xengine_wal_group_syncs

Redo执行GroupCommit的次数。

xengine_wal_synced

Redo日志Sync的次数。

xengine_write_other

在事务流水线中,作为Follower完成提交的次数。

xengine_write_self

在事务流水线中,作为Leader完成提交的次数。

xengine_write_wal

写Redo日志的次数。