本文介紹云數據庫 SelectDB 版動態分區相關的概念和示例,幫助您進行分區的動態管理,降低您的使用成本。
概述
在某些場景下,可能會將數據庫表按照天進行分區劃分。如果需要手動管理分區,可能由于沒有創建分區導致數據導入失敗,這給數據庫管理人員帶來了額外的維護成本。通過動態分區功能,可以在建表時設定動態分區規則。云數據庫 SelectDB 版根據指定的規則創建或刪除分區,也可以在運行時對現有規則進行變更,從而進行分區管理。
目前云數據庫SelectDB版動態分區只支持Range分區且實現了動態添加、刪除分區的功能。
創建動態分區表
動態分區的規則可以在建表時指定,或者在運行時進行修改。當前僅支持對單分區列的分區表設定動態分區規則。建表時指定動態分區規則的語法如下。
CREATE TABLE tbl1
(...)
PROPERTIES
(
"dynamic_partition.prop1" = "value1",
"dynamic_partition.prop2" = "value2",
...
)
全局配置項
以下與動態分區相關的配置影響整個SelectDB實例環境。
dynamic_partition_enable
。是否開啟動態分區功能,默認為true。該參數只影響動態分區表的分區操作,不影響普通表。
可以在運行時執行如下命令生效。
ADMIN SET FRONTEND CONFIG ("dynamic_partition_enable" = "true")
若要全局關閉動態分區,則設置此參數為false即可。
dynamic_partition_check_interval_seconds
。動態分區線程的執行頻率,默認為600(10分鐘),即每10分鐘進行一次調度,自動創建動態分區。
可以在運行時執行如下命令修改。
ADMIN SET FRONTEND CONFIG ("dynamic_partition_check_interval_seconds" = "7200")
表配置項
動態分區的規則參數都以dynamic_partition.
為前綴,動態分區相關的配置的詳細說明如下。
參數名稱 | 默認值 | 參數說明 |
dynamic_partition.enable |
| 是否開啟動態分區特性。可指定為
|
dynamic_partition.time_unit | 無 | 動態分區調度的單位。可指定為
|
dynamic_partition.time_zone |
| 動態分區的時區。 |
dynamic_partition.start |
| 動態分區的起始偏移,為負數。根據 |
dynamic_partition.end | 無 | 動態分區的結束偏移,為正數。根據 |
dynamic_partition.prefix | 無 | 動態創建的分區名前綴。 |
dynamic_partition.create_history_partition |
| 創建歷史分區規則。當不指定 |
dynamic_partition.history_partition_num |
| 指定創建歷史分區數量。當 |
dynamic_partition.reserved_history_periods |
| 需要保留的歷史分區的時間范圍。當 |
dynamic_partition.buckets | 無 | 動態創建的分區所對應的分桶數量。 |
dynamic_partition.start_day_of_week |
| 指定每周的起始點。當 |
dynamic_partition.start_day_of_month |
| 指定每月的起始日期。當 |
dynamic_partition.reserved_history_periods相關參數示例如下
例如:按天分類。
設置動態分區的屬性為:
time_unit="DAY/WEEK/MONTH", end=3, start=-3, reserved_history_periods="[2020-06-01,2020-06-20],[2020-10-31,2020-11-15]"
。則系統會自動保留:
["2020-06-01","2020-06-20"],["2020-10-31","2020-11-15"]
設置動態分區的屬性為:
time_unit="HOUR", end=3, start=-3, reserved_history_periods="[2020-06-01 00:00:00,2020-06-01 03:00:00]"
。則系統會自動保留:
["2020-06-01 00:00:00","2020-06-01 03:00:00"]
這兩個時間段的分區。其中,
reserved_history_periods
的每一個[...,...]
是一對設置項,兩者需要同時被設置,且第一個時間不能大于第二個時間。
歷史分區創建規則
當create_history_partition
為TRUE
,即開啟創建歷史分區功能時,SelectDB會根據dynamic_partition.start
和dynamic_partition.history_partition_num
來決定創建歷史分區的個數。
例如:需要創建的歷史分區數量為expect_create_partition_num
,根據不同的設置具體數量如下。
create_history_partition=true
dynamic_partition.history_partition_num
未設置,即-1。則expect_create_partition_num=end-start
;dynamic_partition.history_partition_num
已設置,則expect_create_partition_num=end-Max(start,-history_partition_num)
;
create_history_partition=false
不會創建歷史分區,則expect_create_partition_num=end-0
。
當expect_create_partition_num
大于max_dynamic_partition_num
(默認500)時,禁止創建過多分區。
歷史分區示例
例如:今天是2021-05-20,按天分區,動態分區的屬性設置為:
create_history_partition=true, end=3, start=-3, history_partition_num=1
,則系統會自動創建以下分區。p20210519 p20210520 p20210521 p20210522 p20210523
例如:今天是2021-05-20,按天分區,動態分區的屬性設置為:
create_history_partition=true, end=3, start=-3, history_partition_num=5
,則系統會自動創建以下分區。p20210517 p20210518 p20210519 p20210520 p20210521 p20210522 p20210523
例如:今天是2021-05-20,按天分區,動態分區的屬性設置為:
create_history_partition=true, end=3, start=-3, history_partition_num=-1
,即不設置歷史分區數量,則系統會自動創建以下分區。p20210517 p20210518 p20210519 p20210520 p20210521 p20210522 p20210523
重要動態分區使用過程中,如果因為一些意外情況導致
dynamic_partition.start
和dynamic_partition.end
之間的某些分區丟失,那么當前時間與dynamic_partition.end
之間的丟失分區會被重新創建,dynamic_partition.start
與當前時間之間的丟失分區不會重新創建。
使用示例
表
tbl1
分區列k1類型為DATE,創建一個動態分區規則。按天分區,只保留最近7天的分區,并且預先創建未來3天的分區。CREATE TABLE tbl1 ( k1 DATE, k2 int ) PARTITION BY RANGE(k1) () DISTRIBUTED BY HASH(k1) PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "DAY", "dynamic_partition.start" = "-7", "dynamic_partition.end" = "3", "dynamic_partition.prefix" = "p", "dynamic_partition.create_history_partition" = "true", "dynamic_partition.buckets" = "32" );
例如:當前日期為2020-05-29。則根據以上規則,表
tbl1
會產生以下分區:p20200529: ["2020-05-29", "2020-05-30") p20200530: ["2020-05-30", "2020-05-31") p20200531: ["2020-05-31", "2020-06-01") p20200601: ["2020-06-01", "2020-06-02")
在第二天,即2020-05-30,會創建新的分區
p20200602: ["2020-06-02", "2020-06-03")
在2020-06-06時,因為
dynamic_partition.start
設置為7,則將刪除7天前的分區,即刪除分區p20200529
。表
tbl1
分區列k1類型為DATETIME
,創建一個動態分區規則。按星期分區,只保留最近2個星期的分區,并且預先創建未來2個星期的分區。CREATE TABLE tbl1 ( k1 DATETIME, ... ) PARTITION BY RANGE(k1) () DISTRIBUTED BY HASH(k1) PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "WEEK", "dynamic_partition.start" = "-2", "dynamic_partition.end" = "2", "dynamic_partition.prefix" = "p", "dynamic_partition.create_history_partition" = "true", "dynamic_partition.buckets" = "8" );
例如:當前日期為2020-05-29,是2020年的第22周。默認每周起始為星期一。則基于以上規則,表
tbl1
會產生以下分區:p2020_22: ["2020-05-25 00:00:00", "2020-06-01 00:00:00") p2020_23: ["2020-06-01 00:00:00", "2020-06-08 00:00:00") p2020_24: ["2020-06-08 00:00:00", "2020-06-15 00:00:00")
其中每個分區的起始日期為該周的周一。同時,因為分區列k1的類型為
DATETIME
,則分區值會補全時分秒部分,且皆為0。在2020-06-15,即第25周時,會刪除2周前的分區,即刪除
p2020_22
。在上面的例子中,例如指定了周起始日為
"dynamic_partition.start_day_of_week" = "3"
,即以每周三為起始日。則分區如下:p2020_22: ["2020-05-27 00:00:00", "2020-06-03 00:00:00") p2020_23: ["2020-06-03 00:00:00", "2020-06-10 00:00:00") p2020_24: ["2020-06-10 00:00:00", "2020-06-17 00:00:00")
即分區范圍為當周的周三到下周的周二。
說明2019-12-31 和 2020-01-01 在同一周內,如果分區的起始日期為 2019-12-31,則分區名為
p2019_53
,如果分區的起始日期為 2020-01-01,則分區名為p2020_01
。表
tbl1
分區列k1類型為DATE
,創建一個動態分區規則。按月分區,不刪除歷史分區,并且預先創建未來2個月的分區。同時設定以每月3號為起始日。CREATE TABLE tbl1 ( k1 DATE, ... ) PARTITION BY RANGE(k1) () DISTRIBUTED BY HASH(k1) PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "MONTH", "dynamic_partition.end" = "2", "dynamic_partition.prefix" = "p", "dynamic_partition.create_history_partition" = "true", "dynamic_partition.history_partition_num" = "6", "dynamic_partition.buckets" = "8", "dynamic_partition.start_day_of_month" = "3" );
例如:當前日期為2020-05-29。則基于以上規則,表
tbl1
會產生以下分區:p202005: ["2020-05-03", "2020-06-03") p202006: ["2020-06-03", "2020-07-03") p202007: ["2020-07-03", "2020-08-03")
因為沒有設置
dynamic_partition.start
,則不會刪除歷史分區。例如:今天為2020-05-20,并設置以每月28號為起始日,則分區范圍為:
p202004: ["2020-04-28", "2020-05-28") p202005: ["2020-05-28", "2020-06-28") p202006: ["2020-06-28", "2020-07-28")
修改動態分區屬性
通過如下命令,可以在運行時修改動態分區的屬性。
ALTER TABLE tbl1 SET( "dynamic_partition.prop1" = "value1", ...);
某些屬性的修改可能會產生沖突。假設之前分區粒度為DAY,并且已經創建了如下分區。
p20200519: ["2020-05-19", "2020-05-20")
p20200520: ["2020-05-20", "2020-05-21")
p20200521: ["2020-05-21", "2020-05-22")
如果此時將分區粒度改為MONTH,則系統會嘗試創建范圍為["2020-05-01", "2020-06-01")
的分區,而該分區的分區范圍和已有分區沖突,所以無法創建。而范圍為["2020-06-01", "2020-07-01")
的分區可以正常創建。因此,2020-05-22到2020-05-30時間段的分區,需要自行填補。
刪除動態分區表的分區
刪除動態分區表的分區,要求提前通過如下命令,關閉動態分區屬性。
ALTER TABLE tbl1 SET ("dynamic_partition.enable" = "false");
然后在通過如下命令,刪除某個指定的分區。
ALTER TABLE tbl1 DROP PARTITION p20200519;
通常動態分區表的分區刪除后,需要重新打開動態分區屬性,以便后續業務運行過程中,仍由數倉系統自動管理分區。
ALTER TABLE tbl1 SET ("dynamic_partition.enable" = "true");
查看動態分區表調度情況
通過以下命令可以進一步查看當前數據庫下,所有動態分區表的調度情況。
mysql> SHOW DYNAMIC PARTITION TABLES;
+-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+
| TableName | Enable | TimeUnit | Start | End | Prefix | Buckets | StartOf | LastUpdateTime | LastSchedulerTime | State | LastCreatePartitionMsg | LastDropPartitionMsg | ReservedHistoryPeriods |
+-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+
| d3 | true | WEEK | -3 | 3 | p | 1 | MONDAY | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | [2021-12-01,2021-12-31] |
| d5 | true | DAY | -7 | 3 | p | 32 | N/A | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
| d4 | true | WEEK | -3 | 3 | p | 1 | WEDNESDAY | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
| d6 | true | MONTH | -2147483648 | 2 | p | 8 | 3rd | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
| d2 | true | DAY | -3 | 3 | p | 32 | N/A | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
| d7 | true | MONTH | -2147483648 | 5 | p | 8 | 24th | N/A | 2020-05-25 14:29:24 | NORMAL | N/A | N/A | NULL |
+-----------+--------+----------+-------------+------+--------+---------+-----------+----------------+---------------------+--------+------------------------+----------------------+-------------------------+
7 rows in set (0.02 sec)
LastUpdateTime: 最后一次修改動態分區屬性的時間。
LastSchedulerTime: 最后一次執行動態分區調度的時間。
State: 最后一次執行動態分區調度的狀態。
LastCreatePartitionMsg: 最后一次執行動態添加分區調度的錯誤信息。
LastDropPartitionMsg: 最后一次執行動態刪除分區調度的錯誤信息。
高級操作
對于一個表來說,動態分區和手動分區可以自由轉換,但二者不能同時存在,只能有一種狀態。
手動分區轉換為動態分區
如果一個表在創建時未指定動態分區,可以通過ALTER TABLE
在運行時修改動態分區相關屬性來轉化為動態分區。
開啟動態分區功能后,將不再允許手動管理分區,會根據動態分區屬性來自動管理分區。
如果已設定dynamic_partition.start
,分區范圍在動態分區起始偏移之前的歷史分區將會被刪除。
動態分區轉換為手動分區
通過執行ALTER TABLE tbl_name SET ("dynamic_partition.enable" = "false")
即可關閉動態分區功能,將其轉換為手動分區表。
關閉動態分區功能后,將不再自動管理分區,需要手動通過ALTER TABLE
方式創建或刪除分區。
常見問題
Q:創建動態分區表時提示“Could not create table with dynamic partition when fe config dynamic_partition_enable is false”。
A:由于動態分區的全局開關
dynamic_partition_enable
為false,導致無法創建動態分區表。執行命令ADMIN SET FRONTEND CONFIG ("dynamic_partition_enable" = "true")
將動態分區開關打開即可。Q:關于動態分區的副本設置
A:動態分區是由系統內部的調度邏輯自動創建的。在自動創建分區時,所使用的分區屬性(包括分區的副本數等),都是單獨使用
dynamic_partition
前綴的屬性,而不是使用表的默認屬性。示例如下。CREATE TABLE tbl1 ( `k1` int, `k2` date ) PARTITION BY RANGE(k2)() DISTRIBUTED BY HASH(k1) BUCKETS 3 PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "DAY", "dynamic_partition.start" = "-3", "dynamic_partition.end" = "3", "dynamic_partition.prefix" = "p", "dynamic_partition.create_history_partition" = "true", "dynamic_partition.buckets" = "32" );
上述示例中,沒有創建任何初始分區(PARTITION BY子句中的分區定義為空),并且設置了
DISTRIBUTED BY HASH(k1) BUCKETS 3
和"dynamic_partition.buckets" = "32"
。前一個參數將成為表的默認參數,而后一個參數成為動態分區專用參數。當系統自動創建分區時,會使用分桶數32(即動態分區專用參數),而不是分桶數3。當通過
ALTER TABLE tbl1 ADD PARTITION
語句手動添加分區時,則會使用分桶數3(即表的默認參數)。即動態分區使用一套獨立的參數設置,只有當沒有設置動態分區專用參數時,才會使用表的默認參數。CREATE TABLE tbl3 ( `k1` int, `k2` date ) PARTITION BY RANGE(k2)( PARTITION p1 VALUES LESS THAN ("2019-10-10") ) DISTRIBUTED BY HASH(k1) BUCKETS 3 PROPERTIES ( "dynamic_partition.enable" = "true", "dynamic_partition.time_unit" = "DAY", "dynamic_partition.start" = "-3", "dynamic_partition.end" = "3", "dynamic_partition.prefix" = "p", "dynamic_partition.create_history_partition" = "true", "dynamic_partition.buckets" = "32" );
這個示例中,有一個手動創建的分區p1。這個分區會使用表的默認設置,即分桶數3。而后續系統自動創建的動態分區,依然會使用動態分區專用參數,即分桶數32。?