1. 程式人生 > 其它 >mysql partitions by range auto (mysql 自動建立按年月的表分割槽)

mysql partitions by range auto (mysql 自動建立按年月的表分割槽)

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

CREATE TABLE`test`(`id`bigint(20)unsignedNOT NULL AUTO_INCREMENT COMMENT'主鍵',`datetime`int(10)unsignedNOT NULL DEFAULT'0'COMMENT'時間',PRIMARY KEY(`id`,`datetime`))ENGINE=InnoDBDEFAULT 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))BEGINDECLARE 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+INTERVAL1DAY+INTERVAL1MONTH);SET PARTITIONNAME=DATE_FORMAT(BEGINTIME,'p%Y%m');SET ENDTIME=UNIX_TIMESTAMP(BEGINTIME+INTERVAL1MONTH);SET ENDTIME_DATETIME=FROM_UNIXTIME(ENDTIME);SELECT COUNT(*)INTO ROWS_CNT FROM information_schema.partitionsWHERE table_schema=IN_SCHEMANAME AND table_name=IN_TABLENAME AND partition_name=PARTITIONNAME;IF ROWS_CNT=0THEN

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;ELSESELECT CONCAT("partition `",PARTITIONNAME,"` for table `",IN_SCHEMANAME,".",IN_TABLENAME,"` already exists")AS result;ENDIF;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 EVERY1MINUTE#執行週期,還有天、月等等STARTS'2016-01-07 18:27:00'ON COMPLETION PRESERVEENABLECOMMENT'Creating partitions'DOBEGIN

#呼叫剛才建立的儲存過程,第一個引數是資料庫名稱,第二個引數是表名稱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 PARTITIONSselect*,FROM_UNIXTIME(datetime)fromtestwheredatetime>UNIX_TIMESTAMP("2015-12-10")anddatetime<UNIX_TIMESTAMP("2015-12-15");