自動(dòng)化管理分區(qū)
您可以通過(guò)創(chuàng)建定時(shí)任務(wù)的方式來(lái)創(chuàng)建、刪除或交換分區(qū),以實(shí)現(xiàn)分區(qū)自動(dòng)化管理。
背景信息
在某些行業(yè)中,固定周期內(nèi)可能會(huì)產(chǎn)生大量的數(shù)據(jù),同時(shí)也會(huì)通過(guò)刪除大量數(shù)據(jù)的方式來(lái)節(jié)省存儲(chǔ)空間。如果新產(chǎn)生的數(shù)據(jù)和需要?jiǎng)h除的數(shù)據(jù)保存在同一張表中,周期性的大批量數(shù)據(jù)更新,極有可能影響業(yè)務(wù)的連續(xù)性。且在分區(qū)表使用不夠普遍的情況下,通常的做法是,由DBA在運(yùn)維時(shí)間內(nèi)定期手動(dòng)創(chuàng)建新表來(lái)承載新的數(shù)據(jù),并且需要?jiǎng)h除無(wú)用數(shù)據(jù)所在的表。
這種場(chǎng)景存在一系列痛點(diǎn):
周期性的大批量更新表,可能會(huì)對(duì)業(yè)務(wù)的連續(xù)性有影響。
DBA在運(yùn)維時(shí)間內(nèi)手動(dòng)更新表數(shù)據(jù),會(huì)增加運(yùn)維成本。
通過(guò)創(chuàng)建定時(shí)任務(wù)的方式來(lái)實(shí)現(xiàn)自動(dòng)化管理分區(qū),既可以避免影響業(yè)務(wù)連續(xù)性,也可以減少不必要的人工操作。
前提條件
集群版本需為PolarDB MySQL版8.0.2版本且Revision version為8.0.2.2.0及以上。您可以通過(guò)查詢版本號(hào)確認(rèn)集群版本。
定時(shí)任務(wù)語(yǔ)法
語(yǔ)法
CREATE
[DEFINER = user]
EVENT
[IF NOT EXISTS]
event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'string']
DO event_body;
參數(shù)說(shuō)明
參數(shù) | 是否必選 | 說(shuō)明 |
DEFINER | 否 | 給指定用戶添加該定時(shí)任務(wù)的使用權(quán)限。 |
IF NOT EXISTS | 否 | 判斷需要?jiǎng)?chuàng)建的事件是否已存在。 |
event_name | 是 | 指定事件名稱(chēng)。 |
schedule | 是 | 指定該事件的調(diào)度時(shí)間。調(diào)度時(shí)間語(yǔ)法支持以下兩種:
其中,
|
ON COMPLETION [NOT] PRESERVE | 否 | 指定事件執(zhí)行完一次后的處理方式。
|
ENABLE、DISABLE、DISABLE ON SLAVE | 否 | 指定事件的一種屬性。取值如下:
|
COMMENT ‘comment’ | 否 | 指定事件的注釋。 |
DO event_body | 是 | 指定事件啟動(dòng)時(shí)需要執(zhí)行的代碼。 說(shuō)明
|
示例
假設(shè)數(shù)據(jù)庫(kù)中存在一張INTERVAL RANGE分區(qū)表orders
,該表以時(shí)間列作為分區(qū)鍵,可以將不同時(shí)間范圍內(nèi)的數(shù)據(jù)劃分到不同的分區(qū)中。建表語(yǔ)句如下所示:
CREATE TABLE orders(
id int,
ordertime datetime
)
PARTITION BY RANGE COLUMNS(ordertime) INTERVAL(DAY, 1)
(
PARTITION p20220520 VALUES LESS THAN('2022-05-20'),
PARTITION p20220521 VALUES LESS THAN('2022-05-21')
);
基于orders
表來(lái)介紹定時(shí)新增分區(qū)、定時(shí)刪除分區(qū)和定時(shí)轉(zhuǎn)換分區(qū)的使用方法。
定時(shí)新增分區(qū)
如果您需要為orders
分區(qū)表定時(shí)新增分區(qū),可以通過(guò)創(chuàng)建定時(shí)任務(wù)的方式定時(shí)觸發(fā)新增分區(qū),示例如下:
DELIMITER ||
CREATE EVENT IF NOT EXISTS add_partition ON SCHEDULE
EVERY 1 DAY STARTS '2022-05-20 22:00:00'
ON COMPLETION PRESERVE
DO
BEGIN
set @pname = concat("alter table orders add partition (partition p",date_format(date_add(curdate(), interval 2 day), '%Y%m%d'), " values less than('", date_add(curdate(), interval 2 day), "'))");
prepare stmt_add_partition from @pname;
execute stmt_add_partition;
deallocate prepare stmt_add_partition;
END ||
DELIMITER ;
假設(shè)當(dāng)前已經(jīng)存在的最大的分區(qū)范圍為:2022-05-20 00:00:00
~2022-05-20 23:59:59
,該定時(shí)任務(wù)可以從2022-05-20 22:00:00
開(kāi)始,每天創(chuàng)建一個(gè)新的分區(qū),來(lái)保存第二天的數(shù)據(jù)。
如果分區(qū)表orders
為INTERVAL RANGE分區(qū),也可以通過(guò)INSERT方式定時(shí)觸發(fā)新增分區(qū),示例如下:
CREATE EVENT IF NOT EXISTS add_partition ON SCHEDULE
EVERY 1 DAY STARTS '2022-05-20 00:00:00'
ON COMPLETION PRESERVE
DO INSERT INTO orders VALUES(id, DATE_ADD(NOW(), INTERVAL 1 DAY));
假設(shè)當(dāng)前最大的分區(qū)范圍是2022-05-20 00:00:00
~2022-05-20 23:59:59
,定時(shí)任務(wù)會(huì)從2022-05-20 00:00:00
開(kāi)始執(zhí)行,每天新增一個(gè)新分區(qū),而且是提前一天新增下一天的分區(qū)。
定時(shí)刪除分區(qū)
如果業(yè)務(wù)上需要定期清理orders
表中無(wú)用的數(shù)據(jù),可以創(chuàng)建一個(gè)定時(shí)任務(wù)刪除對(duì)應(yīng)的分區(qū)。示例如下:
DELIMITER ||
CREATE EVENT IF NOT EXISTS drop_partition ON SCHEDULE
EVERY 1 DAY STARTS '2022-05-21 02:00:00'
ON COMPLETION PRESERVE
DO
BEGIN
set @pname = concat('alter table orders drop partition p', date_format(curdate(), '%Y%m%d'));
prepare stmt_drop_partition from @pname;
execute stmt_drop_partition;
deallocate prepare stmt_drop_partition;
END ||
DELIMITER ;
假設(shè)運(yùn)維時(shí)間從02:00
開(kāi)始,該定時(shí)任務(wù)會(huì)從2022-05-21 02:00:00
開(kāi)始,在每天的02:00
刪除前一天創(chuàng)建的分區(qū)。
定時(shí)轉(zhuǎn)換分區(qū)
如果您不想直接刪除orders
表中的分區(qū),也可以通過(guò)exchange_partition將不再需要的分區(qū)轉(zhuǎn)成一張表,這張表與orders
分區(qū)表完全獨(dú)立,您可以自行決定如何處理這張表中的數(shù)據(jù)。示例如下:
-- 創(chuàng)建一個(gè)與分區(qū)表相同表結(jié)構(gòu)的非分區(qū)表來(lái)做exchange, DDL結(jié)束后分區(qū)數(shù)據(jù)會(huì)被交換出去,原來(lái)的分區(qū)會(huì)變?yōu)榭辗謪^(qū)。
DELIMITER ||
CREATE EVENT IF NOT EXISTS exchange_partition ON SCHEDULE
EVERY 1 DAY STARTS '2022-05-21 02:00:00'
ON COMPLETION PRESERVE
DO
BEGIN
set @pname = concat('create table orders_', date_format(curdate(), '%Y%m%d'), '(id int, ordertime datetime)');
prepare stmt_create_table from @pname;
execute stmt_create_table;
deallocate prepare stmt_create_table;
set @pname = concat('alter table orders exchange partition p', date_format(curdate(), '%Y%m%d'), ' with table orders_', date_format(curdate(), '%Y%m%d'));
prepare stmt_exchange_partition from @pname;
execute stmt_exchange_partition;
deallocate prepare stmt_exchange_partition;
END ||
DELIMITER ;
該任務(wù)會(huì)從2022-05-21 02:00:00
開(kāi)始,在每天的02:00
,將前一天創(chuàng)建的分區(qū)與一個(gè)空表進(jìn)行交換,分區(qū)中原有的數(shù)據(jù)都會(huì)保存在被交換的表中。