记录一下分区代码:
1.建立存储过程,将原表按照时间转化为分区表,并建立当天分区
#alter table to partition table DELIMITER $$ USE `dc_log`$$ DROP PROCEDURE IF EXISTS `create_partition_today`$$ CREATE PROCEDURE `create_partition_today`(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64)) BEGIN DECLARE BEGINTIME TIMESTAMP; DECLARE ENDTIME TIMESTAMP; DECLARE DAYS_ENDTIME INT; DECLARE PARTITIONNAME VARCHAR(16); SET BEGINTIME = NOW(); SET ENDTIME = BEGINTIME + INTERVAL 1 DAY; SET PARTITIONNAME = DATE_FORMAT(BEGINTIME, 'p%Y%m%d'); SET DAYS_ENDTIME = TO_DAYS(ENDTIME); SET @SQL = CONCAT('ALTER TABLE `', IN_SCHEMANAME, '`.`', IN_TABLENAME, '`', ' PARTITION BY RANGE (to_days(create_time)) (PARTITION ', PARTITIONNAME, ' VALUES LESS THAN (', DAYS_ENDTIME, '))'); PREPARE STMT FROM @SQL; EXECUTE STMT; DEALLOCATE PREPARE STMT; END$$ DELIMITER ;
2.建立存储过程,负责检查第二天的分区是否存在,如果不存在则建立
#procedure of build partition of today and next day DELIMITER $$ USE `dc_log`$$ DROP PROCEDURE IF EXISTS `create_partition_by_day`$$ CREATE PROCEDURE `create_partition_by_day`(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64)) BEGIN DECLARE ROWS_CNT INT UNSIGNED; DECLARE BEGINTIME TIMESTAMP; DECLARE ENDTIME TIMESTAMP; DECLARE DAYS_ENDTIME INT; DECLARE PARTITIONNAME VARCHAR(16); SET BEGINTIME = NOW() + INTERVAL 1 DAY; SET PARTITIONNAME = DATE_FORMAT(BEGINTIME, 'p%Y%m%d'); SET ENDTIME = BEGINTIME + INTERVAL 1 DAY; SET DAYS_ENDTIME = TO_DAYS(ENDTIME); SELECT COUNT(*) INTO ROWS_CNT FROM information_schema.partitions WHERE table_schema = IN_SCHEMANAME AND table_name = IN_TABLENAME AND partition_name = PARTITIONNAME; IF ROWS_CNT = 0 THEN SET @SQL = CONCAT('ALTER TABLE `', IN_SCHEMANAME, '`.`', IN_TABLENAME, '`', ' ADD PARTITION (PARTITION ', PARTITIONNAME, ' VALUES LESS THAN (', DAYS_ENDTIME, '))'); PREPARE STMT FROM @SQL; EXECUTE STMT; DEALLOCATE PREPARE STMT; ELSE SELECT CONCAT("partition `", PARTITIONNAME, "` for table `", IN_SCHEMANAME, ".", IN_TABLENAME, "` already exists") AS result; END IF; END$$ DELIMITER ;
3.为了避免数据无限量扩大,建立存储过程,负责清除30天前的分区表数据
DELIMITER $$ USE `dc_log`$$ DROP PROCEDURE IF EXISTS `clear_partition_by_day`$$ CREATE PROCEDURE `clear_partition_by_day`(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64)) BEGIN DECLARE NOWDAYS INT; DECLARE Done INT; DECLARE part VARCHAR(64); DECLARE descr INT; DECLARE rs CURSOR FOR SELECT partition_name part, partition_description descr FROM information_schema.partitions WHERE table_schema = IN_SCHEMANAME AND table_name = IN_TABLENAME; /* 异常处理 */ DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET Done = 1; OPEN rs; SET NOWDAYS = TO_DAYS(NOW()); FETCH rs into part,descr; while Done is null DO IF NOWDAYS - descr > 30 THEN select descr AS cc; SET @SQL = CONCAT('ALTER TABLE `', IN_SCHEMANAME, '`.`', IN_TABLENAME, '`', ' DROP PARTITION ', part); select descr AS aa; SELECT @SQL AS result; select descr AS bb; PREPARE STMT FROM @SQL; EXECUTE STMT; DEALLOCATE PREPARE STMT; END IF; FETCH rs into part,descr; end WHILE; CLOSE rs; END$$ DELIMITER ;
4.这时候创建两个事件,负责按周期去执行建立分区和删除分区
#invoke event to create future partitions #hour event of checking partition existed or not(invoke procedure every day) DELIMITER $$ USE `dc_log`$$ CREATE EVENT IF NOT EXISTS `e_part_manage` ON SCHEDULE EVERY 1 HOUR #every minute STARTS '2018-05-01 18:27:00' ON COMPLETION PRESERVE ENABLE COMMENT 'Creating partitions' DO BEGIN CALL dc_log.create_partition_by_day('dc_log', 'business_log'); END$$ DELIMITER ; #event of clear data which out of date of 30 days DELIMITER $$ USE `dc_log`$$ CREATE EVENT IF NOT EXISTS `clear_data` ON SCHEDULE EVERY 1 DAY #every minute STARTS '2018-05-01 18:27:30' ON COMPLETION PRESERVE ENABLE COMMENT 'clearing data' DO BEGIN CALL clear_partition_by_day('dc_log', 'business_log'); END$$ DELIMITER ;
5.如果事件没有运行,则可能是事件开关未开启
#turn event_scheduler on SET GLOBAL event_scheduler = 'ON'; #打开
6.加入另外一张表操作,修改事件内容
#service_push #same steps of table business_log ALTER TABLE dc_system.service_push DROP PRIMARY KEY; CALL create_partition_today('dc_system', 'service_push'); ALTER EVENT e_part_manage DO BEGIN CALL dc_log.create_partition_by_day('dc_log', 'business_log'); CALL dc_log.create_partition_by_day('dc_system', 'service_push'); END ; ALTER EVENT clear_data DO BEGIN CALL dc_log.clear_partition_by_day('dc_log', 'business_log'); CALL dc_log.clear_partition_by_day('dc_system', 'service_push'); END ;
done