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、gemometrycollection) -
    索引 哈希索引 不支持 -
    空间索引 不支持(所有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,前1000行数据已经提交。
      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 加入Block Cache的字节数
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日志的次数