由于程序大量写入数据库,导致mysql一个表数据量极大,ORACLE里面分区表用的非常好,因此建议MYSQL的表也进行分区表改造,并清理历史数据,经与应用讨论,分区改造要求如下:
1、按天分区;
2、每天删除最早的一个分区,删除前需要备份到历史表;
3、每天新增一个分区,新增的分区比最大的分区大一天,不限于第二天的分区,只要愿意,可以连续执行,连续创建多天分区。
一、创建分区表
创建分区表需要注意两点:
1、分区字段,必须在主键内,否则无法创建;
2、按照时间字段创建,类型应为datetime ,有时候我们习惯用varchar字段来存放时间,需要转换,函数分区需要查询支持函数,很多函数不支持在分区时使用,因此建议直接使用datetime类型。
CREATE TABLE `daf_autoplan_log_tcpdump` (
`logid` int NOT NULL AUTO_INCREMENT ,
`daf_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`host_m_Ip` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`host_m_Port` int NULL DEFAULT NULL ,
`fteo_id` int NULL DEFAULT NULL ,
`host_m_Command` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`cmd_result` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`runtime` datetime NOT NULL ,
`cmdresult` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`sen_sms` int NULL DEFAULT 0 COMMENT '是否发送短信:0 未发送,1发送 2 发送失败' ,
`remark1` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT '0' COMMENT '是否被分析,0未被分析,1:已经被分析' ,
`remark2` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '预留字段' ,
`remark3` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '预留字段' ,
PRIMARY KEY (`logid`,`runtime`),
INDEX `logid` (`logid`, `daf_id`, `host_m_Ip`, `host_m_Port`) USING BTREE
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=2381
ROW_FORMAT=DYNAMIC
PARTITION BY RANGE (TO_DAYS(runtime) ) (
PARTITION p20210905 VALUES LESS THAN ( TO_DAYS('20210906') ),
PARTITION p20210906 VALUES LESS THAN ( TO_DAYS('20210907') ),
PARTITION p20210907 VALUES LESS THAN ( TO_DAYS('20210908') )
);
也支持直接在原表上进行分区改造,但是目前一般思路都是新建表比较好。分区根据需要,建的足够多,一旦自动调度开启,将删除最小的,增加一个最新分区,保持分区数量固定。
二、创建自动分区存储过程
存储过程名称:create_Partition_daf_autoplan_log_tcpdump,包括三个功能:
1、建分区;
2、备份最小分区数据到历史表;
3、删除最小分区。
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
START TRANSACTION;
/* 按照 runtime 字段创建分区,创建之前,取出最大分区名称*/
SELECT REPLACE(partition_name,'p','') INTO @Pmax FROM INFORMATION_SCHEMA.PARTITIONS
WHERE table_name='daf_autoplan_log' ORDER BY partition_ordinal_position DESC LIMIT 1;
SET @Max_date= DATE(DATE_ADD(@Pmax+0, INTERVAL 1 DAY))+1;
SET @Now_date= DATE(DATE_ADD(@Pmax+0, INTERVAL 1 DAY))+0;
SET @s1=CONCAT('ALTER TABLE daf_autoplan_log ADD PARTITION (PARTITION p',@Now_date,' VALUES LESS THAN (TO_DAYS (''',DATE(@Max_date),''')))');
SELECT @s1;
PREPARE stmt2 FROM @s1;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
select partition_name into @Pmin from INFORMATION_SCHEMA.PARTITIONS
where table_name='daf_autoplan_log' order by partition_ordinal_position limit 1;
/*备份最小分区数据到历史表*/
SET @ins=CONCAT('INSERT INTO daf_autoplan_log_history select * from daf_autoplan_log PARTITION(',@Pmin,')');
PREPARE stmt3 FROM @ins;
EXECUTE stmt3;
DEALLOCATE PREPARE stmt3;
/* 删除最小分区 */
SET @s=concat('ALTER TABLE daf_autoplan_log DROP PARTITION ',@Pmin);
PREPARE stmt1 FROM @s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
/* 提交 */
COMMIT ;
END
三、创建event(类似oracle的job)
事件名称:Partition_daf_autoplan_log_event
CREATE DEFINER=`root`@`%`
EVENT `NewEvent`
ON SCHEDULE EVERY 1 DAY STARTS '2021-01-01 02:00:00'
ON COMPLETION NOT PRESERVE
ENABLE
DO
BEGIN
CALL lining.`create_Partition_daf_autoplan_log_tcpdump`;
END;
用navicat创建更方便,且工具一目了然。
四、相关视图
(1)查询event定义
SELECT * FROM INFORMATION_SCHEMA.EVENTS ;
(2)查询调度器开启情况
SELECT @@event_scheduler;
(3)调度开关
ALTER EVENT Partition_daf_autoplan_log_event ENABLE;
ALTER EVENT Partition_daf_autoplan_log_event DISABLE;




