當分區表的資料量持續增長時,舊的歷史資料(冷資料)會佔據大量儲存空間,導致儲存成本不斷攀升。為了在降低成本的同時保留對這些資料的訪問能力,您可以使用資料生命週期管理(DLM)策略,將較舊的分區自動歸檔為高壓縮引擎(X-Engine)格式。通過此功能,您可以實現分區層級的熱溫資料分離。熱資料保留在高效能的InnoDB分區中,而歸檔到X-Engine的溫資料在顯著降低儲存成本的同時,依然支援DML寫入和Online DDL變更,確保業務的連續性。
工作原理
分區表自動歸檔功能基於您在表上定義的DLM(Data Lifecycle Management)策略。其工作流程如下:
定義策略:您可以在建立表(
CREATE TABLE)或修改表(ALTER TABLE)時,定義一個DLM策略。該策略的核心是指定一個條件,例如,當分區數量超過N個時,最舊的分區將被視為歸檔對象。觸發執行:該策略不會即時自動觸發。您需要通過以下任意方式來執行歸檔任務:
手動執行:調用系統預存程序,立即執行所有已定義的DLM策略。
定時調度:建立一個
EVENT,按預設的時間計劃(如每日淩晨)自動調用預存程序來執行策略。
執行歸檔:當策略被執行時,系統會檢查滿足歸檔條件的表分區,並將其儲存引擎從InnoDB線上變更為X-Engine,從而完成歸檔。
適用範圍
使用本功能前,請確保您的叢集滿足以下條件:
產品系列為叢集版:
歸檔為X-Engine行存格式:MySQL 8.0.2且修訂版本為8.0.1.1.31或以上。
歸檔為X-Engine列存表格式:MySQL 8.0.2且修訂版本為8.0.2.2.23及以上。
產品系列為多主叢集(Limitless):MySQL 8.0.2且修訂版本為8.0.2.0.6及以上。
配置並執行分區歸檔
以下將引導您完成從建立歸檔策略到執行並驗證的全過程。
流程概述
建立DLM歸檔策略:在目標資料分割表上定義歸檔規則。
執行DLM歸檔策略:通過手動或定時任務觸發歸檔過程。
查看歸檔狀態與結果:驗證分區是否已成功轉換為X-Engine引擎。
步驟一:建立DLM歸檔策略
為分區表定義歸檔規則,明確何時將哪些分區歸檔至X-Engine。您可以在建立新表時或為已有表添加策略。
方式一:建立新表時定義策略
在
CREATE TABLE語句末尾使用DLM ADD POLICY子句。以下樣本建立了一個sales表,該表以order_time列作為分區鍵,按時間間隔劃分分區。同時,該表存在INTERVAL和DLM兩種策略INTERVAL策略:當插入的資料超過分區範圍時,將自動建立新的分區,時間間隔為1年。
DLM策略:定義了名為
policy_part2part的策略,規定當分區總數超過3個時,最舊的分區將被歸檔為X-Engine引擎。
CREATE TABLE `sales` ( `id` int DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `order_time` datetime NOT NULL, primary key (order_time) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 PARTITION BY RANGE COLUMNS(order_time) INTERVAL(YEAR, 1) (PARTITION p20200101000000 VALUES LESS THAN ('2020-01-01 00:00:00') ENGINE = InnoDB, PARTITION p20210101000000 VALUES LESS THAN ('2021-01-01 00:00:00') ENGINE = InnoDB, PARTITION p20220101000000 VALUES LESS THAN ('2022-01-01 00:00:00') ENGINE = InnoDB) DLM ADD POLICY policy_part2part TIER TO PARTITION ENGINE=XENGINE READ WRITE ON (PARTITIONS OVER 3);方式二:為已有表添加策略
使用
ALTER TABLE語句為現有的分區表添加DLM策略。更多資訊,請參見在ALTER TABLE時建立或刪除DLM策略。ALTER TABLE sales DLM ADD POLICY policy_part2part TIER TO PARTITION ENGINE=XENGINE ON (PARTITIONS OVER 3);文法說明:
ON (PARTITIONS OVER N)是策略的核心,N表示您希望保留在InnoDB引擎中的最新分區數量。當分區總數超過N時,超出部分的最舊分區就會成為歸檔對象。
插入測試資料
使用
proc_batch_insert預存程序向sales分區表中插入一定的測試資料,以觸發INTERVAL策略來自動建立新的分區。DROP PROCEDURE IF EXISTS proc_batch_insert; delimiter $$ CREATE PROCEDURE proc_batch_insert(IN begin INT, IN end INT, IN name VARCHAR(20)) BEGIN SET @insert_stmt = concat('INSERT INTO ', name, ' VALUES(? , ?, ?);'); PREPARE stmt from @insert_stmt; WHILE begin <= end DO SET @ID1 = begin; SET @NAME = CONCAT(begin+begin*281313, '@stiven'); SET @TIME = from_days(begin + 737600); EXECUTE stmt using @ID1, @NAME, @TIME; SET begin = begin + 1; END WHILE; END; $$ delimiter ; CALL proc_batch_insert(1, 3000, 'sales');執行結果如下,表示資料插入成功:
Query OK, 1 row affected (0.50 sec)執行以下命令,查看
sales表的結構資訊。SHOW CREATE TABLE sales \G查詢到的表結構如下,所有分區均是InnoDB引擎的分區:
mysql> SHOW CREATE TABLE sales \G *************************** 1. row *************************** Table: sales Create Table: CREATE TABLE `sales` ( `id` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `order_time` datetime NOT NULL, PRIMARY KEY (`order_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!50500 PARTITION BY RANGE COLUMNS(order_time) */ /*!99990 800020200 INTERVAL(YEAR, 1) */ /*!50500 (PARTITION p20200101000000 VALUES LESS THAN ('2020-01-01 00:00:00') ENGINE = InnoDB, PARTITION p20210101000000 VALUES LESS THAN ('2021-01-01 00:00:00') ENGINE = InnoDB, PARTITION p20220101000000 VALUES LESS THAN ('2022-01-01 00:00:00') ENGINE = InnoDB, PARTITION _p20230101000000 VALUES LESS THAN ('2023-01-01 00:00:00') ENGINE = InnoDB, PARTITION _p20240101000000 VALUES LESS THAN ('2024-01-01 00:00:00') ENGINE = InnoDB, PARTITION _p20250101000000 VALUES LESS THAN ('2025-01-01 00:00:00') ENGINE = InnoDB, PARTITION _p20260101000000 VALUES LESS THAN ('2026-01-01 00:00:00') ENGINE = InnoDB, PARTITION _p20270101000000 VALUES LESS THAN ('2027-01-01 00:00:00') ENGINE = InnoDB, PARTITION _p20280101000000 VALUES LESS THAN ('2028-01-01 00:00:00') ENGINE = InnoDB) */
步驟二:執行DLM歸檔策略
觸發已定義的歸檔策略,開機磁碟分割引擎的轉換過程。您可以根據業務需求選擇手動立即執行或設定定時任務。
方式一:定時調度執行(推薦):對於需要定期進行資料歸檔的生產環境,推薦使用MySQL的
EVENT功能,在業務低峰期(如每日淩晨)自動執行,實現無人值守的自動化營運。以下樣本建立一個事件,從2026-02-01後開始,每天淩晨01:00自動執行所有DLM策略。
CREATE EVENT dlm_system_base_event ON SCHEDULE EVERY 1 DAY STARTS '2026-02-01 01:00:00' do CALL dbms_dlm.execute_all_dlm_policies();方式二:手動立即執行:適用於一次性的歸檔任務或在問題排查後需要手動重試的情境。
直接調用以下預存程序,即可立即觸發所有已定義的DLM策略。
CALL dbms_dlm.execute_all_dlm_policies();
步驟三:查看歸檔狀態與結果
監控歸檔任務的進度,並在任務完成後驗證分區引擎是否已成功變更。
查看策略定義
您可以查詢
mysql.dlm_policies系統資料表,確認策略是否已成功建立。SELECT * FROM mysql.dlm_policies WHERE Table_schema = 'your_database' AND Table_name = 'sales'\G返回結果如下:
*************************** 1. row *************************** Id: 1 Table_schema: your_database Table_name: sales Policy_name: policy_part2part Policy_type: PARTITION Archive_type: PARTITION COUNT Storage_mode: READ WRITE Storage_engine: XENGINE Storage_media: DISK Storage_schema_name: NULL Storage_table_name: NULL Data_compressed: ON Compressed_algorithm: Zstandard Enabled: ENABLED Priority_number: 200 Tier_partition_number: 3 Tier_condition: NULL Extra_info: {"oss_file_filter": "order_time"} Comment: NULL關鍵字段說明:
欄位
說明
Table_schema、Table_name策略所屬的資料庫和表名。
Policy_name策略的自訂名稱。
Storage_engine歸檔的目標儲存引擎,此處為
XENGINE。Tier_partition_number策略中定義保留的InnoDB分區數量,即
PARTITIONS OVER N中的N。查看執行進度
在策略執行期間或執行後,您可以查詢
mysql.dlm_progress系統資料表來跟蹤任務狀態。SELECT * FROM mysql.dlm_progress WHERE Table_schema = 'your_database' AND Table_name = 'sales' ORDER BY Id DESC LIMIT 1\G返回結果如下:
*************************** 1. row *************************** Id: 1 Table_schema: your_database Table_name: sales Policy_name: policy_part2part Policy_type: PARTITION Archive_option: PARTITIONS OVER 3 Storage_engine: XENGINE Storage_media: DISK Data_compressed: ON Compressed_algorithm: Zstandard Archive_partitions: p20200101000000, p20210101000000, p20220101000000, _p20230101000000, _p20240101000000, _p20250101000000 Archive_stage: ARCHIVE_COMPLETE Archive_percentage: 100 Archived_file_info: null Start_time: 2026-02-06 10:50:00 End_time: 2026-02-06 10:50:00 Extra_info: null關鍵字段說明:
欄位
說明
Archive_partitions本次任務中被歸檔的分區列表。
Archive_stage歸檔任務的目前狀態。
ARCHIVE_COMPLETE表示成功,ARCHIVE_ERROR表示失敗。Archive_percentage任務完成百分比。
Start_time、End_time任務的開始和結束時間。
Extra_info額外資訊,尤其在
Archive_stage為ARCHIVE_ERROR時,此處會記錄詳細的錯誤原因。驗證表結構
當歸檔任務完成後,使用
SHOW CREATE TABLE命令查看錶結構,確認舊分區的ENGINE是否已變為XENGINE。SHOW CREATE TABLE sales\G返回結果如下:
*************************** 1. row *************************** Table: sales Create Table: CREATE TABLE `sales` ( `id` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `order_time` datetime NOT NULL, PRIMARY KEY (`order_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020216 PARTITION BY RANGE COLUMNS(order_time) */ /*!99990 800020200 INTERVAL(YEAR, 1) */ /*!99990 800020216 (PARTITION p20200101000000 VALUES LESS THAN ('2020-01-01 00:00:00') ENGINE = XENGINE, PARTITION p20210101000000 VALUES LESS THAN ('2021-01-01 00:00:00') ENGINE = XENGINE, PARTITION p20220101000000 VALUES LESS THAN ('2022-01-01 00:00:00') ENGINE = XENGINE, PARTITION _p20230101000000 VALUES LESS THAN ('2023-01-01 00:00:00') ENGINE = XENGINE, PARTITION _p20240101000000 VALUES LESS THAN ('2024-01-01 00:00:00') ENGINE = XENGINE, PARTITION _p20250101000000 VALUES LESS THAN ('2025-01-01 00:00:00') ENGINE = XENGINE, PARTITION _p20260101000000 VALUES LESS THAN ('2026-01-01 00:00:00') ENGINE = InnoDB, PARTITION _p20270101000000 VALUES LESS THAN ('2027-01-01 00:00:00') ENGINE = InnoDB, PARTITION _p20280101000000 VALUES LESS THAN ('2028-01-01 00:00:00') ENGINE = InnoDB) */
應用於生產環境
策略設計:根據業務情境合理設計
PARTITIONS OVER N中的N值。例如,對於訂單類資料,可保留最近6個月的資料在InnoDB分區以保證查詢效能;對於日誌類資料,可僅保留最近30天的資料。監控與警示:建立對
mysql.dlm_progress表中Archive_stage欄位的監控。當出現ARCHIVE_ERROR狀態時,應立即觸發警示,以便及時介入處理。