1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
   | DELIMITER $$ CREATE PROCEDURE `partition_create`(SCHEMANAME varchar(64), TABLENAME varchar(64), PARTITIONNAME varchar(64), CLOCK int) BEGIN         
 
 
 
          
 
 
          DECLARE RETROWS INT;         SELECT COUNT(1) INTO RETROWS         FROM information_schema.partitions         WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND partition_description >= CLOCK;
          IF RETROWS = 0 THEN                 
 
 
 
                  SELECT CONCAT( "partition_create(", SCHEMANAME, ",", TABLENAME, ",", PARTITIONNAME, ",", CLOCK, ")" ) AS msg;                 SET @sql = CONCAT( 'ALTER TABLE ', SCHEMANAME, '.', TABLENAME, ' ADD PARTITION (PARTITION ', PARTITIONNAME, ' VALUES LESS THAN (', CLOCK, '));' );                 PREPARE STMT FROM @sql;                 EXECUTE STMT;                 DEALLOCATE PREPARE STMT;         END IF; END$$ DELIMITER ; DELIMITER $$ CREATE PROCEDURE `partition_drop`(SCHEMANAME VARCHAR(64), TABLENAME VARCHAR(64), DELETE_BELOW_PARTITION_DATE BIGINT) BEGIN         
 
 
 
          DECLARE done INT DEFAULT FALSE;         DECLARE drop_part_name VARCHAR(16);
          
 
 
 
          DECLARE myCursor CURSOR FOR                 SELECT partition_name                 FROM information_schema.partitions                 WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND CAST(SUBSTRING(partition_name FROM 2) AS UNSIGNED) < DELETE_BELOW_PARTITION_DATE;         DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
          
 
 
 
          SET @alter_header = CONCAT("ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " DROP PARTITION ");         SET @drop_partitions = "";
          
 
          OPEN myCursor;         read_loop: LOOP                 FETCH myCursor INTO drop_part_name;                 IF done THEN                         LEAVE read_loop;                 END IF;                 SET @drop_partitions = IF(@drop_partitions = "", drop_part_name, CONCAT(@drop_partitions, ",", drop_part_name));         END LOOP;         IF @drop_partitions != "" THEN                 
 
 
 
                  SET @full_sql = CONCAT(@alter_header, @drop_partitions, ";");                 PREPARE STMT FROM @full_sql;                 EXECUTE STMT;                 DEALLOCATE PREPARE STMT;
                  SELECT CONCAT(SCHEMANAME, ".", TABLENAME) AS `table`, @drop_partitions AS `partitions_deleted`;         ELSE                 
 
 
                  SELECT CONCAT(SCHEMANAME, ".", TABLENAME) AS `table`, "N/A" AS `partitions_deleted`;         END IF; END$$ DELIMITER ; DELIMITER $$ CREATE PROCEDURE `partition_maintenance`(SCHEMA_NAME VARCHAR(32), TABLE_NAME VARCHAR(32), KEEP_DATA_DAYS INT, HOURLY_INTERVAL INT, CREATE_NEXT_INTERVALS INT) BEGIN         DECLARE OLDER_THAN_PARTITION_DATE VARCHAR(16);         DECLARE PARTITION_NAME VARCHAR(16);         DECLARE OLD_PARTITION_NAME VARCHAR(16);         DECLARE LESS_THAN_TIMESTAMP INT;         DECLARE CUR_TIME INT;
          CALL partition_verify(SCHEMA_NAME, TABLE_NAME, HOURLY_INTERVAL);         SET CUR_TIME = UNIX_TIMESTAMP(DATE_FORMAT(NOW(), '%Y-%m-%d 00:00:00'));
          SET @__interval = 1;         create_loop: LOOP                 IF @__interval > CREATE_NEXT_INTERVALS THEN                         LEAVE create_loop;                 END IF;
                  SET LESS_THAN_TIMESTAMP = CUR_TIME + (HOURLY_INTERVAL * @__interval * 3600);                 SET PARTITION_NAME = FROM_UNIXTIME(CUR_TIME + HOURLY_INTERVAL * (@__interval - 1) * 3600, 'p%Y%m%d%H00');                 IF(PARTITION_NAME != OLD_PARTITION_NAME) THEN                         CALL partition_create(SCHEMA_NAME, TABLE_NAME, PARTITION_NAME, LESS_THAN_TIMESTAMP);                 END IF;                 SET @__interval=@__interval+1;                 SET OLD_PARTITION_NAME = PARTITION_NAME;         END LOOP;
          SET OLDER_THAN_PARTITION_DATE=DATE_FORMAT(DATE_SUB(NOW(), INTERVAL KEEP_DATA_DAYS DAY), '%Y%m%d0000');         CALL partition_drop(SCHEMA_NAME, TABLE_NAME, OLDER_THAN_PARTITION_DATE);
  END$$ DELIMITER ; DELIMITER $$ CREATE PROCEDURE `partition_verify`(SCHEMANAME VARCHAR(64), TABLENAME VARCHAR(64), HOURLYINTERVAL INT(11)) BEGIN         DECLARE PARTITION_NAME VARCHAR(16);         DECLARE RETROWS INT(11);         DECLARE FUTURE_TIMESTAMP TIMESTAMP;
          
 
          SELECT COUNT(1) INTO RETROWS         FROM information_schema.partitions         WHERE table_schema = SCHEMANAME AND table_name = TABLENAME AND partition_name IS NULL;
          
 
          IF RETROWS = 1 THEN                 
 
 
 
 
                  SET FUTURE_TIMESTAMP = TIMESTAMPADD(HOUR, HOURLYINTERVAL, CONCAT(CURDATE(), " ", '00:00:00'));                 SET PARTITION_NAME = DATE_FORMAT(CURDATE(), 'p%Y%m%d%H00');
                                   SET @__PARTITION_SQL = CONCAT("ALTER TABLE ", SCHEMANAME, ".", TABLENAME, " PARTITION BY RANGE(`clock`)");                 SET @__PARTITION_SQL = CONCAT(@__PARTITION_SQL, "(PARTITION ", PARTITION_NAME, " VALUES LESS THAN (", UNIX_TIMESTAMP(FUTURE_TIMESTAMP), "));");
                                   PREPARE STMT FROM @__PARTITION_SQL;                 EXECUTE STMT;                 DEALLOCATE PREPARE STMT;         END IF; END$$ DELIMITER ;
  DELIMITER $$ CREATE PROCEDURE`partition_maintenance_all`(SCHEMA_NAME VARCHAR(32)) BEGIN                CALL partition_maintenance(SCHEMA_NAME, 'history', 30, 24, 14);                CALL partition_maintenance(SCHEMA_NAME, 'history_log', 30, 24, 14);                CALL partition_maintenance(SCHEMA_NAME, 'history_str', 30, 24, 14);                CALL partition_maintenance(SCHEMA_NAME, 'history_text', 30, 24, 14);                CALL partition_maintenance(SCHEMA_NAME, 'history_uint', 30, 24, 14);                CALL partition_maintenance(SCHEMA_NAME, 'trends', 120, 24, 14);                CALL partition_maintenance(SCHEMA_NAME, 'trends_uint', 120, 24, 14); END$$ DELIMITER ;%
   |