一数据库版本
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.
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.
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.
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.
Commit complete.
LEO1@LEO1>drop table leo5;
Table dropped.
同一张表被3次drop,如果我们想恢复其中有三条记录的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.
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,如需转载请自行联系原作者