Oracle 9i通过闪回查询恢复丢失的或被删除的数据Oracle9i: Recovering lost data through Flashback Query

如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!

诗檀软件专业数据库修复团队

服务热线 : 13764045638 QQ号:47079569 邮箱:service@parnassusdata.com

 

目的

——-

 

本文介绍了新的9i闪回功能,它提供发出查询和访问数据的功能,就像它是在过去的某个点。同时展示了如何使用游标来实现闪回功能的例子。

 

 

范围 & 应用

——————-

 

本文针对想过去某点查看数据的DBA

。这在数据可能被错误删除或更新的情况下特别有用,且执行时间点恢复来检索丢失的数据是不可取或不实际的。

 

 

Oracle9i: 通过闪回恢复丢失的数据

————————————————

 

闪回查询的一个重要用法是取之前的数据并使其成为当前数据的功能。虽然闪回查询不能使你直接使数据向前到当前,可以使用游标来有效做到这一点。

 

闪回查询的实现是使用了撤消undo结构,与9i数据库维持以提供事务支持的结构相同。从Oracle 9i起,数据库有能力通过自动撤消管理(AUM)在指定的撤销表空间中自动管理撤销段。在使用闪回查询之前,强烈建议建立设置数据库运行AUM。这是因为闪回查询依赖于undo_retention时间,这仅在AUM下有效。这个撤销保留期间指定被提交的事务在可能被覆盖前应在撤销段保留多久时间。接着,这一期间就成为了可以“闪回”多远的限制。请注意,如果你没有创建一个足够大的撤销表空间,撤消信息可能在撤消保留期结束前被覆盖。有关在AUM下设置数据库的详细信息,请参考Note: 135090.1

 

初始设置:

————–

 

o   通过创建undo表空间开始:

 

SQL> create undo tablespace UNDOTBS datafile

‘/database/901/V901/undotbs01.dbf’ size 100M;

 

o   一旦你创建了undo表空间,你需要在init.ora或spfile中设置以下参数来配置实例使用    AUM,指定保留时间(在这里是1200 秒)并使用创建的undo表空间:

undo_management=auto

undo_retention=1200

undo_tablespace=UNDOTBS

 

注:UNDO_RETENTION和UNDO_TABLESPACE都可以被动态更改,但UNDO_MANAGEMENT不能。你将需要重启数据库实例来更改其设定。

 

 

o   要使用闪回查询功能,用户必须有

在DBMS_FLASHBACK包的EXECUTE权限。

 

SQL> connect / as sysdba

Connected.

SQL> grant execute on dbms_flashback to testuser;

Grant succeeded.

 

 

———————————–

例#1:闪回到日期/时间:

———————————–

 

要发出一个闪回查询,你需要调用在 DBMS_FLASHBACK 包中的一个程序来回到特定日期/时间值或一个系统更改号(SCN)。要指定日期/时间值,使用

如下例所示DBMS_FLASHBACK.ENABLE_AT_TIME过程:To specify a date/time value, use the

DBMS_FLASHBACK.ENABLE_AT_TIME procedure as shown in this example below:

 

 

o   在testuser的schema,即scott.emp表中当前数据的副本中创建表(假定TESTUSER有必要的权限来访问scott的schema的emp表):

 

SQL> connect testuser/testuser;

Connected.

SQL> create table emp_flash as select * from scott.emp;

Table created.

SQL> select count(*) from emp_flash;

 

COUNT(*)

———-

15

 

o   闪回到日期/时间 – 在这里是当前时间的5分钟前:

 

================================================================================

注:从emp_flash表被创建后等待至少5分钟执行下一个步骤。这是由于闪回时间可能要舍去5分钟,这可能导致闪回时间在创建表之前。在这种情况下会收到一个ORA-01466错误。参见下面的附加信息了解详情。

================================================================================

 

SQL> delete from emp_flash;

15 rows deleted.

SQL> commit;

Commit complete.

SQL> select count(*) from emp_flash;

 

COUNT(*)

———-

0

 

SQL> execute DBMS_FLASHBACK.ENABLE_AT_TIME(sysdate – 5/1440);

PL/SQL procedure successfully completed.

SQL> select count(*) from emp_flash;

 

COUNT(*)

———-

15

 

SQL> execute DBMS_FLASHBACK.DISABLE;

PL/SQL procedure successfully completed.

SQL> select count(*) from emp_flash;

 

COUNT(*)

———-

0

 

在DBMS_FLASHBACK.ENABLE_AT_TIME和 DBMS_FLASHBACK.DISABLE之间执行的查询返回了过去5分钟的数据。注意在DBMS_FLASHBACK.DISABLE命令后,emp_flash表再次没有行。

 

——————————————-

例#2:闪回恢复丢失的数据:

——————————————-

 

虽然在例1使用的技术使你查看数据过去的形式,任何尝试使用INSERT或UPDATE语句使这些被删除行到当前的操作将失败。当启用闪回查询模式时,你只能发出SELECT语句。直到你使用DBMS_FLASHBACK.DISABLE过程退出闪回查询模式才能使用DML语句。

 

 

这个例子将显示闪回查询更有效的使用,即通过使用游标,使先前的数据再次成为当前数据的的功能。游标能同时用于先前和当前的数据,使得目的实现。当你在闪回查询模式打开一个游标,即使调用DBMS_FLASHBACK.DISABLE后游标的内容仍保留在该模式下。

 

To bring prior data forward into the present, you need to enable flashback

query mode, open a cursor to return the data you want to work with from the past,

and then exit flashback query mode.  The cursor continues to return data from

the past, while any DML statements you now issue affect the present. 要使先前数据向前到当前,你需要启用闪回查询模式,打开游标从过去返回你需要操作的数据,然后退出闪回查询模式。游标继续从过去返回数据,而任何现在发出的DML语句影响当前。

 

o   在testuser schema中创建表:

 

SQL> connect testuser/testuser;

Connected.

SQL> create table emp_recover as select * from scott.emp;

Table created.

SQL> select count(*) from emp_recover;

 

COUNT(*)

———-

15

 

================================================================================

注:像之前一样,从emp_flash表被创建后至少等待5分钟,然后这下一步。

================================================================================

 

SQL> VARIABLE SCN_SAVE NUMBER;

SQL> EXECUTE :SCN_SAVE := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER;

PL/SQL procedure successfully completed.

SQL> PRINT SCN_SAVE

 

SCN_SAVE

———-

6.4455E+12

 

SQL> select count(*) from emp_recover;

 

COUNT(*)

———-

15

 

SQL> delete from emp_recover;

15 rows deleted.

SQL> commit;

Commit complete.

SQL> select count(*) from emp_recover;

 

COUNT(*)

———-

0

—————————————————————————

以下会使被删除的行返回当前:

—————————————————————————

 

SQL> DECLARE

2  CURSOR FLASH_RECOVER IS

3  select * from emp_recover;

4  emp_recover_rec emp_recover%ROWTYPE;

5  begin

6  DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(:SCN_SAVE);

7  open FLASH_RECOVER;

8  DBMS_FLASHBACK.DISABLE;

9  loop

10  FETCH FLASH_RECOVER INTO emp_recover_rec;

11  EXIT WHEN FLASH_RECOVER%NOTFOUND;

12  insert into emp_recover

13  values

14  (emp_recover_rec.empno,

15   emp_recover_rec.ename,

16   emp_recover_rec.job,

17   emp_recover_rec.mgr,

18   emp_recover_rec.hiredate,

19   emp_recover_rec.sal,

20   emp_recover_rec.comm,

21   emp_recover_rec.deptno);

22   end loop;

23  CLOSE FLASH_RECOVER;

24  commit;

25  end;

26  /

 

PL/SQL procedure successfully completed.

 

SQL> select count(*) from emp_recover;

 

COUNT(*)

———-

15

 

额外信息

———————-

 

o   闪回查询结果始终基于一个SCN(系统变更编号)。 Oracle9i每隔5分钟跟踪SCN并记录最后五天的操作信息。在数据库启动后每5分钟记录SCN /时间映射。BMS_FLASHBACK.ENABLE_AT_TIME 过程使用此日志以确定与你指定时间相关的SCN并使用该SCN作为你发出的任何闪回查询的基础。这引入了使用DBMS_FLASHBACK.ENABLE_AT_TIME时的两个限制。首先是如果你需要返回五天以上,你需要手动确定并且使用SCN,因为映射信息不保留5天以上。第二个限制是,你发送给DBMS_FLASHBACK.ENABLE_AT_TIME的任何时间值被有效地向下舍入到最接近五分钟的增量。这可能导致数据可能比你需要的最多早5分钟。如果你必须保持精度,应该使用 SCN。

 

o   SYSDATE函数总返回当前系统日期,即使在闪回查询会话下使用。这对于使用SYSDATE的查询有影响。如果你有一个查询返回今天执行的所有事务,且该查询确定“今天”使用SYSDATE,则如果你闪回到昨天,可能会出现意外的结果。你需要考虑在任何执行的闪回查询使用SYSDATE的影响。

 

o   类似于SYSDATE函数,DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER函数始终返回当前SCN,不论你是否在闪回查询模式。

 

o   闪回查询模式只能在事务开始时输入。如果你已经发出DML语句来更改数据,那么你必须在能闪回之前提交。此外,你将无法闪回到表结构中最近更改的时间点之前。这是因为闪回查询使用当前数据字典的数据。即使对一列数据类型的简单更改限制了你的闪回能力。

Comment

*

沪ICP备14014813号-2

沪公网安备 31010802001379号