All Products
Search
Document Center

PolarDB:Usage

Last Updated:Nov 10, 2024

To reduce storage costs and improve storage efficiency, you can enable the automatic archiving of cold data from PolarStore to Object Storage Service (OSS) by using data lifecycle management (DLM) policies.

Prerequisites

  • The cluster runs one of the following database engine versions:

    • PolarDB for MySQL 8.0.1 whose revision version is 8.0.1.1.32 or later.

    • PolarDB for MySQL 8.0.2 whose revision version is 8.0.2.2.9 or later.

    For information about how to query the database engine version of a cluster, see Query the engine version.

    Note

    If the cluster runs PolarDB for MySQL 8.0.2 whose revision version is 8.0.2.2.11.1 or later, DLM-related changes to the database are not recorded in binary logs.

  • Before you use DLM policies, you must enable the cold data archiving feature. For more information, see Enable cold data archiving.

    Note

    If the cold data archiving feature is disabled when you use DLM policies, the following error is reported:

    ERROR 8158 (HY000): [Data Lifecycle Management] DLM storage engine is not support. The value of polar_dlm_storage_mode is OFF.

Limits

  • You can use DLM policies only on partitioned tables. The partitioned tables must use the RANGE COLUMN partitioning method and cannot contain subpartitions.

  • You cannot use DLM policies on a partitioned table on which global secondary indexes (GSIs) are created.

  • You cannot directly modify a DLM policy in a PolarDB for MySQL cluster. To modify a DLM policy, delete the policy and then create a new policy.

  • After you create a DLM policy on a table, cold data is archived based on the policy. If DDL operations on the original table such as adding or removing columns and modifying data types cause inconsistent schemas between the original table and the archived table, the subsequently archived data cannot be parsed. Before you perform such DDL operations, you must delete the DLM policy on the table. To use the automatic cold data archiving feature again later, you can recreate a DLM policy and specify a new name for the archived table. The new name of the archived table cannot be the same as the original name of the archived table.

  • We recommend that you use INTERVAL RANGE partitioning to automatically partition tables and use DLM policies to archive infrequently accessed partition data to OSS.

    Note

    INTERVAL RANGE partitioning is supported only for clusters that run PolarDB for MySQL 8.0.2 whose revision version is 8.0.2.2.0 or later.

  • To use a DLM policy, configure the policy by executing the CREATE TABLE or ALTER TABLE statement.

  • DLM policies are not displayed in the output of the SHOW CREATE TABLE statement. You can view all DLM policies for the tables in a cluster from the mysql.dlm_policies table.

Usage notes

  • After cold data is archived, the archived table in OSS becomes read-only and provides poor query performance. Check whether the archived table can meet the query performance requirements of your business in advance.

  • After a partition in a partitioned table is archived to OSS, data in the partition becomes read-only. SQL statements cannot be executed on the partitioned table.

  • When you perform a backup operation, data that is transferred to OSS is not backed up. When you restore data to a previous point in time, data stored in OSS is not restored.

Syntax

Create a DLM policy

  • Create a DLM policy by executing the CREATE TABLE statement

    CREATE TABLE [IF NOT EXISTS] tbl_name
        (create_definition,...)
        [table_options]
        [partition_options]
        [dlm_add_options]
    
    dlm_add_options:
        DLM ADD
            [(dlm_policy_definition [, dlm_policy_definition] ...)]
    
    dlm_policy_definition:
        POLICY policy_name
        [TIER TO TABLE/TIER TO PARTITION/TIER TO NONE]
        [ENGINE [=] engine_name]
        [STORAGE SCHEMA_NAME [=] storage_schema_name]
        [STORAGE TABLE_NAME [=] storage_table_name]
        [STORAGE [=] OSS]
        [READ ONLY]
        [COMMENT 'comment_string']
        [EXTRA_INFO 'extra_info']
        ON [(PARTITIONS OVER num)]           
  • Create a DLM policy by executing the ALTER TABLE statement

    ALTER TABLE tbl_name
        [alter_option [, alter_option] ...]
        [partition_options]
        [dlm_add_options]
    
    dlm_add_options:
        DLM ADD
            [(dlm_policy_definition [, dlm_policy_definition] ...)]
    
    dlm_policy_definition:
        POLICY policy_name
        [TIER TO TABLE/TIER TO PARTITION/TIER TO NONE]
        [ENGINE [=] engine_name]
        [STORAGE SCHEMA_NAME [=] storage_schema_name]
        [STORAGE TABLE_NAME [=] storage_table_name]
        [STORAGE [=] OSS]
        [READ ONLY]
        [COMMENT 'comment_string']
        [EXTRA_INFO 'extra_info']
        ON [(PARTITIONS OVER num)]      

DLM policy parameters

Parameter

Required

Description

tbl_name

Yes

The name of the table.

policy_name

Yes

The name of the DLM policy.

TIER TO TABLE

Yes

Archives tables to OSS.

TIER TO PARTITION

Yes

Archives partitions to OSS.

Note
  • This feature is in canary release. To use the feature, go to Quota Center. Find the quota name that corresponds to the polardb_mysql_hybrid_partition quota ID and click Apply in the Actions column.

  • You can archive the partitions of a partitioned table to OSS only if your cluster runs PolarDB for MySQL 8.0.2 whose revision version is 8.0.2.2.17 or later.

  • If you use this feature, make sure that the total number of partitions in the partitioned table does not exceed 8,192.

TIER TO NONE

Yes

Deletes the data that you want to archive.

engine_name

No

The storage engine to which the data is archived. Data can be archived only to the CSV storage engine.

storage_schema_name

No

The scheme of the archived table. By default, the archived table retains the same schema as the source table.

storage_table_name

No

The name of the archived table. You can specify a table name. By default, the table name is in the following format: <Current table name>_<Current DLM policy name>.

STORAGE [=] OSS

No

Specifies that the archived data is stored in OSS (default).

READ ONLY

No

Specifies that the archived data is read-only (default).

comment_string

No

The comment of the DLM policy.

extra_info

No

Specifies the OSS file filter information of the destination OSS table.

Note
  • You can archive partitions of partitioned tables to OSS only if your cluster runs PolarDB for MySQL Enterprise Edition 8.0.2 whose revision version is 8.0.2.2.25 or later.

  • This feature takes effect only if the destination table does not exist. If the destination OSS table does not exist, the system automatically generates FILE_FILTER attributes based on the OSS_FILE_FILTER value in the EXTRA_INFO parameter, and automatically generates filter data during archiving. If the destination table already exists, the existing file filter takes precedence.

EXTRA_INFO format: {"oss_file_filter":"field_filter[,field_filter]"}. field_filter is in the following format:

field_filter := field_name[:filter_type]
filter_type := bloom

ON (PARTITIONS OVER num)

Yes

Archives data when the number of partitions exceeds the specified num value.

Manage a DLM policy

  • Enable a DLM policy.

    ALTER TABLE table_name DLM ENABLE POLICY [(dlm_policy_name [, dlm_policy_name] ...)]
  • Disable a DLM policy.

    ALTER TABLE table_name DLM DISABLE POLICY [(dlm_policy_name [, dlm_policy_name] ...)]
  • Delete a DLM policy.

    ALTER TABLE table_name DLM DROP POLICY [(dlm_policy_name [, dlm_policy_name] ...)]

In the preceding statements, the table_name parameter specifies the name of a table, and the dlm_policy_name parameter specifies the name of the policy that you want to manage. You can specify multiple policy names.

Execute a DLM policy

  • Execute the DLM policies on all tables in the current cluster.

    CALL dbms_dlm.execute_all_dlm_policies();
  • Execute the DLM policies on a specific table.

    CALL dbms_dlm.execute_table_dlm_policies('database_name', 'table_name');

    In the preceding statements, the database_name parameter specifies the name of a database, and the table_name parameter specifies the name of a table.

You can use the MySQL event feature to execute DLM policies during cluster O&M. This prevents an impact on the performance of your database during peak hours. You can also periodically transfer expired data to reduce your storage costs. Syntax to execute DLM policies by creating an event:

CREATE
    EVENT
    [IF NOT EXISTS]
    event_name
    ON SCHEDULE schedule
    [COMMENT 'comment']
    DO event_body;

schedule: {
  EVERY interval
  [STARTS timestamp [+ INTERVAL interval] ...]
}

interval:
    quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
              WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
              DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}

event_body: {
      CALL dbms_dlm.execute_all_dlm_policies();
    | CALL dbms_dlm.execute_table_dlm_policies('database_name', 'table_name');
}

The following table describes the parameters in the preceding sample code.

Parameter

Required

Description

event_name

Yes

The name of the event.

schedule

Yes

The schedule on which to execute the event.

comment

No

The comment for the event.

event_body

Yes

The content of the event. The content must be the statement that executes the DLM policy by using the event.

Note
  • If you specify the CALL dbms_dlm.execute_all_dlm_policies() statement, the event executes all DLM policies on the cluster. Therefore, you must create one event for each cluster.

  • If you specify the CALL dbms_dlm.execute_table_dlm_policies('database_name', 'table_name'); statement, the event executes all DLM policies only on the specified table. Therefore, you must create one event for each table that has DLM policies defined to archive data in the table at a specified time.

interval

Yes

The interval at which the event is executed.

timestamp

Yes

The time when event execution starts.

database_name

Yes

The name of the database.

table_name

Yes

The name of the table.

For information about the MySQL event feature, see MySQL event documentation.

For examples of how to archive partitioned table data to OSS, see Examples.

Examples

Archive data in a partitioned table to an OSS foreign table

  1. Create a DLM policy

    In the following example, a partitioned table named sales is created. The table uses the order_time column as the partition key and adopts interval partitioning. An interval policy and a DLM policy are defined for the table.

    • Interval policy: When data inserted into the table falls outside the partitioning interval of one year, a new partition is automatically created.

    • DLM policy: If the number of partitions in the table exceeds 3, the DLM policy is triggered and performs the following actions:

      • If the sales_history foreign table does not exist, create the table and archive cold data to the table.

      • If the sales_history foreign table exists and resides in the built-in OSS space, directly archive cold data to the table.

    Note

    To create an INTERVAL RANGE partitioned table, make sure that the requirements are met. For more information, see Interval range partitioning.

    1. Create a table named sales with a DLM policy defined.

      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 test_policy TIER TO TABLE ENGINE=CSV STORAGE=OSS READ ONLY
      STORAGE TABLE_NAME = 'sales_history' EXTRA_INFO '{"oss_file_filter":"id,name:bloom"}' ON (PARTITIONS OVER 3);

      The DLM policy is named test_policy. If the number of partitions in the table exceeds 3, cold data is archived from the current table to OSS in the CSV format. The archived table is named sales_history and is read-only. If the OSS foreign table does not exist, the system automatically creates the table and an OSS file filter on the id and name columns.

    2. The DLM policies of the current table are stored in the mysql.dlm_policies system table. You can view the details of the DLM policies in the system table. For more information about the mysql.dlm_policies system table, see Table formats. To view the scheme of the mysql.dlm_policies system table, execute the following statement:

      mysql> SELECT * FROM mysql.dlm_policies\G

      Sample result:

      *************************** 1. row ***************************
                         Id: 3
               Table_schema: gg
                 Table_name: sales
                Policy_name: test_policy
                Policy_type: TABLE
               Archive_type: PARTITION COUNT
               Storage_mode: READ ONLY
             Storage_engine: CSV
              Storage_media: OSS
        Storage_schema_name: gg
         Storage_table_name: sales_history
            Data_compressed: OFF
       Compressed_algorithm: NULL
                    Enabled: ENABLED
            Priority_number: 10300
      Tier_partition_number: 3
             Tier_condition: NULL
                 Extra_info: {"oss_file_filter": "id,name:bloom,order_time"}
                    Comment: NULL
      1 row in set (0.03 sec)      

      The sales table contains three partitions. No data is archived.

    3. Insert 3,000 rows of test data into the sales table to trigger the automatic creation of interval 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');
    4. In this case, the number of partitions in the sales table exceeds three. Execute the following statement to view the scheme of the table:

      mysql> SHOW CREATE TABLE sales\G

      Sample result:

      *************************** 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) */
      1 row in set (0.03 sec)

      New partitions are created in the table, and the number of partitions in the table exceeds 3. Data can be archived because the execution requirement for the DLM policy is met.

  2. Execute the DLM policy

    1. You can execute SQL statements to directly execute DLM policies or use the MySQL event feature to periodically execute DLM policies. If the O&M start time of your cluster is 01:00 every day starting October 11, 2022, the DLM policy is executed at 01:00 every day. You can create the following event:

      CREATE EVENT dlm_system_base_event
             ON SCHEDULE EVERY 1 DAY
          STARTS '2022-10-11 01:00:00'
          do CALL 
      dbms_dlm.execute_all_dlm_policies();

      At 01:00 every day, the event begins to execute DLM policies on all tables.

    2. To view the schema of the sales table, execute the following statement:

      mysql> SHOW CREATE TABLE sales\G

      Sample result:

      *************************** 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 _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) */
      1 row in set (0.03 sec)

      The current table has only three partitions.

    3. You can view the execution records of DLM policies in the mysql.dlm_progress table. For more information about the mysql.dlm_progress table, see Table formats. To view the schema of the mysql.dlm_progress table, execute the following statement:

      mysql> SELECT * FROM mysql.dlm_progress\G

      Sample result:

      *************************** 1. row ***************************;
                        Id: 1
              Table_schema: test
                Table_name: sales
               Policy_name: test_policy
               Policy_type: TABLE
            Archive_option: PARTITIONS OVER 3
            Storage_engine: CSV
             Storage_media: OSS
           Data_compressed: OFF
      Compressed_algorithm: NULL
        Archive_partitions: p20200101000000, p20210101000000, p20220101000000, _p20230101000000, _p20240101000000, _p20250101000000
             Archive_stage: ARCHIVE_COMPLETE
        Archive_percentage: 0
        Archived_file_info: null
                Start_time: 2024-07-26 17:56:20
                  End_time: 2024-07-26 17:56:50
                Extra_info: null
      1 row in set (0.00 sec)

      The cold data originally stored in the p20200101000000, p20210101000000, p20220101000000, _p20230101000000, _p20240101000000, and _p20250101000000 partitions is transferred to an OSS foreign table.

    4. To view the schema of the OSS foreign table, execute the following statement:

      mysql> SHOW CREATE TABLE sales_history\G

      Sample result:

      *************************** 1. row ***************************;
             Table: sales_history
      Create Table: CREATE TABLE `sales_history` (
        `id` int(11) DEFAULT NULL,
        `name` varchar(20) DEFAULT NULL,
        `order_time` datetime DEFAULT NULL,
         PRIMARY KEY (`order_time`)
      ) /*!99990 800020213 STORAGE OSS */ ENGINE=CSV DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci /*!99990 800020204 NULL_MARKER='NULL' */ /*!99990 800020223 OSS META=1 */ /*!99990 800020224 OSS_FILE_FILTER='id,name:bloom,order_time' */
      1 row in set (0.15 sec)

      The table is a CSV-formatted table whose data is stored in OSS. The specified columns are added to the OSS file filter. The order_time column is the partition key. Therefore, an OSS file filter is automatically created on the column.

    5. Query data in the sales and sales_history tables.

      SELECT COUNT(*) FROM sales;
      +----------+
      | count(*) |
      +----------+
      |      984 |
      +----------+
      1 row in set (0.01 sec)
      
      SELECT COUNT(*) FROM sales_history;
      +----------+
      | count(*) |
      +----------+
      |     2016 |
      +----------+
      1 row in set (0.57 sec)           

      The preceding results show that the total number of data rows is 3,000, which is the same as the number of data rows originally inserted into the sales table.

    6. Query data in the OSS foreign table by using the OSS file filter. Before you perform this operation, make sure that OSS file filter is enabled.

      mysql> explain select * from sales_history where id = 9;
      +----+-------------+---------------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------------------------------+
      | id | select_type | table         | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                                                       |
      +----+-------------+---------------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------------------------------+
      |  1 | SIMPLE      | sales_history | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 2016 |    10.00 | Using where; With pushed engine condition (`test`.`sales_history`.`id` = 9) |
      +----+-------------+---------------+------------+------+---------------+------+---------+------+------+----------+-----------------------------------------------------------------------------+
      1 row in set, 1 warning (0.59 sec)
      
      mysql>  select * from sales_history where id = 9;
      +------+----------------+---------------------+
      | id   | name           | order_time          |
      +------+----------------+---------------------+
      |    9 | 2531826@stiven | 2019-07-04 00:00:00 |
      +------+----------------+---------------------+
      1 row in set (0.19 sec)

Archive partitions in a partitioned table to OSS

  1. Create a DLM policy

    In the following example, a partitioned table named sales is created. The table uses the order_time column as the partition key and adopts interval partitioning. An interval policy and a DLM policy are defined for the table.

    • Interval policy: When data inserted into the table falls outside the partitioning interval of one year, a new partition is automatically created.

    • DLM policy: When the number of partitions in the table exceeds 3, the DLM policy is executed to transfer previous partitions to OSS.

    1. Create a table named sales.

      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=CSV STORAGE=OSS READ ONLY ON (PARTITIONS OVER 3);

      The DLM policy of the table is named policy_part2part. When the number of partitions in the table exceeds 3, previous partitions are transferred to OSS.

    2. View DLM policies in the mysql.dlm_policies table.

      SELECT * FROM mysql.dlm_policies\G

      Sample result:

      *************************** 1. row ***************************
                         Id: 2
               Table_schema: test
                 Table_name: sales
                Policy_name: policy_part2part
                Policy_type: PARTITION
               Archive_type: PARTITION COUNT
               Storage_mode: READ ONLY
             Storage_engine: CSV
              Storage_media: OSS
        Storage_schema_name: NULL
         Storage_table_name: NULL
            Data_compressed: OFF
       Compressed_algorithm: NULL
                    Enabled: ENABLED
            Priority_number: 10300
      Tier_partition_number: 3
             Tier_condition: NULL
                 Extra_info: null
                    Comment: NULL
      1 row in set (0.03 sec)
    3. Use the proc_batch_insert stored procedure to insert test data into the sales table and trigger the interval policy to create new partitions.

      CALL proc_batch_insert(1, 3000, 'sales');

      The following results indicate that the data is inserted:

      Query OK, 1 row affected, 1 warning (0.99 sec)
    4. To view the schema of the sales table, execute the following statement:

      SHOW CREATE TABLE sales \G

      Sample result:

      *************************** 1. row ***************************
             Table: sales
      Create Table: CREATE TABLE `sales` (
        `id` int(11) DEFAULT NULL,
        `name` varchar(20) DEFAULT NULL,
        `order_time` datetime DEFAULT 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) */
      1 row in set (0.03 sec)
  2. Execute the DLM policy

    1. Execute the following statement to execute the DLM policy:

      CALL dbms_dlm.execute_all_dlm_policies();
    2. View the execution records of the DLM policy in the mysql.dlm_progress table.

      SELECT * FROM mysql.dlm_progress \G

      Sample result:

      *************************** 1. row ***************************
                        Id: 4
              Table_schema: test
                Table_name: sales
               Policy_name: policy_part2part
               Policy_type: PARTITION
            Archive_option: PARTITIONS OVER 3
            Storage_engine: CSV
             Storage_media: OSS
           Data_compressed: OFF
      Compressed_algorithm: NULL
        Archive_partitions: p20200101000000, p20210101000000, p20220101000000, _p20230101000000, _p20240101000000, _p20250101000000
             Archive_stage: ARCHIVE_COMPLETE
        Archive_percentage: 100
        Archived_file_info: null
                Start_time: 2023-09-11 18:04:39
                  End_time: 2023-09-11 18:04:40
                Extra_info: null
      1 row in set (0.02 sec)
    3. To view the schema of the sales table, execute the following statement:

      SHOW CREATE TABLE sales \G

      Sample result:

      *************************** 1. row ***************************
             Table: sales
      Create Table: CREATE TABLE `sales` (
        `id` int(11) DEFAULT NULL,
        `name` varchar(20) DEFAULT NULL,
        `order_time` datetime DEFAULT NULL,
         PRIMARY KEY (`order_time`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci CONNECTION='default_oss_server'
      /*!99990 800020205 PARTITION BY RANGE  COLUMNS(order_time) */ /*!99990 800020200 INTERVAL(YEAR, 1) */
      /*!99990 800020205 (PARTITION p20200101000000 VALUES LESS THAN ('2020-01-01 00:00:00') ENGINE = CSV,
       PARTITION p20210101000000 VALUES LESS THAN ('2021-01-01 00:00:00') ENGINE = CSV,
       PARTITION p20220101000000 VALUES LESS THAN ('2022-01-01 00:00:00') ENGINE = CSV,
       PARTITION _p20230101000000 VALUES LESS THAN ('2023-01-01 00:00:00') ENGINE = CSV,
       PARTITION _p20240101000000 VALUES LESS THAN ('2024-01-01 00:00:00') ENGINE = CSV,
       PARTITION _p20250101000000 VALUES LESS THAN ('2025-01-01 00:00:00') ENGINE = CSV,
       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) */
      1 row in set (0.03 sec)

      The preceding results show that the p20200101000000, p20210101000000, p20220101000000, _p20230101000000, _p20240101000000, and _p20250101000000 partitions in the sales table are transferred to OSS. Only the _p20260101000000, _p20270101000000, and _p20280101000000 partitions that store hot data in the table are retained in InnoDB. The sales table becomes a hybrid partitioned table. For information about how to query data in a hybrid partitioned table, see Query data in a hybrid partitioned table.

Delete cold data

  1. Create a DLM policy

    In the following example, a partitioned table named sales is created. The table uses the order_time column as the partition key and adopts interval partitioning. An interval policy and a DLM policy are defined for the table.

    • Interval policy: When data inserted into the table falls outside the partitioning interval of one year, a new partition is automatically created.

    • DLM policy: When the number of partitions in the table exceeds 3, the DLM policy is executed to delete cold data.

    1. Create a table named sales with a DLM policy defined.

      CREATE TABLE `sales` (
        `id` int DEFAULT NULL,
        `name` varchar(20) DEFAULT NULL,
        `order_time` datetime DEFAULT 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 test_policy TIER TO NONE ON (PARTITIONS OVER 3);

      The DLM policy of the table is named test_policy. The policy is executed when the number of partitions in the table exceeds three. In this case, cold data is deleted.

    2. To view the schema of the mysql.dlm_policies table, execute the following statement:

      SELECT * FROM mysql.dlm_policies\G

      Sample result:

      *************************** 1. row ***************************
                         Id: 4
               Table_schema: test
                 Table_name: sales
                Policy_name: test_policy
                Policy_type: NONE
               Archive_type: PARTITION COUNT
               Storage_mode: NULL
             Storage_engine: NULL
              Storage_media: NULL
        Storage_schema_name: NULL
         Storage_table_name: NULL
            Data_compressed: OFF
       Compressed_algorithm: NULL
                    Enabled: ENABLED
            Priority_number: 50000
      Tier_partition_number: 3
             Tier_condition: NULL
                 Extra_info: null
                    Comment: NULL
      1 row in set (0.01 sec)
    3. Insert test data into the sales table to trigger the automatic creation of interval partitions. Use the proc_batch_insert stored procedure to insert new data. The table has the following schema:

      CALL proc_batch_insert(1, 3000, 'sales');
      Query OK, 1 row affected, 1 warning (0.99 sec)
    4. To view the schema of the sales table, execute the following statement:

      SHOW CREATE TABLE sales \G

      Sample result:

      *************************** 1. row ***************************
             Table: sales
      Create Table: CREATE TABLE `sales` (
        `id` int(11) DEFAULT NULL,
        `name` varchar(20) DEFAULT NULL,
        `order_time` datetime DEFAULT 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) */
      1 row in set (0.03 sec)
  2. Execute the DLM policy

    1. Execute the following statement to directly execute the DLM policy:

      CALL dbms_dlm.execute_all_dlm_policies();
    2. When the DLM policy is executed, view the data in the mysql.dlm_progress table.

      SELECT * FROM mysql.dlm_progress \G

      Sample result:

      *************************** 1. row ***************************
                        Id: 1
              Table_schema: test
                Table_name: sales
               Policy_name: test_policy
               Policy_type: NONE
            Archive_option: PARTITIONS OVER 3
            Storage_engine: NULL
             Storage_media: NULL
           Data_compressed: OFF
      Compressed_algorithm: NULL
        Archive_partitions: p20200101000000, p20210101000000, p20220101000000, _p20230101000000, _p20240101000000, _p20250101000000
             Archive_stage: ARCHIVE_COMPLETE
        Archive_percentage: 100
        Archived_file_info: null
                Start_time: 2023-01-09 17:31:24
                  End_time: 2023-01-09 17:31:24
                Extra_info: null
      1 row in set (0.03 sec)

      The cold data originally stored in the p20200101000000, p20210101000000, p20220101000000, _p20230101000000, _p20240101000000, and _p20250101000000 partitions is deleted.

    3. The sales table has the following schema:

      SHOW CREATE TABLE sales \G

      Sample result:

      *************************** 1. row ***************************
             Table: sales
      Create Table: CREATE TABLE `sales` (
        `id` int(11) DEFAULT NULL,
        `name` varchar(20) DEFAULT NULL,
        `order_time` datetime DEFAULT 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 _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) */
      1 row in set (0.02 sec)

Create or delete a DLM policy by executing the ALTER TABLE statement

  • Create a DLM policy by executing the ALTER TABLE statement.

    ALTER TABLE t DLM ADD POLICY test_policy TIER TO TABLE ENGINE=CSV STORAGE=OSS READ ONLY
    STORAGE TABLE_NAME = 'sales_history' ON (PARTITIONS OVER 3);

    The DLM policy of the t table is named test_policy. The policy is executed when the number of partitions in the table exceeds three. In this case, data in the previous partitions of the t table is archived to OSS. The archived table in OSS is named sales_history.

  • Enable the test_policy DLM policy on the t table.

    ALTER TABLE t DLM ENABLE POLICY test_policy;
  • Disable the test_policy DLM policy on the t table.

    ALTER TABLE t DLM DISABLE POLICY test_policy;
  • Delete the test_policy DLM policy on the t table.

    ALTER TABLE t DLM DROP POLICY test_policy;

Troubleshoot execution errors

After DLM policies are executed, errors may occur due to inappropriate configurations. Error records are stored in the mysql.dlm_progress table. Execute the following statement to view the error records:

SELECT * FROM mysql.dlm_progress WHERE Archive_stage = "ARCHIVE_ERROR";

Find the details of an error in the Extra_info field, confirm the cause of the error, and then delete the current error record or change the value of the Archive_stage field of the current error record to ARCHIVE_COMPLETE. Execute the call dbms_dlm.execute_all_dlm_policies; statement to manually execute the DLM policy or wait for the next execution cycle to automatically execute the DLM policy.

Note

If a policy has an execution record in the ARCHIVE_ERROR state, the policy is not automatically executed in order to ensure data security. You must confirm the cause of the error and change the status of the error record. Then, the policy is executed.