使用說明
自動歸檔冷數(shù)據(jù)功能Data Lifecycle Management(簡稱DLM)支持將低頻使用的冷數(shù)據(jù)定期自動地從PolarStore轉(zhuǎn)存到低成本的OSS存儲介質(zhì)上,以達到降本增效的效果。
前提條件
集群版本需滿足以下條件之一:
PolarDB MySQL版8.0.1版本且小版本為8.0.1.1.32或以上。
PolarDB MySQL版8.0.2版本且小版本為8.0.2.2.9或以上。
您可以通過查詢版本號,來確認集群版本。
說明集群版本為PolarDB MySQL版8.0.2版本且小版本為8.0.2.2.11.1或以上時,使用DLM功能不記錄Binlog日志。
使用DLM策略需要先開啟冷數(shù)據(jù)歸檔。
說明如果您未開啟冷數(shù)據(jù)歸檔功能,報錯結(jié)果如下:
ERROR 8158 (HY000): [Data Lifecycle Management] DLM storage engine is not support. The value of polar_dlm_storage_mode is OFF.
使用限制
DLM功能目前僅支持分區(qū)表,分區(qū)表不能包含二級分區(qū)。分區(qū)方式需要為RANGE COLUMN類型。
暫不支持在創(chuàng)建全局二級索引(GSI)的分區(qū)表上使用DLM功能。
PolarDB MySQL版不支持修改DLM策略,您可以先刪除原有策略,再創(chuàng)建策略。
當前表上存在DLM策略時,如果執(zhí)行某些DDL操作,使歸檔表和原表的表結(jié)構不一致(例如,加減列、修改列類型等),會導致后續(xù)歸檔的數(shù)據(jù)無法被解析。因此在執(zhí)行此類DDL操作時,需要先刪除當前表上的DLM策略。后續(xù)如需使用數(shù)據(jù)自動歸檔功能,可以重新創(chuàng)建DLM策略,并指定歸檔表名為新的表名,新表名與之前歸檔的表名不能重復。
建議使用INTERVAL RANGE分區(qū)功能自動拓展分區(qū),同時使用DLM功能將低頻使用的分區(qū)的數(shù)據(jù)歸檔到OSS上。
說明當前僅PolarDB MySQL版8.0.2版本且小版本為8.0.2.2.0及以上的集群支持INTERVAL RANGE分區(qū)。
DLM功能需要在
CREATE TABLE
或者ALTER TABLE
時指定。目前DLM策略在
SHOW CREATE TABLE
時不會展示。您可以從mysql.dlm_policies表中查看所有表上的DLM策略信息。
注意事項
冷數(shù)據(jù)歸檔完成后,OSS上的歸檔表只讀,且查詢性能較差。您需要提前測試數(shù)據(jù)歸檔后能否滿足您的查詢性能要求。
將分區(qū)表中的分區(qū)歸檔至OSS后,歸檔至OSS上的分區(qū)中的數(shù)據(jù)只讀,且不支持對該分區(qū)表執(zhí)行DDL操作。
執(zhí)行備份操作時,不會備份已轉(zhuǎn)存至OSS上的數(shù)據(jù),且OSS上的數(shù)據(jù)不支持按時間點恢復。
語法說明
創(chuàng)建DLM策略
在CREATE TABLE時創(chuàng)建DLM策略
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)]
在ALTER TABLE時創(chuàng)建DLM策略
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策略參數(shù)說明
參數(shù) | 是否必選 | 說明 |
tbl_name | 是 | 表名稱。 |
policy_name | 是 | 策略名稱。 |
TIER TO TABLE | 是 | 歸檔至表。 |
TIER TO PARTITION | 是 | 將分區(qū)歸檔至OSS。 說明
|
TIER TO NONE | 是 | 直接刪除需要歸檔的數(shù)據(jù)。 |
engine_name | 否 | 歸檔數(shù)據(jù)存放的引擎,目前僅支持將數(shù)據(jù)歸檔到CSV引擎中。 |
storage_schema_name | 否 | 歸檔為表時,表所在的數(shù)據(jù)庫。默認為當前表所在數(shù)據(jù)庫。 |
storage_table_name | 否 | 歸檔為表時,表的名稱,您可以指定表名稱。默認為 |
STORAGE [=] OSS | 否 | 歸檔后的數(shù)據(jù)存儲在OSS引擎上(默認)。 |
READ ONLY | 否 | 歸檔后的數(shù)據(jù)只讀(默認)。 |
comment_string | 否 | DLM策略的備注。 |
extra_info | 否 | 指目標OSS表上的OSS_FILE_FILTER信息。 說明
|
ON(PARTITIONS OVER num) | 是 | 分區(qū)數(shù)量大于num時,進行數(shù)據(jù)歸檔。 |
變更DLM策略
使DLM策略生效。
ALTER TABLE table_name DLM ENABLE POLICY [(dlm_policy_name [, dlm_policy_name] ...)]
使DLM策略失效。
ALTER TABLE table_name DLM DISABLE POLICY [(dlm_policy_name [, dlm_policy_name] ...)]
刪除DLM策略。
ALTER TABLE table_name DLM DROP POLICY [(dlm_policy_name [, dlm_policy_name] ...)]
其中,table_name
是當前表名稱,dlm_policy_name
是當前需要修改的策略名稱,策略名稱可以配置多個。
執(zhí)行DLM策略
執(zhí)行當前集群上所有表上的DLM策略。
CALL dbms_dlm.execute_all_dlm_policies();
執(zhí)行單張表上的DLM策略。
CALL dbms_dlm.execute_table_dlm_policies('database_name', 'table_name');
其中,
database_name
是當前表所在的數(shù)據(jù)庫名稱,table_name
是當前表的表名稱。
您可以通過mysql event功能,在您的集群運維期間執(zhí)行DLM策略,既能避免在業(yè)務高峰期執(zhí)行DLM而影響數(shù)據(jù)庫性能,也可以定期轉(zhuǎn)移過期數(shù)據(jù),減少您的數(shù)據(jù)庫存儲費用。通過EVENT執(zhí)行DLM策略語法:
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');
}
參數(shù)說明如下:
參數(shù) | 是否必選 | 說明 |
event_name | 是 | 當前EVENT的名稱。 |
schedule | 是 | 當前EVENT的執(zhí)行時間和周期。 |
comment | 否 | 當前EVENT的備注。 |
event_body | 是 | 當前EVENT具體執(zhí)行的內(nèi)容。需要設置為通過EVENT執(zhí)行DLM策略的語句。 說明
|
interval | 是 | EVENT的執(zhí)行周期。 |
timestamp | 是 | 開始執(zhí)行EVENT的時間。 |
database_name | 是 | 數(shù)據(jù)庫名稱。 |
table_name | 是 | 表名稱。 |
MySQL EVENT功能說明請參見MySQL EVENT官方文檔。
使用示例請參見冷數(shù)據(jù)歸檔到OSS示例。
示例
將分區(qū)表中的數(shù)據(jù)歸檔至OSS外表
創(chuàng)建DLM策略
以下示例將創(chuàng)建
sales
分區(qū)表,該表以order_time
列作為分區(qū)鍵,按時間間隔劃分分區(qū)。同時,該表存在INTERVAL和DLM兩種策略:INTERVAL策略:當插入的數(shù)據(jù)超過分區(qū)范圍時,將自動創(chuàng)建新的分區(qū),時間間隔為1年。
DLM策略:定義當前表僅有3個分區(qū),當分區(qū)數(shù)量大于3,執(zhí)行DLM策略時:
如果不存在OSS外表
sales_history
,則創(chuàng)建新的OSS外表sales_history
,并將冷數(shù)據(jù)轉(zhuǎn)存到sales_history
外表中。如果存在
sales_history
外表,且sales_history
表在內(nèi)置的OSS 空間上,則直接將冷數(shù)據(jù)轉(zhuǎn)存到sales_history
外表中。
說明創(chuàng)建
INTERVAL RANGE
分區(qū)表需要滿足創(chuàng)建條件。INTERVAL使用請參見PolarDB INTERVAL。創(chuàng)建帶有DLM策略的
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 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);
該表的DLM策略名稱為
test_policy
,當分區(qū)數(shù)量大于3時,會將當前表的冷數(shù)據(jù)轉(zhuǎn)存為CSV格式,并存儲在OSS上。轉(zhuǎn)存后的表名稱為sales_history
,數(shù)據(jù)只讀。同時,如果歸檔表OSS不存在,會自動創(chuàng)建OSS表,并在id
和name
列上創(chuàng)建OSS_FILE_FILTER。當前表的DLM策略會存儲在系統(tǒng)表
mysql.dlm_policies
中,您可以通過該表查看DLM策略的詳細信息。表mysql.dlm_policies
詳情請參見表結(jié)構說明。查看mysql.dlm_policies
表結(jié)構信息。mysql> SELECT * FROM mysql.dlm_policies\G
執(zhí)行結(jié)果如下:
*************************** 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)
目前
sales
表的分區(qū)數(shù)量為3,不會進行數(shù)據(jù)歸檔。向
sales
分區(qū)表中插入3000的測試數(shù)據(jù),保證數(shù)據(jù)超過當前表的分區(qū)定義,觸發(fā)INTERVAL自動創(chuàng)建新的分區(qū)。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');
此時,觸發(fā)了INTERVAL自動創(chuàng)建新的分區(qū),導致
sales
表的分區(qū)增加,表結(jié)構變?yōu)椋?/p>mysql> SHOW CREATE TABLE sales\G
執(zhí)行結(jié)果如下:
*************************** 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)
已經(jīng)創(chuàng)建了新的分區(qū),且分區(qū)數(shù)量大于3,滿足DLM策略的執(zhí)行條件,可以進行數(shù)據(jù)歸檔。
執(zhí)行DLM策略
您可以通過SQL語句直接執(zhí)行DLM策略,或者通過MySQL的EVENT功能,定期執(zhí)行DLM策略。假設從2022-10-11開始,您的集群運維開始時間是每天凌晨1點,則每天凌晨1點開始執(zhí)行DLM策略。創(chuàng)建對應的執(zhí)行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();
1點后,這個EVENT會執(zhí)行所有表上的DLM策略。
執(zhí)行以下命令,查看
sales
表結(jié)構信息。mysql> SHOW CREATE TABLE sales\G
執(zhí)行結(jié)果如下:
*************************** 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)
當前表僅剩3個分區(qū)。
您可以通過
mysql.dlm_progress
表查看DLM策略的執(zhí)行記錄,表dlm_progress
定義請參見表結(jié)構說明。執(zhí)行以下命令,查看mysql.dlm_progress
表結(jié)構信息。mysql> SELECT * FROM mysql.dlm_progress\G
執(zhí)行結(jié)果如下:
*************************** 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)
存放低頻冷數(shù)據(jù)的分區(qū),包括p20200101000000、p20210101000000、p20220101000000、_p20230101000000、 _p20240101000000、 _p20250101000000都已轉(zhuǎn)存到OSS外表上。
執(zhí)行以下命令,查看OSS外表的表結(jié)構。
mysql> SHOW CREATE TABLE sales_history\G
執(zhí)行結(jié)果如下:
*************************** 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)
該表變?yōu)閿?shù)據(jù)存儲在OSS引擎的CSV表,查詢方法與查詢本地表的方法相同。同時,指定的列已經(jīng)加入到OSS_FILE_FILTER中,并且由于
order_time
是分區(qū)鍵,也會自動創(chuàng)建 OSS_FILE_FILTER。分別查詢
sales
和sales_history
兩張表上的數(shù)據(jù)。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)
可以看到數(shù)據(jù)總和正好為3000,與開始時
sales
表插入的數(shù)據(jù)量一致。在OSS外表上通過OSS_FILE_FILTER查詢(需要開啟OSS_FILE_FILTER開關):
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)
將分區(qū)表中的分區(qū)歸檔至OSS
創(chuàng)建DLM策略
以下示例將創(chuàng)建一張表名為
sales
的分區(qū)表,該表以order_time
列作為分區(qū)鍵,按時間間隔劃分分區(qū)。同時,該表存在INTERVAL和DLM兩種策略:INTERVAL策略:當插入的數(shù)據(jù)超過分區(qū)范圍時,將自動創(chuàng)建新的分區(qū),時間間隔為1年。
DLM策略:定義當前表僅有3個分區(qū),當分區(qū)數(shù)量大于3時,執(zhí)行DLM策略會直接將之前的分區(qū)轉(zhuǎn)存至OSS。
創(chuàng)建
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);
該表的DLM策略名稱為
policy_part2part
,當分區(qū)數(shù)量大于3時,會將舊的分區(qū)轉(zhuǎn)存至OSS。在
mysql.dlm_policies
表中查看DLM策略。SELECT * FROM mysql.dlm_policies\G
執(zhí)行結(jié)果如下:
*************************** 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)
使用
proc_batch_insert
存儲過程向sales
分區(qū)表中插入一定的測試數(shù)據(jù),以觸發(fā)INTERVAL策略來自動創(chuàng)建新的分區(qū)。CALL proc_batch_insert(1, 3000, 'sales');
執(zhí)行結(jié)果如下,表示數(shù)據(jù)插入成功:
Query OK, 1 row affected, 1 warning (0.99 sec)
執(zhí)行以下命令,查看
sales
表的結(jié)構信息。SHOW CREATE TABLE sales \G
執(zhí)行結(jié)果如下:
*************************** 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)
執(zhí)行DLM策略
通過以下命令來執(zhí)行DLM策略。
CALL dbms_dlm.execute_all_dlm_policies();
通過
mysql.dlm_progress
表查看DLM執(zhí)行記錄。SELECT * FROM mysql.dlm_progress \G
執(zhí)行結(jié)果如下:
*************************** 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)
執(zhí)行以下命令,查看
sales
表結(jié)構信息。SHOW CREATE TABLE sales \G
執(zhí)行結(jié)果如下:
*************************** 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)
由查詢到的表結(jié)構信息可以看出,
sales
分區(qū)表中的p20200101000000
、p20210101000000
、p20220101000000
、_p20230101000000
、_p20240101000000
以及_p20250101000000
分區(qū)均轉(zhuǎn)存至OSS,InnoDB引擎中僅保留了3個熱數(shù)據(jù)分區(qū)_p20260101000000
、_p20270101000000
和_p20280101000000
。sales
表變?yōu)榱嘶旌戏謪^(qū)表,查詢混合分區(qū)表中的數(shù)據(jù)操作方法請參見查詢混合分區(qū)。
將冷數(shù)據(jù)直接刪除
創(chuàng)建DLM策略
以下示例將創(chuàng)建
sales
分區(qū)表,該表以order_time
列作為分區(qū)鍵,按時間間隔劃分分區(qū)。同時,該表存在INTERVAL和DLM兩種策略:INTERVAL策略:當插入的數(shù)據(jù)超過分區(qū)范圍時,將自動創(chuàng)建新的分區(qū),時間間隔為1年。
DLM策略:定義當前表僅有3個分區(qū),當分區(qū)數(shù)量大于3,執(zhí)行DLM策略時,將直接刪除冷數(shù)據(jù)。
創(chuàng)建帶有DLM策略的
sales
表。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);
該表的DLM策略名稱為
test_policy
,策略的執(zhí)行條件為分區(qū)數(shù)量大于3。執(zhí)行DLM策略時會直接刪除冷數(shù)據(jù)。執(zhí)行以下命令,查看
mysql.dlm_policies
表。SELECT * FROM mysql.dlm_policies\G
執(zhí)行結(jié)果如下:
*************************** 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)
向
sales
分區(qū)表中插入一定的測試數(shù)據(jù),以觸發(fā)INTERVAL自動創(chuàng)建新的分區(qū)。使用proc_batch_insert
存儲過程插入新的數(shù)據(jù)。表結(jié)構如下:CALL proc_batch_insert(1, 3000, 'sales'); Query OK, 1 row affected, 1 warning (0.99 sec)
執(zhí)行如下命令,查看
sales
表結(jié)構信息。SHOW CREATE TABLE sales \G
執(zhí)行結(jié)果如下:
*************************** 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)
執(zhí)行DLM策略
通過以下命令直接執(zhí)行DLM策略。
CALL dbms_dlm.execute_all_dlm_policies();
DLM策略執(zhí)行時,查看
mysql.dlm_progress
表中數(shù)據(jù)。SELECT * FROM mysql.dlm_progress \G
表中結(jié)果如下:
*************************** 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)
存放低頻冷數(shù)據(jù)的分區(qū),包括
p20200101000000
、p20210101000000
、p20220101000000
、_p20230101000000
、_p20240101000000
和_p20250101000000
都已被刪除。sales
表結(jié)構如下:SHOW CREATE TABLE sales \G
執(zhí)行結(jié)果如下:
*************************** 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)
在ALTER TABLE時創(chuàng)建或刪除DLM策略
執(zhí)行錯誤處理
DLM策略執(zhí)行過程中,可能因為配置原因,出現(xiàn)DLM策略執(zhí)行錯誤的情況。此時,錯誤記錄會存儲在mysql.dlm_progress
表中。通過如下命令查看錯誤記錄:
SELECT * FROM mysql.dlm_progress WHERE Archive_stage = "ARCHIVE_ERROR";
在Extra_info字段中找到錯誤的詳細信息,確認錯誤原因后,刪除當前記錄或者修改當前記錄的Archive_stage為ARCHIVE_COMPLETE,再通過call dbms_dlm.execute_all_dlm_policies;
命令手動執(zhí)行DLM策略或者等待下一個執(zhí)行周期自動執(zhí)行。
如果當前策略的執(zhí)行記錄中,存在狀態(tài)為ARCHIVE_ERROR的記錄,考慮到數(shù)據(jù)安全的原因,該條策略不會再自動執(zhí)行,您需要在確認執(zhí)行失敗原因并修改對應的記錄后,該條策略才會繼續(xù)執(zhí)行。