当分区表的数据量持续增长时,旧的历史数据(冷数据)会占据大量存储空间,导致存储成本不断攀升。为了在降低成本的同时保留对这些数据的访问能力,您可以使用数据生命周期管理(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状态时,应立即触发告警,以便及时介入处理。