• mysql 分区处理数据


    记录一下分区代码:

    1.建立存储过程,将原表按照时间转化为分区表,并建立当天分区

    #alter table to partition table
    DELIMITER $$
    USE `dc_log`$$
    DROP PROCEDURE IF EXISTS `create_partition_today`$$
    CREATE PROCEDURE `create_partition_today`(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64))
      BEGIN
        DECLARE BEGINTIME TIMESTAMP;
        DECLARE ENDTIME TIMESTAMP;
        DECLARE DAYS_ENDTIME INT;
        DECLARE PARTITIONNAME VARCHAR(16);
        SET BEGINTIME = NOW();
        SET ENDTIME = BEGINTIME + INTERVAL 1 DAY;
        SET PARTITIONNAME = DATE_FORMAT(BEGINTIME, 'p%Y%m%d');
        SET DAYS_ENDTIME = TO_DAYS(ENDTIME);
        SET @SQL = CONCAT('ALTER TABLE `', IN_SCHEMANAME, '`.`', IN_TABLENAME, '`',
                            ' PARTITION BY RANGE (to_days(create_time))
        (PARTITION ', PARTITIONNAME, ' VALUES LESS THAN (', DAYS_ENDTIME, '))');
        PREPARE STMT FROM @SQL;
        EXECUTE STMT;
        DEALLOCATE PREPARE STMT;
      END$$
    DELIMITER ;

    2.建立存储过程,负责检查第二天的分区是否存在,如果不存在则建立

    #procedure of build partition of today and next day
    DELIMITER $$
    USE `dc_log`$$
    DROP PROCEDURE IF EXISTS `create_partition_by_day`$$
    CREATE PROCEDURE `create_partition_by_day`(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64))
      BEGIN
        DECLARE ROWS_CNT INT UNSIGNED;
        DECLARE BEGINTIME TIMESTAMP;
        DECLARE ENDTIME TIMESTAMP;
        DECLARE DAYS_ENDTIME INT;
        DECLARE PARTITIONNAME VARCHAR(16);
        SET BEGINTIME = NOW() + INTERVAL 1 DAY;
        SET PARTITIONNAME = DATE_FORMAT(BEGINTIME, 'p%Y%m%d');
        SET ENDTIME = BEGINTIME + INTERVAL 1 DAY;
        SET DAYS_ENDTIME = TO_DAYS(ENDTIME);
        SELECT COUNT(*)
        INTO ROWS_CNT
        FROM information_schema.partitions
        WHERE table_schema = IN_SCHEMANAME AND table_name = IN_TABLENAME AND partition_name = PARTITIONNAME;
        IF ROWS_CNT = 0
        THEN
          SET @SQL = CONCAT('ALTER TABLE `', IN_SCHEMANAME, '`.`', IN_TABLENAME, '`',
                            ' ADD PARTITION (PARTITION ', PARTITIONNAME, ' VALUES LESS THAN (', DAYS_ENDTIME, '))');
          PREPARE STMT FROM @SQL;
          EXECUTE STMT;
          DEALLOCATE PREPARE STMT;
        ELSE
          SELECT CONCAT("partition `", PARTITIONNAME, "` for table `", IN_SCHEMANAME, ".", IN_TABLENAME,
                        "` already exists") AS result;
        END IF;
      END$$
    DELIMITER ;

    3.为了避免数据无限量扩大,建立存储过程,负责清除30天前的分区表数据

    DELIMITER $$
    USE `dc_log`$$
    DROP PROCEDURE IF EXISTS `clear_partition_by_day`$$
    CREATE PROCEDURE `clear_partition_by_day`(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64))
      BEGIN
        DECLARE NOWDAYS INT;
        DECLARE Done INT;
        DECLARE part VARCHAR(64);
        DECLARE descr INT;
        DECLARE rs CURSOR FOR SELECT
                                partition_name        part,
                                partition_description descr
                              FROM information_schema.partitions
                              WHERE
                                table_schema = IN_SCHEMANAME
                                AND table_name = IN_TABLENAME;
        /* 异常处理 */
        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET Done = 1;
        OPEN rs;
        SET NOWDAYS = TO_DAYS(NOW());
        FETCH rs into part,descr;
        while Done is null DO
          IF NOWDAYS - descr > 30
            THEN
              select descr AS cc;
              SET @SQL = CONCAT('ALTER TABLE `', IN_SCHEMANAME, '`.`', IN_TABLENAME, '`',
                                ' DROP PARTITION ', part);
              select descr AS aa;
              SELECT @SQL AS result;
              select descr AS bb;
              PREPARE STMT FROM @SQL;
              EXECUTE STMT;
              DEALLOCATE PREPARE STMT;
            END IF;
          FETCH rs into part,descr;
        end WHILE;
        CLOSE rs;
      END$$
    DELIMITER ;

    4.这时候创建两个事件,负责按周期去执行建立分区和删除分区

    #invoke event to create future partitions
    #hour event of checking partition existed or not(invoke procedure every day)
    DELIMITER $$
    USE `dc_log`$$
    CREATE EVENT IF NOT EXISTS `e_part_manage`
      ON SCHEDULE EVERY 1 HOUR #every minute
      STARTS '2018-05-01 18:27:00'
      ON COMPLETION PRESERVE
    ENABLE
      COMMENT 'Creating partitions'
    DO BEGIN
      CALL dc_log.create_partition_by_day('dc_log', 'business_log');
    END$$
    DELIMITER ;
    #event of clear data which out of date of 30 days
    DELIMITER $$
    USE `dc_log`$$
    CREATE EVENT IF NOT EXISTS `clear_data`
      ON SCHEDULE EVERY 1 DAY #every minute
      STARTS '2018-05-01 18:27:30'
      ON COMPLETION PRESERVE
    ENABLE
      COMMENT 'clearing data'
    DO BEGIN
      CALL clear_partition_by_day('dc_log', 'business_log');
    END$$
    DELIMITER ;

    5.如果事件没有运行,则可能是事件开关未开启

    #turn event_scheduler on
    SET GLOBAL event_scheduler = 'ON'; #打开

    6.加入另外一张表操作,修改事件内容

    #service_push #same steps of table business_log
    ALTER TABLE dc_system.service_push DROP PRIMARY KEY;
    CALL create_partition_today('dc_system', 'service_push');
    ALTER EVENT e_part_manage
    DO BEGIN
      CALL dc_log.create_partition_by_day('dc_log', 'business_log');
      CALL dc_log.create_partition_by_day('dc_system', 'service_push');
    END ;
    ALTER EVENT clear_data
    DO BEGIN
      CALL dc_log.clear_partition_by_day('dc_log', 'business_log');
      CALL dc_log.clear_partition_by_day('dc_system', 'service_push');
    END ;

    done

  • 相关阅读:
    java RSA 加签验签【转】
    json遍历 分别使用【原】
    oracle 递归和connect by【转】
    css before after基本用法【转】
    Java Web基础——Action+Service +Dao三层的功能划分
    JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分
    UUID
    在ssh框架中service-action-jsp-formbeam-dao的调用顺序
    Singleton模式(单例模式)
    真正理解、区分Action,Service和Dao功能
  • 原文地址:https://www.cnblogs.com/garfieldcgf/p/8999932.html
Copyright © 2020-2023  润新知