zoukankan      html  css  js  c++  java
  • Oracle误删除表数据后的恢复具体解释

    Oracle误删除表数据后的恢复具体解释

     

    測试环境:

    SYSTEM:IBM AIX 5L                         Oracle Version:10gR2

     

    1. undo_retention參数的查询改动

    使show parameter undo命令查看当的数据库參数undo_retention设置。

    显演示样例如以下:

    SQL> show parameter undo

    NAME                                 TYPE        VALUE

    ------------------------------------ ----------- ------------------------------

    undo_management                      string      AUTO

    undo_retention                       integer     900

    undo_tablespace                      string      UNDOTBS2

    undo_retention(保持力),900单位是15分钟

    改动默认的undo_retention參数设置:

    SQL> ALTER SYSTEM SET undo_retention=10800 SCOPE=BOTH;

    System altered.

    SQL> show parameter undo

    NAME                                 TYPE        VALUE

    ------------------------------------ ----------- ------------------------------

    undo_management                      string      AUTO

    undo_retention                       integer     10800

    undo_tablespace                      string      UNDOTBS2

    undo_retention 10800,单位秒,即3小时。

    2. oracle误删除表数据后的的高速恢复功能方法

    2.1 方法一
    通过oracle提供的回闪功能
    exec dbms_flashback.enable_at_time(to_date('2011-04-15 08:21:00','yyyy-mm-dd hh24:mi:ss'));

    set serveroutput on
    DECLARE r_temp hr.job_history%ROWTYPE;
    CURSOR c_temp IS SELECT * FROM hr.job_history;
    BEGIN
    OPEN c_temp;
    dbms_flashback.disable;
    LOOP
    FETCH c_temp INTO r_temp;
    EXIT WHEN c_temp%NOTFOUND;
    insert into hr.job_history(EMPLOYEE_ID,JOB_ID,START_DATE,END_DATE) values (r_temp.EMPLOYEE_ID,r_temp.JOB_ID,r_temp.START_DATE,r_temp.END_DATE);
    commit;
    END LOOP;
    CLOSE c_temp;
    END;
    这样的办法能够将删除的数据恢复到相应的表中,首先要保证该用户有运行dbms_flashback包的权限

    2.2 方法二
    insert into hr.job_history
    select * from hr.job_history as of timestamp to_timestamp('2011-04-15 08:20:00', 'yyyy-mm-dd hh24:mi:ss');
    这样的方法简单,easy掌握,功能和上面的一样,此处的时间为你误操作之前的时间,最好是离误操作比較近的,由于oracle保存在回滚保持段里的数据时间有一定的时间限制,这个限制undo_retention 这个參数值决定。

    查看FIRST_CHANGE#,NEXT_CHANGE#,FIRST_TIME

    SQL> set pagesize 9999

    SQL> col fscn for 999999999

    SQL> col nscn for 999999999

    SQL> select name,FIRST_CHANGE# fscn,NEXT_CHANGE# nscn,FIRST_TIME from v$archived_log;

    当前的SCN为:

    SQL> select dbms_flashback.get_system_change_number fscn from dual;

          FSCN

    ----------

       3435958


    使用应用用户尝试闪回

    SQL> connect username/password

    Connected.


    现有数据:

    SQL> select count(*) from hs_passport;

      COUNT(*)

    ----------

        851998

    创建恢复表

    SQL> create table hs_passport_recov as select * from hs_passport where 1=0;

    Table created.


    选择SCN向前恢复

    SQL> select count(*) from hs_passport as of scn 12929970422;

      COUNT(*)

    ----------

        861686


    尝试多个SCN,获取最佳值(假设能得知详细时间,那么能够获得准确的数据闪回)

    SQL> select count(*) from hs_passport as of scn &scn;

    Enter value for scn: 12929941968

    old   1: select count(*) from hs_passport as of scn &scn

    new   1: select count(*) from hs_passport as of scn 12929941968

      COUNT(*)

    ----------

        861684

    SQL> /

    Enter value for scn: 12927633776

    old   1: select count(*) from hs_passport as of scn &scn

    new   1: select count(*) from hs_passport as of scn 12927633776

    select count(*) from hs_passport as of scn 12927633776

                         *

    ERROR at line 1:

    ORA-01466: unable to read data - table definition has changed

    SQL> /

    Enter value for scn: 12929928784

    old   1: select count(*) from hs_passport as of scn &scn

    new   1: select count(*) from hs_passport as of scn 12929928784

      COUNT(*)

    ----------

        825110

    SQL> /

    Enter value for scn: 12928000000

    old   1: select count(*) from hs_passport as of scn &scn

    new   1: select count(*) from hs_passport as of scn 12928000000

    select count(*) from hs_passport as of scn 12928000000

                         *

    ERROR at line 1:

    ORA-01466: unable to read data - table definition has changed


    最后选择恢复到SCN为12929941968的时间点

    SQL> insert into hs_passport_recov select * from hs_passport as of scn 12929941968;

    861684 rows created.

    SQL> commit;

    Commit complete.

    数据恢复简单样例

    在过去,假设用户误删/更新了数据后,作为用户并没有什么直接的方法来进行恢复,他们必须求助DBA来对数据库进行恢复,到了Oracle9i,这一难堪局面有所改善。Oracle 9i中提供了一项新的技术手段--闪回查询,用户使用闪回查询能够及时取得误操作前的数据,并能够针对错误进行对应的恢复措施,而这一切都无需DBA干预。

    3. 以下我们通过一个样例来详细说明闪回查询的使用方法

    演示样例
    3.1 使用闪回查询前必须确定以下两个參数:
    UNDO_MANAGEMENT = AUTO
    undo_retention = 10800; 

    这个时间能够随便设,表示在系统中保留提交了的UNDO信息的时间,10800就是保留3小时,即180分钟。

    3.2 使用闪回查询
    SQL> conn /as sysdba

    Connected.

    SQL> drop user lsf cascade;

    User dropped.

    SQL> create user lsf identified by lsf;

    User created.

    SQL> grant connect,resource to lsf;

    Grant succeeded.

    SQL> grant execute on dbms_flashback to lsf;

    Grant succeeded.

    SQL> conn lsf/lsf

    Connected.

    SQL> create table T(id int, name varchar2(20));

    Table created.

    SQL> insert into T values(1,'lsf');

    1 row created.

    SQL> insert into T values(2,'lsf');

    1 row created.

    SQL> insert into T values(3,'lsf');

    1 row created.

    SQL> commit;

    Commit complete.

    SQL> select * from T;

            ID NAME

    ---------- ------------------------------------------------------------

             1 lsf

             2 lsf

             3 lsf

    SQL> set time on

    10:12:50 SQL> delete from T where id=1;

    1 row deleted.

    10:13:02 SQL> commit;

    Commit complete.

    10:13:10 SQL> select * from T;

            ID NAME

    ---------- ------------------------------------------------------------

             2 lsf

             3 lsf

    10:13:18 SQL> execute DBMS_FLASHBACK.ENABLE_AT_TIME(to_date('2011-04-15 10:12:50','YYYY-MM-DD HH24:MI:SS'));

    PL/SQL procedure successfully completed.

    10:13:50 SQL> select * from T;

            ID NAME

    ---------- ------------------------------------------------------------

             1 lsf

             2 lsf

             3 lsf

    10:13:57 SQL> execute DBMS_FLASHBACK.DISABLE;

    PL/SQL procedure successfully completed.

    10:15:48 SQL> select * from T;

            ID NAME

    ---------- ------------------------------------------------------------

             2 lsf

             3 lsf


    3.3 使用闪回查询恢复数据
    10:16:59 SQL> truncate table T;

    Table truncated.

    10:18:15 SQL> select * from T;

    no rows selected


    10:18:22 SQL> insert into T values(1,'lsf');

    1 row created.

    10:19:42 SQL> insert into T values(2,'lsf');

    1 row created.

    10:19:48 SQL> insert into T values(3,'lsf');

    1 row created.

    10:19:55 SQL> insert into T values(4,'lsf');

    1 row created.

    10:20:07 SQL> insert into T values(5,'lsf');

    1 row created.

    10:20:15 SQL> insert into T values(6,'lsf');

    1 row created.

    10:20:21 SQL> commit;

    Commit complete.

    10:20:26 SQL> select * from T;

            ID NAME

    ---------- ------------------------------------------------------------

             1 lsf

             2 lsf

             3 lsf

             4 lsf

             5 lsf

             6 lsf

    6 rows selected.

    10:20:56 SQL> delete T;

    6 rows deleted.


    10:21:27 SQL> commit;

    Commit complete.


    10:21:40 SQL> declare

    10:22:29   2  cursor flash_recover is

    10:22:43   3  select * from T;

    10:22:50   4  t_recode T%rowtype;

    10:23:11   5  begin

    10:23:14   6  DBMS_FLASHBACK.ENABLE_AT_TIME(to_date('2011-04-15 10:20:56','YYYY-MM-DD HH24:MI:SS'));

    10:24:22   7  open flash_recover;

    10:24:39   8  DBMS_FLASHBACK.DISABLE;

    10:24:59   9  loop

    10:25:05  10  FETCH flash_recover into t_recode;

    10:25:24  11  EXIT WHEN flash_recover%NOTFOUND;

    10:25:45  12  insert into T values(t_recode.id,t_recode.name);

    10:26:35  13  end loop;

    10:26:39  14  CLOSE FLASH_RECOVER;

    10:26:50  15  commit;

    10:26:56  16  end;

    10:26:58  17  /

    PL/SQL procedure successfully completed.


    10:27:00 SQL> select * from T;

            ID NAME

    ---------- ------------------------------------------------------------

             1 lsf

             2 lsf

             3 lsf

             4 lsf

             5 lsf

             6 lsf

    6 rows selected.


    我们能够已经恢复了全部的6条纪录,可是因为闪回查询的局限性有可能不能恢复全部的6条记录,原因就在以下。

    4. 局限性

    4.1 闪回查询是基于SCN的,尽管我运行的是:
    DBMS_FLASHBACK.ENABLE_AT_TIME(to_date('2011-04-15 10:20:56','YYYY-MM-DD HH24:MI:SS'));
    但Oracle并不会精确的这个时间点,而是ROUND DOWN到近期的一次SCN,然后从这个SCN開始进行恢复。而Oracle 9i是每五分钟记录一次SCN的,并将SCN和相应时间的映射做个纪录。 

    因此假设使用DBMS_FLASHBACK.ENABLE_AT_TIME来进行恢复,为了避免恢复失败,我能够先等5分钟,然后再进行恢复。
    使用DBMS_FLASHBACK.ENABLE_AT_TIME进行恢复另一个缺点,那就是在Oracle 9i中SCN和相应时间的映射信息仅仅会保留5天,因此我们无法通过DBMS_FLASHBACK.ENABLE_AT_TIME来恢复5天前的数据。假设你想使用闪回查询来恢复5天前的数据,你必须自己来确定须要恢复的SCN,然后使用DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(SCN_NUMBER); 来定位你的恢复时间点,以下是用法:
    10:27:27 SQL> VARIABLE SCN_SAVE NUMBER;

    10:32:47 SQL> EXECUTE :SCN_SAVE := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER;

    PL/SQL procedure successfully completed.

    10:33:24 SQL> print SCN_SAVE;

      SCN_SAVE

    ----------

       3438420

    10:33:41 SQL> execute DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(:SCN_SAVE);

    PL/SQL procedure successfully completed.

    10:34:31 SQL> select * from T;

            ID NAME

    ---------- ------------------------------------------------------------

             1 lsf

             2 lsf

             3 lsf

             4 lsf

             5 lsf

             6 lsf

    6 rows selected.


    另外,在使用DBMS_FLASHBACK.ENABLE_AT_TIME前,你必须设定你的NLS_DATE_FORMAT的精确程度,Oracle默认的是精确到天,假设你不设定,像上面的样例你不会得到预期结果。

    4.2 假设你使用sysdate和DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER来获取时间点或者SCN值,你必须注意它们取得都是当前的时间点和SCN值。

    4.3 你仅仅能在事务開始时进入闪回查询模式,假设之前有DML操作,则必须COMMIT

    4.4 闪回查询无法恢复到表结构改变之前,由于闪回查询使用的当前的数据字典

  • 相关阅读:
    centos 安装 TortoiseSVN svn 客户端
    linux 定时任务 日志记录
    centos6.5 安装PHP7.0支持nginx
    linux root 用户 定时任务添加
    composer 一些使用说明
    laravel cookie写入
    laravel composer 安装指定版本以及基本的配置
    mysql 删除重复记录语句
    linux php redis 扩展安装
    linux php 安装 memcache 扩展
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4353795.html
Copyright © 2011-2022 走看看