參考文章:https://blog.csdn.net/xlxxcc/article/details/52486426
1.以日自動創建與刪除分區
調用示例:CALL proc_day_partition('t_base_log_abnormal',180,1);
刪除180天之前的分區
CREATE DEFINER=`root`@`localhost` PROCEDURE `proc_day_partition`( IN `v_tablename` VARCHAR(50), IN `v_drop_interval` INT, IN `v_add_interval` INT ) LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN DECLARE v_add_interval_1 int; DECLARE flag int default 0; SET v_add_interval_1=v_add_interval+1; START TRANSACTION; -- 自動創建今日分區 select count(0) into flag from INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = schema() AND TABLE_Name=v_tablename and partition_name=CONCAT('p',DATE_FORMAT(NOW(),'%Y%m%d')); if flag = 0 then SET @t=CONCAT('alter table ',v_tablename,' add partition ','(','partition ', CONCAT('p',DATE_FORMAT(now(),'%Y%m%d')), ' VALUES LESS THAN (TO_DAYS (''',DATE_FORMAT(date_add(now(),interval v_add_interval day),'%Y%m%d'),''')))'); SELECT @t; PREPARE stmt FROM @t; EXECUTE stmt; DEALLOCATE PREPARE stmt; end if; -- 刪除過期分區 if v_drop_interval > 0 then select count(0) into flag from INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = schema() AND TABLE_Name=v_tablename and partition_name=CONCAT('p',DATE_FORMAT(DATE_SUB(NOW(),INTERVAL v_drop_interval DAY),'%Y%m%d')); if flag = 1 then SET @s=CONCAT('alter table ',v_tablename,' drop partition ', CONCAT('p',DATE_FORMAT(DATE_SUB(NOW(),INTERVAL v_drop_interval DAY),'%Y%m%d'))); SELECT @s; PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; end IF; end if; -- 自動創建明天分區 select count(0) into flag from INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = schema() AND TABLE_Name=v_tablename and partition_name=CONCAT('p',DATE_FORMAT(DATE_ADD(NOW(),INTERVAL v_add_interval DAY),'%Y%m%d')); if flag = 0 then SET @t=CONCAT('alter table ',v_tablename,' add partition ','(','partition ', CONCAT('p',DATE_FORMAT(DATE_ADD(NOW(),INTERVAL v_add_interval DAY),'%Y%m%d')), ' VALUES LESS THAN (TO_DAYS (''',DATE_FORMAT(date_add(now(),interval v_add_interval_1 day),'%Y%m%d'),''')))'); SELECT @t; PREPARE stmt FROM @t; EXECUTE stmt; DEALLOCATE PREPARE stmt; end IF; COMMIT; END
上述腳本,在原文的基礎上做了優化,主要是判斷分區是否存在,刪除一個不存在的分區會發生錯誤;自動創建今日的分區;判斷是否要刪除分區等等。
CREATE DEFINER=`root`@`localhost` EVENT `event_partition` ON SCHEDULE EVERY 1 DAY STARTS '2018-09-17' ON COMPLETION NOT PRESERVE ENABLE COMMENT '' DO BEGIN CALL proc_add_drop_partition('t_base_log',0,1); CALL proc_add_drop_partition('t_gps',60,1); END
創建事件,執行存儲過程。
2.以月自動創建和刪除分區
調用示例:CALL proc_month_partition('t_base_log_abnormal',0,1);
不刪除分區
CREATE DEFINER=`root`@`%` PROCEDURE `proc_month_partition`( IN `v_tablename` VARCHAR(50), IN `v_drop_interval` INT, IN `v_add_interval` INT ) LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER COMMENT '' BEGIN -- 創建月分區 -- v_tablename:分區表名 -- v_drop_interval:過期天數,為0表示不刪除分區 -- v_add_interval :創建分區間隔,以月單位 DECLARE v_add_interval_1 int; DECLARE flag int default 0; SET v_add_interval_1=v_add_interval+1; START TRANSACTION; -- 自動創建當月分區 select count(0) into flag from INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = schema() AND TABLE_Name=v_tablename and partition_name=CONCAT('p',DATE_FORMAT(NOW(),'%Y%m')); if flag = 0 then SET @t=CONCAT('alter table ',v_tablename,' add partition ','(','partition ', CONCAT('p',DATE_FORMAT(now(),'%Y%m')), ' VALUES LESS THAN (TO_DAYS (''',DATE_FORMAT(date_add(now(),interval v_add_interval MONTH),'%Y%m%d'),''')))'); SELECT @t; PREPARE stmt FROM @t; EXECUTE stmt; DEALLOCATE PREPARE stmt; end if; -- 刪除過期分區 if v_drop_interval > 0 then select count(0) into flag from INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = schema() AND TABLE_Name=v_tablename and partition_name=CONCAT('p',DATE_FORMAT(DATE_SUB(NOW(),INTERVAL v_drop_interval DAY),'%Y%m01')); if flag = 1 then SET @s=CONCAT('alter table ',v_tablename,' drop partition ', CONCAT('p',DATE_FORMAT(DATE_SUB(NOW(),INTERVAL v_drop_interval DAY),'%Y%m'))); SELECT @s; PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt; end IF; end if; -- 自動創建下月分區 select count(0) into flag from INFORMATION_SCHEMA.partitions WHERE TABLE_SCHEMA = schema() AND TABLE_Name=v_tablename and partition_name=CONCAT('p',DATE_FORMAT(DATE_ADD(NOW(),INTERVAL v_add_interval MONTH),'%Y%m')); if flag = 0 then SET @t=CONCAT('alter table ',v_tablename,' add partition ','(','partition ', CONCAT('p',DATE_FORMAT(DATE_ADD(NOW(),INTERVAL v_add_interval DAY),'%Y%m')), ' VALUES LESS THAN (TO_DAYS (''',DATE_FORMAT(date_add(now(),interval v_add_interval_1 MONTH),'%Y%m01'),''')))'); SELECT @t; PREPARE stmt FROM @t; EXECUTE stmt; DEALLOCATE PREPARE stmt; end IF; COMMIT; END