mysql分区交换存储过程(根据pre表分区字段数量来决定交换多少个分区)

思路:hive数据插入pre表(根据pre表分区字段数量来决定交换多少个分区),再新建pre表插入数据到mid表,最后mid表和目标表分区交换。

                              hive数仓->pre表->mid表->目标表

注意:pre表的分区字段需要单独加上索引,会加快pre表数据插入mid表的速度。

        pre表、mid表、目标表三者表结构一定要相同,且pre表、mid表不能为分区表。

具体步骤:

第一步:统计pre表开始日期

第二步:统计pre表结束日期

第三步:删除mid表(如果存在,需要先删除)

第四步:开始创建mid表

第五步:删除mid表分区

第六步:统计pre表分区数据量

循环开始

   判断pre表分区数据量是否大于 0

           pre表分区数据量大于 0 ,继续执行循环内容
                   第七步:truncate mid表
                   第八步:插入数据过程(pre表->mid表)
                   第九步:目标表分区交换
          pre表分区数据量小于等于 0 ,不继续执行循环内容

循环结束

第十步:删除mid表

第十一步:插入日志

日志表建表语句:


CREATE TABLE procedure_execute_detail_log (
  id INT AUTO_INCREMENT PRIMARY KEY,
  tablename_schema varchar(100) DEFAULT NULL COMMENT '表所属数据库名',
  tablename varchar(100) DEFAULT NULL COMMENT '目标表名称',
  partition_field varchar(100) DEFAULT NULL COMMENT '分区字段',
  msg LONGTEXT DEFAULT NULL COMMENT '存储过程返回信息out',
  procedure_execute_date DATE DEFAULT NULL COMMENT '存储过程-执行日期',
  procedure_execute_start_date datetime DEFAULT NULL COMMENT '存储过程执行-开始时间',
  procedure_execute_end_date datetime DEFAULT NULL COMMENT '存储过程执行-结束时间',
  INDEX `index_procedure_execute_date`(`procedure_execute_date`) USING BTREE,
  INDEX `index_tablename`(`tablename`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存储过程日志表'

-- SELECT LAST_INSERT_ID(); -- 查看当前序列
-- ALTER TABLE students AUTO_INCREMENT = 1001; --重置自增序列
-- select AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = '数据库名称' AND TABLE_NAME = '表名称' limit 1

代码执行结果:

注意:此存储过程遇到报错,直接退出程序,不会继续执行!!!!!!!
第一步:统计pre表开始日期	分区交换开始日期:2023-11-01   =>用时:00:00:00.000000
第二步:统计pre表结束日期	分区交换结束日期:2023-11-29   =>用时:00:00:00.000000
第三步:删除mid表  =>用时:00:00:00.000000
第四步:开始创建mid表  =>用时:00:00:11.000000
第五步:删除mid表分区  =>用时:00:00:04.000000
循环开始..........
			第1次循环
			第六步:统计pre表2023-11-29分区数据量  =>用时:00:00:00.000000
					pre表2023-11-29分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:00.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:04.000000
							第九步:目标表分区交换  =>用时:00:00:01.000000
			第2次循环
			第六步:统计pre表2023-11-28分区数据量  =>用时:00:00:00.000000
					pre表2023-11-28分区数据量小于等于 0 ,不继续执行循环内容
			第3次循环
			第六步:统计pre表2023-11-27分区数据量  =>用时:00:00:00.000000
					pre表2023-11-27分区数据量小于等于 0 ,不继续执行循环内容
			第4次循环
			第六步:统计pre表2023-11-26分区数据量  =>用时:00:00:00.000000
					pre表2023-11-26分区数据量小于等于 0 ,不继续执行循环内容
			第5次循环
			第六步:统计pre表2023-11-25分区数据量  =>用时:00:00:00.000000
					pre表2023-11-25分区数据量小于等于 0 ,不继续执行循环内容
			第6次循环
			第六步:统计pre表2023-11-24分区数据量  =>用时:00:00:00.000000
					pre表2023-11-24分区数据量小于等于 0 ,不继续执行循环内容
			第7次循环
			第六步:统计pre表2023-11-23分区数据量  =>用时:00:00:00.000000
					pre表2023-11-23分区数据量小于等于 0 ,不继续执行循环内容
			第8次循环
			第六步:统计pre表2023-11-22分区数据量  =>用时:00:00:00.000000
					pre表2023-11-22分区数据量小于等于 0 ,不继续执行循环内容
			第9次循环
			第六步:统计pre表2023-11-21分区数据量  =>用时:00:00:00.000000
					pre表2023-11-21分区数据量小于等于 0 ,不继续执行循环内容
			第10次循环
			第六步:统计pre表2023-11-20分区数据量  =>用时:00:00:00.000000
					pre表2023-11-20分区数据量小于等于 0 ,不继续执行循环内容
			第11次循环
			第六步:统计pre表2023-11-19分区数据量  =>用时:00:00:00.000000
					pre表2023-11-19分区数据量小于等于 0 ,不继续执行循环内容
			第12次循环
			第六步:统计pre表2023-11-18分区数据量  =>用时:00:00:00.000000
					pre表2023-11-18分区数据量小于等于 0 ,不继续执行循环内容
			第13次循环
			第六步:统计pre表2023-11-17分区数据量  =>用时:00:00:00.000000
					pre表2023-11-17分区数据量小于等于 0 ,不继续执行循环内容
			第14次循环
			第六步:统计pre表2023-11-16分区数据量  =>用时:00:00:00.000000
					pre表2023-11-16分区数据量小于等于 0 ,不继续执行循环内容
			第15次循环
			第六步:统计pre表2023-11-15分区数据量  =>用时:00:00:00.000000
					pre表2023-11-15分区数据量小于等于 0 ,不继续执行循环内容
			第16次循环
			第六步:统计pre表2023-11-14分区数据量  =>用时:00:00:00.000000
					pre表2023-11-14分区数据量小于等于 0 ,不继续执行循环内容
			第17次循环
			第六步:统计pre表2023-11-13分区数据量  =>用时:00:00:00.000000
					pre表2023-11-13分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:00.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:06.000000
							第九步:目标表分区交换  =>用时:00:00:01.000000
			第18次循环
			第六步:统计pre表2023-11-12分区数据量  =>用时:00:00:00.000000
					pre表2023-11-12分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:00.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:03.000000
							第九步:目标表分区交换  =>用时:00:00:00.000000
			第19次循环
			第六步:统计pre表2023-11-11分区数据量  =>用时:00:00:00.000000
					pre表2023-11-11分区数据量小于等于 0 ,不继续执行循环内容
			第20次循环
			第六步:统计pre表2023-11-10分区数据量  =>用时:00:00:00.000000
					pre表2023-11-10分区数据量小于等于 0 ,不继续执行循环内容
			第21次循环
			第六步:统计pre表2023-11-09分区数据量  =>用时:00:00:00.000000
					pre表2023-11-09分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:01.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:03.000000
							第九步:目标表分区交换  =>用时:00:00:01.000000
			第22次循环
			第六步:统计pre表2023-11-08分区数据量  =>用时:00:00:00.000000
					pre表2023-11-08分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:00.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:03.000000
							第九步:目标表分区交换  =>用时:00:00:01.000000
			第23次循环
			第六步:统计pre表2023-11-07分区数据量  =>用时:00:00:00.000000
					pre表2023-11-07分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:00.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:03.000000
							第九步:目标表分区交换  =>用时:00:00:00.000000
			第24次循环
			第六步:统计pre表2023-11-06分区数据量  =>用时:00:00:00.000000
					pre表2023-11-06分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:01.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:03.000000
							第九步:目标表分区交换  =>用时:00:00:00.000000
			第25次循环
			第六步:统计pre表2023-11-05分区数据量  =>用时:00:00:00.000000
					pre表2023-11-05分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:00.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:04.000000
							第九步:目标表分区交换  =>用时:00:00:00.000000
			第26次循环
			第六步:统计pre表2023-11-04分区数据量  =>用时:00:00:00.000000
					pre表2023-11-04分区数据量小于等于 0 ,不继续执行循环内容
			第27次循环
			第六步:统计pre表2023-11-03分区数据量  =>用时:00:00:00.000000
					pre表2023-11-03分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:01.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:03.000000
							第九步:目标表分区交换  =>用时:00:00:01.000000
			第28次循环
			第六步:统计pre表2023-11-02分区数据量  =>用时:00:00:00.000000
					pre表2023-11-02分区数据量小于等于 0 ,不继续执行循环内容
			第29次循环
			第六步:统计pre表2023-11-01分区数据量  =>用时:00:00:00.000000
					pre表2023-11-01分区数据量大于 0 ,继续执行循环内容
							第七步:truncate mid表  =>用时:00:00:00.000000
							第八步:插入数据过程(pre表->mid表)  =>用时:00:00:03.000000
							第九步:目标表分区交换  =>用时:00:00:00.000000
循环结束..........
第十步:删除mid表

全部代码:

/*
调用方式
call exchange_partition_table('fopdata','test_partitions','p_day',@msg);

select @msg;
*/

/*
步骤  代码                                                                           说明
步骤1 START TRANSACTION;                                                            开始一个事务
步骤2 DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;                               声明一个异常处理程序,当发生异常时回滚事务
步骤3 SAVEPOINT sp1;                                                                创建一个保存点,用于回滚到这个点
步骤4 INSERT INTO table_name (column1, column2, …) VALUES (value1, value2, …);      执行需要回滚的数据库操作,例如插入一条数据
步骤5 RELEASE SAVEPOINT sp1;                                                        释放保存点,表示我们确认这个点之后的操作都是正确的
步骤6 COMMIT;                                                                       提交事务,表示整个事务执行完毕
步骤7 END;                                                                          存储过程结束


CREATE TABLE procedure_execute_detail_log (
  id INT AUTO_INCREMENT PRIMARY KEY,
  tablename_schema varchar(100) DEFAULT NULL COMMENT '表所属数据库名',
  tablename varchar(100) DEFAULT NULL COMMENT '目标表名称',
  partition_field varchar(100) DEFAULT NULL COMMENT '分区字段',
  msg LONGTEXT DEFAULT NULL COMMENT '存储过程返回信息out',
  procedure_execute_date DATE DEFAULT NULL COMMENT '存储过程-执行日期',
  procedure_execute_start_date datetime DEFAULT NULL COMMENT '存储过程执行-开始时间',
  procedure_execute_end_date datetime DEFAULT NULL COMMENT '存储过程执行-结束时间',
  INDEX `index_procedure_execute_date`(`procedure_execute_date`) USING BTREE,
  INDEX `index_tablename`(`tablename`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存储过程日志表'

-- SELECT LAST_INSERT_ID(); -- 查看当前序列
-- ALTER TABLE students AUTO_INCREMENT = 1001; --重置自增序列
-- select AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = '数据库名称' AND TABLE_NAME = '表名称' limit 1
*/



DROP PROCEDURE IF EXISTS exchange_partition_table;

DELIMITER $$
CREATE PROCEDURE `exchange_partition_table`(
    IN  tablename_schema VARCHAR (50), -- 表所属数据库名
    IN tablename VARCHAR (50), -- 目标表名称
    IN partition_field VARCHAR (50), -- 分区字段
    OUT msg LONGTEXT) -- 输出日志 @msg
BEGIN
DECLARE error_code VARCHAR(50) DEFAULT ''; -- 错误代码
DECLARE error_msg TEXT;                    -- 报错信息
DECLARE date_cycles int DEFAULT 1;         -- 循环次数
DECLARE error_location VARCHAR(50) DEFAULT '';         -- 错误定位编号
DECLARE errorcontext_1 VARCHAR(2000) DEFAULT '';           -- 报错原因

DECLARE start_second_time VARCHAR(200) DEFAULT '';           -- 开始时间
DECLARE end_second_time VARCHAR(200) DEFAULT '';           -- 结束时间
DECLARE diffenrence_second_time_1 VARCHAR(200) DEFAULT '';           -- 程序用时多少

DECLARE  procedure_execute_date VARCHAR(200) DEFAULT ''; -- 存储过程-执行日期
DECLARE  procedure_execute_start_date VARCHAR(200) DEFAULT '';-- 存储过程执行-开始时间
DECLARE  procedure_execute_end_date VARCHAR(200) DEFAULT '';-- 存储过程执行-结束时间



DECLARE i  INT DEFAULT 0;
DECLARE p_cnt  INT DEFAULT 0;
DECLARE p_date VARCHAR(20);
DECLARE p_sql  VARCHAR(2000);
DECLARE create_tab  VARCHAR(2000);
DECLARE table_mid  VARCHAR(2000);
DECLARE remove_partition  VARCHAR(2000);
DECLARE drop_tab  VARCHAR(2000);
DECLARE insert_log  LONGTEXT;

-- CONTINUE EXIT
-- DECLARE CONTINUE HANDLER FOR SQLEXCEPTION  -- 异常信息处理
 DECLARE EXIT HANDLER FOR SQLEXCEPTION   -- 抛异常,就退出程序 ,报错才会执行以下内容
        BEGIN
        -- 获取异常code,异常信息
              GET DIAGNOSTICS CONDITION 1
                error_code = RETURNED_SQLSTATE, error_msg= MESSAGE_TEXT;
                SET msg = CONCAT_ws('',msg,'\n',errorcontext_1,'\n报错信息: 错误编号:',error_code,', 内容:',error_msg);
                -- select  msg;

                -- 报错也需要继续插入日志
                SET procedure_execute_end_date=DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s'); -- 存储过程执行-结束时间
                SET insert_log = CONCAT_ws('','insert into ',tablename_schema,'.procedure_execute_detail_log (tablename_schema,tablename,partition_field,msg,procedure_execute_date,procedure_execute_start_date,procedure_execute_end_date)
                        values("',tablename_schema,'","',tablename,'","',partition_field,'","',msg,'",DATE_FORMAT("'
                        ,procedure_execute_date,'","%Y-%m-%d"),DATE_FORMAT("'
                        ,procedure_execute_start_date,'","%Y-%m-%d %H:%i:%s"),DATE_FORMAT("'
                        ,procedure_execute_end_date,'","%Y-%m-%d %H:%i:%s"));');
                SET @dt = insert_log;
                PREPARE stmt FROM @dt;
                EXECUTE stmt;
                DEALLOCATE PREPARE stmt; 
                commit;
                -- select insert_log;
              --    ROLLBACK;
              --  RELEASE SAVEPOINT sp1;
              --  commit;
        END;
/*
--  注意 执行分区交换,pre表 p_day字段必须加索引,否则会执行很慢。
*/
SET procedure_execute_date=DATE_FORMAT(now(),'%Y-%m-%d'); -- 存储过程-执行日期  '2023-12-04'
SET procedure_execute_start_date=DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s');-- 存储过程执行-开始时间

SET msg = CONCAT('注意:此存储过程遇到报错,直接退出程序,不会继续执行!!!!!!!');

SET msg = CONCAT(msg,'\n第一步:统计pre表开始日期');
SET errorcontext_1 = CONCAT('报错位置:执行第一步失败');  -- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET p_sql = CONCAT('select min(',partition_field,') into @pre_start_time from ', CONCAT(tablename_schema,'.',tablename), '_pre ;');
SET @s = p_sql;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第一步用时
SET msg = CONCAT(msg,'\t分区交换开始日期:',@pre_start_time,'   =>用时:',diffenrence_second_time_1);

SET msg = CONCAT(msg,'\n第二步:统计pre表结束日期');
SET errorcontext_1 = CONCAT('报错位置:执行第二步失败');  -- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET p_sql = CONCAT('select max(',partition_field,') into @pre_end_time from ', CONCAT(tablename_schema,'.',tablename), '_pre ;');
SET @s = p_sql;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;  
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第二步用时
SET msg = CONCAT(msg,'\t分区交换结束日期:',@pre_end_time,'   =>用时:',diffenrence_second_time_1);

-- 循环次数
-- 日期格式:yyyy-mm-dd 判断                                                             -- 日期格式: yyyy-mm判断   
if length(@pre_end_time)=10 then 
        set date_cycles=datediff(@pre_end_time,@pre_start_time)+1;
    elseif length(@pre_end_time)=7 then 
        set date_cycles=PERIOD_DIFF(REPLACE(@pre_end_time,'-',''),REPLACE(@pre_start_time,'-',''))+1;
    else 
        SET msg = CONCAT(msg,'\n输入参数分区字段错误!!!!!');
end if; 

SET msg = CONCAT(msg,'\n第三步:删除mid表');
set table_mid = CONCAT(tablename, '_mid');
SET errorcontext_1 = CONCAT('报错位置:执行第三步失败');  -- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET create_tab = CONCAT('drop table IF  EXISTS ', CONCAT(tablename_schema,'.',table_mid),';');
SET @s = create_tab;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第三步用时


SET msg = CONCAT(msg,'  =>用时:',diffenrence_second_time_1,'\n第四步:开始创建mid表');
set table_mid = CONCAT(tablename, '_mid');
SET errorcontext_1 = CONCAT('报错位置:执行第四步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET create_tab = CONCAT('create table IF NOT EXISTS ', CONCAT(tablename_schema,'.',table_mid), ' like ',CONCAT(tablename_schema,'.',tablename),';');
SET @s = create_tab;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt; 
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第四步用时


SET msg = CONCAT(msg,'  =>用时:',diffenrence_second_time_1,'\n第五步:删除mid表分区');
SET errorcontext_1 = CONCAT('报错位置:执行第五步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET remove_partition = CONCAT('alter table ', CONCAT(tablename_schema,'.',table_mid), ' remove partitioning;');
SET @s = remove_partition;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt; 
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第五步用时
SET msg = CONCAT(msg,'  =>用时:',diffenrence_second_time_1,'\n循环开始..........');


WHILE i < date_cycles DO
    if length(@pre_end_time)=10 then -- yyyy-mm-dd
        SET p_date = DATE_FORMAT(DATE_SUB(@pre_end_time, INTERVAL i DAY), '%Y-%m-%d');
    elseif length(@pre_end_time)=7 then -- yyyy-mm
        set p_date = DATE_FORMAT(concat_ws('',PERIOD_ADD(REPLACE(@pre_end_time,'-',''), -i),'01'),'%Y-%m'); 
    else 
        SET msg = CONCAT(msg,'\n输入参数分区字段错误!!!!!');
    end if;
    SET msg = CONCAT(msg,'\n\t\t\t第',i+1,'次循环');


    SET msg = CONCAT(msg,'\n\t\t\t第六步:统计pre表',p_date,'分区数据量');
    SET errorcontext_1 = CONCAT('报错位置:执行第六步失败');-- 用于定位报错位置
    set start_second_time=unix_timestamp(); -- 开始时间
    SET p_sql = CONCAT('SELECT COUNT(1) INTO @cnt FROM ', CONCAT(tablename_schema,'.',tablename), '_pre WHERE ',partition_field,' = ?;');
    SET @s = p_sql;
    SET @p1 = p_date;
    PREPARE stmt FROM @s;
    EXECUTE stmt USING @p1;
    DEALLOCATE PREPARE stmt; 
    set end_second_time=unix_timestamp(); -- 结束时间
    set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第六步用时
    SET msg = CONCAT(msg,'  =>用时:',diffenrence_second_time_1);
    
    -- 判断分区数据量大于 0 
    SET p_cnt = @cnt;
    IF p_cnt > 0 THEN
        SET msg = CONCAT(msg,'\n\t\t\t\t\tpre表',p_date,'分区数据量大于 0 ,继续执行循环内容');
        SET msg = CONCAT(msg,'\n\t\t\t\t\t\t\t第七步:truncate mid表');
        SET errorcontext_1 = CONCAT('报错位置:执行第七步失败');-- 用于定位报错位置
        set start_second_time=unix_timestamp(); -- 开始时间
        SET p_sql = CONCAT('TRUNCATE TABLE ',  CONCAT(tablename_schema,'.',table_mid), ';');
        SET @s = p_sql;
        PREPARE stmt FROM @s;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        set end_second_time=unix_timestamp(); -- 结束时间
        set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第七步用时
        
        SET msg = CONCAT(msg,'  =>用时:',diffenrence_second_time_1,'\n\t\t\t\t\t\t\t第八步:插入数据过程(pre表->mid表)');
        SET errorcontext_1 = CONCAT('报错位置:执行第八步失败');
        set start_second_time=unix_timestamp(); -- 开始时间
        SET p_sql = CONCAT('INSERT INTO ',  CONCAT(tablename_schema,'.',table_mid), ' SELECT * FROM ', CONCAT(tablename_schema,'.',tablename), '_pre WHERE ', CONCAT(tablename_schema,'.',tablename), '_pre.',partition_field,' = ?;');
        SET @s = p_sql;
        PREPARE stmt FROM @s;
        EXECUTE stmt USING @p1;
        DEALLOCATE PREPARE stmt;
        set end_second_time=unix_timestamp(); -- 结束时间
        set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第八步用时

        /*
        -- 以下判断作用是分区名称p20231101,去除日期-
        if length(@pre_end_time)=10 then -- yyyy-mm-dd
            SET p_date = DATE_FORMAT(DATE_SUB(@pre_end_time, INTERVAL i DAY), '%Y%m%d'); -- 分区名称
        elseif length(@pre_end_time)=7 then -- yyyy-mm
            set p_date = DATE_FORMAT(concat_ws('',PERIOD_ADD(REPLACE(@pre_end_time,'-',''), -i),'01'),'%Y%m'); -- 分区名称
        else 
            SET msg = CONCAT(msg,'\n输入参数分区字段错误!!!!!');
        end if;
        */
        

        SET msg = CONCAT(msg,'  =>用时:',diffenrence_second_time_1,'\n\t\t\t\t\t\t\t第九步:目标表分区交换');
        SET errorcontext_1 = CONCAT('报错位置:执行第九步失败');-- 用于定位报错位置
        set start_second_time=unix_timestamp(); -- 开始时间
        SET p_sql = CONCAT('ALTER TABLE ', CONCAT(tablename_schema,'.',tablename), ' EXCHANGE PARTITION p', replace(p_date,'-',''), ' WITH TABLE ',  CONCAT(tablename_schema,'.',table_mid), ' WITHOUT validation;');
        SET @s = p_sql;
        PREPARE stmt FROM @s;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        set end_second_time=unix_timestamp(); -- 结束时间
        set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第九步用时
        SET msg = CONCAT(msg,'  =>用时:',diffenrence_second_time_1);

    else 
        if date_cycles=i+1 then 
            SET msg = CONCAT(msg,'\n\t\t\t\t\tpre表',p_date,'分区数据量小于等于 0 ,不继续执行循环内容,退出循环');
        else
            SET msg = CONCAT(msg,'\n\t\t\t\t\tpre表',p_date,'分区数据量小于等于 0 ,不继续执行循环内容');
        end if;

    END IF;
    SET i = i + 1;
END WHILE; 


SET msg = CONCAT(msg,'\n循环结束..........');
SET msg = CONCAT(msg,'\n第十步:删除mid表');
SET errorcontext_1 = CONCAT('报错位置:执行第十步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET drop_tab = CONCAT('drop table IF  EXISTS ', CONCAT(tablename_schema,'.',table_mid), ';');
SET @dt = drop_tab;
PREPARE stmt FROM @dt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt; 
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第十步用时

SET errorcontext_1 ='';-- 以上步骤全部执行成功,将报错位置置成空值
SET msg = CONCAT(msg,'  =>用时:',diffenrence_second_time_1,'\n所有步骤执行成功。。。。。。。');
select msg;-- 打印返回信息

-- 第十一步:存储过程返回信息插入日志procedure_execute_detail_log表
SET errorcontext_1 = CONCAT('报错位置:执行第十一步失败');-- 用于定位报错位置
SET procedure_execute_end_date=DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s'); -- 存储过程执行-结束时间
SET insert_log = CONCAT_ws('','insert into ',tablename_schema,'.procedure_execute_detail_log (tablename_schema,tablename,partition_field,msg,procedure_execute_date,procedure_execute_start_date,procedure_execute_end_date)
values("',tablename_schema,'","',tablename,'","',partition_field,'","',msg,'",DATE_FORMAT("'
,procedure_execute_date,'","%Y-%m-%d"),DATE_FORMAT("'
,procedure_execute_start_date,'","%Y-%m-%d %H:%i:%s"),DATE_FORMAT("'
,procedure_execute_end_date,'","%Y-%m-%d %H:%i:%s"));');
SET @dt = insert_log;
PREPARE stmt FROM @dt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt; 
commit;




END
$$
DELIMITER;

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值