Hologres支援表資源回收筒功能,能夠將執行DROP TABLE操作所刪除的表自動儲存至資源回收筒。您可以根據業務需求對已刪除的表進行恢複,以避免因誤操作造成的資料丟失。
使用限制
僅Hologres V3.1及以上版本的執行個體支援表資源回收筒功能。
資源回收筒中的表仍存在部分記憶體佔用,因此,建立了向量索引的表暫不建議開啟資源回收筒功能,參見Proxima Graph索引使用指南(即將下線)。
回收機制
使用DROP TABLE [CASCADE]或DROP DYNAMIC TABLE [CASCADE]命令刪除的內部表、分區表(分區父表和子表)或Dynamic Table表,會自動進入資源回收筒。
資源回收筒中的表會單獨存放在名為hg_recyclebin的Schema中,表名與被刪除前相同,資料、表屬性、表索引等都會被保留在資源回收筒中。
如果執行的是TRUNCATE或INSERT OVERWRITE命令,表不進入資源回收筒。
不支援回收外部表格、視圖(VIEW)及物化視圖(MATERIALIZED VIEW)。
如果表設定了TTL,TTL在資源回收筒中仍然生效。系統會根據設定的TTL,定期清理表資料。
開啟/關閉資源回收筒
--開啟對應db的資源回收筒功能
ALTER DATABASE <db_name> SET hg_enable_recyclebin = ON;
--關閉對應db的資源回收筒功能
ALTER DATABASE <db_name> SET hg_enable_recyclebin = OFF; V3.1或以上版本的建立執行個體和存量執行個體,預設開啟表資源回收筒功能,被刪除的表會自動進入表資源回收筒。
關閉資源回收筒後,資源回收筒中已有的表可以被恢複和清理。但關閉之後,被刪除的表將不會進入資源回收筒。
僅當前執行個體的Superuser可執行該SQL命令,一個DB只需執行一次。
恢複表
您可使用如下命令恢複已刪除的表,如果有同名表,可通過指定table_id進行還原。
RECOVER TABLE <table_name> [WITH (table_id = xxxx)]; 注意事項如下:
恢複表時
會恢複表的資料和表屬性、表索引(如PK、Clustering Key、Segment Key)等,如果表設定了TTL,則TTL在資源回收筒中仍然生效,系統會根據設定的TTL,定期清理表資料。
恢複表之前
如果Schema中存在同名表,需要先刪除或重新命名同名表,否則會導致RECOVER執行失敗。但如果同名表有設定PK、Clustering key,需要將該同名表移動到其他Schema,才能執行RECOVER,詳情請參見下方的使用樣本。
如果表所在的Schema已經被刪除,恢複表操作將會失敗。
對於分區表
對於Dynamic Table動態表
Dynamic Table恢複後是普通表,只能查資料,不具備自動重新整理的能力,如有需要請重新建立Dynamic Table,詳情請參見ALTER DYNAMIC TABLE。
恢複Dynamic Table的基表時,Dynamic Table不會被恢複。
對於級聯情境
執行
DROP TABLE xxx CASCADE命令刪除表時,其依賴對象VIEW、MATERIALIZED VIEW均會被刪除,在RECOVER表時,只能恢複目標表,無法恢複VIEW、MATERIALIZED VIEW和Dynamic Table,也不能恢複級聯的Dynamic Table。例如:Dynamic Table依賴view1,view1依賴table1,
DROP TABLE table1 CASCADE命令會將Dynamic Table和view1一起刪除。執行RECOVER命令後,Dynamic Table和view1都不能恢複,需要重新手動建立。恢複表的許可權
執行RECOVER需要具備一定的許可權。詳情請參見許可權說明。
管理資源回收筒
資源回收筒支援的操作
資源回收筒中的表支援如下操作:
RECOVER(恢複表)、PURGE(清理表)。
通過
hologres.hg_recyclebin查看資源回收筒表詳情。
查看資源回收筒表詳情
您可通過如下語句查看資源回收筒中的表詳情:
表Owner在資源回收筒中僅能查看自己作為Owner的表,看不到其他使用者的表。Superuser可以查看所有資源回收筒中的所有表。
SELECT * FROM hologres.hg_recyclebin;返回資訊的參數說明如下:
參數名 | 描述 |
table_id | 表在資源回收筒中的ID,唯一值,用來識別表. |
schema_name | 表被刪除前所在的Schema。 |
table_name | 被刪除的表名。 |
table_owner | 表被刪除前的Owner。 |
dropby | 表的刪除者。 |
drop_time | 表被刪除的時間。 |
查看資源回收筒中表格儲存體
通過如下文法查看資源回收筒中表的儲存量。其中:
table_id不是必填項,在當Schema名和表名完全重複時,可以通過table_id指定特定的表。--查看資源回收筒中表格儲存體的大小 SELECT hologres.hg_recyclebin_relation_size('<schema_name.table_name>'[,<table_id>]); --通過如下文法可以帶上儲存單位 SELECT PG_SIZE_PRETTY(hologres.hg_recyclebin_relation_size('<schema_name.table_name>'[,<table_id>]));使用樣本如下:
--假設被刪除的表名為tbl1,從屬於public Schema SELECT hologres.hg_recyclebin_relation_size('public.tbl1'); --如果資源回收筒中有多個表的Schema名和表名完全一樣,則額外需要使用table_id來指定查詢特定表的儲存量。例如: SELECT hologres.hg_recyclebin_relation_size('public.tbl1', 42);通過監控指標查看每個DB的表資源回收筒佔用的儲存。
Hologres從V3.1.32、V3.2.12、V4.0.2版本開始,提供表資源回收筒的儲存監控指標,可以查看每個DB資源回收筒中的儲存。
設定資源回收筒的保留時間
被刪除的表進入資源回收筒後,預設保留1天,超過1天系統將自動清理該表,且無法恢複。您可設定開啟或關閉資源回收筒,也可根據業務需求使用如下文法修改資源回收筒的保留時間長度。
ALTER DATABASE <db_name> SET hg_recyclebin_retention_days = 5; --修改表的保留時間長度為5天資源回收筒中的表仍然會參與儲存計費,收取儲存費用。
保留時間長度的單位是天,最少1天,最多10天。
僅Superuser有權執行該語句,且在DB層級生效。
清理資源回收筒中的表
您可通過PURGE命令手動清理資源回收筒中的表。命令如下:
--清理單個表
purge TABLE {table_name};
--清空資源回收筒中的所有表,需要使用superuser執行。
CALL hologres.hg_purge_all_tables();命令執行成功後,表將會被立即刪除,資源回收筒中無法查到,也無法恢複。
只能清理Table,不能清理級聯的Dynamic Table。
清理表許可權:執行PURGE需要具備一定的許可權,詳情請參見許可權說明。
刪除後的表不進入資源回收筒
預設通過DROP TABLE或DROP Dynamic Table [CASCADE]命令刪除的表會進入到資源回收筒,您可通過如下命令設定刪除後的表不進入資源回收筒。
DROP TABLE <table_name> [CASCADE] FORCE;許可權說明
資源回收筒的查詢許可權
表Owner僅可查詢自己刪除的表,無法查看其他使用者刪除的表。
Superuser可以查詢資源回收筒中的所有表。
刪除/恢複/清理資源回收筒中的表的許可權
刪除表
僅Superuser、Developer/Admin使用者組(SPM/SLPM)及表Owner(專家許可權模型)有權執行
DROP命令刪除表,使其進入資源回收筒。清理表
僅Superuser、Developer/Admin使用者組(SPM/SLPM)及表Owner(專家許可權模型)有權執行
PURGE命令,清理資源回收筒中的表。恢複表
僅Superuser、Developer/Admin使用者組(SPM/SLPM)、表Owner(專家許可權模型)及表的刪除者有權執行
RECOVER命令,將表恢複至原始狀態。
在SPM/SLPM許可權模型下,只有表進入資源回收筒之前的Developer/Admin使用者組才有許可權操作資源回收筒中的表。如果表進入資源回收筒後,新增了從屬於Developer/Admin使用者組的使用者,則該使用者無權操作資源回收筒中的表。
當從SPM/SLPM切換到專家模式時,僅Superuser可以還原和清理資源回收筒中的存量表。
特殊樣本:
如果user1是schema1的Owner,user2是schema1.table2的Owner,那麼user1可以刪除schema1以及schema1.table2,但是無法訪問schema1.table2,因為user2沒有給user1授權。
--1、user1建立schema1,並將建表許可權授予user2
CREATE SCHEMA schema1;
GRANT CREATE ON SCHEMA schema1 TO "BASIC$user2";
--2、user2建立schema1.table2,成為表owner
CREATE TABLE schema1.table2(id INT);
--user1可以刪除schema1以及下面的所有對象,包括table2,但無法查看table2
SELECT * FROM schema1.table2;
# ERROR: permission denied for table table2
DROP SCHEMA schema1 CASCADE;
# DROP CASCADES TO TABLE schema1.table2
# DROP SCHEMA如果要恢複table2,有如下兩種方法:
user1是表的刪除者,可以恢複schema1下的表。
user2是表Owner,可以恢複表。
使用樣本
刪除表進入資源回收筒並恢複
樣本1:刪除普通表並恢複
準備一張普通表,並執行刪除操作。
CREATE TABLE tbl1 ( id INT NOT NULL) WITH ( orientation = 'column', distribution_key = 'id', clustering_key = 'id', event_time_column = 'id'); INSERT INTO tbl1 SELECT i FROM GENERATE_SERIES(1, 1000000) i; DROP TABLE tbl1;查看資源回收筒,確認表已經進入資源回收筒。
SELECT * FROM hologres.hg_recyclebin;返回結果如下:
table_id | schema_name | table_name | table_owner | dropby | drop_time ---------+-------------+------------+-----------------+-------------+----------------------- 14| public | tbl1 | xx_developer | 1365xxxxxxxx| 2025-04-17 19:23:10+08 (1 row)查看錶的儲存:
SELECT (hologres.hg_recyclebin_relation_size('tbl1')/1024)::text||'KB' AS hg_recyclebin_relation_size;表格儲存體結果如下:
hg_recyclebin_relation_size ----------------------------- 1336KB (1 row)恢複表。
--恢複普通表tbl1的所有資料和屬性(包括pk、clustering key等) RECOVER TABLE tbl1;
樣本2:刪除分區表並恢複
準備一張分區表,對應的父表和子表如下:
CREATE TABLE tbl2_parent(id INT) PARTITION BY list (id); CREATE TABLE tbl2_child_1 PARTITION OF tbl2_parent FOR VALUES IN (1); CREATE TABLE tbl2_child_2 PARTITION OF tbl2_parent FOR VALUES IN (2);刪除其中一張子表並恢複,恢複後的子表是一張普通表,需要手動Attach到原來的分區父表上。
--刪除一張分區子表 DROP TABLE tbl2_child_1; --分區子表進入資源回收筒 SELECT * FROM hologres.hg_recyclebin;返回結果如下:
table_id | schema_name | table_name | table_owner | dropby | drop_time ----------+-------------+--------------+------------------+-----------+------------------------ 16 | public | tbl2_child_1 | xx_developer | 1365xxxxx | 2025-04-17 19:33:30+08 (1 row)恢複該分區子表,並查看該表的結構為一張普通表,不再是一張分區子表。
RECOVER TABLE tbl2_child_1; SELECT hg_dump_script('tbl2_child_1');返回結果如下:
hg_dump_script -------------------------------------------------------------- BEGIN; + + /* + DROP TABLE public.tbl2_child_1; + */ + CREATE TABLE public.tbl2_child_1 ( + id INTEGER + ) WITH ( + orientation = 'column', + storage_format = 'orc', + table_group = 'xxxx_tg_default', + table_storage_mode = 'any', + time_to_live_in_seconds = '3153600000' + ); + + + + COMMENT ON TABLE public.tbl2_child_1 IS NULL; + ALTER TABLE public.tbl2_child_1 OWNER TO "xx_developer"; + + + END; + (1 row)刪除分區父表,恢複後,仍然是分區表。
--刪除分區父表 DROP TABLE tbl2_parent CASCADE; --查看資源回收筒,父表以及子表都進入資源回收筒 SELECT * FROM hologres.hg_recyclebin;返回結果如下:
table_id | schema_name | table_name | table_owner | dropby | drop_time ---------+-------------+--------------+---------------+---------------+------------------------ 17 | public | tbl2_child_2 | xx_developer | 1365xxxxxxxx | 2025-04-17 19:41:04+08 15 | public | tbl2_parent | xx_developer | 1365xxxxxxxx | 2025-04-17 19:41:04+08恢複分區父表。
RECOVER TABLE tbl2_parent;在PSQL用戶端中執行如下語句查看分區父表DDL。
\d+ tbl2_parent;返回結果如下,其子表也一併被恢複。
Partitioned table "public.tbl2_parent" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+---------+--------------+------------- id | integer | | | | plain | | Partition key: LIST (id) Partitions: tbl2_child_2 FOR VALUES IN (2)
樣本4:恢複重名表
如果表刪除後,在DB中建立了一個重名表,此時恢複已刪除的表會報錯,需要重新命名已有表。
建立表tbl6,並執行刪除。
CREATE TABLE tbl6(id INT); --刪除表,並進入資源回收筒 DROP TABLE tbl6;重新建立一個重名表tbl6,並恢複已刪除的表tbl6。
CREATE TABLE tbl6(id INT); RECOVER TABLE tbl6;返回結果如下,恢複失敗,因為存在重名表,需要刪除或RENAME重名表。
ERROR: Table public.tbl6 already exists將已有表tbl6重新命名為tbl6_rename後,再次恢複已刪除的表tbl6,即可執行成功。
ALTER TABLE tbl6 rename to tbl6_rename; RECOVER TABLE tbl6;
如果已有的重名表,設定了跟刪除的表相同的PK、Clustering key,無法重名表來恢複刪除的表。需要將已有的重名表移動Schema或者刪除才能恢複。
建立表tbl1,並執行刪除。
--建立一張表並設定pk和clustering key CREATE TABLE tbl1 ( col1 INT, col2 INT, col3 INT, PRIMARY KEY (col1, col2) ) WITH ( clustering_key = 'col1' ); --刪除這張表 DROP TABLE tbl1; --重新建立一張重名表,並設定pk和clustering key CREATE TABLE tbl1 ( col1 INT, col2 INT, col3 INT, PRIMARY KEY (col1, col2) ) WITH ( clustering_key = 'col1' ); --查看資源回收筒 SELECT * FROM hologres.hg_recyclebin;返回結果如下。
table_id | schema_name | table_name | table_owner | dropby | drop_time ----------+-------------+------------+------------------+------------------+------------------------ 493497 | public | tbl1 | 13659371xxx| 13659371xxx | 2025-04-17 20:11:08+08在資源回收筒直接恢複tbl1表將報錯。
--在資源回收筒恢複刪除的表,報錯,無法恢複 RECOVER TABLE tbl1;報錯資訊如下。
ERROR: Table public.tbl1 already exists重新命名tbl1表再恢複將報錯。
--重新命名已有表 ALTER TABLE tbl1 RENAME TO tbl2; --恢複仍然報錯,因為已有表存在pk和clustering key RECOVER TABLE tbl1;報錯資訊如下。
ERROR: relation "tbl1_pkey" already EXISTS IN SCHEMA "public"將tbl1表移動到其他Schema下,再進行恢複,才可恢複成功。
CREATE SCHEMA test; ALTER TABLE tbl2 SET SCHEMA test; --可以成功recover RECOVER TABLE tbl1;
刪除表不進入資源回收筒
--刪除普通表不清除
CREATE TABLE tbl1(id INT);
DROP TABLE tbl1 FORCE; 清理資源回收筒中的表
CREATE TABLE tbl1(id INT);
DROP TABLE tbl1;
--強制移除資源回收筒中的表
PURGE TABLE tbl1;