开发者

MySQL按月自动设置表分区的实现

开发者 https://www.devze.com 2024-08-13 12:13 出处:网络 作者: LaFeng233
目录开始检查1.创建分区函数检查是否成功创建函数2.创建存储过程,用于自动生成分区3.创建自动删除半年以前的表空间函数4.创建调度任务,修改到每月最后一天执行执行存储过程5.进行测试开始检查
目录
  • 开始检查
  • 1.创建分区函数
    • 检查是否成功创建函数
  • 2.创建存储过程,用于自动生成分区
    • 3.创建自动删除半年以前的表空间函数
      • 4.创建调度任务,修改到每月最后一天执行执行存储过程
        • 5.进行测试

          开始检查

          首先,确保 ticket_history_info表是一个分区表。如果未设置分区,需要修改表结构以支持分区,将 ticket_history_info 表设置为按日期范围进行分区

          ALTER TABLE ticket_history_info
          PARTITION BY RANGE (TO_DAYS(CALL_DATE)) (
              PARTITION p0 VALUES LESS THAN (TO_DAYS('2022-09-01'))
          );
          

          1.创建分区函数

          -- 创建分区函数
          DELIMITER //
          CREATE FUNCTION get_partition_name(p_date DATE)
          RETURNS VARCHAR(20)
          DETERMINISTIC
          BEGIN
              DECLARE p_month VARCHAR(2);
              DECLARE p_year VARCHAR(4);
              SET p_month = LPAD(MONTH(p_date), 2, '0php');
              SET p_year = YEAR(p_date);
              RETURN CONCAT('p', p_year, p_month); 
          END//
          DELIMITER ;
          

          检查是否成功创建函数

          SHOW FUNCTION STATUS LIKE 'get_partition_name';

          2.创建存储过程,用于自动生成分区

          -- 存储过程
          DELIMITER //
          CREATE PROCEDURE create_monthly_partition()
          BEGIN
              DECLARE next_month VARCHAR(20);
              DECLARE next_month_first_day DATE;
              
              -- 计算下一个月份的名称和下个月的第一天
              SET next_month = CONCAT('p', DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y%m'));
              SET next_month_first_day = LAST_DAY(DATE_ADD(CURDATE(), INTERVAL 1 MONTH)) + INTERVAL 1 DAY;
              
              -- 检查分区是否已存在
            VQmbv  IF NOT EXISTS (
                  SELECT NULL
                  FROM information_schema.PARTITIONS
                  WHERE TABLE_NAME = 'ticket_history_info' AND TABLE_SCHEMA = 'ccm' AND PARTITION_NAME = next_month
              ) THEN
                  -- 创建新的分区
                  SET @sql = CONCAT('ALTER TABLE ticket_history_info ADD PARTITION (PARTITION ', next_month, ' VALUES LESS THAN (TO_DAYS(\编程'', next_month_first_day, '\')))');
          
                  PREPARE stmt FROM @sql;
                  EXECUTE stmt;
                  DEALLOCATE PREPARE stmt;
              END IF;
          END//
          DELIMITER ;

           进行测试

           检查是否成功创建函数

          SHOW PROCEDURE STATUS LIKE 'create_monthly_partition';

          执行函数

          CALL create_monthly_partition();

          查询表分区,查看是否成功分区。

          SELECT PARTITION_NAME FROM information_schema.PARTITIONS WHERE TABLE_NAME = '表名' AND TABLE_SCHEMA = '数据库名';

          可通过修改本地系统时间,来进行反复测试是否可按照月份进行分区。

          MySQL按月自动设置表分区的实现

          返回成功,显示已创建表分区。

          MySQL按月自动设置表分区的实现

          3.创建自动删除半年以前的表空间函数

          DELIMITER //
          
          CREATE PROCEDURE delete_old_partitions()
          BEGIN
              DECLARE done INT DEFAULT FALSE;
              DECLARE drop_partition_name VARCHAR(64);
              DECLARE cur CURSOR FOR 
                  SELECT PARTITION_NAME 
                  FROM information_schema.PARTITIONS 
                  WHERE TABLE_SCHEMA = '数据库名' 
                    AND TABLE_NAME = 'ticket_history_info' 
                    AND PARTITION_DESCRIPTION < TO_DAYS(NOW() - INTERVAL 6 MONTH);
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
          
              OPEN cur;
          
              read_loop: LOOP
                  FETCH cur INTO drop_partition_name;
                  IF done THEpythonN
                      LEAVE read_loop;
                  END IF;
                  SET @sql = CONCAT('ALTER TABLE ticket_history_info DROP PARTITION ', drop_partition_name);
                  PREPARE stmt FROM @sql;
                  EXECUTE stmt;
                  DEALLOCATE PREPARE stmt;
              END LOOP;
          
              CLOSE cur;
          
             -- 删除超过半年的数据
              DELETE FROM ticket_history_info_copy1
              WHERE CALL_DATE < CURDATE() - INTERVAL 6 MONTH;
          
          END//
          
          DELIMITER ;
          

          4.创建调度任务,修改到每月最后一天执行执行存储过程

          CREATE EVENT IF NOT EXISTS monthly_partition_event
          ON SCHEDULE EVERY 1 MONTH
          STARTS CONCAT(DATE_FORMAT(LAST_DAY(CURRENT_DATE), '%Y-%m-'), DAY(LAST_DAY(CURRENT_DATE)), ' 23:00:00')
          DO
          BEGIN
              CALL create_monthly_partition();
              CALL delete_old_partitions();
          END;
          

          查看事件调度器是否启动

          SET GLOBAL event_scheduler = ON;

          查看事件

          SHOW EVENTS;
          

          SHOW EVENTS FROM `数据库名`;

          创建成功

          MySQL按月自动设置表分区的实现

          5.进行测试

          插入测试数据进行测试,根据CALL_DATE字段进行数据分区,

          INSERT INTO ticket_history_info (CALL_DATE, SRC_ADD, CALLING_NUM, DURATION) VALUES
          ('2024-05-24 00:00:00', 'Addre编程客栈ss1', '1234567890', 60),
          ('2024-06-20 00:00:00', 'Address2', '0987654321', 120),
          ('2024-05-10 00:00:00', 'Address3', '1122334455', 180),
          ('2024-10-01 00:00:00', 'Address4', '5566778899', 240);

          -查询每个分区的行数

          SELECT PARTITION_NAME, TABLE_ROWS
          FROM information_schema.PARTITIONS
          WHERE TABLE_SCHEMA = 'ccm' AND TABLE_NAME = 'ticket_history_info';

          或者单独查询某一个分区的数据

          SELECT *
          FROM ticket_history_info PARTITION (p202406);

          到此这篇关于mysql按月自动设置表分区的实现的文章就介绍到这了,更多相关MySQL 表分区内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)! 

          0

          精彩评论

          暂无评论...
          验证码 换一张
          取 消

          关注公众号