Oracle Flashback 知行合一

  1. 云栖社区>
  2. 博客>
  3. 正文

Oracle Flashback 知行合一

技术小胖子 2017-11-08 22:38:00 浏览1117
展开阅读全文

数据库版本

SYS@LEO1>select* from v$version;

BANNER

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

Oracle Database 11g Enterprise EditionRelease 11.2.0.1.0 - 64bit Production

PL/SQLRelease 11.2.0.1.0 - Production

CORE    11.2.0.1.0      Production

TNS forLinux: Version 11.2.0.1.0 - Production

NLSRTLVersion 11.2.0.1.0 - Production

交流区

今天又和大家见面了,おはようございます(日本见面语),刚刚看完火影记住了这么一句。来让我们看看今天讲点什么呢,喔上次讲的是RMAN这个神奇的备份工具,这次我们继续这个备份与恢复话题,从另一个角度来讲一讲10g刚刚出的一个新特性叫“FlashBack闪回”,可能大家注意到题目的最后四个字“知行合一”,为什么要写这四个字呢,它来自明朝一位猛人之口(当然不是宦官),他叫“王守仁”一位杰出的哲学家,他告诉我们学习知识,不能光空想,但也不能毫无头绪的实践。

知行合一:知是指科学知识,行是指人的实践,所谓认识事物的道理与在现实中运用此道理,是密不可分的一回事。

要在知与行反复的验证中领悟原理,循序渐进,方可大成。

什么是闪回:通俗易懂的讲就是把你所做的事回退回去。比如你走路回家,但发现走错了,怎么办?你可以按原来的方向倒着走回去,回退到起点,重新走一遍。它不同于redo,因为redo当发现错误时,即重新做一遍->前滚。

Flashback 是按照原来的路线回退回来->倒带子->回滚。

Flashback闪回场景:

使用UNDO闪回&闪回归档

(1)闪回查询

(2)闪回版本查询

(3)闪回事务查询

(4)闪回表

使用recyclebin闪回

(5)闪回drop

使用闪回日志

(6)闪回数据库

Flashback可以解决:多种误删除(表误删除,数据误删除,数据库误删除)和查询过去某一时间点的历史数据(不对现有数据做修改)

实验

1.演示闪回查询的三种方式,闪回查询,闪回版本查询,闪回事务查询。

在闪回查询中最常用的就是这三种

闪回查询:查看过去某一时间点的历史数据,不对现有数据做修改,请记住这是闪回到过去的一个“时间点”。

Oracle内部都会把时间转换成SCN号,也就是说即查看过去某一个SCN号的历史数据,读undo信息不修改现有数据

LEO1@LEO1>create table leo1 (x int,yint,z int);          创建一个表

Table created.

LEO1@LEO1>insert into leo1 values(1,1,1);              插入三行数据

1 row created.

LEO1@LEO1>insert into leo1values(2,2,2);

1 row created.

LEO1@LEO1>insert into leo1values(3,3,3);

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from leo1;                        已经commit

        X          Y          Z

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

        1          1          1

        2          2          2

        3          3          3

LEO1@LEO1>alter session setnls_date_format='yyyy-mm-dd hh24:mi:ss';  定义日期时间格式

Session altered.

LEO1@LEO1>select sysdate from dual;                                当前日期和时间

SYSDATE

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

2013-05-16 12:22:51

LEO1@LEO1>selectdbms_flashback.get_system_change_number from dual; 调用函数获得scn

GET_SYSTEM_CHANGE_NUMBER

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

                 1108807

LEO1@LEO1>select current_scn fromv$database;                       这种方法也可以获得

CURRENT_SCN

-----------

1108819

LEO1@LEO1>delete from leo1 where x=1 orx=2;           删除2

2 rows deleted.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from leo1;                         现在表里还剩1

        X          Y          Z

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

        3          3          3

【参】Books->Application Developer’s Guide - Fundamentals -> 10 Developing FlashbackApplication -> Using Flashback Query (SELECT … AS OF)

如果我们想看看2013-05-1612:22:51时候,表里的数据分布情况怎么办呢,这时就用上了闪回查询

使用时间戳构造闪回查询

LEO1@LEO1>select * from leo1 as oftimestamp to_timestamp('2013-05-16 12:22:51','yyyy-mm-dd hh24:mi:ss');

        X          Y          Z

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

        1          1          1

        2          2          2

        3          3          3

使用SCN构造闪回查询,scn  timestamp 更精确,一个timestamp包含好几个scn

LEO1@LEO1>select * from leo1 as of scn1108819;

        X          Y          Z

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

        1          1          1

        2          2          2

        3          3          3

这种闪回的数据,都来自undo段,如果undo信息不够用,才报ora-01555错误

它只是查询过去时间的数据,表中的数据还是没有变化

LEO1@LEO1>select * from leo1;

        X          Y          Z

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

        3          3          3

闪回版本查询:顾名思义,这是基于数据版本闪回,查询一个时间段内的数据变化,Oracle会记录这个时间段内的所有数据版本和操作,任君选择。每一次commit就算一个版本,读undo信息不修改现有数据

LEO1@LEO1>create table leo2 as select *from leo1;     我们创建一个leo2

Table created.

LEO1@LEO1>insert into leo2values(5,5,5);

commit;

insert into leo2 values(6,6,6);

commit;

insert into leo2 values(7,7,7);

commit;

update leo2 set x=55 where x=5;

commit;

update leo2 set x=66 where x=6;

commit;

update leo2 set x=77 where x=7;

commit;

delete from leo2;

commit;

我们插入3条记录->更新3条记录->全删除

LEO1@LEO1>select * from leo2;

no rows selected

LEO1@LEO1>col versions_starttime fora30;

LEO1@LEO1>col versions_endtime for a30;

LEO1@LEO1>col versions_operation for a5;

LEO1@LEO1>selectversions_xid,versions_starttime,versions_endtime,versions_operation,x,y,z fromleo2 versions between timestamp minvalue and maxvalue;

VERSIONS_XID     VERSIONS_STARTTIME   VERSIONS_ENDTIME   VERSI          X          Y          Z

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

06000C004B030000 16-MAY-13 04.15.14 PM                     D              3          3          3

                                     16-MAY-1304.15.14 PM               3         3          3

06000C004B030000 16-MAY-13 04.15.14 PM                     D            77          7          7

06000C004B030000 16-MAY-13 04.15.14 PM                     D            66          6          6

06000C004B030000 16-MAY-13 04.15.14 PM                     D            55          5          5

0800170045030000 16-MAY-13 04.15.14PM16-MAY-13 04.15.14 PM  U             77          7          7

01001B008E020000 16-MAY-13 04.15.14PM16-MAY-13 04.15.14 PM  U             66          6          6

0A00130087020000 16-MAY-13 04.15.14PM16-MAY-13 04.15.14 PM  U             55          5          5

020018004C030000 16-MAY-13 04.15.14 PM16-MAY-13 04.15.14 PM  I              7          7          7

070016002B030000 16-MAY-13 04.15.14 PM 16-MAY-1304.15.14 PM  I              6          6          6

040010007A020000 16-MAY-13 04.15.14 PM 16-MAY-1304.15.14 PM  I              5          5          5

11 rows selected.

伪列说明

versions_startscn          版本起始scn

versions_endscn          版本结束scn

versions_starttime        版本开始时间

versions_endtime         版本结束时间

versions_operation        执行的操作

versions_xid              操作事务ID

timestamp minvalue and maxvalue    时间戳最小值与最大值

这是倒序,每一次commit称为一个独立版本040010007A020000 070016002B030000 020018004C030000 这是三次插入的版本x y z是修改后的值,0A00130087020000 01001B008E0200000800170045030000 是三次更新的版本,06000C004B030000是删除的版本,删除操作我们有三条记录(告诉我们删除了哪些内容)但版本号都是一样的因此算一个版本,我们一共有7个版本。

现在我说明一下“闪回版本查询”在实际中的应用,在生产中“闪回版本查询”与“闪回事务查询”结合使用的,

版本查询可以让DBA能够获得过去时间段中的所有改变而不是特定值,检索出DBA想要查的那个事务ID,有了事务ID我们就可以结合“事务查询”进行“事务闪回”,撤销错误的事务操作。这个版本查询也不是想查多久就查多久的,最大的可用版本依赖于undo_retention参数。如果不够会报:ora-01555,下面我们看看,如何正确使用查询到的版本。

闪回事务查询:基于事务闪回,查询过去某一个事务的历史数据

事务:上一个commit,下一个commit就算一次事务,通过flashback_transaction_query视图可以找到事务,然后撤销事务查看过去的历史数据,读undo信息不修改现有数据

LEO1@LEO1>selectxid,logon_user,table_name,operation,undo_sql,row_id fromflashback_transaction_query where table_name='LEO2';
XID               LOGON_USER    TABLE_NAME    OPERATION   UNDO_SQL   ROW_ID

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

01001B008E020000  LEO1          LEO2           UNKNOWN                                                                                                                                                          

我们在查询这个视图的时候会发现,只有事务id,操作用户,操作表这三列,其他都是unknown,这是因为oracle默认没有提供这些详细附加信息,需要开启附加选项才可,这和log miner的原理一样。

切记需要重新打开一个session执行如下操作

LEO1@LEO1>alter database addsupplemental log data;       启动收集详细信息选项

Database altered.

重新执行一遍上面的DML操作,此处省略。。。。。。

LEO1@LEO1>select xid,logon_user,table_name,operation,undo_sql,row_idfrom flashback_transaction_query where table_name='LEO2';

XID  LOGON_USER TABLE_NAME  OPERATION  UNDO_SQL    ROW_ID                                                                   

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

0100010090020000 LEO1  LEO2 INSERT     delete from"LEO1"."LEO2" where ROWID = 'AAAR9rAAFAAAACMAAA';                    AAAR9rAAFAAAACMAAA

0900140043030000 LEO1  LEO2  INSERT     delete from"LEO1"."LEO2" where ROWID = 'AAAR9rAAFAAAACMAAB';                    AAAR9rAAFAAAACMAAB

040019007B020000 LEO1  LEO2  INSERT     delete from"LEO1"."LEO2" where ROWID = 'AAAR9rAAFAAAACMAAC';                    AAAR9rAAFAAAACMAAC

分段说明:这三条就是刚才我们做的插入操作,undo_sql字段显示插入操作的“逆操作”,如果我们做了误操作的话,可以用给的逆操作SQL进行撤销,大家会发现这里还有一个rowid字段,rowid表示这条记录在物理磁盘上的地址,使用rowid来定位记录是最快捷的。

020012004E030000 LEO1  LEO2 UPDATE  update"LEO1"."LEO2" set "X" = '5' where ROWID = 'AAAR9rAAFAAAACMAAA';           AAAR9rAAFAAAACMAAA

030019004C030000 LEO1  LEO2 UPDATE  update"LEO1"."LEO2" set "X" = '6' where ROWID ='AAAR9rAAFAAAACMAAB';          AAAR9rAAFAAAACMAAB

070001002E030000 LEO1  LEO2 UPDATE  update "LEO1"."LEO2" set "X" = '7' whereROWID = 'AAAR9rAAFAAAACMAAC';          AAAR9rAAFAAAACMAAC

这三条是我们刚做的update操作,如果发现更新误操作了,可以用逆操作SQL撤销

08000B0047030000 LEO1 LEO2 DELETE insert into"LEO1"."LEO2"("X","Y","Z")values ('77','7','7');                   AAAR9rAAFAAAACMAAC

08000B0047030000 LEO1 LEO2 DELETE insert into"LEO1"."LEO2"("X","Y","Z")values ('66','6','6');                   AAAR9rAAFAAAACMAAB

08000B0047030000 LEO1 LEO2 DELETE insert into"LEO1"."LEO2"("X","Y","Z")values ('55','5','5');                   AAAR9rAAFAAAACMAAA

这三个事务id全都一样的记录是我们delete操作,我们可以用insert语句进行撤销

小结:到此我们三个闪回查询全部完整的演示了一遍,总结一下,这三种方式的闪回共同点都是利用undo表空间的数据进行历史数据查询,不对现有数据作修改操作。我们在使用的时候要根据场景来综合应用。


2.模拟一次ora-01555错误。

讲之前阐述一下原理,我们要“知行合一”嘛,不要忘记

原因:就是当一个select查询等待时间太长,这个过程中查询的数据被修改完毕commit了,此时它的前映像就为inactive状态,如果这时候有其他会话也想用undo段,就会把inactive状态的回滚区覆盖掉,这时正好select查询完毕想读取它的前映像,发现已经被覆盖了,此时oracle会报ora-01555错误。理解原理很重要

我用一种叫做闪回查询的功能来实现ora-01555

flashback query:原理也是使用undo segment中的前映像,来查询出我们修改之前的数据映像,一般用于误操作恢复。可以基于时间闪回还可以基于SCN号闪回,一秒钟包括好几个SCN号,不管基于什么oracle内部都是按照SCN号顺序操作的。只要我们查找的原映像被覆盖了,就会报ora-01555错误。

实验

Oracle 11g时候已经有了解决方案了,隆重推出“闪回归档”的方法,后面我会演示如何利用“闪回归档”避免“ora-01555

我们就来演示下,当前映像被覆盖后发生的ora-01555

SYS@LEO1>create undo tablespaceundotbs02 datafile '/u02/app/oracle/oradata/LEO1/undotbs02.dbf' size 5mautoextend off;

Tablespace created.

LEO1@LEO1>selecttablespace_name,file_name,autoextensible from dba_data_files wheretablespace_name='UNDOTBS02';

TABLESPACE_NAME     FILE_NAME                                     AUT

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

UNDOTBS02           /u02/app/oracle/oradata/LEO1/undotbs02.dbf         NO

创建一个新的undo表空间undotbs02,大小2m,设的小一点,方便我们循环覆盖

SYS@LEO1>alter system setundo_tablespace='UNDOTBS02';     切换数据库默认undo表空间

System altered.

SYS@LEO1>show parameter undo                                     

NAME                              TYPE      VALUE

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

undo_management                   string      AUTO

undo_retention                      integer     900

undo_tablespace                     string      UNDOTBS02

SYS@LEO1>create table leo3 as select *from dba_objects;          创建表leo3

Table created.

SYS@LEO1>select current_scn fromv$database;                  当前SCN

CURRENT_SCN

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

   1121723

SYS@LEO1>delete from leo3 whereobject_type in ('TABLE','INDEX');   删除6752

6725 rows deleted.

SYS@LEO1>commit;                                          提交

Commit complete.

SYS@LEO1>select object_type from leo3 asof scn 1121723 where object_type in('TABLE','INDEX') and rownum<10;

OBJECT_TYPE

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

TABLE

INDEX

TABLE

TABLE

INDEX

TABLE

INDEX

INDEX

INDEX

大家看这些数据,就是从undo segment中读取出来的,我们需要指定当时的SCN进行闪回查询

作一个匿名块,按顺序循环覆盖undo段,把SCN=1121723的前映像覆盖后,我们再去查,就会报ora-01555

SYS@LEO1>show user 

USER is "SYS"

SYS@LEO1>begin

for i in 1..10000 loop

delete from leo3 where object_type in('TABLE','INDEX');

rollback;

end loop;

end;

/

2    3    4   5    6    7  

PL/SQL procedure successfully completed.

SYS@LEO1>select object_type from leo3 asof scn 1121723 where object_type in('TABLE','INDEX') and rownum<10;

select object_type from leo3 as of scn1121723 where object_type in('TABLE','INDEX') and rownum<10

                        *

ERROR at line 1:

ORA-01555: snapshot too old: rollbacksegment number 10 with name "_SYSSMU10_3331052151$" too small

小结:经过不懈的努力,终于模拟出来ORA-01555错误,这也可以证明undo分配是按顺序循环使用,不可跨区覆盖,undo回收也是按顺序循环回收,不可跨区回收。


3.演示误删除表后的恢复。

下面我们讲解一下“闪回表”and“闪回drop”,这是2种不同的误操作恢复,一种是恢复表中数据,一种是恢复被删除的表。

闪回表:把现有表还原到过去某一时间点的状态,对现有数据做修改,读undo信息

LEO1@LEO1>create table leo4 (x int,yint,z int);       创建一个leo4

Table created.

LEO1@LEO1>insert into leo4values(5,5,5);           插入3

1 row created.

LEO1@LEO1>insert into leo4values(6,6,6);

1 row created.

LEO1@LEO1>insert into leo4values(7,7,7);

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from leo4;                    查看一下

        X          Y          Z

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

        5          5          5

        6          6          6

        7          7          7

LEO1@LEO1>select current_scn fromv$database;     作一个标记,标注我们要闪回的位置

CURRENT_SCN

-----------

   1124184

LEO1@LEO1>delete from leo4 where x=5 orx=6;       删除2

2 rows deleted.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from leo4;                     还剩1

        X          Y          Z

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

        7          7          7

LEO1@LEO1>alter table leo4 enable rowmovement;     启动行移动

Table altered.

行移动:闪回后的行物理位置会发生变化,原来的位置可能被占用,因为你在delete后就会给删除的行打上delete标签,凡是有这种标签的行都可以被覆盖的,如果新数据占用了原来的位置覆盖了老数据,那么在闪回原来的行时就需要移动到新的物理位置存放。

LEO1@LEO1>flashback table leo4 to scn1124184;       闪回表到scn=1124184

Flashback complete.

LEO1@LEO1>select * from leo4;                     被删除的表记录恢复回来了

        X          Y          Z

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

        5          5          5

        6          6          6

        7          7          7

闪回drop:防止误删除表 drop table leo4;利用recyclebin回收站完成闪回,不在读取undo信息了

这次我们用的是回收站,回收站占用的是表空间的存储区,当空间紧张时回收站被挤占,当空间被全部占用时,回收站也就不存在了,每个表空间都有一个回收站,默认是开启on

LEO1@LEO1>show parameter recyclebin

NAME                                 TYPE       VALUE

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

recyclebin                              string     on

LEO1@LEO1>create table leo5 (x int);

Table created.

LEO1@LEO1>insert into leo5 values(10);

1 row created.

LEO1@LEO1>drop table leo5;

Table dropped.

LEO1@LEO1>create table leo5 (x int);

Table created.

LEO1@LEO1>insert into leo5 values(100);

1 row created.

LEO1@LEO1>insert into leo5 values(200); 

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>drop table leo5;

Table dropped.

LEO1@LEO1>create table leo5 (x int);

Table created.

LEO1@LEO1>insert into leo5 values(1000);

1 row created.

LEO1@LEO1>insert into leo5 values(2000);

1 row created.

LEO1@LEO1>insert into leo5 values(3000);

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>drop table leo5;

Table dropped.

同一张表被3drop,如果我们想恢复其中有三条记录的leo5怎么办呢

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME

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

LEO5             BIN$3ODW6UVvIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:26:22

LEO5             BIN$3ODW6UVuIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:25:13

LEO5             BIN$3ODW6UVtIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:24:08

LEO1@LEO1>selectoriginal_name,object_name,type from recyclebin;

ORIGINAL_NAME   OBJECT_NAME                    TYPE

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

LEO5             BIN$3ODW6UVvIjHgQKjAZAERuQ==$0TABLE

LEO5             BIN$3ODW6UVuIjHgQKjAZAERuQ==$0TABLE

LEO5             BIN$3ODW6UVtIjHgQKjAZAERuQ==$0TABLE

LEO1@LEO1>select * from tab;                  

TNAME                          TABTYPE  CLUSTERID

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

BIN$3ODW6UVtIjHgQKjAZAERuQ==$0 TABLE

BIN$3ODW6UVuIjHgQKjAZAERuQ==$0 TABLE

BIN$3ODW6UVvIjHgQKjAZAERuQ==$0 TABLE

我们用上述三种方式都可以看到回收站中的表,它会以一种特殊的方式来命名

LEO1@LEO1>select * from"BIN$3ODW6UVvIjHgQKjAZAERuQ==$0";

        X

----------

     1000

      2000

     3000

LEO1@LEO1>select * from"BIN$3ODW6UVuIjHgQKjAZAERuQ==$0";

        X

----------

      100

      200

LEO1@LEO1>select * from"BIN$3ODW6UVtIjHgQKjAZAERuQ==$0";

        X

----------

       10
看看回收站中被我们drop的三个版本,哪个是我们想要恢复的,其中有3条记录是我们想要恢复的

对回收站中指定的内容进行闪回

LEO1@LEO1>flashback table"BIN$3ODW6UVvIjHgQKjAZAERuQ==$0" to before drop;

Flashback complete.

LEO1@LEO1>select * from leo5;

        X

----------

     1000

     2000

     3000

LEO1@LEO1>show recyclebin                         现在回收站还剩2个版本

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME

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

LEO5             BIN$3ODW6UVuIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:25:13

LEO5             BIN$3ODW6UVtIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:24:08

清空回收站

LEO1@LEO1>purge table"BIN$3ODW6UVuIjHgQKjAZAERuQ==$0";        清空指定的表

Table purged.

LEO1@LEO1>show recyclebin;                                      已经清空

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME

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

LEO5             BIN$3ODW6UVtIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:24:08

LEO1@LEO1>purge recyclebin;                                     清空所有表

Recyclebin purged.

LEO1@LEO1>show recyclebin;                                      

LEO1@LEO1>selectoriginal_name,object_name,type from recyclebin;     数据字典里也没有了

no rows selected

4.演示闪回归档。

所谓闪回归档:这是Oracle 11g新特性,保存历史undo到数据文件,可以避免ora-01555,在11g之前是不保存undo数据的,这种方式有利必有弊,如果我们想要的undo数据被覆盖了就不能实现快速恢复和回滚操作。

闪回归档原理:是从定义在表空间中的闪回基表来还原数据,默认undo数据保留期5分钟,当然我们可以指定更长时间。Oracle会自动清除超出保留期的闪回基表。例如保留期7天,过了7天自动删除闪回基表

当然也允许手工删除闪回归档

1)删除全部闪回归档

Alter flashback archive fda1 purge all;

2)删除1天之前的闪回归档

Alter flashback archive fda1 purge beforetimestamp (systimestamp – interval ‘1’ day);

3)删除scn123456之前的闪回归档

Alter flashback archive fda1 purge beforescn 123456;

fbda进程:负责捕获undo数据到闪回基表

实验

创建存放闪回基表的表空间leo_flashback_1

LEO1@LEO1>create tablespaceleo_flashback_1 datafile '/u02/app/oracle/oradata/LEO1/leo_flashback_1.dbf'size 20m autoextend off;

Tablespace created.

LEO1@LEO1>conn / as sysdba              切换成sys管理员用户

Connected.

指定表空间leo_flashback_1为默认闪回归档fbda1存放目录,保留期设置为7天,默认是5分钟

SYS@LEO1>create flashback archivedefault fbda1 tablespace leo_flashback_1 retention 7 day;

Flashback archive created.

定义非默认闪回归档fbda2,限额为10m(这个闪回归档fbda2只能存放10m基表)保留期设置为30

SYS@LEO1>create flashback archive fbda2tablespace leo_flashback_1 quota 10m retention 30 day;

Flashback archive created.

SYS@LEO1>conn leo1/leo1;                  链接leo1

Connected.

创建表leo6使用默认闪回归档fbda1保留期7

LEO1@LEO1>create table leo6 (namevarchar2(20),avg number,employment varchar2(30)) flashback archive;

Table created.

LEO1@LEO1>insert into leo6values('leonarding',18,'DBA');

1 row created.

LEO1@LEO1>insert into leo6values('tigerfish',28,'data analyze');

1 row created.

LEO1@LEO1>insert into leo6values('sun_vn',38,'develop engineer');

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from leo6;

NAME             AVG      EMPLOYMENT

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

leonarding          18       DBA

tigerfish            28       data analyze

sun_vn             38       develop engineer

LEO1@LEO1>select current_scn fromv$database;               标记当前scn=1128826

CURRENT_SCN

-----------

   1128826

LEO1@LEO1>delete from leo6 where avg=18or avg=38;          删除2条记录

2 rows deleted.

LEO1@LEO1>commit; 

Commit complete.

[oracle@leonarding1 trace]$ tail -falert_LEO1.log

Fri May 17 15:26:31 2013

Starting backgroundprocess FBDA

Fri May 17 15:26:31 2013

FBDA started with pid=28,OS id=9328

告警日志里面显示FBDA进程已经开始工作,开始捕捉undo数据写入闪回表空间leo_flashback_1

定义一个新undo表空间

LEO1@LEO1>create undo tablespaceundotbs03 datafile '/u02/app/oracle/oradata/LEO1/undotbs03.dbf' size 20mautoextend off;

Tablespace created.

LEO1@LEO1>alter system setundo_tablespace='UNDOTBS03';         修改默认undo表空间为UNDOTBS03

System altered.

LEO1@LEO1>show parameter undo

NAME                                 TYPE      VALUE

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

undo_management                      string      AUTO

undo_retention                         integer    900

undo_tablespace                        string     UNDOTBS03  已经修改成功

LEO1@LEO1>drop tablespace undotbs02including contents and datafiles; 删除原来的undo表空间

Tablespace dropped.

LEO1@LEO1>alter system flushbuffer_cache;                        清空undo缓冲区

System altered.

LEO1@LEO1>select * from leo6;                                  当下leo6表中只有1

NAME                       AVGEMPLOYMENT

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

tigerfish                    28 data analyze

LEO1@LEO1>select * from leo6 as of scn1128826;                   我们闪回到scn=1128826

NAME             AVG      EMPLOYMENT

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

leonarding          18       DBA

tigerfish            28       data analyze

sun_vn             38       develop engineer

这里用到的undo映像就是闪回归档中的,因为我们刚才的undo表空间已经删除了,oracle在删除之前利用fbda进程把undo映像写入闪回归档,我们才能看到现在的历史数据,闪回归档不修改现有数据哦:)

介绍一下闪回归档数据字典

闪回归档表空间信息

LEO1@LEO1>select * fromdba_flashback_archive_ts;

FLASHBACK_ARCHIVE_NAME     FLASHBACK_ARCHIVE#  TABLESPACE_NAME      QUOTA_IN_MB

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

FBDA1                       1                    LEO_FLASHBACK_1

FBDA2                       2                    LEO_FLASHBACK_1       10

闪回归档信息

LEO1@LEO1>select FLASHBACK_ARCHIVE_NAME,RETENTION_IN_DAYS,STATUSfrom dba_flashback_archive;

FLASHBACK_ARCHIVE_NAME         RETENTION_IN_DAYS       STATUS

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

FBDA1                                          7         DEFAULT

FBDA2                                         30

闪回归档基表

LEO1@LEO1>selecttable_name,flashback_archive_name,archive_table_name,status fromdba_flashback_archive_tables;

TABLE_NAME   FLASHBACK_ARCHIVE_NAME     ARCHIVE_TABLE_NAME         STATUS

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

LEO6           FBDA1                       SYS_FBA_HIST_73594           ENABLED

LEO6表是通过SYS_FBA_HIST_73594闪回基表恢复的,基本后缀id就是原表的对象号

LEO1@LEO1>select object_name fromdba_objects where object_id=73594;

OBJECT_NAME

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

LEO6

LEO1@LEO1>selecttable_name,tablespace_name from user_tables;

TABLE_NAME                     TABLESPACE_NAME

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

SYS_FBA_DDL_COLMAP_73594       LEO_FLASHBACK_1    leo6表结构改变记录

SYS_FBA_TCRV_73594              LEO_FLASHBACK_1    每次事务改变记录

SYS_TEMP_FBT                                        临时闪回表

SYS_FBA_HIST_73594                                   每个字段改变记录

调整配额为12M

LEO1@LEO1>alter flashback archive fbda2modify tablespace leo_flashback_1 quota 12m;

Flashback archive altered.

调整保留期为1

LEO1@LEO1>alter flashback archive fbda2modify retention 1 day;

Flashback archive altered.

删除fbda2闪回归档

LEO1@LEO1>drop flashback archive fbda2;

Flashback archive dropped.

撤销leo6表的闪回归档属性

LEO1@LEO1>alter table leo6 no flashbackarchive;

Table altered.

小结:在使用闪回归档时,请注意配额限制和保留期限制,在创建表的时候要指定闪回归档属性才行。

5.演示闪回数据库

闪回数据库:把整个库回退到过去的某一状态,这是基于闪回日志的回退。Oracle 10g才刚刚引入新特性,是通过后台进程RVWR来写入闪回日志的。

闪回数据库原理:启动闪回前提条件是开启归档,归档日志可以辅助闪回日志完成闪回工作,往回闪不用归档,往前闪会用到归档。日志块每三秒钟定期采集一次前映像,比如想恢复到10点的状态,而我们只能闪回到9:55分,还差五分钟内容就需要归档日志or重做日志来进行前滚恢复。

闪回要求数据库为归档状态,如果没有启动alter  database archivelog;   执行这条命令启动归档

LEO1@LEO1>conn / as sysdba

Connected.

SYS@LEO1>archive log list 

Database log mode             Archive Mode

Automatic archival             Enabled

Archive destination             /u02/app/oracle/archdata

Oldest online log sequence      3

Next log sequence to archive     5

Current log sequence           5

确认数据库是否开启了flashback功能

SYS@LEO1>select flashback_on fromv$database;      还没有启动,这是抓取控制文件信息

FLASHBACK_ON

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

NO

修改db_recovery_file_dest快速恢复区目录和db_recovery_file_dest_size快速恢复区大小两个参数,这是存放闪回日志的地方,必须被指定

[oracle@leonarding1 oracle]$ mkdirflashback_area                    创建一个快速恢复区目录

SYS@LEO1>alter system setdb_recovery_file_dest_size=1g;                        先设置大小

System altered.

SYS@LEO1>alter system setdb_recovery_file_dest='/u02/app/oracle/flashback_area';   再设置路径

System altered.

指定闪回日志保留期2(2880分钟)

SYS@LEO1>alter system setdb_flashback_retention_target=2880 scope=both;

System altered.

SYS@LEO1>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@LEO1>startup mount                         启动到mount状态

ORACLE instance started.

Total System Global Area  471830528 bytes

Fixed Size                  2214456 bytes

Variable Size             222299592 bytes

Database Buffers          239075328 bytes

Redo Buffers                8241152 bytes

Database mounted.

SYS@LEO1> show parameter db_recovery                      快速恢复区已经设置好了

NAME                             TYPE       VALUE

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

db_recovery_file_dest                string       /u02/app/oracle/flashback_area

db_recovery_file_dest_size            big integer  1G

SYS@LEO1>alter database flashback on;              mount状态下才能启动flashback功能

Database altered.

SYS@LEO1>alter database open;                    打开数据库

Database altered.

SYS@LEO1>select flashback_on fromv$database;      确认flashback功能已经成功开启

FLASHBACK_ON

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

YES

SYS@LEO1>create table leo10 as select *from dba_objects;          创建个表

Table created.

SYS@LEO1>select count(*) from leo10;                           72200条记录

COUNT(*)

----------

    72200

SYS@LEO1>select current_scn fromv$database;                    标记scn

CURRENT_SCN

-----------

   1144328

SYS@LEO1>drop table leo10 purge;                              直接删除

Table dropped.

SYS@LEO1>show recyclebin                                    不进回收站

SYS@LEO1>

如果我们想把leo10表恢复回来有几种方法呢,第一RMAN恢复第二 Flashback 闪回数据库

如果要闪回数据库,在文件打开的状态下是不可应用闪回日志的,因此我们切换到mount状态

SYS@LEO1>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@LEO1>startup mount                                 

ORACLE instance started.

Total System Global Area  471830528 bytes

Fixed Size                  2214456 bytes

Variable Size             222299592 bytes

Database Buffers          239075328 bytes

Redo Buffers                8241152 bytes

Database mounted.

SYS@LEO1>alter session set nls_date_format='yyyy-mon-ddhh24:mi:ss';

Session altered.

SYS@LEO1>select oldest_flashback_timefrom v$flashback_database_log;           允许闪回的最早时间

OLDEST_FLASHBACK_TIM

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

2013-may-18 10:00:12

SYS@LEO1>select oldest_flashback_scnfrom v$flashback_database_log;           允许闪回的最早scn

OLDEST_FLASHBACK_SCN

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

            1143915

SYS@LEO1>flashback database to scn1144328;                               闪回到删除之前

Flashback complete.

SYS@LEO1>alter database open resetlogs;                               非一致性打开数据库

Database altered.

1.数据文件头scn同步控制文件

2.清空redo日志,重置状态为unused

3.归档日志编码从1开始

4.数据库进入一个新的生命周期

SYS@LEO1>select count(*) from leo10;                                 完美恢复

COUNT(*)

----------

    72200

补充:不同粒度级别的闪回

基于时间点闪回

flashback database totime="to_date('2013-05-16 12:00:00','yyyy-mm-dd hh24:mi:ss')";

基于时间戳闪回,闪回到1小时之前

flashback database totimestamp(sysdate-1/24);

基于SCN号闪回

flashback database to scn 1144328;

基于日志序号闪回

flashback database to sequence=1000thread=1;

基于还原点闪回

flashback database to restore pointleo_point1;

小结:我们可以根据实际情况来综合分析使用哪种闪回,注意闪回数据库是对整个库进行闪回,所有的session操作都会还原,这是一种极端情况下的还原谨慎使用。

闪回查询闪回版本闪回事务闪回归档闪回数据库 01555 






 本文转自 ztfriend 51CTO博客,原文链接:http://blog.51cto.com/leonarding/1203129,如需转载请自行联系原作者


网友评论

登录后评论
0/500
评论
技术小胖子
+ 关注