MySQL-通过存储过程来添加和删除分区(List分区)

1.背景原因

当前MySQL不支持在添加和删除分区时,使用IF NOT EXISTS和IF EXISTS。所以在执行调度任务时,直接通过ADD PARTITION和DROP PARTITION不可避免会报错。本文通过创建存储过程来添加和删除分区,可以避免在分区存在时添加分区报错,或者分区不存在时删除分区报错的问题。

本文介绍的是关于LIST分区的添加和删除。

2.前提准备

创建List分区表

复制代码
DROP TABLE  IF  EXISTS `list_part_table` ;

CREATE TABLE  IF  NOT  EXISTS `list_part_table`  (
  `id` bigint(32) NOT NULL COMMENT '主键',
  `request_time` datetime(0) NOT NULL COMMENT '请求时间',
  `response_time` datetime(0) NOT NULL COMMENT '响应时间',
  `time_used` int(11) NOT NULL COMMENT '耗时(ms)',
  `create_by` varchar(48)  DEFAULT NULL COMMENT '创建人',
  `update_by` varchar(48)  DEFAULT NULL COMMENT '修改人',
  `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
  PRIMARY KEY (`id`, `request_time`) USING BTREE
) PARTITION BY list(TO_DAYS(request_time)) (
    PARTITION p0 VALUES IN  (0)
 ) ;

查看表中的分区信息

复制代码
select  *  from  information_schema.partitions  where table_name like 'list_part_table%' ;

3.添加和删除分区语句

(1)添加分区

复制代码
alter  table  list_part_table  add partition(partition  p202001 values in (202001));

alter  table  list_part_table  add partition(partition  p20201201 values in (20201201));

查看表的分区信息

复制代码
select  * from  information_schema.partitions  where table_name like 'list_part_table%' ;

(2)删除分区

复制代码
alter  table  list_part_table  drop partition  p202001,p20201201 ;

查看表的分区信息

复制代码
select  * from  information_schema.partitions  where table_name like 'list_part_table%' ;

4.通过存储过程添加LIST分区

(1)添加分区的存储过程

复制代码
DROP  PROCEDURE  IF EXISTS create_list_partition ;

DELIMITER $$

CREATE PROCEDURE  IF  NOT  EXISTS create_list_partition (par_value bigint, tb_schema varchar(128),tb_name varchar(128))

BEGIN

  DECLARE par_name varchar(32);

  DECLARE par_value_str varchar(32);

  DECLARE par_exist int(1);

DECLARE _err int(1);

  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND SET _err = 1;

  START TRANSACTION;

SET par_value_str = CONCAT('', par_value);

    SET par_name = CONCAT('p', par_value);

    SELECT  COUNT(1) INTO par_exist  FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = tb_schema AND TABLE_NAME = tb_name AND PARTITION_NAME = par_name;

    IF (par_exist = 0) THEN

      SET @alter_sql = CONCAT('alter table ', tb_name, ' add PARTITION (PARTITION ', par_name, ' VALUES IN (', par_value_str, '))');

      PREPARE stmt1 FROM @alter_sql;

      EXECUTE stmt1;

    END IF;

  COMMIT;

  END

$$

(2)调用存储过程添加分区

添加分区

复制代码
CALL create_list_partition(202201, 'test', 'list_part_table');

CALL create_list_partition(202202, 'test', 'list_part_table');

CALL create_list_partition(20230912, 'test', 'list_part_table');

CALL create_list_partition(20230913, 'test', 'list_part_table');

查看表的分区信息

复制代码
select  * from  information_schema.partitions  where table_name like 'list_part_table%' ;

5.通过存储过程删除LIST分区

(1)删除分区的存储过程

复制代码
DROP PROCEDURE  IF  EXISTS drop_list_partition ;

DELIMITER $$

CREATE PROCEDURE  IF  NOT  EXISTS drop_list_partition (part_value bigint, tb_schema varchar(128), tb_name varchar(128))

BEGIN

  DECLARE str_day varchar(64);

  DECLARE _err int(1);

  DECLARE done int DEFAULT 0;

  DECLARE par_name varchar(64);

  DECLARE cur_partition_name CURSOR FOR  SELECT  partition_name FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA = tb_schema AND table_name = tb_name  ORDER BY partition_ordinal_position;

  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND SET _err = 1;

  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

  SET str_day = CONCAT('',part_value);

  OPEN cur_partition_name;

  REPEAT

    FETCH cur_partition_name INTO par_name;

    IF (str_day = SUBSTRING(par_name, 2)) THEN

      SET @alter_sql = CONCAT('alter table ', tb_name, ' drop PARTITION ', par_name);

      PREPARE stmt1 FROM @alter_sql;

      EXECUTE stmt1;

    END IF;

  UNTIL done END REPEAT;

  CLOSE cur_partition_name;

END

$$

(2)调用存储过程删除分区

删除分区

复制代码
CALL drop_list_partition(202201, 'test', 'list_part_table');

CALL drop_list_partition(202202, 'test', 'list_part_table');

查看表的分区信息

复制代码
select  * from  information_schema.partitions  where table_name like 'list_part_table%' ;
相关推荐
Cloud云卷云舒16 小时前
云卷云舒:从Oracle/MySQL迁移到HaishanDB:迁移评估工具核心技术拆解
mysql·oracle·ai-native·haishandb·信创数据库替换
用户713335851562419 小时前
MySQL - 事务、redo/undo 日志与 MVCC
mysql
用户713335851562420 小时前
MySQL - InnoDB 的 Buffer Pool
mysql
欲速不达88201 天前
Mysql并发DML锁等待的优化
数据库·mysql
L1624761 天前
MySQL 全环境生产快速安装 + 完整配置手册(整合国产银河麒麟适配 + 主从补充版)
数据库·mysql
前端世界1 天前
MySQL 基础入门(学习第4天)——约束与 DML 操作详解
数据库·学习·mysql
Vect__1 天前
MySQL 数据类型和约束:从字段设计到表结构建模
数据库·mysql
Mico181 天前
MySQL 8.0.35 基于GTID 主从复制安装增强半同步复制
android·mysql·adb
CodexDave2 天前
MySQL事务隔离级别与MVCC机制解析
前端·数据库·mysql·nginx·性能优化·负载均衡
王琦03182 天前
生产环境中使用通用二进制包安装
mysql