Hologres支持表回收站功能,能够将执行DROP TABLE
操作所删除的表自动保存至回收站。您可以根据业务需求对已删除的表进行恢复,以避免因误操作造成的数据丢失。
使用限制
仅Hologres V3.1及以上版本的实例支持表回收站功能。
回收机制
使用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);
设置回收站的保留时间
被删除的表进入回收站后,默认保留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;