暂无图片
暂无图片
6
暂无图片
暂无图片
暂无图片

MYSQL分区表创建、自动备份、自动删除、自动创建

原创 red_hope 2021-09-08
4337

由于程序大量写入数据库,导致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;

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论