Redrock Postgres 文档
主页 切换暗/亮/自动模式 切换暗/亮/自动模式 切换暗/亮/自动模式 返回首页

回收站

在删除一个表时,数据库不会立即删除与该表关联的物理文件和回收占用空间。数据库会重命名表,并将其和任何关联对象放置到回收站中,如果表被错误删除,则可以在以后进行恢复。

什么是回收站?

回收站实际上是一个数据字典表,包含有关丢弃对象的信息。删除的表和任何关联对象(如索引、约束、类型等),它们的物理文件会保留一段时间,并且仍占用空间。

它们会继续被计入用户空间配额,直到指定从回收站中清除,或者由于表空间需要被删除时,数据库必须清空回收站。

每个用户都可以被认为有自己的回收站,因为除非用户具有 SUPERUSER 权限,否则用户在回收站中唯一有权访问的对象是用户拥有的对象。用户可以使用以下语句在回收站中查看其模式中的对象:

SELECT * FROM pg_catalog.pg_recyclebin
   WHERE namespace = to_regnamespace(CURRENT_SCHEMA)::oid;

DDL 命令删除的对象将会被移动到回收站。在移动到回收站的已删除对象中包括以下类型的对象:

  • 回滚段
  • 索引
  • 约束
  • 类型
  • 函数

当您删除表空间时,表空间中的对象不会放置在回收站中,数据库会清除回收站中位于表空间中的任何对象。同样:

  • 删除用户时,属于该用户的任何对象都不会放置在回收站中,并且回收站中的任何对象都会清除。
  • 删除模式时,属于该模式的任何对象都不会放置在回收站中,并且回收站中的任何对象都会清除。

回收站中的对象命名

当删除的表移动到回收站时,该表及其关联的对象将被指定为系统生成的名称。这是必要的,以避免如果多个表具有相同的名称,可能会出现名称冲突。在以下情况下可能发生这种情况:

  • 用户删除表,用相同的名称重新创建表,然后再次删除表。
  • 两个用户有同名的表,两个用户都删除他们的表。

删除对象重命名约定如下:

pg_dropped_[object_type]_[object_id]

其中:

  • object_type 是对象类型名称,例如:table, index, constraint, type, function。
  • object_id 是该对象的唯一标识符,这使得回收站名称在当前数据库中唯一。

查看和查询回收站中的对象

您可以查询系统表pg_recyclebin以识别数据库分配给已删除对象的名称,如以下示例所示:

SELECT objname, oldname FROM pg_catalog.pg_recyclebin
   WHERE namespace = to_regnamespace('hr')::oid;
       objname         |  oldname
-----------------------+-----------
pg_dropped_table_18762 | employees

您还可以使用GUI管理工具(如DBeaver、pgAdmin 4)查看回收站的内容,在指定数据库下展开系统模式pg_recyclebin以查看所有已删除的对象。

您可以查询回收站中的对象,就像查询其他对象一样。但是,您必须用它在回收站中的标识指定对象的名称。例如:

SELECT * FROM pg_recyclebin.pg_dropped_table_18762;

清除回收站中的对象

如果您决定永远不会从回收站恢复一个删除对象,则可以使用VACUUM语句从回收站中彻底删除指定对象及其关联对象,并释放其存储空间。您需要与删除对象时相同的权限。

使用VACUUM语句清除表时,可以使用回收站中已知表的名称或表的原始名称。回收站名称可以从系统表pg_recyclebin中获取,如“查看和查询回收站中的对象”所示。以下假设示例清除表hr.employees,该表在放入回收站时被重命名为pg_recyclebin.pg_dropped_table_18762

VACUUM pg_recyclebin.pg_dropped_table_18762;

您可以使用以下语句获得相同的结果:

VACUUM hr.employees;

如果您具有 SUPERUSER 权限或您是当前数据库所有者,则可以使用以下语句清除整个回收站,并释放对象占用的空间:

VACUUM;

您还可以使用VACUUM语句从回收站中清除索引或回滚段。

从回收站恢复表

使用 CREATE TABLELIKE 语句可以恢复在回收站中的已删除对象。

您应该指定回收站中已删除表的名称。回收站名称可以从系统表pg_recyclebin中获取,如“查看和查询回收站中的对象”所示。要使用 CREATE TABLELIKE 语句,您需要访问已删除表所需的SELECT权限。

以下示例恢复 employees 表,并为其分配新名称:

CREATE TABLE hr.employees2 (LIKE pg_recyclebin.pg_dropped_table_18762 INCLUDING ALL);
INSERT INTO hr.employees2 SELECT * FROM pg_recyclebin.pg_dropped_table_18762;

如果您多次删除表,回收站中系统生成的对象名称非常有用。例如,假设您在回收站中有三个版本的 employees 表,并且您希望恢复第二个版本。您可以查询回收站,然后恢复到系统生成的相应对象名称,如以下示例所示。在查询中包括删除时间可以帮助您验证您正在恢复正确的表。

SELECT objname, oldname, droptime FROM pg_catalog.pg_recyclebin;

查询结果:

       objname         |  oldname  |      droptime
-----------------------+-----------+--------------------
pg_dropped_table_18762 | employees | 2016-02-05 21:05:52
pg_dropped_table_18924 | employees | 2016-02-05 21:25:13
pg_dropped_table_19510 | employees | 2016-02-05 22:05:53

恢复指定的表对象:

CREATE TABLE hr.employees2 (LIKE pg_recyclebin.pg_dropped_table_18924 INCLUDING ALL);
INSERT INTO hr.employees2 SELECT * FROM pg_recyclebin.pg_dropped_table_18924;