全部產品
Search
文件中心

AnalyticDB:資料存放區冷熱分層

更新時間:Apr 09, 2025

雲原生資料倉儲AnalyticDB PostgreSQL版支援冷熱階層式存放區,可以將訪問頻次低的熱錶轉換為冷表格儲存體到OSS中,以降低儲存成本。本文介紹資料存放區冷熱分層的使用限制和使用方法。

說明

本文中將儲存在本地磁碟的資料表稱為熱表,將儲存在遠端OSS的資料表稱為冷表。

版本限制

  • 核心版本為6.3.11.1及以上的AnalyticDB for PostgreSQL6.0版執行個體。

  • 核心版本為7.0.3.0及以上的AnalyticDB for PostgreSQL7.0版執行個體。

說明

您可以在控制台執行個體的基本資料頁查看核心小版本。如不滿足上述版本要求,需要您升級核心小版本

使用限制

  • 不支援Serverless模式。

  • AnalyticDB PostgreSQL 6.0版AnalyticDB PostgreSQL 7.0版執行個體的資料存放區冷熱分層使用限制略有差異,請根據執行個體版本查看對應的限制。

    6.0版執行個體

    • 支援將非分區錶轉為冷表。

    • 支援將分區錶轉為冷表或部分子分區轉為冷分區。

    • 已建立索引的分區表,其子分區暫不支援轉為冷分區。包含冷分區的分區表也不支援建立索引。

    • 熱錶轉為冷表後,原表上關聯的主鍵、索引、序列、rule、注釋等將被自動刪除,且無法找回。

    • 冷表或者冷分區的資料處於唯讀狀態,不支援修改(寫入、刪除、更新),或者任何DDL操作(ALTER COLUMNDROP COLUMN等)。冷表支援被刪除(DROP TABLE)。

    • AnalyticDB for PostgreSQL暫不支援將冷表或者冷分區直接轉熱。您可以通過CREATE TABLE AS SELECT建立熱表並將冷表的資料移轉至該熱表。

    7.0版執行個體

    • 支援將非分區錶轉為冷表。

    • 支援將分區錶轉為冷表或部分子分區轉為冷分區。

    • 冷表或者冷分區允許讀取和寫入操作,不支援刪除和更新操作。冷表的DDL操作(ALTER COLUMNDROP COLUMN等)目前處於邀測階段,如有需要請提交工單聯絡支援人員。

    • 包含主鍵或者已建立唯一索引的分區表,其子分區暫不支援轉為冷分區。包含普通索引的分區表則不受限制,其子分區可以轉化為冷分區。

    • 熱錶轉為冷表後,原表上關聯的主鍵、索引、序列、rule、注釋等將被自動刪除,且無法找回。

    • AnalyticDB for PostgreSQL暫不支援將冷表或者冷分區直接轉熱。您可以通過CREATE TABLE AS SELECT建立熱表並將冷表的資料移轉至該熱表。

冷儲存計費

熱錶轉為冷表後資料存放區在遠端OSS,會產生儲存費用,計費規則如下:

  • 冷儲存採取隨用隨付方式。

  • 每5分鐘採集更新冷存使用量,小時級出賬。

  • 價格和OSS的標準儲存價格一致,請參見OSS產品定價

    以中國內地地區為例,OSS定價為0.017美元/GB/月,每小時的定價則為0.0000236111美元/GB,實際價格以賬單頁面為準。

您可在賬單詳情 > 明細賬單中查看冷儲存的計費賬單詳情。

使用方法

重要
  • 遷移到冷表的過程中會有建立暫存資料表並寫入資料,以及將資料上傳至OSS的過程,會存在一定的本地I/O和網路I/O,可能對執行個體中已經啟動並執行查詢產生一定的效能影響,使用時請注意對業務的影響。

  • 熱錶轉為冷表後其佔用的本地磁碟空間會被釋放。

  • AnalyticDB PostgreSQL 6.0版執行個體,系統會在設定的轉冷時間點開始調度,轉冷過程中調度和排隊會有一定耗時,AnalyticDB PostgreSQL 7.0版執行個體無需調度,在執行轉冷語句後立即轉冷。具體需要的轉冷時間與執行個體規格、同時上傳的表數量和表的資料量有關。詳情請參見效能資料

AnalyticDB PostgreSQL 6.0版AnalyticDB PostgreSQL 7.0版執行個體的資料存放區冷熱分層使用方法不同,請根據執行個體版本選擇對應的文法操作。

6.0版執行個體

普通表整錶轉冷

文法

ALTER TABLE <tableName> SET ttl interval '<scheduling_interval>' move to storage_cold;

樣本

建立一個普通表tiered_storage_heap並寫入資料。

CREATE TABLE tiered_storage_heap (a int, b int);
INSERT INTO tiered_storage_heap SELECT random() * 1000,1 FROM generate_series(1,1000);
  • 樣本一:指定三天后(3days)將普通表tiered_storage_heap轉冷。例如,2023年07月17日09:00:00執行ALTER TABLE操作,那麼三天后(2023年07月20日09:00:00)會將tiered_storage_heap整錶轉冷。

    ALTER TABLE tiered_storage_heap SET ttl interval '3days' move to storage_cold;
  • 樣本二:指定任意時間點(2023年07月28日 16:53:58)將普通表tiered_storage_heap轉冷。

    ALTER TABLE tiered_storage_heap SET ttl '2023-07-28 16:53:58'::Timestamp move to storage_cold;
  • 樣本三:將轉冷時間點設為過去的時間點,可以立刻對錶進行轉冷。

    • 指定轉冷時間點為三天前(-3days)。執行如下命令,對錶立刻轉冷。

      ALTER TABLE tiered_storage_heap SET ttl interval '-3days' move to storage_cold;
    • 指定過去的具體時間點。若目前時間為2023年07月17日16:53:58,您可以執行如下命令,對錶立刻轉冷。

      ALTER TABLE tiered_storage_heap SET ttl '2022-07-16 16:53:58'::Timestamp move to storage_cold;

分區表按子分區轉冷

文法

ALTER TABLE <分區子表名> SET ttl interval '<scheduling_interval>' move to storage_cold;

您可以使用psql執行\d+查看具體分區表的子表名。

樣本

建立一個分區表tiered_storage_partition_hdfs

CREATE TABLE tiered_storage_partition_hdfs(a int,b int) distributed by (a) partition by range(a) (start(1) end(20) every(10));
說明

本樣本會產生2個分區子表tiered_storage_partition_hdfs_1_prt_1tiered_storage_partition_hdfs_1_prt_2

向分區子表tiered_storage_partition_hdfs_1_prt_1中寫入資料。

INSERT INTO tiered_storage_partition_hdfs_1_prt_1 values(1, 1), (2, 2), (3, 3), (4, 4);

指定三天后將分區子表tiered_storage_partition_hdfs_1_prt_1轉冷。例如,2023年07月17日09:00:00執行ALTER TABLE操作,那麼三天后(2023年07月20日09:00:00)會將tiered_storage_partition_hdfs_1_prt_1子分區整錶轉冷,其他分區均不會有任何遷移操作。

ALTER TABLE tiered_storage_partition_hdfs_1_prt_1 SET ttl interval '3days' move to storage_cold;

查詢指定表的冷熱狀態

您可以選擇任意一種方式查詢表的冷熱狀態。冷表返回cold,熱表返回hot。

  • 方式一:

    SELECT pg_tiered_storage_relation_status('<table_name>'::regclass::oid::bigint);
  • 方式二:

    SELECT pg_tiered_storage_relation_status(<表的oid>::bigint);

    通過SELECT oid FROM pg_class where relname='<table_name>';查詢表的oid。

7.0版執行個體

普通表整錶轉冷

文法

SELECT pg_tiered_storage_move_table_to_storage_cold('<schema_name>', '<table_name>');

樣本

public的Schema中建立一個普通表tiered_storage_heap_oss並寫入資料。

CREATE TABLE tiered_storage_heap_oss (a int, b int) DISTRIBUTED BY(a) ;
INSERT INTO  tiered_storage_heap_oss SELECT random() * 1000,1 FROM generate_series(1,100);
  • 樣本一:整表立即轉冷。

    執行以下語句,將普通表整表立即轉冷。

    SELECT pg_tiered_storage_move_table_to_storage_cold('public', 'tiered_storage_heap_oss');
  • 樣本二:使用pg_cron設定整表定時轉冷。

    假設執行使用者為etl_user,將資料庫etl中的普通表tiered_storage_heap_oss,設定在次日淩晨1點將普通錶轉冷。串連到postgres資料庫,執行以下語句。

    SELECT cron.schedule('etl_table_transfer_to_cold', '0 1 * * *', 'SELECT pg_tiered_storage_move_table_to_storage_cold('public', 'tiered_storage_heap_oss');', 'etl', 'etl_user');

    次日淩晨1點後檢查轉冷成功後,可執行以下語句,刪除該定時任務。

    SELECT cron.unschedule(<定時任務ID>);
    說明

    定時任務ID為建立任務時自動產生的,可以通過查看cron.job表的jobid欄位查看。

分區表按子分區轉冷

文法

SELECT pg_tiered_storage_move_table_to_storage_cold('<schema_name>', '<分區子表名>');

您可以使用psql執行\d+查看具體分區表的子表名。

樣本

  • 樣本一:對分區子表立即轉冷。

    public的Schema中建立一個分區表tiered_storage_partition_oss

    CREATE TABLE tiered_storage_partition_oss(a int,b int) DISTRIBUTED BY (a) PARTITION BY range(a) (start(1) end(20) every(10));
    說明

    本樣本會產生2個分區子表tiered_storage_partition_oss_1_prt_1tiered_storage_partition_oss_1_prt_2

    向分區子表tiered_storage_partition_oss_1_prt_1中寫入資料。

    INSERT INTO  tiered_storage_partition_oss_1_prt_1 VALUES(1, 1), (2, 2), (3, 3), (4, 4);

    將分區子表立即轉冷。

    SELECT pg_tiered_storage_move_table_to_storage_cold('public', 'tiered_storage_partition_oss_1_prt_1');
  • 樣本二:使用pg_cron設定按天分區的分區子表定時轉冷。

    在資料庫etl中建立按天分區的daily_log_details分區表。

    CREATE TABLE daily_log_details (id INT, log_message text, created_date character varying(64))
    PARTITION BY LIST (created_date)
    (
       PARTITION p20230601 VALUES ('20230601'),
       PARTITION p20230602 VALUES ('20230602'),
       PARTITION p20230603 VALUES ('20230603'),
       PARTITION p20230604 VALUES ('20230604'),
       PARTITION p20230605 VALUES ('20230605'),
       PARTITION p20230606 VALUES ('20230606'),
       PARTITION p20230607 VALUES ('20230607'),
       PARTITION p20230608 VALUES ('20230608'),
       PARTITION p20230609 VALUES ('20230609'),
       PARTITION p20230610 VALUES ('20230610'),
       PARTITION p20230611 VALUES ('20230611'),
       DEFAULT PARTITION others
    );

    設定將10天前的分區子錶轉冷,執行使用者為etl_user,轉冷執行時間為3點。按照如下步驟操作。

    1. 在資料庫etl中建立清理函數。

      CREATE OR REPLACE FUNCTION pg_tiered_storage_move_partition_daily_table_to_cold_storage(schemaname text, tablename text) RETURNS void
      AS $$
      DECLARE
          fetch_overdue_partition_sql text;
          cold_storage_sql text;
          target record;
      BEGIN
          fetch_overdue_partition_sql := 'WITH targetpartitions AS
          (SELECT * FROM pg_partitions 
          WHERE tablename = $1
          AND schemaname = $2 
          AND partitionlevel = 1
          AND partitionisdefault = FALSE)
          SELECT partitiontablename FROM targetpartitions WHERE 
          to_date(substring(targetpartitions.partitionname FROM 2), ''YYYYMMDD'') <= current_date - INTERVAL ''10 days''';
          
          -- fetch overdue partitions
          FOR target IN EXECUTE fetch_overdue_partition_sql USING tablename, schemaname LOOP 
             cold_storage_sql := 'SELECT pg_tiered_storage_move_table_to_storage_cold($1::text, $2::text)';
             raise notice 'sql %', cold_storage_sql;
             EXECUTE cold_storage_sql USING schemaname, target.partitiontablename;
          END LOOP;
      END;
      $$
      LANGUAGE plpgsql;
    2. 串連到postgres資料庫執行轉冷語句。

      SELECT cron.schedule('etl_daily_transfer_to_cold', '0 3 * * *', 'SELECT pg_tiered_storage_move_partition_daily_table_to_cold_storage(''public'', ''daily_log_details'');', 'etl', 'etl_user');
  • 樣本三:使用pg_cron設定按月分區的分區子表定時轉冷。

    在資料庫etl中建立按月分區的month_log_details分區表。

    CREATE TABLE month_log_details (id INT, log_message text, created_date character varying(64))
    PARTITION BY LIST (created_date)
    (
       PARTITION p202306 VALUES ('202306'),
       PARTITION p202307 VALUES ('202307'),
       PARTITION p202308 VALUES ('202308'),
       PARTITION p202309 VALUES ('202309'),
       PARTITION p202310 VALUES ('202310'),
       DEFAULT PARTITION others
    );

    設定將3個月前的分區子錶轉冷,執行使用者為etl_user,轉冷執行時間為5點。按照如下步驟操作。

    1. 在資料庫etl中建立清理函數。

      CREATE OR REPLACE FUNCTION pg_tiered_storage_move_partition_table_to_cold_storage(schemaname text, tablename text) RETURNS void
      AS $$
      DECLARE
          fetch_overdue_partition_sql text;
          cold_storage_sql text;
          target record;
      BEGIN
          fetch_overdue_partition_sql := 'WITH targetpartitions AS
          (SELECT * FROM pg_partitions 
          WHERE tablename = $1
          AND schemaname = $2 
          AND partitionlevel = 1
          AND partitionisdefault = FALSE)
          SELECT partitiontablename FROM targetpartitions WHERE 
          to_date(substring(targetpartitions.partitionname FROM 2), ''YYYYMM'') <= current_date - INTERVAL ''3 months''';
          
          -- fetch overdue partitions
          FOR target IN EXECUTE fetch_overdue_partition_sql USING tablename, schemaname LOOP 
             cold_storage_sql := 'SELECT pg_tiered_storage_move_table_to_storage_cold($1::text, $2::text)';
             raise notice 'sql %', cold_storage_sql;
             EXECUTE cold_storage_sql USING schemaname, target.partitiontablename;
          END LOOP;
      END;
      $$
      LANGUAGE plpgsql;
    2. 串連到postgres資料庫執行轉冷語句。

      SELECT cron.schedule('etl_month_transfer_to_cold', '0 5 1 * *', 'SELECT pg_tiered_storage_move_partition_table_to_cold_storage(''public'', ''month_log_details'');', 'etl', 'etl_user');

查詢指定表的冷熱狀態

執行以下語句,查詢表的冷熱狀態。冷表返回cold,熱表返回hot。

SELECT pg_tiered_storage_table_status('<schema_name>', '<table_name>|<分區子表名>')

查看冷熱資料存放區量

登入雲原生資料倉儲AnalyticDB PostgreSQL版控制台,在基本資料頁面的執行個體運行狀態卡片中查看熱儲存總量冷儲存總量

備份恢複

AnalyticDB PostgreSQL版冷熱階層式存放區支援備份恢複,具體恢複規則如下。

6.0版執行個體

當具備完整備份時,可以恢複到任意時間點的狀態,恢復點的冷熱狀態與備份時刻一致。

7.0版執行個體

當具備完整備份時,可以恢複到指定時間點的狀態。恢復點的冷熱狀態與備份時刻一致。AnalyticDB PostgreSQL 7.0版存在如下限制:

  • 如果資料錶轉冷後無資料寫入,可以恢複到任意時間點的狀態。

  • 如果資料錶轉冷後有資料寫入,可以恢複到轉冷前任何備份點的狀態,如果恢複到冷存狀態,暫時只能恢複到冷表最後一次寫入對應的狀態。

為了支援備份恢複,被DROP後的資料表對應的OSS空間不會立刻釋放,會額外延長儲存一段時間。延長儲存的時間與備份恢複設定的資料備份保留天數一致。延長儲存的時間內對應OSS空間依然會產生費用。

備份恢複的詳細資料,請參見備份恢複功能介紹

擴縮容

AnalyticDB PostgreSQL 6.0版執行個體縮容會時會將冷表遷移至本地暫存資料表以進行資料重分布,縮容完成後會重新上傳資料至OSS並清理本地暫存資料表,需要保證縮容後的所有節點剩餘空間大於冷表佔用空間之和才能縮容成功。縮容過程會從OSS下載資料,縮容完成時間受限於OSS下載資料的頻寬,請合理評估縮容時間。

對於AnalyticDB PostgreSQL 7.0版執行個體,擴縮容不涉及冷存部分的資料,不需要進行重分布或者資料拉回本地,不需要考慮冷存所佔磁碟空間。

效能資料

按照如下語句分別對節點規格為2C8G的4節點執行個體和2C8G的8節點執行個體進行測試。

CREATE TABLE t333 (a int, b int);
INSERT INTO t333 SELECT random() * 1000000, random()*1000000 FROM generate_series(1,3000000000);

AnalyticDB PostgreSQL 6.0版執行個體執行ALTER TABLE t333 SET ttl interval '-3days' move to storage_cold;轉冷語句。

AnalyticDB PostgreSQL 7.0版執行個體執行SELECT pg_tiered_storage_move_table_to_storage_cold('public', 't333');轉冷語句。

單錶轉冷時間的測試結果如下。

熱表大小(GB)

4節點執行個體轉冷時間(秒)

8節點執行個體轉冷時間(秒)

6.0版執行個體

7.0版執行個體

6.0版執行個體

7.0版執行個體

1

10

5

5

2.8

10

96

48

42

25.2

100

848

490

333

243