As data volume in a partitioned table grows, older historical data (cold data) consumes significant storage space and increases storage costs. To reduce storage costs while retaining data access, you can use a Data Lifecycle Management (DLM) policy to automatically archive older partitions to the high-compression engine (X-Engine) format. This feature allows you to separate hot and warm data at the partition level. Hot data remains in high-performance InnoDB partitions, while warm data archived to X-Engine significantly reduces storage costs and continues to support DML writes and Online DDL changes.
How it works
The automatic partition archiving feature uses a Data Lifecycle Management (DLM) policy that you define on a table. It works as follows:
Define a policy: You can define a DLM policy when you create a table with
CREATE TABLEor modify a table withALTER TABLE. The policy's core is a condition that specifies when to archive. For example, if the number of partitions exceeds a threshold, the oldest partition is marked for archiving.Trigger execution: The policy does not trigger automatically. You must initiate the archive task in one of two ways:
Manual execution: Call a system stored procedure to immediately execute all defined DLM policies.
Scheduled execution: Create an
EVENTto automatically call the stored procedure and execute the policies on a predefined schedule, such as daily during off-peak hours.
Perform the archive: When the policy is executed, the system identifies table partitions that meet the archiving conditions and changes their storage engine from InnoDB to X-Engine online to complete the archive.
Prerequisites
Before you use this feature, ensure that your cluster meets the following requirements:
Edition: Cluster Edition.
Kernel version:
To archive to the X-Engine row-based format:
MySQL 8.0.2, revision version 8.0.2.2.34.1 or later.
To archive to the X-Engine columnar table format:
MySQL 8.0.2, revision version 8.0.2.2.34.1 or later.
Configure and perform partition archiving
This section guides you through creating, executing, and verifying an archive policy.
Process overview
Create a DLM archive policy: Define the archiving rules on the target partitioned table.
Execute the DLM archive policy: Trigger the archiving process manually or through a scheduled task.
View the archive status and results: Verify that the partitions have been successfully converted to the X-Engine engine.
Step 1: Create a DLM archive policy
You can define an archiving policy when you create a partitioned table or add one to an existing table.
Method 1: Define a policy when creating a new table
Use the
DLM ADD POLICYclause at the end of theCREATE TABLEstatement. The following example creates asalestable that uses theorder_timecolumn as the partitioning key. This table has two policies: an INTERVAL policy and a DLM policy.INTERVAL policy: Automatically creates new partitions for one-year intervals when inserted data falls outside the existing partition ranges.
DLM policy: Defines a policy named
policy_part2part. This policy specifies that when the total number of partitions exceeds three, the oldest partition is marked for archiving to 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);Method 2: Add a policy to an existing table
Use the
ALTER TABLEstatement to add a DLM policy to an existing partitioned table. For more information, see Create or delete a DLM policy in ALTER TABLE.ALTER TABLE sales DLM ADD POLICY policy_part2part TIER TO PARTITION ENGINE=XENGINE ON (PARTITIONS OVER 3);Syntax description:
ON (PARTITIONS OVER N)is the core of the policy, whereNis the number of recent partitions to keep in the InnoDB engine. When the total number of partitions exceedsN, the oldest partitions beyond this number are marked for archiving.
Insert test data
Use the
proc_batch_insertstored procedure to insert test data into thesalespartitioned table. This triggers the INTERVAL policy to automatically create new partitions.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');The following result indicates that the data is inserted successfully:
Query OK, 1 row affected (0.50 sec)Run the following command to view the
salestable structure.SHOW CREATE TABLE sales \GThe output shows the table structure, in which all partitions currently use the InnoDB engine.
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) */
Step 2: Execute the DLM archive policy
Trigger the defined archive policy to start the partition engine conversion process. You can choose to execute it manually or set up a scheduled task based on your business needs.
Method 1: Scheduled execution (Recommended): For production environments that require regular data archiving, we recommend using the MySQL
EVENTfeature to automatically run the task during off-peak hours, such as in the early morning. This approach automates the task.The following example creates an event that starts on 2026-02-01 and runs daily at 01:00 to execute all DLM policies.
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();Method 2: Manual execution: This method is suitable for one-time archive tasks or for manually retrying a task after troubleshooting.
Call the following stored procedure to immediately trigger all defined DLM policies.
CALL dbms_dlm.execute_all_dlm_policies();
Step 3: View the archive status and results
Monitor the archive task's progress. After the task completes, verify that the partition engines have changed.
View the policy definition
Query the
mysql.dlm_policiessystem table to confirm that the policy was created.SELECT * FROM mysql.dlm_policies WHERE Table_schema = 'your_database' AND Table_name = 'sales'\GThe following result is returned:
*************************** 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: NULLKey field descriptions:
Field
Description
Table_schema,Table_nameThe database and table to which the policy belongs.
Policy_nameThe custom name of the policy.
Storage_engineThe target storage engine for archived partitions. In this example, it is
XENGINE.Tier_partition_numberThe policy defines the number of InnoDB partitions to retain. This is the
NinPARTITIONS OVER N.View the execution progress
During or after policy execution, you can query the
mysql.dlm_progresssystem table to track the task status.SELECT * FROM mysql.dlm_progress WHERE Table_schema = 'your_database' AND Table_name = 'sales' ORDER BY Id DESC LIMIT 1\GThe following result is returned:
*************************** 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: nullKey field descriptions:
Field
Description
Archive_partitionsThe partitions archived in this task.
Archive_stageThe current status of the archive task.
ARCHIVE_COMPLETEindicates success, andARCHIVE_ERRORindicates failure.Archive_percentageThe completion percentage of the task.
Start_time,End_timeThe start and end times of the task.
Extra_infoAdditional information. If
Archive_stageisARCHIVE_ERROR, this field contains error details.Verify the table structure
After the archive task is complete, use the
SHOW CREATE TABLEcommand to view the table structure and confirm that theENGINEof the archived partitions has changed toXENGINE.SHOW CREATE TABLE sales\GThe following result is returned:
*************************** 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) */
Production considerations
Policy design: Choose an appropriate
Nvalue inPARTITIONS OVER Nbased on your business scenario. For example, for order data, you might keep the most recent six months of data in InnoDB partitions to ensure query performance. For log data, you might only need to keep the last 30 days of data.Monitoring and alerting: Monitor the
Archive_stagefield in themysql.dlm_progresstable. When the status isARCHIVE_ERROR, trigger an immediate alert for timely intervention.