ITPub博客

首页 > 数据库 > Oracle > ORACLE FLAHBACK 系列(包含版本9与版本10)(zt)

ORACLE FLAHBACK 系列(包含版本9与版本10)(zt)

原创 Oracle 作者:jolly10 时间:2008-05-14 15:35:33 0 删除 编辑
ORACLE FLAHBACK 系列(包含版本9与版本10)(zt)[@more@]

第一章、前言

根据以往的经验,很多操作失误或者用户错误,将导致应用停顿甚至终止,但是,实际上,防止这种误操作的办法是非常用限的。如果没有良好的计划与高超的技术,一个很小的错误将可能导致一个很大的影响,如错误的删除(delete)数据或者是删除(drop)一个表。

那怎么样来防止这种“不小心的操作呢”,Oracle从版本9开始,就开始提供了flashback query(闪回查询)的功能,最初的功能也是很有限的,不仅完全依赖于自动Undo(AUM),对于droptruncateDDL操作是毫无办法,而且,由于受到Undo空间限制,能闪回的时间也是有限的。Oracle的版本10中,对falshback做了巨大的改进,不再仅仅是局限于AUM的闪回查询了,甚至可以闪回整个数据库,您将真正的回到操作之前的状态。


在以下的章节中,我们将了解到如下的内容

1、 Oracle 9i开始的flashback query

2、 Oracle 9i开始的flashback exp

3、 Oracle 10gflashback database

4、 Oracle 10g flashback table

5、 Oracle 10g flashback drop

6、 Oracle 10g flashback version query

7、 Oracle 10g flashback transaction query

第二章、从Oracle 9i开始的flashback query

2.1Oracle 9iflashback query

在过去,如果用户错误操作数据后,除了不完全恢复外,没有好的解决办法,到了Oracle9i,这一个难堪局面有所改善。Oracle 9i中提供了一项新的技术手段——flashback query(闪回查询),这个功能的实现,由一个新的包DBMS_FLASH来实现。用户使用闪回查询可以及时取得误操作前的数据,并可以针对错误进行相应的恢复措施。

如果需要用到闪回查询,必须在init.ora或者是spfile.ora中设置以下参数UNDO_MANAGEMENT = AUTO ,在Oracle9i中,该参数默认就是AutoAUM)。与此相关的其它参数还有:

SQL> show parameter undo

NAME TYPE VALUE

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

undo_management string AUTO

undo_retention integer 10800

undo_suppress_errors boolean FALSE

undo_tablespace string UNDOTBS

除了确保以上参数中的UNDO_MANAGEMENT = AUTO外,还要注意另外一个参数undo_retention = n(秒),它决定了能往前闪回的最大时间,从参数也可以看到,这个参数决定了Undo最多的保存时间,越大的值,就会需要更多的Undo空间的支持。我们可以通过如下的命令来修改该参数

SQL> ALTER SYSTEM SET undo_retention = 1200;

System altered.

以上的命令,告诉OracleUndo信息将保持1200(20分钟),这个将确保任何提交后的信息在Undo中将保持20分钟,除了可以一定程度的防止Ora-01555错误外,Falshback query将也直接的应用到其中的信息。

现在,我们用一个简单的例子来说明Oracle 9iflashback query

1、创建FLASH用户

SQL> create user flash identified by flash;

SQL> grant connect, resource to flash;

SQL> grant execute on dbms_flashback to flash;

SQL> connect flash/flash

2、创建一个测试表

SQL> CREATE TABLE tst(t number(5));

Table created.

SQL> INSERT INTO tst VALUES(1);

1 row created.

SQL> INSERT INTO tst VALUES(2);

1 row created.

SQL> COMMIT;

Commit complete.

SQL> CREATE TABLE keep_date (date_scn_tracking date);

Table created.

SQL> SELECT * FROM tst;

T

----------

1

2

注意在执行步骤3或者步骤4之前,等待5分钟。

3. 删除记录

SQL> execute dbms_flashback.disable;

PL/SQL procedure successfully completed.

SQL> INSERT INTO keep_date select sysdate from dual;

1 row created.

SQL> COMMIT;

Commit complete.

SQL> DELETE FROM tst WHERE t = 1;

1 row deleted.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM tst;

T

----------

2

通过以上的操作,我们插入了两条记录,并删除了其中一条记录,现在的结果是,我们这里只有一条记录了。在以下的操作中,我们将通过flashback query找到删除的记录

4. 闪回查询

SQL> declare

2 restore_scn date;

3 begin

4 select date_scn_tracking into restore_scn from keep_date;

5 dbms_flashback.enable_at_time(restore_scn);

6 end;

7 /

PL/SQL procedure successfully completed.

SQL> SELECT * FROM tst;

T

----------

1

2

可以看到,虽然我们删除记录并提交了,但是通过特定操作,我们还能查询到删除前的两条记录,

这里需要特别注意的是,Oracle 9i是每五分钟记录一次SCN的,并将SCN和对应时间的映射做个纪录。如果原来插入的记录到做闪回的时间在5分钟之内,用基于时间的flashback可能并查询不到记录,因为如果是基于时间点的查询,也是转化为最近的一次SCN,然后从这个SCN开始进行恢复,因此,如果需要精确的查询,我们可以采用基于SCNflashback,它将能精确的闪回到需要恢复的时间,关于获取SCN,我们可以通过DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER或者LOGMNR。如

DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(SCN_NUM);

来定位你的恢复时间点,下面是使用方法:

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

----------

2.1202E+11

SQL>execute DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(:SCN_SAVE);

最后注意,Oracle 9iFlashback有如下限制。

·采用时间点的恢复,不能精确到最近5分钟,如果需要更精确的查询,需要采用SCN

·不能flashback5天以前的数据,这个并不是undo_retention所能决定的。

·闪回查询无法恢复到表结构改变之前,因为闪回查询使用的当前的数据字典。

·由于受到undo_retention的影响,对于undo_retention之前的时间,flashback不保证能成功

·对于drop,truncate等不记录回滚的操作,flashback是无能为力的。

2.2Oracle 10gflashback query

Oracle 9iflashback query10g中也有了新的变化,10g中可以简单的利用查询语句实现flashback query,而不再需要象9i那样需要调用DBMS_FLASHBACK包。

SELECT * FROM TABLENAME AS OF TIMESTAMP

TO_TIMESTAMP('2003-04-04 09:30:00', 'YYYY-MM-DD HH:MI:SS')

WHERE ……;

或者

SELECT * FROM TABLENAME AS OF SCN

SCN_NUMBER

WHERE ……;

我们可以通过一个简单例子来说明这个问题

SQL> create table t1 as select * from dba_objects;

Table created

SQL> select count(*) from t1;

COUNT(*)

----------

43116

可见,现在记录是43116,我们获得现在的系统SCN

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER

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

377688

然后,我们删除该表

SQL> delete from t1;

43116 rows deleted

SQL> commit;

Commit complete

通过如下检查的查询

SQL> SELECT count(*) FROM t1 AS OF SCN 377688;

COUNT(*)

----------

43116;

我们可以看到,查询到的记录数依然是删除前的记录数。

10g除了操作上的简单外(不需要调用DBMS_FLASHBACK包),而且在基于时间上的flashback不再有5分钟的限制了,也可以象SCN一样进行精确的flashback query

第二章、从Oracle 9i开始的flashback exp

9i开始,exp工具开始提供闪回导出,就是说,在现在时间,可以导出上一个时间点的数据,exp工具将提供两种闪回导出的方法,以下是9i以后版本exp新增的两个参数,默认情况下,它们都是”none”,如果被设置指定的值,将调用DBMS_FLASH包来获取时间点上的数据

·基于SCN的导出SCN (FLASHBACK_SCN)基于特定SCN的导出

·基于时间的导出time (FLASHBACK_TIME),基于特定的时间,但是影射为最近的SCN

1. 参数FLASHBACK_SCN

这个参数指定了一个exp导出的特定的SCN,导出的所有数据将保持这个SCN的一致性。默认情况下是none,表示不 调用flashback query,如

exp system/manager file=exp.dmp flashback_scn=2106860

2. 参数 FLASHBACK_TIME.

这个参数表示导出将基于"YYYY-MM-DD HH24:MI:SS"的一个时间戳,exp将找到最近的一个SCN来代替这个时间戳来进行导出。 默认是none,表示不调用flashback query,格式如

exp system/manager file=exp.dmp flashback_time='"2002-07-19 13:24:26"'

Oracle 9iflashback exp如同oracle 9iflashback query,它们有着同样的局限性(其实exp就是调用dbms_flash包),所以同样需要设定AUMundo_retention,如果是时间方式,也不能精确到最近5分钟。除此之外,因为exp调用了dbms_flash包,所以普通用户如果想采用这种方式的导出,必须授权,如

sqlplus /nolog

SQL> connect / as sysdba

SQL> GRANT execute ON dbms_flashback TO test;

SQL> exit

这两个参数也不支持交互方式的导出,只能用命令行方式或者是参数文件。而且在表空间传输方式的时候,不能使用该方式。任何表结构的修改或者是Drop,truncateDDL语句也影响这种导出方式,因为这些操作将引起undo无法正常会到以前的数据。

下面将举例说明该问题

首先,我们设置相关环境变量

如果在win下面

C:> SET NLS_DATE_FORMAT=YYYY-MM-DD HH24:MI:SS

--如果是C SHELL

-- $ setenv NLS_DATE_FORMAT 'YYYY-MM-DD HH24:MI:SS'

-- KORN-shell:

-- $ export NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'

-- VMS:

-- DEFINE/NOLOG NLS_DATE_FORMAT "YYYY-MM-DD HH24:MI:SS"

SQL>conn / as sysdba

SQL>GRANT EXECUTE ON dbms_flashback to test;

-- 我们用SCOTT用户登录并创建测试表

SQL>conn test/test

SQL>CREATE TABLE flash AS SELECT * FROM USER_OBJECTS;

SQL>SELECT COUNT(*) FROM flash;

COUNT(*)

----------

14;

SQL> SELECT SYSDATE, dbms_flashback.get_system_change_number FROM DUAL;

SYSDATE GET_SYSTEM_CHANGE_NUMBER

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

2004-4-13 13:15:21 386524

如果是版本9,为了防止ORA-1466 "table definition has changed"错误,需要等待5分钟后操作,现在,假定等待了5分钟,我们开始删除表。

SQL> DELETE FROM flash;

SQL>COMMIT;

SQL>SELECT COUNT(*) FROM flash;

COUNT(*)

----------

0

可以看到,记录已经被清除了,现在,我们运行导出命令,可以看到,有14行从flash表中导出

HOST exp test/test file=exp_flash.dmp log=exp_flash.log tables=flash

flashback_scn=386524

当然,10g也支持flashback exp,而且如同其它flashback的改进一样,在10g中,你可以精确的利用时间点来导出了。

第三章、ORACLE 10gFLAHSBACK新特性

Oracle 10gflashback有了强劲的改进,从普通的falshback query发展到了多种形式,主要表现在如下几个主要方面。通过Oracle 10g,你甚至可以不需要从备份恢复,完成恢复工作。

l Oracle Flashback Database

这个特性允许你通过SQL语句FLASHBACK DATABSE语句,让数据库前滚到当前的前一个时间点或者SCN,而不需要做时间点的恢复。

l Oracle Flashback Table

这个特性允许你利用SQL语句FLASHBACK TABLE语句,确保回滚到表的前一个时间点。

l Oracle Flashback Drop

Oracle 10g开始提供一个类似垃圾站的功能,来恢复不小心被drop的表

l Oracle Flashback Version Query

利用保存的回滚信息,你可以看到特定的表在时间段内的任何修改,如电影的回放一样,你将了解表在该期间的任何变化

l Oracle Flashback Transaction Query

这个特性将确保您检查数据库的任何改变在一个事务级别。你可以利用它来诊断问题,性能分析和审计事务

3.1Flashback database

闪回数据库可以迅速的时数据库回到误操作或人为错误的前一个时间点,如实际中的“撤消”操作,将可以不利用备份就快速的实现时间点的恢复(有后悔药可以吃了)。实际上,Oracle为了实现这一个功能,创建了另外一组日志,就是Flashback Logs(前滚日志),记录数据库的前滚操作。如果希望能闪回数据库,需要设置如下参数:

·DB_RECOVER_FILE_DEST

·DB_RECOVER_FILE_DEST_SIZE

这两个参数来确定Flashback日志的存放地点与该恢复区的大小。在创建数据库的时候,Oracle将自动创建恢复区(需要注意,该恢复区可不仅仅是为了flashback log,还可以用来归档,备份与恢复),但是默认是关闭Flashback database功能。如果想要利用这一功能,DBA就必须正确的配置该日志区的大小,如一个数据库的数据库,每天有10%的块发生改变,那么一天(24小时)的Flash Recovery Area就是1/10个数据库大小。DBA也可以动态的改变其大小以满足不同的需求。

另外一个参数DB_FLASHBACK_RETENTION_TARGET参数允许您设定闪回数据的保存时间,单位是分。默认是一天(24*60

如果想启动FLASHBACK DATABASE的功能,您必须在MOUNT模式下,执行alter database flashback on命令。或者是alter tablespace tsname flashback on,数据库将采集falshback log,如果需要关系该功能,则修改OnOFF

如果想执行flashback database命令,你可以在两种方式下执行:RMANSQLPLUS,如

SQL >flashback database to time to_date(xxx);

SQL >flashback database to time TO_TIMESTAMP (xxx);

SQL >flashback database to scn xxx

SQL >flashback database to sequence xxx thread 1

SQL>flashback database to timestamp(sysdate-1/24)

我们下面看看具体的例子说明

SQL> startup mount

ORACLE instance started.

Total System Global Area 113246208 bytes

Fixed Size 787708 bytes

Variable Size 87030532 bytes

Database Buffers 25165824 bytes

Redo Buffers 262144 bytes

Database mounted.

SQL> alter database flashback on;

alter database flashback on

*

ERROR at line 1:

ORA-38706: Cannot turn on FLASHBACK DATABASE logging.

ORA-38707: Media recovery is not enabled.

可以看到flashback还必须要归档的保证

SQL> alter database archivelog;

Database altered.

SQL> alter database flashback on;

Database altered.

SQL> alter database open;

Database altered.

SQL> archive log list

Database log mode Archive Mode

Automatic archival Enabled

Archive destination USE_DB_RECOVERY_FILE_DEST

Oldest online log sequence 13

Next log sequence to archive 15

Current log sequence 15

经过以上步骤,我们确保了flashback database的功能,我们还可以发现,10g的自动归档是不需要手工干预的,只要开启了归档,就是自动归档了,归档区也在DB_RECOVERY_FILE_DEST参数指定的地点。

通过如下的查询

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

Session altered.

SQL> SELECT OLDEST_FLASHBACK_SCN, OLDEST_FLASHBACK_TIME

2 FROM V$FLASHBACK_DATABASE_LOG;

OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TI

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

1135440 2004-04-06 15:20:57

我们可以知道,可以前滚恢复到的最早的SCN与时间点是多少,如果没有确保flashback database,该视图将没有查询结果。

我们创建三个一样的表

SQL> create table t1 as select * from dba_objects;

Table created.

SQL> create table t2 as select * from t1;

Table created.

SQL> create table t3 as select * from t1;

Table created.

SQL> set time on;

SQL> select sysdate from dual;

SYSDATE

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

2004-04-06 15:29:33

我们确定了一个时间点

现在,我们分别truncate一个表与drop一个表,模拟误操作。

15:30:10 SQL> truncate table t2;

Table truncated.

15:30:43 SQL> drop table t3;

Table dropped.

没有备份,我们利用flashback来恢复数据库到2004-04-06 15:29:33时间点。

15:39:02 SQL> shutdown immediate;

Database closed.

Database dismounted.

ORACLE instance shut down.

15:39:31 SQL> startup mount exclusive

ORACLE instance started.

15:41:19 SQL> FLASHBACK DATABASE TO timestamp(to_date('2004-04-06 15:29:33','yyyy-mm-dd hh24:mi:ss'));

Flashback complete.

之后,我们可以用ALTER DATABASE OPEN READ ONLY来检查结果是否正确如果满足结果则可以用resetlog来正式启动数据库注意一旦resetlogs之后将不能再flashbackresetlogs之前的时间点。

15:41:32 SQL> alter database open resetlogs;

Database altered.

我们现在查询那三个表

15:42:10 SQL> select count(*) from t1;

COUNT(*)

----------

47708

15:42:47 SQL> select count(*) from t2;

COUNT(*)

----------

47708

15:42:50 SQL> select count(*) from t3;

COUNT(*)

----------

47708

发现truncate的记录或者是drop的表都存在,现在数据库已经前滚到前一个时间点了。

15:44:56 SQL> SELECT OLDEST_FLASHBACK_SCN, OLDEST_FLASHBACK_TIME

15:45:05 2 FROM V$FLASHBACK_DATABASE_LOG;

OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TI

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

1136169 2004-04-06 15:41:50

同时发现数据库的最早的flashback的时间与scn都回到resetlog的时间点了。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/271283/viewspace-1004034/,如需转载,请注明出处,否则将追究法律责任。

上一篇: DBA优化之路(zt)
请登录后发表评论 登录
全部评论

注册时间:2008-02-20

  • 博文量
    263
  • 访问量
    761517