全部产品
Search
文档中心

云原生数据库 PolarDB:归档分区表为X-Engine引擎格式

更新时间:Feb 10, 2026

当分区表的数据量持续增长时,旧的历史数据(冷数据)会占据大量存储空间,导致存储成本不断攀升。为了在降低成本的同时保留对这些数据的访问能力,您可以使用数据生命周期管理(DLM)策略,将较旧的分区自动归档为高压缩引擎(X-Engine)格式。通过此功能,您可以实现分区级别的热温数据分离。热数据保留在高性能的InnoDB分区中,而归档到X-Engine的温数据在显著降低存储成本的同时,依然支持DML写入和Online DDL变更,确保业务的连续性。

工作原理

分区表自动归档功能基于您在表上定义的DLM(Data Lifecycle Management)策略。其工作流程如下:

  1. 定义策略:您可以在创建表(CREATE TABLE)或修改表(ALTER TABLE)时,定义一个DLM策略。该策略的核心是指定一个条件,例如,当分区数量超过N个时,最旧的分区将被视为归档对象。

  2. 触发执行:该策略不会实时自动触发。您需要通过以下任意方式来执行归档任务:

    • 手动执行:调用系统存储过程,立即执行所有已定义的DLM策略。

    • 定时调度:创建一个EVENT,按预设的时间计划(如每日凌晨)自动调用存储过程来执行策略。

  3. 执行归档:当策略被执行时,系统会检查满足归档条件的表分区,并将其存储引擎从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及以上。

配置并执行分区归档

以下将引导您完成从创建归档策略到执行并验证的全过程。

流程概述

  1. 创建DLM归档策略:在目标分区表上定义归档规则。

  2. 执行DLM归档策略:通过手动或定时任务触发归档过程。

  3. 查看归档状态与结果:验证分区是否已成功转换为X-Engine引擎。

步骤一:创建DLM归档策略

为分区表定义归档规则,明确何时将哪些分区归档至X-Engine。您可以在创建新表时或为已有表添加策略。

  • 方式一:创建新表时定义策略

    CREATE TABLE语句末尾使用DLM ADD POLICY子句。以下示例创建了一个sales表,该表以order_time列作为分区键,按时间间隔划分分区。同时,该表存在INTERVALDLM两种策略

    • 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时,超出部分的最旧分区就会成为归档对象。

插入测试数据

  1. 使用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)
  2. 执行以下命令,查看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();

步骤三:查看归档状态与结果

监控归档任务的进度,并在任务完成后验证分区引擎是否已成功变更。

  1. 查看策略定义

    您可以查询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_schemaTable_name

    策略所属的数据库和表名。

    Policy_name

    策略的自定义名称。

    Storage_engine

    归档的目标存储引擎,此处为XENGINE

    Tier_partition_number

    策略中定义保留的InnoDB分区数量,即PARTITIONS OVER N中的N

  2. 查看执行进度

    在策略执行期间或执行后,您可以查询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_timeEnd_time

    任务的开始和结束时间。

    Extra_info

    额外信息,尤其在Archive_stageARCHIVE_ERROR时,此处会记录详细的错误原因。

  3. 验证表结构

    当归档任务完成后,使用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状态时,应立即触发告警,以便及时介入处理。