mysql partitions by range auto (mysql 自動創建按年月的表分區)


環境:mysql 5.5
第一:怎么創建表分區
第二:怎么按年月格式(201601)自動創建分區
 
1、創建表,時間字段datetime由於業務需要必須要是unix_timestamp, 由於是按照時間來進行分區的,所以datetime這個字段必須要是主鍵。否則創建分區的時候會報錯。
 
           

CREATE TABLE `test` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵', `datetime` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '時間', PRIMARY KEY (`id`,`datetime`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='測試表分區'/*!50100 PARTITION BY RANGE (datetime)(PARTITION p201511 VALUES LESS THAN (UNIX_TIMESTAMP("2015-12-01 00:00:00")) ENGINE = InnoDB, PARTITION p201512 VALUES LESS THAN (UNIX_TIMESTAMP("2016-01-01 00:00:00")) ENGINE = InnoDB) */;

2、創建存儲過程,用於下面MYSQL的event定時器調用,自動創建就是event來完成的。這段存儲過程的內容就是創建下月分區的意思。
 
           

DELIMITER $$

#該表所在數據庫名稱USE `test`$$DROP PROCEDURE IF EXISTS `create_partition_by_month`$$CREATE PROCEDURE `create_partition_by_month`(IN_SCHEMANAME VARCHAR(64), IN_TABLENAME VARCHAR(64))BEGIN DECLARE ROWS_CNT INT UNSIGNED; DECLARE BEGINTIME TIMESTAMP; DECLARE ENDTIME INT UNSIGNED; DECLARE PARTITIONNAME VARCHAR(16); DECLARE ENDTIME_DATETIME VARCHAR(30); SET BEGINTIME = DATE(NOW() - INTERVAL DAY(NOW()) DAY + INTERVAL 1 DAY + INTERVAL 1 MONTH); SET PARTITIONNAME = DATE_FORMAT( BEGINTIME, 'p%Y%m' ); SET ENDTIME = UNIX_TIMESTAMP(BEGINTIME + INTERVAL 1 MONTH); SET ENDTIME_DATETIME = FROM_UNIXTIME(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 (UNIX_TIMESTAMP('", 

ENDTIME_DATETIME ,"')) ENGINE = InnoDB);" );

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 ;

2.1查看已經創建的存儲過程。
show procedure status where db='logtop';
 
3、創建event。每分鍾執行一次,檢查下個月的表分區是否已經創建,如果沒有創建,則調用上面的存儲過程創建。
 
           

DELIMITER $$

#該表所在的數據庫名稱USE `test`$$CREATE EVENT IF NOT EXISTS `e_part_manage`ON SCHEDULE EVERY 1 MINUTE #執行周期,還有天、月等等STARTS '2016-01-07 18:27:00'ON COMPLETION PRESERVEENABLECOMMENT 'Creating partitions'DO BEGIN

#調用剛才創建的存儲過程,第一個參數是數據庫名稱,第二個參數是表名稱 CALL test.create_partition_by_month('test','test');END$$DELIMITER ;

3.1查看已經創建的event
 
           

SELECT * FROM information_schema.EVENTS;

4、檢查MYSQL是否開啟event,默認是Off,請設置成On,
 
            
SHOW VARIABLES LIKE 'event_scheduler' ;
SHOW GLOBAL VARIABLES LIKE 'event_scheduler' ;
SET GLOBAL event_scheduler = ON; #打開
只在全局設置的話,當MYSQL重啟后該參數又會被重置成Off,所以需要在my.cnf里加上
 
            

vim /etc/my.cnf

[mysqld]

event_scheduler=ON

5、插入測試數據
 
            

INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-10"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-11"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-12"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-13"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-13"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-14"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-15"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-16"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-17"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-18"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-19"));INSERT INTO `test`.`test` (`datetime`) VALUES (unix_timestamp("2015-12-20"));

6、查看數據在每個分區中的分布情況
 
            

SELECT PARTITION_NAME, TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='test';

 
 
            

#添加分區

ALTER TABLE `test`.`test` ADD PARTITION (PARTITION p201601 VALUES LESS THAN (UNIX_TIMESTAMP("2016-02-01 00:00:00")) ENGINE = InnoDB);

#刪除分區ALTER TABLE test.testDROP PARTITION p201511;

查看查詢SQL是否使用的分區
 
            

explain PARTITIONS select *,FROM_UNIXTIME(datetime) from test where datetime > UNIX_TIMESTAMP("2015-12-10") and datetime < UNIX_TIMESTAMP("2015-12-15");

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM