延續昨天的流程內容,做到能輸入參數(資料庫&資料表)判斷有無分區的作用~
確保有切表的狀況下就能方便進行下一步作業,把資料中最早的日期至今天日期的分區都先切分區出來,後續再來做保留幾天資料的動作。
有一個尚未切分區的資料表act,且本身已經有資料在內了,想用該表欄位created_at(建立時間)當做partition key切表,除了切分區還要能達到自動新增分區與刪除舊資料分區的動作,方便資料上的維護。
CREATE DATABASE t7;
CREATE TABLE `act` (
`actives_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`status` bigint(20) NOT NULL,
`start_time` int(11) unsigned NOT NULL,
`end_time` int(11) unsigned NOT NULL,
`platform_id` bigint(20) DEFAULT NULL,
`updated_at` int(11) unsigned NOT NULL,
`created_at` int(11) unsigned NOT NULL COMMENT '建立時間',
PRIMARY KEY (`actives_id`,`created_at`)
);
先將數據寫入,檢驗最後跑流程後的數據分佈是否都在對的地方(分區)。
INSERT INTO act (status,start_time,end_time,platform_id,updated_at,created_at) values(1,1000000,1000000,666,1000000,1632499200),(2,1000000,1000000,666,1000000,1632758400),(2,1000000,1000000,666,1000000,1632758400),(2,1000000,1000000,666,1000000,1632931200),(2,1000000,1000000,666,1000000,1632931200),(5,1000000,1000000,666,1000000,1633104000);
-- 有6筆數據&建立日期
mysql> select actives_id,created_at,from_unixtime(created_at) from act;
+------------+------------+---------------------------+
| actives_id | created_at | from_unixtime(created_at) |
+------------+------------+---------------------------+
| 1 | 1632499200 | 2021-09-24 16:00:00 |
| 2 | 1632758400 | 2021-09-27 16:00:00 |
| 3 | 1632758400 | 2021-09-27 16:00:00 |
| 4 | 1632931200 | 2021-09-29 16:00:00 |
| 5 | 1632931200 | 2021-09-29 16:00:00 |
| 6 | 1633104000 | 2021-10-01 16:00:00 |
+------------+------------+---------------------------+
6 rows in set (0.00 sec)
ps. 複製前一天文章procdure 到新資料庫: t7
CALL check_part('t7','act');
跑完切出來2個分區內的資料,符合我們預期的結果。
繼續進行後續流程 ...
在已存在分區資料表中做分區。
概念: 取pmax分區前一個分區內容當作最大值,與今天日期相比看差幾天就補對應幾天分區。
Today: 2021/10/02
實作流程
DELIMITER ||
DROP PROCEDURE IF EXISTS add_part ||
CREATE PROCEDURE add_part(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64))
BEGIN
DECLARE n_sysdate date; --當天日期
DECLARE max_partition_day date; --現有分區最大值
DECLARE p_name VARCHAR(255) ;
DECLARE p_description VARCHAR(255) ;
--取分區最大值做判斷
select from_unixtime(partition_description) into max_partition_day from information_schema.partitions where table_schema = IN_SCHEMANAME and table_name = IN_TABLENAME AND partition_description < 'MAXVALUE' order by partition_description desc limit 1;
set n_sysdate = sysdate();
--判斷與當天日期差幾天(要新增的分區數)
WHILE max_partition_day <= (n_sysdate) DO
SET p_name = date_format(max_partition_day ,'p%Y%m%d');
SET p_description = unix_timestamp(max_partition_day + INTERVAL 1 DAY);
SET @sql = concat('ALTER TABLE ', IN_SCHEMANAME, '.', IN_TABLENAME, ' REORGANIZE PARTITION `pmax` INTO (partition ', p_name, ' values less than (', p_description, '),PARTITION `pmax` VALUES LESS THAN MAXVALUE )');
SELECT @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET max_partition_day = max_partition_day + INTERVAL 1 DAY;
END WHILE;
SET @STEP = "STEP: add historical date to today [ PASS ]";
SELECT @STEP;
END ||
DELIMITER ;
CALL add_part('t7','act');
如果要採預先分區的話就只要拿上面的內容做小部分修改即可達到要求。
WHILE max_partition_day <= (n_sysdate) DO
改成
WHILE max_partition_day <= (n_sysdate + INTERVAL 5 DAY) DO
以上面加5天來舉例如下~
今天實作新建分區的整個流程~
最後重要的舊資料清除&每天觸發執行動作。在明天做最後的ending~