从Oracle表中恢复已删除的行

13

能否从Oracle表中恢复删除的行?我的数据存储在名为CCO的模式下的一个叫做MANUAL_TRANSACTIONS的表中。我不小心删除了一些50万行,并且已经提交了。现在我想要恢复它们。我正在使用Oracle 11g R2版本。谢谢。


我有几个问题。1)您是否有包含已删除记录的备份。2)您是否启用了闪回功能? - Kent Anderson
谢谢。我在数据库方面很差。我没有任何备份。我使用TOAD执行所有的数据库操作。我不知道FLASHBACK。 - santhosha
请尝试Ravi Tiwari和ik_zelf提到的Flashback。如果这不起作用,我能想到的最后一个选择是服务器备份。那应该是最后的选择。 - Kent Anderson
11个回答

20

您可以使用Oracle Flashback Query来恢复详细信息。 您可以查询表在删除之前的时间点的内容,以了解丢失了哪些数据,并在适当的情况下将丢失的数据重新插入到数据库中。 以下是样例查询:

select * from MANUAL_TRANSACTION as of timestamp to_timestamp('28-APR-2014 12:30:00', 'DD-MON-YYYY HH:MI:SS') where ' clause based on your deleted data';

来源: http://docs.oracle.com/cd/B19306_01/backup.102/b14192/flashptr002.htm


我遇到了这个错误。查找错误 ORA-08186:指定的时间戳无效。 - santhosha
你尝试以什么格式插入时间戳? - Ravi.
请将您的AS OF子句替换为以下内容(不带引号):"AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '120' MINUTE)"。 - Kent Anderson
我不确定我的数据是什么时候被删除的。我猜是三天前。我相应地更改了分钟,但是出现了以下错误。查找错误ORA-01466:无法读取数据 - 表定义已更改。 - santhosha
@santhosha 可能是由于一个 DDL 语句更改了你的表结构导致的错误。 - Ravi.

13

答案已经给出,只是我从上面学到的。

FLASHBACK只能由DBA执行(我猜测),但我们可以使用以下查询:

 Insert into MANUAL_TRANSACTIONS
    (SELECT * FROM MANUAL_TRANSACTIONS AS OF 
    TIMESTAMP TO_TIMESTAMP('2018-07-23 06:41:59', 'YYYY-MM-DD HH:MI:SS'));

或者您可以使用此查询获取一天的记录

Insert into MANUAL_TRANSACTIONS
(SELECT * FROM MANUAL_TRANSACTIONS AS OF 
TIMESTAMP TO_TIMESTAMP('2018-07-23', 'YYYY-MM-DD'));

我的表中有一个长数据类型的列。虽然我可以通过基于时间戳的选择查询看到已删除的行,但当我尝试将已删除的行插入回原始表时,我收到了“SQL错误:ORA-00997:非法使用LONG数据类型”的错误消息。根据https://dev59.com/Pl4b5IYBdhLWcg3wchXs中给出的解决方法,我将列类型更新为CLOB,但现在当我再次运行恢复查询时,我收到了“SQL错误:ORA-01466:无法读取数据 - 表定义已更改”的错误消息。 - vinsinraw

4
select * from MY_TABLE as of timestamp to_timestamp('04-MAY-2017 12:30:00', 'DD-MON-YYYY HH:MI:SS') where ID=1822904;   --- 12Hr  Clock 

上述查询对我有效。您甚至可以使用以下查询查找24小时时间范围。
select * from MY_TABLE as of timestamp to_timestamp('04-MAY-2017 13:30:00', 'DD-MON-YYYY HH24:MI:SS') where ID=1822904;

2

如果您有备份和Oracle 12c,您可以使用表时间点恢复PITR):

RECOVER TABLE 'SCHEMA'.'TAB_NAME'
  UNTIL TIME xxxxyyy
  AUXILIARY DESTINATION '/u01/aux'  
  REMAP TABLE 'SCHEMA'.'TAB_NAME':'TAB_NAME_PREV';

此时的数据将可用:

SELECT * FROM SCHEMA.TAB_NAME_PREV;

2
是的,您可以使用闪回查询(flash back query)。 使用Oracle闪回查询(SELECT AS OF) 这需要假设撤消表空间足够大,并且具有足够的撤消保留。如果撤消已经释放,您可能需要在克隆数据库中执行恢复和恢复操作,然后将数据复制到原始数据库中。还要检查TSPITR(TableSpace Point In Time Recovery)。这仅在数据库以归档日志模式运行并且有备份可用时才可能进行。

1

插入到表名中(选择自SYSDATE-4/24时间戳的TABLE_NAME表中的所有内容)


请详细说明您的问题,仅仅提供代码可能难以理解。 - mle

1

我知道这个回答有些晚了,在长时间搜索如何在Oracle中恢复和还原表格后,我终于找到了一个好的方法,通过使用restore point来进行还原,根据Pro Oracle Database 12C Administration一书,在对表格进行任何操作之前,您可以使用以下语句使用restore point

CREATE RESTORE POINT <your_key_point_name>;

如果要使用还原点恢复表,则可以使用以下方法:

FLASHBACK TABLE <[your_schema.]your_table_name> TO RESTORE POINT <your_key_point_name>;

除了以上关于使用 FLASHBACK 进行恢复的答案,忘记考虑了两个关键点:

  1. 必须启用 FLASHBACK 回收站模式才能使用
  2. 在使用 FLASHBACK 进行任何行恢复之前,必须启用表格中的行移动(使用 ALTER TABLE <[your_schema.]your_table_name> enable ROW MOVEMENT)。根据Oracle文档 link 所述:

在您使用 Flashback Table 之前,必须确保在将要回滚或返回到以前状态的表上启用了行移动。


0

有一些选项:

  1. 闪回查询

    create table before_delete as select * from Table as of TIMESTAMP XX;

  2. 如果启用了Oracle补充日志,则可以使用Logminer获取删除语句的撤消SQL

-- 切换日志文件以获得最小的重做活动 alter system switch logfile;

-- 挖掘最后写入的归档日志

exec dbms_logmnr.add_logfile('archivelog/redologfile', options => dbms_logmnr.new);
exec dbms_logmnr.start_logmnr(options => dbms_logmnr.dict_from_online_catalog);
select operation, sql_redo from v$logmnr_contents where seg_name = 'EMP';
  1. Oracle PRM-DUL 是最后的选择。即使在 Oracle 块中删除行片段时只是标记了带有删除掩码的行标志,但仍然可以通过扫描 Oracle 数据块读取行片段。PRM-DUL 可以扫描整个表,找出每个被标记为已删除的记录/行片段,并将其写入平面文件。

0
请使用以下查询:
Insert into MANUAL_TRANSACTIONS
(SELECT * FROM MANUAL_TRANSACTIONS AS OF 
TIMESTAMP TO_TIMESTAMP('2014-04-27 11:59:59 PM', 'YYYY-MM-DD HH:MI:SS PM'))

1
你能详细解释一下你的答案吗? - Charles Clayton
对我有用,但最后我必须删除 PM。 - Gustavo

0
FLASHBACK TABLE <TABLE_NAME> TO TIMESTAMP(TO_DATE('27-APR-2014 23:59:59','DD-MON-YYYY HH24: MI: SS'));

将表中的数据恢复到指定时间(前提是表未被截断)。

在您的情况下:

FLASHBACK TABLE MANUAL_TRANSACTIONS TO TIMESTAMP(TO_DATE('27-APR-2014 23:59:59','DD-MON-YYYY HH24: MI: SS'));


这是一个时间错误。查找错误ORA-08189:无法回滚表,因为未启用行移动。 - santhosha
坏消息。只有在该表启用行移动功能时,才能回溯到时间戳。 - A Nice Guy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接