【问题标题】:Recovering deleted rows from oracle table从 oracle 表中恢复已删除的行
【发布时间】:2014-06-13 14:38:52
【问题描述】:

这是否可以从 oracle 表中恢复已删除的行?我的数据存储在 MANUAL_TRANSACTIONS 表中。架构名称是 CCO。我不小心删除了表中的大约 50 万行并且也进行了提交。现在我想恢复它们。我正在使用 Oracle 11g R2。谢谢

【问题讨论】:

  • 我有几个问题。 1)您是否有包含已删除记录的备份。 2) 是否启用了闪回功能?
  • 谢谢。我的数据库很差。我没有任何备份。我使用 TOAD 来执行我所有的数据库操作。我不知道闪回。
  • 请按照 Ravi Tiwari 和 ik_zelf 的说明尝试闪回 如果这不起作用,我能想到的最后一个选项是服务器备份。这应该是最后的选择。

标签: oracle


【解决方案1】:

您可以使用 Oracle 闪回查询恢复详细信息。 您可以在删除之前查询表的内容以找出丢失的数据,如果合适,可以将丢失的数据重新插入数据库。 这是示例查询:

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: 指定的时间戳无效
  • 您要以什么格式插入时间戳?
  • 将您的 AS OF 子句替换为以下内容(不带引号):“AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '120' MINUTE)”
  • 我不确定我的数据何时被删除。我假设它是 3 天前。我相应地更改了分钟,但抛出以下错误。查找错误 ORA-01466:无法读取数据 - 表定义已更改
  • @santhosha 这个错误很可能是因为 DDL 语句改变了你的表结构。
【解决方案2】:

答案已经给出了我在上面学到的内容。 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 Error: ORA-00997: 非法使用 LONG 数据类型" 。根据@stackoverflow.com/questions/29116396/… 给出的解决方法,我将列类型更新为 CLOB,但现在当我再次运行恢复查询时,我得到“SQL 错误:ORA-01466:无法读取数据 - 表定义已更改”。
【解决方案3】:
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;

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      如果您有备份和 Oracle 12c,您可以使用 Table Point In Time Recovery (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;
      

      【讨论】:

        【解决方案6】:

        我知道答案为时已晚,经过长时间搜索如何在 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 &lt;[your_schema.]your_table_name&gt; enable ROW MOVEMENT)。根据oracle文档link

        在您可以使用闪回表之前,您必须确保在要闪回或返回到先前状态的表上启用行移动。

        【讨论】:

          【解决方案7】:
          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: 由于未启用行移动,无法闪回表
          • 坏消息。仅当在该表上启用行移动时,闪回时间戳才有效
          【解决方案8】:

          使用这个查询,

          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'))
          

          【讨论】:

          • 你能解释一下你的答案吗?
          • 为我工作,但最后我不得不删除 PM。
          【解决方案9】:

          有一些选择:

          1. 闪回查询为

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

          2. Logminer 如果启用了 Oracle 补充日志,你可以为你的删除语句获取 undo sql

          -- 再次切换日志文件以获得最小的重做活动 更改系统切换日志文件;

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

          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 可以扫描整个表,找出标记为已删除的每条记录/行并写入平面文件。

          【讨论】:

            【解决方案10】:

            你可以尝试的是:

            1. 闪回查询,可从 oracle 10g 获得,可能因 ora-01555 快照太旧而失败
            2. redo logminer , mine redo 可能会找到 undo sql
            3. prm-dul工具(oracle的商业恢复工具),可以扫描oracle块,甚至可以找到已删除的行块

            【讨论】:

              【解决方案11】:

              INSERT INTO TABLE_NAME(SELECT * FROM TABLE_NAME AS OF TIMESTAMP(SYSDATE - 4/24)

              【讨论】:

              • 请详细说明你的问题,只是放代码很难理解。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-12-18
              • 1970-01-01
              • 1970-01-01
              • 2016-02-20
              • 2021-04-05
              • 2012-02-11
              • 2021-07-30
              相关资源
              最近更新 更多