全部產品
Search
文件中心

ApsaraDB for SelectDB:動態分區

更新時間:Jul 06, 2024

本文介紹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

TRUE

是否開啟動態分區特性。可指定為TRUEFALSE

  • TRUE:開啟動態分區。

  • FALSE:則會忽略該表的動態分區規則。

dynamic_partition.time_unit

動態分區調度的單位。可指定為HOURDAYWEEKMONTH

  • HOUR表示按小時建立或刪除分區,動態建立的分區名尾碼格式為yyyyMMddHH,例如2020032501。小時為單位的分區列資料類型不能為 DATE。

  • DAY表示按天時建立或刪除分區,動態建立的分區名尾碼格式為yyyyMMdd,例如20200325

  • WEEK表示按星期建立或刪除分區,動態建立的分區名尾碼格式為yyyy_ww。即當前日期屬於這一年的第幾周,例如2020-03-25建立的分區名尾碼為2020_13, 表明目前為2020年第13周。

  • MONTH表示按月建立或刪除分區,動態建立的分區名尾碼格式為yyyyMM,例如202003

dynamic_partition.time_zone

Asia/Shanghai

動態分區的時區。

dynamic_partition.start

-2147483648

動態分區的起始位移,為負數。根據time_unit屬性的不同,以當天(星期/月)為基準,分區範圍在此位移之前的分區將會被刪除。預設值即不刪除歷史分區。

dynamic_partition.end

動態分區的結束位移,為正數。根據time_unit屬性的不同,以當天(星期/月)為基準,提前建立對應範圍的分區。

dynamic_partition.prefix

動態建立的分區名首碼。

dynamic_partition.create_history_partition

false

建立歷史分區規則。當不指定dynamic_partition.start屬性時,該參數不生效。當置為true時,會自動建立所有分區,具體建立規則見下文歷史分區建立規則。同時,FE的參數max_dynamic_partition_num會限制總分區數量,以避免一次性建立過多分區。當期望建立的分區個數大於max_dynamic_partition_num值時,操作將被禁止。

dynamic_partition.history_partition_num

-1

指定建立歷史分區數量。當create_history_partitiontrue時,該參數用於指定建立歷史分區數量。預設值即表時未設定。

dynamic_partition.reserved_history_periods

"NULL"

需要保留的歷史分區的時間範圍。當dynamic_partition.time_unit設定為 "DAY/WEEK/MONTH" 時,需要以[yyyy-MM-dd,yyyy-MM-dd],[...,...]格式進行設定。當dynamic_partition.time_unit設定為 "HOUR" 時,需要以[yyyy-MM-dd HH:mm:ss,yyyy-MM-dd HH:mm:ss],[...,...]的格式來進行設定。

dynamic_partition.buckets

動態建立的分區所對應的分桶數量。

dynamic_partition.start_day_of_week

1

指定每周的起始點。當time_unitWEEK時,該參數用於指定每周的起始點。取值為1到7。其中1表示周一,7表示周日。預設值即表示每周以周一為起始點。

dynamic_partition.start_day_of_month

1

指定每月的起始日期。當time_unitMONTH時,該參數用於指定每月的起始日期。取值為1到 28。其中1表示每月1號,28表示每月28號。暫不支援以29、30、31號為起始日,以避免因閏年或閏月帶來的歧義。預設值即表示每月以1號位起始點。

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_partitionTRUE,即開啟建立歷史資料分割函數時,SelectDB會根據dynamic_partition.startdynamic_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)時,禁止建立過多分區。

歷史分區樣本

  1. 例如:今天是2021-05-20,按天分區,動態分區的屬性設定為:create_history_partition=true, end=3, start=-3, history_partition_num=1,則系統會自動建立以下分區。

    p20210519
    p20210520
    p20210521
    p20210522
    p20210523
  2. 例如:今天是2021-05-20,按天分區,動態分區的屬性設定為:create_history_partition=true, end=3, start=-3, history_partition_num=5,則系統會自動建立以下分區。

    p20210517
    p20210518
    p20210519
    p20210520
    p20210521
    p20210522
    p20210523
  3. 例如:今天是2021-05-20,按天分區,動態分區的屬性設定為:create_history_partition=true, end=3, start=-3, history_partition_num=-1即不設定歷史分區數量,則系統會自動建立以下分區。

    p20210517
    p20210518
    p20210519
    p20210520
    p20210521
    p20210522
    p20210523
    重要

    動態分區使用過程中,如果因為一些意外情況導致dynamic_partition.startdynamic_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。