RDS MySQL提供阿里雲自研的X-Engine儲存引擎,支援事務並且可以大幅降低磁碟空間佔用。
產品介紹
X-Engine是阿里雲資料庫產品事業部自研的聯機交易處理OLTP(On-Line Transaction Processing)資料庫儲存引擎。作為自研資料庫PolarDB的儲存引擎之一,已經廣泛應用在阿里集團內部諸多業務系統中,包括交易歷史庫、DingTalk歷史庫等核心應用,大幅縮減了業務成本,同時也作為雙十一大促的關鍵資料庫技術,挺過了數百倍平時流量的衝擊。
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執行個體。
RDS MySQL 5.5、5.6、5.7的使用者如果需要使用X-Engine引擎,請遷移至RDS MySQL 8.0版本執行個體。詳情請參見RDS執行個體間的資料移轉。
建立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日誌的次數。 |