您的位置:首页 > 数据库 > Oracle

数据恢复[Oracle] Flashback闪回机制

2013-05-13 23:59 459 查看
最近研究数据恢复,稍微总结一下,以后继续补充:

数据库

级别:Flashback Database

表级别:Flashback Drop和Flashback Table,Flashback Data Archive

记录级别:Flashback Version Query和Flashback Transaction Query

Flashback家族Flashback Log
Tablespace Recycle Bin
UNDO作用
Flashback Database
Yes回滚数据库
Flashback Drop
Yes恢复误删除的表
Flashback Version Query
Yes恢复误操纵的数据
Flashback Transaction Query
Yes同上
Flashback Table
Yes同上

Flashback 技巧发展过程



Flashback Query

和Flashback

Table

都是利用undo实现回退功能,当须要闪回到过去某一时刻时,先利用Flashback Query查询,确认闪回的SCN或Timestamp,然后再利用Flashback Table真正实现闪回。

1. 9i 的 Flashback Query

9i的Flashback Query可以查询过去某个时光点对象的状态,测试如下:

系统当前时光为:

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

A105024@O02DMS1>select sysdate from dual;

SYSDATE

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

2011-12-16:02:51:16

test内外有一条数据:

A105024@O02DMS1>select * from test;

ID

----------

1

现把该数据删除:

A105024@O02DMS1>delete from test;

A105024@O02DMS1>commit;

此时test表中无数据:

A105024@O02DMS1>select * from test;

no rows selected

但是可以通过Flashback Query查询删除之前的数据:

A105024@O02DMS1>select * from test as of timestamp to_timestamp('2011-12-16:02:51:16','yyyy-mm-dd:hh24:mi:ss');

ID

----------

1

必要时还可以

恢复

数据:

A105024@O02DMS1>insert into test select * from test as of timestamp to_timestamp('2011-12-16:02:51:16','yyyy-mm-dd:hh24:mi:ss');

A105024@O02DMS1>commit;

2. Flashback Version Query

10g

新引入的Version Query可以看到过去某个时光段内,数据是如何变更的,也就是数据的演变历史,为此,10g还引入了一个新的伪列ORA_ROWSCN:记录该数据最后一次修改时的SCN。

A105024@O02DMS1>create table test (id number, name varchar(10));

A105024@O02DMS1>insert into test values (1,'first');

A105024@O02DMS1>commit;

A105024@O02DMS1>update test set name='second' where id=1;

A105024@O02DMS1>commit;

A105024@O02DMS1>update test set name='third' where id=1;

A105024@O02DMS1>commit;

我们创建了一个测试表,插入一条数据,并对该数据进行两次更新,下面看如何用Version Query获得数据的演变历史:

A105024@O02DMS1>select versions_xid,versions_startscn,versions_endscn,versions_operation,id,name from test versions between scn minvalue and maxvalue where id=1;

每日一道理

自己把自己说服了,是一种理智的胜利;自己被自己感动了,是一种心灵的升华;自己把自己征服了,是一种人生的成功。

VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN VERSIONS_OPERATION ID NAME

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

12000900D0720000 6629455993 U 1 third

0C0018003D720000 6629455988 6629455993 U 1 second

0D002A00AD6E0000 6629455888 6629455988 I 1 first

从下往上看,恰好对应着我们之前对该数据的操纵历史。

从下面加黑这行可以看出,在SCN 6629455888和6629455993 这段期间,数据的状态为(1,second),对应的操纵为update。

3. Flashback Transaction Query

Transaction Query可以查看事务的演变历史,使用这个功能须要拜访flashback_transaction_query视图。

A105024@O02DMS1>create table test (id number);

开始第一个事务:

A105024@O02DMS1>insert into test values (1);

A105024@O02DMS1>update test set id=11 where id=1;

A105024@O02DMS1>commit;

开始第二个事务:

A105024@O02DMS1>insert into test values (2);

A105024@O02DMS1>update test set id=22 where id=2;

A105024@O02DMS1>commit;

查看flashback_transaction_query视图获得事务的演变历史:

A105024@O02DMS1>select XID,OPERATION,COMMIT_SCN,UNDO_SQL from flashback_transaction_query where xid in

2 (select versions_xid from test versions between scn minvalue and maxvalue);

XID OPERATION COMMIT_SCN UNDO_SQL

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

10000D000C720000 UPDATE 6629456273 update "A105024"."TEST" set "ID" = '2' where ROWID = 'AACsnzAAEAAABSnAAB';

10000D000C720000 INSERT 6629456273 delete from "A105024"."TEST" where ROWID = 'AACsnzAAEAAABSnAAB';

10000D000C720000 BEGIN 6629456273

0C0002002A720000 UPDATE 6629456260 update "A105024"."TEST" set "ID" = '1' where ROWID = 'AACsnzAAEAAABSnAAA';

0C0002002A720000 INSERT 6629456260 delete from "A105024"."TEST" where ROWID = 'AACsnzAAEAAABSnAAA';

0C0002002A720000 BEGIN 6629456260

4. Flashback Table

根据Flashback Query的演变历史,就能够确定须要回退的时光点,然后再利用Flashback Table功能真正实现回退,注意:在真正回退之前,必须启用row movement。

Flashback drop是从Oracle 10g

开始才有的功能,道理是每个表空间都市有严格回收站的逻辑区域,当drop时,被删除的表及其关联对象不会被物理删除,只是转移到回收站中,给用户供给一个恢复

的可能。



使用Flashback drop须要注意以下几点:

1. 对system表空间无效

2. sqlplus的版本不能低于10g,否则很多命令没法使用

下面做个测试:

SQL> create table

test as select * from dba_objects;

SQL> drop table test;

SQL> show recyclebin;

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME

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

TEST BIN$S5L+aNpzQmOScn8VfpJBAA==$0 TABLE 2011-12-15:22:38:30

SQL> create table test as select * from dba_objects where 2=1;

SQL> drop table test;

SQL> show recyclebin;

ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME

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

TEST BIN$XHwrz1OaQaSeq/NQIE85hw==$0 TABLE 2011-12-15:22:39:34

TEST BIN$S5L+aNpzQmOScn8VfpJBAA==$0 TABLE 2011-12-15:22:38:30

此时recyclebin里有两个test表,查看中两个表的数据个数:

SQL> select count(*) from "BIN$XHwrz1OaQaSeq/NQIE85hw==$0";

COUNT(*)

----------

0

SQL> select count(*) from "BIN$S5L+aNpzQmOScn8VfpJBAA==$0";

COUNT(*)

----------

1000000

假设想要恢复后一张表:

SQL> flashback table "BIN$S5L+aNpzQmOScn8VfpJBAA==$0" to before drop;

Flashback complete.

SQL> select count(*) from test;

COUNT(*)

----------

1000000

假设当初还要恢复前一张表,并重新命名为test2:

SQL> flashback table "BIN$XHwrz1OaQaSeq/NQIE85hw==$0" to before drop rename to t

est2;

Flashback complete.

SQL> select count(*) from test2;

COUNT(*)

----------

0

1. 配置Flashback Database

1)Flashback 功能默许是关闭的:

SQL> select name,flashback_on from v$database;

NAME FLASHBACK_ON

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

O01DMS0 NO

2)配置Flash recovery area:

SQL> alter system set db_recovery_file_dest_size=2G scope=both;

SQL> alter system set db_recovery_file_dest='H:\flashback' scope=both;

3)启用Flashback Database 功能:

SQL> shutdown immediate

SQL> startup mount

SQL> alter database flashback on;

SQL> select name,flashback_on from v$database;

NAME FLASHBACK_ON

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

O01DMS0 YES

4)设置db_flashback_retention_target:

SQL> alter system set db_flashback_retention_target=1440 scope=both;

5)打开数据库



SQL> alter database open;

2. Flashback Database 操纵

1)模拟数据丢失:

SQL> create

table

test as select * from dba_objects;

Table created.

SQL> select count(*) from test;

COUNT(*)

----------

10318

SQL> truncate table test;

Table truncated.

SQL> select count(*) from test;

COUNT(*)

----------

0

2)确认能

恢复

的时光点

能回退的最早时光,取决于保存的Flashback database log的多少,可以从v$flashback_database_log查看:

SQL> select to_char(OLDEST_FLASHBACK_TIME,'yyyy-mm-dd hh24:mi:ss') from v$flashback_database_log;

TO_CHAR(OLDEST_FLAS

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

2011-12-15 02:41:48

3)恢复数据到指定时光点

SQL> shutdown immediate;

SQL> startup mount;

SQL> flashback database to timestamp to_timestamp('2011-12-15 02:43:00','yyyy-mm-dd hh24:mi:ss');

Flashback complete.

恢复成功后,最好先以readonly的方法打开数据库,以确认恢复达到预期,如果没有达到预期,还可以再进行恢复:

SQL> alter database open read only;

Database altered.

SQL> select count(*) from test;

select count(*) from test

*

ERROR at line 1:

ORA-00942: table or view does not exist

SQL> shutdown immediate;

SQL> startup mount;

SQL> flashback database to timestamp to_timestamp('2011-12-15 02:49:00','yyyy-mm-dd hh24:mi:ss');

Flashback complete.

SQL> alter database open read only;

Database altered.

SQL> select count(*) from test;

COUNT(*)

----------

10318

4)打开数据库

恢复成功后,以resetlog方法打开数据库:

SQL> shutdown immediate;

SQL> startup mount

SQL> alter database open resetlogs;

Oracle11g则为flashback家族又带来一个新的成员:flashback data archive。

初看起来,flashback data archive和flashback query没有太大的不同,都是通过as of能够查询之前的数据,但是他们的实现机制是不一样的。Flashback query是通过直接从undo中读取信息来构造旧数据,这样就有一个限制,就是undo中的信息不能被覆盖。而undo段是循环使用的,只要事务提交,之前的undo信息就可能被覆盖,虽然可以通过undo_retention等参数来延长undo的存活期,但这个参数会影响全部的事务,设置过大,可能致使undo tablespace快速膨胀。

Falshback data archive特性则通过将变更数据另外存储到创建的flashback archive中,以和undo区分开来,这样就能够通过为flashback archive独自设置存活策略,使得可以闪回到指定时光之前的旧数据而不影响undo策略。并且可以根据须要指定哪些数据库对象须要保存历史变更数据,而不是将数据库中全部对象的变更数据都保存下来,这样可以极大的减少空间需求。

文章结束给大家分享下程序员的一些笑话语录:

人工智能今天的发展水平:8乘8的国际象棋盘其实是一个体现思维与创意的强大媒介。象棋里蕴含了天文数字般的变化。卡斯帕罗夫指出,国际象棋的合法棋步共有1040。在棋局里每算度八步棋,里面蕴含的变化就已经超过银河系里的繁星总数。而地球上很少有任何数量达到这个级别。在金融危机之前,全世界的财富总和大约是1014人民币,而地球人口只有1010。棋盘上,所有可能的棋局总数达到10120,这超过了宇宙里所有原子的总数!经典语录网
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: