Rotate archive partitions

Developed In: SQL — Contributed by: Gregory Haase

script to illustrate article by Greg Haase "Using Partitioning and Event Scheduler to Prune Archive Tables"


Gregory Haase
SQL
  1. DELIMITER $$
  2.  
  3. DROP PROCEDURE IF EXISTS `db_stats`.`rotate_archive_partitions`$$
  4. CREATE PROCEDURE `db_stats`.`rotate_archive_partitions`(IN p_retention_days INT)
  5. BEGIN
  6. /*
  7.   * Script to archive table partitions. Creates new partitions and drops old ones
  8.   * We select from information schema, and use a whole lot of dynamic sql.
  9.   */
  10.  
  11. DECLARE l_cutoff_date BIGINT(20);
  12. DECLARE l_table_name VARCHAR(100);
  13. DECLARE l_new_partitions VARCHAR(200);
  14. DECLARE l_old_partitions VARCHAR(100);
  15. DECLARE sql_make_partitions VARCHAR(1000);
  16. DECLARE sql_drop_partitions VARCHAR(1000);
  17.  
  18. DECLARE done INT DEFAULT 0;
  19. DECLARE c_table_name CURSOR FOR SELECT a.table_name
  20. FROM information_schema.TABLES a,
  21. information_schema.COLUMNS b
  22. WHERE a.table_name = b.table_name
  23. AND a.engine = 'archive'
  24. AND b.column_name = 'date_string';
  25. DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
  26.  
  27. -- if p_retention_days is null, we keep 7 days
  28. IF (p_retention_days IS NULL) THEN
  29. SET p_retention_days = 7;
  30. END IF;
  31.  
  32. -- get the cutoff date - this is p_retention_days from midnight
  33. SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL p_retention_days DAY),'%Y%m%d')
  34. INTO l_cutoff_date;
  35.  
  36. -- temporary table holds potential new partition names (date_string) and values less than clause (date_limit)
  37. DROP TEMPORARY TABLE IF EXISTS `db_stats`.`tmp_partition_days`;
  38. CREATE TEMPORARY TABLE `db_stats`.`tmp_partition_days` AS
  39. SELECT DATE_FORMAT(CURDATE(),'%Y%m%d') date_string,
  40. CONCAT(DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 DAY),'%Y%m%d'),'0000') date_limit
  41. UNION
  42. SELECT DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 DAY),'%Y%m%d') date_string,
  43. CONCAT(DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 2 DAY),'%Y%m%d'),'0000') date_limit
  44. UNION
  45. SELECT DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 2 DAY),'%Y%m%d') date_string,
  46. CONCAT(DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 3 DAY),'%Y%m%d'),'0000') date_limit
  47. UNION
  48. SELECT DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 3 DAY),'%Y%m%d') date_string,
  49. CONCAT(DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 4 DAY),'%Y%m%d'),'0000') date_limit;
  50.  
  51. -- open cursor
  52. OPEN c_table_name;
  53. REPEAT
  54. FETCH c_table_name INTO l_table_name;
  55. IF NOT done THEN
  56.  
  57. SELECT NULL INTO l_new_partitions;
  58.  
  59. -- generate list of new partitions to create
  60. SELECT GROUP_CONCAT(CONCAT('PARTITION p',a.date_string,' VALUES LESS THAN (',a.date_limit,')'))
  61. INTO l_new_partitions
  62. FROM tmp_partition_days a
  63. WHERE a.date_string NOT IN (SELECT RIGHT(partition_name,8)
  64. FROM information_schema.partitions
  65. WHERE table_name = l_table_name)
  66. ORDER BY a.date_string ASC;
  67.  
  68. IF (l_new_partitions IS NOT NULL) THEN
  69.  
  70. -- create new partitions by reorganizing the last partition (always pEOW)
  71. SET sql_make_partitions = CONCAT('ALTER TABLE `',l_table_name,'` REORGANIZE PARTITION pEOW INTO (',l_new_partitions,', PARTITION pEOW VALUES LESS THAN MAXVALUE)');
  72. SET @sqlstatement = sql_make_partitions;
  73. PREPARE sqlquery FROM @sqlstatement;
  74. EXECUTE sqlquery;
  75. DEALLOCATE PREPARE sqlquery;
  76.  
  77. END IF;
  78.  
  79.  
  80. -- find and drop partitions older than p_retention_days
  81. SELECT GROUP_CONCAT(partition_name)
  82. INTO l_old_partitions
  83. FROM information_schema.partitions
  84. WHERE RIGHT(partition_name,8) < l_cutoff_date
  85. AND partition_name <> 'pEOW'
  86. AND table_name = l_table_name;
  87.  
  88. IF (l_old_partitions IS NOT NULL) THEN
  89.  
  90. SET sql_drop_partitions = CONCAT('ALTER TABLE `',l_table_name,'` DROP PARTITION ',l_old_partitions);
  91. SET @sqlstatement = sql_drop_partitions;
  92. PREPARE sqlquery FROM @sqlstatement;
  93. EXECUTE sqlquery;
  94. DEALLOCATE PREPARE sqlquery;
  95.  
  96. END IF;
  97.  
  98. -- close cursor
  99. END IF;
  100. UNTIL done END REPEAT;
  101. CLOSE c_table_name;
  102.  
  103. END $$
  104.  
  105. DROP EVENT IF EXISTS `db_stats`.`e_rotate_archive_partitions`$$
  106. CREATE EVENT `db_stats`.`e_rotate_archive_partitions`
  107. ON SCHEDULE
  108. EVERY 1 DAY
  109. STARTS curdate() + INTERVAL '8:07' HOUR_MINUTE
  110. DO
  111. call db_stats.rotate_archive_partitions(7)$$
  112.  
  113.  
  114. DELIMITER ;
  115.  

You must be logged in to tag this tool

A stored procedure to show all grants in the database. Get Diploma AND Online accredited High School AND Home school online

This article shows the simplest setup of a MySQL cluster. No whistles and bells, just to get started. Online High School AND Get a GED Online

Votes

  • Rated 5.00 out of 5
Rated 5.00 out of 5 with 1 votes cast.
You must be logged in to vote.

Watches

2 members are watching this tool
You must be logged in to track this tool.

Provide Feedback

Please note:
HTML will be purified, but we allow for a number of HTML tags so that you have the flexibility to decorate your comment text to some extent. The comments allow the following HTML tags:

strong, b, em, blockquote, a, code, pre

To put code into your comment, simply encapsulate your code with
[code language="XXX"][/code], where XXX is any common language, for instance "PHP", "SQL", "C", etc.



You must be logged in to comment