本文介紹ApsaraDB for SelectDB動態分區相關的概念和樣本,協助您進行分區的動態管理,降低您的使用成本。
概述
在某些情境下,可能會將資料庫表按照天進行分區劃分。如果需要手動管理分區,可能由於沒有建立分區導致資料匯入失敗,這給資料庫管理員帶來了額外的維護成本。通過動態資料分割函數,可以在建表時設定動態分區規則。ApsaraDB for 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=truedynamic_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。