暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

1147.Oracle Recycle bin 回收站详解

原创 张鹏 2023-08-16
3104

1147.Oracle Recycle bin 回收站详解
闪回删除和回收站

在 Oracle 数据库的早期版本中,如果错误地删除了表,则必须将数据库恢复到以前的时 间以恢复删除的表。此过程通常非常耗时,并且会导致丢失其它事务处理的工作。 Oracle Database 10g 引入了闪回删除功能,您可以使用此功能还原 DROP TABLE 语句的 结果,而不必使用时间点恢复。 注:初始化参数 RECYCLEBIN 用于控制闪回删除功能是打开 (ON) 还是关闭 (OFF)。如果 将该参数设置为 OFF,则删除的表不会进入回收站。如果将该参数设置为 ON,则删除的 表将进入回收站,并且可以进行恢复。默认情况下,将 RECYCLEBIN 设置为 ON。

回收站

如果不启用回收站,则删除表时,与该表及其相关对象关联的空间会立即变为可回收 (也就是说,该空间可用于其它对象)。 如果启用了回收站,则删除表时,则与该表及其相关对象关联的空间不会立即变为可回收, 即使该空间确实显示在 DBA_FREE_SPACE 中。相反,会将删除的对象临时放在回收站中, 这些对象仍属于其各自的所有者。在空间不紧张时,绝不会自动回收回收站对象使用的空 间。这样,便可以在尽可能长的期限内恢复回收站对象。 将删除的表移动到回收站时,将使用系统生成的名称对该表及其关联对象和约束条件 进行重命名。该操作非常有必要,因为这可以避免以后使用相同名称创建新对象时发生 名称冲突。 回收站本身是一个数据词典表,用于维护已删除对象的原始名称与各自系统生成名称之间 的关系。可以使用 DBA_RECYCLEBIN 视图查询回收站的内容。
幻灯片中的图表说明了这种新的行为:

  1. 在表空间中创建了名为 EMPLOYEES 的表。
  2. 删除 EMPLOYEES 表。
  3. 此时,EMPLOYEES 占用的区被视为可用空间。
  4. 将 EMPLOYEES 重命名并插入到回收站中。

从回收站还原表

还原删除的表和相关对象。
如果多个回收站条目具有相同原始名称,则:
– 使用系统生成的唯一名称来还原特定版本
– 使用原始名称时,还原的表遵循后进先出 (LIFO) 的规则
重命名原始名称(如果当前正在使用该名称)。
使用 FLASHBACK TABLE … TO BEFORE DROP 命令从回收站恢复表及其所有可能的 相关对象。可以指定表的原始名称或删除对象时分配给对象的系统生成名称。
如果指定原始名称,且回收站包含多个具有该名称的对象,则最先恢复最晚移动到回收站 的对象(LIFO:后进先出)。如果需要检索表的较早版本,则可以指定要检索的表的系 统生成名称,或发出其它 FLASHBACK TABLE … TO BEFORE DROP 语句,直到检索 到所需的表。
如果自删除原始表后已经在同一方案中创建了名称相同的新表,则系统会返回一个错误, 除非您同时指定了 RENAME TO 子句。
注:闪回删除的表时,恢复的索引、触发器和约束条件将保留各自的回收站名称。因此, 建议在闪回删除的表前查询回收站和 DBA_CONSTRAINTS。使用这种方法,可以将恢复 的索引、触发器和约束条件重命名为更实用的名称。

回收站:自动回收空间

只要回收站对象使用的空间没有被回收,就可以使用闪回删除功能恢复这些对象。下面 是回收站对象回收策略:
明确发出 PURGE 命令时手动进行清除
在空间紧张时自动进行清除:对象处于回收站中时,DBA_FREE_SPACE 也会报告 其对应空间,因为可以自动回收这些空间。然后按以下顺序使用特定表空间中的 空闲空间:
与回收站对象不对应的空闲空间。
与回收站对象对应的空闲空间。在这种情况下,将使用先进先出 (FIFO) 算法 自动将回收站对象从回收站中清除。
自动分配的可用空间(如果表空间是可以自动扩展的)。

假定在 TBS1 表空间内创建一个新表。如果向此表空间分配了与回收站对象不对应的可用 空间,则首先使用此可用空间。如果该空间不够,则使用与 TBS1 内驻留的回收站对象对 应的可用空间。如果使用了某些回收站对象的可用空间,则会从回收站中自动清除这些对 象。此时,将无法再使用闪回删除功能恢复这些对象。如果仍未满足空间需求,则作为最 后的方法,会在可能的情况下扩展 TBS1 表空间。

回收站:手动回收空间

PURGE {TABLE |INDEX }
PURGE TABLESPACE [USER ]
PURGE [USER_|DBA_]RECYCLEBIN
回收站:手动回收空间
使用 PURGE 命令可从回收站中永久地删除对象。从回收站中清除某个对象时,会从数据 库中永久地删除该对象及其相关对象。因此,将无法再使用闪回删除功能恢复从回收站中 清除的对象。下面是可能使用的一些 PURGE 命令:
PURGE TABLE 清除指定表
PURGE INDEX 清除指定索引。
PURGE TABLESPACE 清除驻留在指定表空间内的所有对象。此外,也可能清除相 关的、驻留在其它表空间中的对象。此外,还可以指定 USER 子句,以仅清除属于 指定用户的那些对象,这些对象对于指定表空间运行于较低的磁盘限额上。
PURGE RECYCLEBIN 清除属于当前用户的所有对象。RECYCLEBIN 与 USER_RECYCLEBIN 功能相同。
PURGE DBA_RECYCLEBIN 清除所有对象。要发出此命令,必须具有足够的系统权 限或 SYSDBA 系统权限。
注:对于 PURGE TABLE 和 PURGE INDEX 命令,如果指定原始名称且 回收站包含多个具有该名称的对象,则首先清除位于回收站中时间最长的对象 (FIFO)。

不使用回收站
不使用回收站
DROP TABLE [PURGE]
DROP TABLESPACE [INCLUDING CONTENTS] ;
DROP USER [CASCADE] ;

可以使用 DROP TABLE PURGE 命令从数据库中永久地删除表及其相关对象。使用此命 令时,对应的对象不会移到回收站中。此命令的功能与 DROP TABLE 在先前版本中提供 的功能相同。
发出 DROP TABLESPACE …INCLUDING CONTENTS 命令后,表空间中的对象不会移 到回收站中。而且,回收站中属于该表空间的对象也会被清除。发出没有 INCLUDING CONTENTS 子句的相同命令时,要使命令能够成功地得以执行,表空间必须是空的。但回 收站中可以有属于该表空间的对象。这种情况下,会清除这些对象。
发出 DROP USER …CASCADE 命令后,将从数据库中永久地删除该用户及其拥有的所 有对象。回收站中属于已删除用户的所有对象都将被清除。

查询回收站
SELECT owner, original_name, object_name, type, ts_name, droptime, related, space FROM dba_recyclebin WHERE can_undrop = ‘YES’;
SELECT original_name, object_name, type, ts_name, droptime, related, space FROM user_recyclebin WHERE can_undrop = ‘YES’;
SQL> SHOW RECYCLEBIN
可以通过查询 user_recyclebin 或 RECYCLEBIN 查看已经删除的所有对象。 dba_recyclebin 显示所有用户已删除的以及仍驻留在回收站中的所有对象。 还可以使用 SQL*Plus SHOW RECYCLEBIN 命令。此命令只显示可“取消删除”的那些 对象。
以下示例显示了如何从回收站中提取重要信息:
original_name 是对象删除前的名称。
object_name 是对象删除后的系统生成名称。
type 是对象的类型。
ts_name 是对象所属的表空间的名称。
droptime 是删除对象的日期。
related 是已删除对象的对象标识符。
space 是对象当前使用的块数。
还可以使用 DNT 查看回收站的内容。

查询已删除的表中的数据

删除了表后,表会移动到回收站中,其原始名称将更改为唯一的系统生成名称。因为仍 拥有已删除的表,所以仍可以通过 DBA_TABLES、DBA_OBJECTS、DBA_SEGMENTS 等各种字典视图查看该表的特性。为了区分在回收站中的表与不在回收站中的表, DBA_TABLES 视图包含名为 DROPPED 的新列,对于已删除但仍驻留在回收站中的表, 该列设置为 YES。
因此,只要系统生成的表名称位于回收站中,就可以对其使用 SELECT 语句以及闪回 查询。 但是,不能对驻留在回收站中的对象发出任何 DML 或 DDL 语句。

从回收站中恢复被drop的表

恢复oracle中误删除drop掉的表
查看回收站中表
select object_name,original_name,partition_name,type,ts_name,createtime,droptime from recyclebin;
恢复表
SQL>flashback table test_drop to before drop;或
SQL>flashback table “BIN$b+XkkO1RS5K10uKo9BfmuA==$0” to before drop;
注:必须9i或10g以上版本支持,flashback无法恢复全文索引
以下为参考资料
使用 Oracle Database 10g 中的闪回表特性,可以毫不费力地恢复被意外删除的表
  以下是一个不该发生却经常发生的情况:用户删除了一个非常重要的表 ― 当然是意外地删除 ― 并需要尽快地恢复。(在某些时候,这个不幸的用户可能就是 DBA!)
  Oracle9i Database 推出了闪回查询选项的概念,以便检索过去某个时间点的数据,但它不能闪回 DDL 操作,如删除表的操作。唯一的恢复方法是在另一个数据库中使用表空间的时间点恢复,然后使用导出/导入或其他方法,在当前数据库中重新创建表。这一过程需要 DBA 进行大量工作并且耗费宝贵的时间,更不用说还要使用另一个数据库进行克隆。
  请使用 Oracle Database 10g 中的闪回表特性,它使得被删除表的恢复过程如同执行几条语句一样简单。让我们来看该特性是如何工作的。
  删除那个表!
  首先,让我们查看当前模式中的表。
  SQL> select * from tab;
  TNAME
  TABTYPE
  CLUSTERID
  --------------------- - – -- — ------
  RECYCLETEST
  TABLE
  现在,我们意外地删除了该表:
  SQL> drop table recycletest;
  Table dropped.
  现在让我们来查看该表的状态。
  SQL> select * from tab;
  TNAME
  TABTYPE
  CLUSTERID
  --------------------------- - – -- — ------
  BIN$04LhcpndanfgMAAAAAANPw==$0 TABLE
  表 RECYCLETEST 已不存在,但是请注意出现新表 BIN$04LhcpndanfgMAAAAAANPw==$0。这就是所发生的事情:被删除的表 RECYCLETEST 并没有完全消失,而是重命名为一个由系统定义的名称。它存在于同一个表空间中,具有与原始表相同的结构。如果在该表上定义了索引或触发器,则它们也被重命名,使用与表相同的命名规则。任何相关源(如过程)都失效;原始表的触发器和索引被改为放置在重命名的表 BIN$04LhcpndanfgMAAAAAANPw==$0 上,保持被删除表的完整对象结构。
  表及其相关对象被放置在一个称为"回收站"的逻辑容器中,它类似于您 PC 机中的回收站。但是,对象并没有从它们原先所在的表空间中删除;它们仍然占用那里的空间。回收站只是一个列出被删除对象目录的逻辑结构。在 SQLPlus 提示符处使用以下命令来查看其内容(您需要使用 SQLPlus 10.1 来进行此操作):
  SQL> show recyclebin
  ORIGINAL NAME
  RECYCLEBIN NAME
  OBJECT TYPE
  DROP TIME
  ------------- - – ----------------------- - – ----- - – --------------
  RECYCLETEST
  BIN$04LhcpndanfgMAAAAAANPw==$0 TABLE
  2004-02-16:21:13:31
  结果显示了表的原始名称 RECYCLETEST,并显示了回收站中的新名称,该名称与我们看到的删除后所创建的新表名称相同。(注意:确切的名称可能因平台不同而不同。)为恢复该表,您所需要做的就是使用 FLASHBACK TABLE 命令:
  SQL> FLASHBACK TABLE RECYCLETEST TO BEFORE DROP;
  FLASHBACK COMPLETE.
  SQL> SELECT * FROM TAB;
  TNAME
  TABTYPE
  CLUSTERID
  --------------------------- - – -- — ------
  RECYCLETEST
  TABLE
  瞧!表毫不费力地恢复了。如果现在查看回收站,它将是空的。
  记住,将表放在回收站里并不在原始表空间中释放空间。要释放空间,您需要使用以下命令清空回收站:
  PURGE RECYCLEBIN;
  但是如果您希望完全删除该表而不需要使用闪回特性,该怎么办?在这种情况下,可以使用以下命令永久删除该表:
  DROP TABLE RECYCLETEST PURGE;
  此命令不会将表重命名为回收站中的名称,而是永久删除该表,就象 10g 之前的版本一样。
  管理回收站
  如果在该过程中没有实际删除表 ― 因而没有释放表空间 ― 那么当被删除的对象占用了所有空间时,会发生什么事?
  答案很简单:这种情况根本不会出现。当表空间被回收站数据完全占满,以至于必须扩展数据文件来容纳更多数据时,可以说表空间处于"空间压力"情况下。此时,对象以先进先出的方式从回收站中自动清除。在删除表之前,相关对象(如索引)被删除。
  同样,空间压力可能由特定表空间定义的用户限额而引起。表空间可能有足够的空余空间,但用户可能将其在该表空间中所分配的部分用完了。在这种情况下,Oracle 自动清除该表空间中属于该用户的对象。
  此外,有几种方法可以手动控制回收站。如果在删除名为 TEST 的特定表之后需要从回收站中清除它,可以执行
  PURGE TABLE TEST;
  或者使用其回收站中的名称:
  PURGE TABLE “BIN$04LhcpndanfgMAAAAAANPw==$0”;
  此命令将从回收站中删除表 TEST 及所有相关对象,如索引、约束等,从而节省了空间。但是,如果要从回收站中永久删除索引,则可以使用以下命令来完成工作:
  purge index in_test1_01;
  此命令将仅仅删除索引,而将表的拷贝留在回收站中。
  有时在更高级别上进行清除可能会有用。例如,您可能希望清除表空间 USERS 的回收站中的所有对象。可以执行:
  PURGE TABLESPACE USERS;
  您也许希望只为该表空间中特定用户清空回收站。在数据仓库类型的环境中,用户创建和删除许多临时表,此时这种方法可能会有用。您可以更改上述命令,限定只清除特定的用户:
  PURGE TABLESPACE USERS USER SCOTT;
  诸如 SCOTT 等用户可以使用以下命令来清空自己的回收站
  PURGE RECYCLEBIN;
  DBA 可以使用以下命令清除任何表空间中的所有对象
  PURGE DBA_RECYCLEBIN;
  可以看到,可以通过多种不同方法来管理回收站,以满足特定的需要。
  表版本和闪回功能
  用户可能会经常多次创建和删除同一个表,如:
  CREATE TABLE TEST (COL1 NUMBER);
  INSERT INTO TEST VALUES (1);
  commit;
  DROP TABLE TEST;
  CREATE TABLE TEST (COL1 NUMBER);
  INSERT INTO TEST VALUES (2);
  commit;
  DROP TABLE TEST;
  CREATE TABLE TEST (COL1 NUMBER);
  INSERT INTO TEST VALUES (3);
  commit;
  DROP TABLE TEST;
  此时,如果您要对表 TEST 执行闪回操作,那么列 COL1 的值应该是什么?常规想法可能认为从回收站取回表的第一个版本,列 COL1 的值是 1。实际上,取回的是表的第三个版本,而不是第一个。因此列 COL1 的值为 3,而不是 1。
  此时您还可以取回被删除表的其他版本。但是,表 TEST 的存在不允许出现这种情况。您有两种选择:
  使用重命名选项:
  FLASHBACK TABLE TEST TO BEFORE DROP RENAME TO TEST2;
  FLASHBACK TABLE TEST TO BEFORE DROP RENAME TO TEST1;
  这些语句将表的第一个版本恢复到 TEST1,将第二个版本恢复到 TEST2。 TEST1 和 TEST2 中的列 COL1 的值将分别是 1 和 2。或者,
  使用表的特定回收站名称进行恢复。为此,首先要识别表的回收站名称,然后执行:
  FLASHBACK TABLE “BIN$04LhcpnoanfgMAAAAAANPw==$0” TO BEFORE DROP RENAME TO TEST2;
  FLASHBACK TABLE “BIN$04LhcpnqanfgMAAAAAANPw==$0” TO BEFORE DROP RENAME TO TEST1;
  这些语句将恢复被删除表的两个版本。
  警告…
  取消删除特性使表恢复其原始名称,但是索引和触发器等相关对象并没有恢复原始名称,它们仍然使用回收站的名称。在表上定义的源(如视图和过程)没有重新编译,仍然保持无效状态。必须手动得到这些原有名称并应用到闪回表。
  信息保留在名为 USER_RECYCLEBIN 的视图中。在对表进行闪回操作前,请使用以下查询来检索原有名称。
  SELECT OBJECT_NAME, ORIGINAL_NAME, TYPE
  FROM USER_RECYCLEBIN
  WHERE BASE_OBJECT = (SELECT BASE_OBJECT FROM USER_RECYCLEBIN
  WHERE ORIGINAL_NAME = ‘RECYCLETEST’)
  AND ORIGINAL_NAME != ‘RECYCLETEST’;
  OBJECT_NAME
  ORIGINAL_N TYPE
  --------------------------- - – — - – ----
  BIN$04LhcpnianfgMAAAAAANPw==$0 IN_RT_01
  INDEX
  BIN$04LhcpnganfgMAAAAAANPw==$0 TR_RT
  TRIGGER
  在表进行闪回操作后,表 RECYCLETEST 上的索引和触发器将按照 OBJECT_NAME 列中所示进行命名。根据以上查询,可以使用原始名称重新命名对象,如下所示:
  ALTER INDEX “BIN$04LhcpnianfgMAAAAAANPw==$0” RENAME TO IN_RT_01;
  ALTER TRIGGER “BIN$04LhcpnganfgMAAAAAANPw==$0” RENAME TO TR_RT;
  一个值得注意的例外情况是位图索引。当删除位图索引时,它们并不放置在回收站中 ― 因此无法检索它们。约束名称也无法从视图中检索。必须从其他来源对它们进行重命名。
闪回表的其他用途
  闪回删除表功能不仅限于恢复表的删除操作。与闪回查询类似,您还可以使用它将表恢复到不同的时间点,形如flashback table tmm2076 TO TIMESTAMP to_timestamp(‘2007-05-22
12:00:00’,‘yyyy-mm-dd hh24:mi:ss’)
弹出ORA-08189错误,需要执行以下命令先:
alter table tmm2076 enable row movement这个命令的作用是,允许oracle修改分配给行的rowid。
然后再flashback,数据被恢复完毕。

恢复实例:

drop table test_rel1;
create table test_rel1 as select * from dba_objects;
commit;
drop table test_rel1;
create table test_rel1 as select * from dba_objects;
commit;
drop table test_rel1;
create table test_rel1 as select * from dba_objects;
commit;

生成闪回语句

select original_name
,droptime
,‘flashback table "’||object_name||’" to before drop rename to ‘||original_name||’_bak’||rank() over (partition by original_name order by droptime)||’;’ flashback_script
from user_recyclebin
where to_date(droptime,‘yyyy-mm-dd hh24:mi:ss’)>=to_date(‘2022-09-21 00:00:01’,‘yyyy-mm-dd hh24:mi:ss’)
and type=‘TABLE’
order by 1,2 desc;

根据删除时间恢复指定版本的表数据

flashback table “BIN$6RZtTcO6IiLgUAoKVHrOGg==$0” to before drop rename to TEST_REL1_bak3;
flashback table “BIN$6RZtTcO5IiLgUAoKVHrOGg==$0” to before drop rename to TEST_REL1_bak2;
flashback table “BIN$6RZtTcO4IiLgUAoKVHrOGg==$0” to before drop rename to TEST_REL1_bak1;

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论