个人闪回技术小结


概述:Flashback 技术在Oracle 10g中提供了更强大的功能。它包括了table level的Flashback Query, Flashback Version Query, Flashback Transaction Quey, Flashback Table and Flashback Drop 和database level的Flashback database。

其中,Flashback Query, Flashback Version Query, Flashback Transaction Quey 和Flashback Table 是基于undo data的,而Flashback Drop 是基于recycle bin的。

Flashback database 需要Flashback logs 和 Archivelog mode 还有Flash recovery area。

 

一、Flashback Query  as of time,依赖回滚段内容,不需要归档和闪回模式,不论服务是否重启只要回归段存在即可,但缺点是约束及索引不被闪回

_td as of timestamp to_timestamp('2010-03-15 14:40:00', 'yyyy-mm-dd hh24:mi:ss');

insert into  back_table select * from  tssa.block_td as of timestamp systimestamp - interval '60' minute
 where block_id not in (select block_id   from tssa.block_td)
 
 
 insert into block_td
 select * from tssa.block_td as of timestamp to_timestamp('2010-03-15 14:40:00', 'yyyy-mm-dd hh24:mi:ss')
 where block_id not in (select block_id from block_td)

 select * from block_td as of timestamp sysdate-60/1440;


insert into block_td  select * from block_td as of timestamp sysdate-60/1440

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

二、Flashback Query  as of scn


仍以前文中创建的表为例,既然是基于scn的查询,我们首先就需要得到scn,这里我们通过dbms_flashback.get_system_change_number函数来获取oracle当前的scn,之后再执行数据的修改操作。

JSSWEB> select dbms_flashback.get_system_change_number from dual;


GET_SYSTEM_CHANGE_NUMBER

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

                  344197


JSSWEB> delete jss_tb1 where id>10;


已删除10行。


JSSWEB> commit;


提交完成。


JSSWEB> select * from jss_tb1 as of scn 344197;


        ID VL

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

      

已选择20行。


执行insert,将删除的数据重新恢复回表jss_tb1

JSSWEB> insert into jss_tb1 select *from jss_tb1 as of scn 344197

  2  where id not in(select id from jss_tb1);


已创建10行。


JSSWEB> commit;


提交完成。


事实上,Oracle在内部都是使用scn,即使你指定的是as of timestamp,oracle也会将其转换成scn,系统时间标记与scn之间存在一张表,即SYS下的SMON_SCN_TIME

JSSWEB> desc sys.smon_scn_time;

 名称                                        是否为空? 类型

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


 THREAD                                      NUMBER

 TIME_MP                                    NUMBER

 TIME_DP                                    DATE

 SCN_WRP                                    NUMBER

 SCN_BAS                                    NUMBER

 NUM_MAPPINGS                               NUMBER

 TIM_SCN_MAP                                RAW(1200)

 SCN                                        NUMBER

 ORIG_THREAD                                 NUMBER


每隔5分钟,系统产生一次系统时间标记与scn的匹配并存入sys.smon_scn_time表,该表中记录了最近1440个系统时间标记与scn的匹配记录,由于该表只维护了最近的1440条记录,因此如果使用as of timestamp的方式则只能flashback最近5天内的数据(假设系统是在持续不断运行并无中断或关机重启之类操作的话)。注意理解系统时间标记与scn的每5分钟匹配一次这句话,举个例子,比如scn:339988,339989分别匹配08-05-30 13:52:00和2008-13:57:00,则当你通过as of timestamp查询08-05-30 13:52:00或08-05-30 13:56:59这段时间点内的时间时,oracle都会将其匹配为scn:339988到undo表空间中查找,也就说在这个时间内,不管你指定的时间点是什么,查询返回的都将是08-05-30 13:52:00这个时刻的数据。

当然,具体的情况,我想你亲自执行一下select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') from sys.smon_scn_time,会理解的更深刻一些。


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


三、Flashback Version Query
通过versions between能够查看指定时间段内undo表空间中记录的不同版本(注意,只包括被提交的记录)。

VERSIONS_STARTSCN
VERSIONS_STARTTIME
 该记录操作时的scn或时间,如果为空,表示该行记录是在查询范围外创建的。
 
VERSIONS_ENDSCN

VERSIONS_ENDTIME
 该记录失效时的scn或时间,如果为空,说明记录当前时间在当前表内存在,或者已经被删除了,可以配合着VERSIONS_OPERATION列来看,如果VERSIONS_OPERATION列值为D,说明该列已被删除,如果该列为空,则说明记录在这段时间无操作。
 
VERSIONS_XID
 该操作的事务ID
 
VERSIONS_OPERATION
 对该行执行的操作:I表示insert,D表示delete,U表示update。

提示:对于索引键的update操作,版本查询可能会将其识别成两个操作:DELETE和INSERT。
 
--先来查询一下当前的scn,方面我们后面确认选择的范围

JSSWEB> select dbms_flashback.get_system_change_number from dual;


GET_SYSTEM_CHANGE_NUMBER

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

                  372466


JSSWEB> update jss_tb1 set id=id+100 where id>15;


已更新5行。


JSSWEB> commit;


提交完成。


JSSWEB> delete jss_tb1 where id<5;


已删除4行。


JSSWEB> commit;


提交完成。


JSSWEB> insert into jss_tb1 values (201,'A1');


已创建 1 行。


JSSWEB> insert into jss_tb1 values (202,'B1');


已创建 1 行。


JSSWEB> commit;


提交完成。


--再来查询一下当前的scn,方面我们后面确认选择的范围

JSSWEB> select dbms_flashback.get_system_change_number from dual;


GET_SYSTEM_CHANGE_NUMBER

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

                  372538


通过versions between,我们就可以看到表jss_tb1中的记录的变化情况:

JSSWEB> select id,vl,versions_startscn,versions_endscn,versions_operation

  2  from jss_tb1 versions between scn 372466 and 372538 order by 2;


JSSWEB> select id,vl,versions_startscn,versions_endscn,versions_operation

  2  from jss_tb1 versions between timestamp to_date('2010-03-15 14:40:00', 'yyyy-mm-dd hh24:mi:ss') and  to_date('2010-03-15 14:40:00', 'yyyy-mm-dd hh24:mi:ss')
      


已选择26行。


根据这个结果返回我们首先来看id<5的记录,每个记录各有两个版本,一行的VERSIONS_STARTSCN和VERSIONS_OPERATION有值,记录了开始时的SCN和执行的操作,另一行则是VERSIONS_ENDSCN有值,记录了该版本失效时的scn。

Id>200的有两条记录,是我们自己手工添加中,从VERSIONS_OPERATION列可以看出操作是insert。

另有5行id>100 and id<200的,从VERSIONS_OPERATION列可以看出操作是update,这是我们手工执行update set的结果。

----------------------------------------------------------------------------------------------
四、Transaction query事务查询
Flashback的事务查询是通过查询flashback_transaction_query视图来实现的。通过查询该视图能够获得一些事务执行时的信息,甚至包括UNDO语句。

SQL> delete from jss_tb1 where id <10;
 
5 rows deleted


SQL>  select versions_xid, versions_operation from jss_tb1 versions between scn 640935 and 640952 order by 2;
 
VERSIONS_XID     VERSIONS_OPERATION
---------------- ------------------
0100040011010000 D
0100040011010000 D
0100040011010000 D
0100040011010000 D
0100040011010000 D
 
16 rows selected
 
SQL> select xid,commit_scn,commit_timestamp,operation,undo_sql from flashback_transaction_query q where q.xid in(select versions_xid from jss_tb1 versions between scn 640935 and 640952);

 
XID              COMMIT_SCN COMMIT_TIMESTAMP OPERATION                        UNDO_SQL
---------------- ---------- ---------------- -------------------------------- --------------------------------------------------------------------------------
0100040011010000     640945 2010-3-17 23:06: DELETE                           insert into "TSSA"."JSS_TB1"("ID","VL") values ('9','H');
0100040011010000     640945 2010-3-17 23:06: DELETE                           insert into "TSSA"."JSS_TB1"("ID","VL") values ('8','G');
0100040011010000     640945 2010-3-17 23:06: DELETE                           insert into "TSSA"."JSS_TB1"("ID","VL") values ('7','F');
0100040011010000     640945 2010-3-17 23:06: DELETE                           insert into "TSSA"."JSS_TB1"("ID","VL") values ('6','E');
0100040011010000     640945 2010-3-17 23:06: DELETE                           insert into "TSSA"."JSS_TB1"("ID","VL") values ('5','D');
0100040011010000     640945 2010-3-17 23:06: BEGIN                           
 

 

下面做个演示,首先删除一条数据:

JSSWEB> select *from jss_tb1;


        ID VL

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

         5 E

         6 F

         7 G

         8 H

         9 I

        11 K

        12 L

        13 M

        14 N

        15 O

       116 P

       117 Q

       118 R

       119 S

       120 T

        10 J


已选择16行。


JSSWEB> select dbms_flashback.get_system_change_number from dual;


GET_SYSTEM_CHANGE_NUMBER

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

                  413946


JSSWEB> delete jss_tb1 where id<3;


已删除0行。


JSSWEB> rollback;


回退已完成。


JSSWEB> delete jss_tb1 where id=5;


已删除 1 行。


JSSWEB> commit;


提交完成。


JSSWEB> select dbms_flashback.get_system_change_number from dual;


GET_SYSTEM_CHANGE_NUMBER

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

                  413959


Flashback_transaction_query

JSSWEB> select xid,commit_scn,commit_timestamp,operation,undo_sql

  2  from flashback_transaction_query q where q.xid in(

  3  select versions_xid from jss_tb1 versions between scn 413946 and 413959);


XID              COMMIT_SCN COMMIT_TIMESTAMP    OPERATION    UNDO_SQL

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

05002F0082000000     413958 2008-06-04 21:32:02 DELETE       insert into "JSS"."JSS_TB1"("ID","VL") values ('5','E');

05002F0082000000     413958 2008-06-04 21:32:02 BEGIN

注:由于事务ID是保存在版本查询中,因此我们需要通过版本查询来关联出flashback的事务信息,这也是前面操作前要通过dbms_flashback包取scn的原因。


上述的查询结果已经清晰的向我们展示了我们所做的操作以及操作的时间等(实际执行的语句该视图并没有记录,只能通过undo_sql和operation推测),随着我们将事务范围的不断扩大,我们可以持续向前翻阅曾经做过的操作。当然,实际使用的时候需要注意,由于该视图存储记录量较大(究竟有多大呢,目前尚未找到相关文档有明确说明,初步预计,应该与smon_scn_time的存储规则有关系),查询的时候建议通过关键列过滤,比如logon_user啦,table_name或table_owner之类的,这么比起来这项操作倒确实与logminer非常想像,这简直就是个活的logminer啊,虽然只是一段时间内的。

ORA-30052: invalid lower limit snapshot expression
//这个是我在实验过程中遇到的一个错误,搞了半天老是报这个错误,后来官方文档读了很久才意识到可能是undo_retention出了问题。察看了一下,只有
900,立马改成10800...后先用scn试了一下,可以后把scn转换成timestamp又试了一下,终于可以了...这个东西可真难用啊!!!

SQL>alter system set undo_retention=10800 scope=both;

SQL> show parameter undo_retention;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_retention                       integer     10800

 

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


五、Flash Table
闪回表:
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
 
TO_CHAR(SYSDATE,'YY
-------------------
2008-07-22 12:18:15

存在用户tssa并具有操作权限后

 

SQL> connect tssa/tssa2006
Connected.
SQL> alter table zmassage enable row movement;
 
Table altered.

flashback table ioms_duty_td to timestamp to_timestamp('2008-07-22 12:18:15','yyyy-mm-dd hh24:mi:ss');


Flashback complete.

 

六 闪回对象

闪回数据库对象:
以tssa登陆
SQL> show recyclebin;
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
IOMS_DUTY_TD     BIN$UpWRHkRKSRbgQICFegRtWQ==$0 TABLE        2008-07-22:12:50:45


SQL> flashback table IOMS_DUTY_TD to before drop;
 
Flashback complete.
-----------------------------------------------------------------------------------
从RECYCLEBIN中恢复

要恢复recyclebin中的表,注意语句如下:Flashback table [objName] to before drop,这个obj_name即可以是表名,也可以是recyclebin中的对象表(支持同时操作多个表,表名之间以逗号分隔即可),由于该项功能是恢复被删除表,因此官方对其还有另外一称谓:flashback drop。


下面举个例子,从recyclebin中恢复一个被删除的表:

JSSWEB> select object_name,original_name from recyclebin;


OBJECT_NAME                    ORIGINAL_NAME

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

BIN$u/7I62WxS12jMVO358SFgw==$0 JSS_TB3


JSSWEB> select object_name,original_name from recyclebin;


OBJECT_NAME                    ORIGINAL_NAME

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

BIN$u/7I62WxS12jMVO358SFgw==$0 JSS_TB3


JSSWEB> flashback table jss_tb3 to before drop;


闪回完成。


JSSWEB> select object_name,original_name from recyclebin;


未选定行


Flashback table语句同时提示了一个rename to [newTBname]的子句,如果要恢复的表在当前schema中已经存在同名的表,建议你在恢复时通过rename to 子句为待恢复的表指定一个新的表名,不然数据库会报ORA-38312错误,再举个例子:

JSSWEB> drop table jss_tb3;


表已删除。


JSSWEB> create table jss_tb3 as select *from jss_tb1;


表已创建。


JSSWEB> flashback table jss_tb3 to before drop;

flashback table jss_tb3 to before drop

*

第 1 行出现错误:

ORA-38312: 原始名称已被现有对象使用


你看,正如其提示的那样,该表被删除之后,又执行过创建同名表的操作,因此恢复的时候就会报错,怎么办呢,用rename to.....

JSSWEB> flashback table jss_tb3 to before drop rename to jss_tb3_bak;


闪回完成。

 

六 闪回数据库

1,―――――――――――数据库必须处于归档模式:
SQL> archive log list;
Database log mode              No Archive Mode
Automatic archival             Disabled
Archive destination            USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     24
Current log sequence           26
――――――――――――――――――――――――――――――――――――
把数据库改成归档模式
――――――――――――――――――――――――――――――――――――
SQL> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     24
Next log sequence to archive   26
Current log sequence           26
2,――――――――――――――建立闪回区
SQL> connect sys/sys123 as sysdba;

SQL> select  file_type from v$flah_recovery_area_usage;―――测试是否存在闪回区?
select  file_type from v$flah_recovery_area_usage
                       *
ERROR at line 1:
ORA-00942: table or view does not exist

SQL> alter system set db_recovery_file_dest_size=1g scope=both;
 
System altered.

alter system set db_recovery_file_dest='/u01/app/oracle/flash_recovery_area'scope=both;
alter system set db_recovery_file_dest='/arch/oracle/flash_recovery_area'scope=both;

/arch/oracle/flash_recovery_area

System altered.

SQL> show parameter db_recovery_file_dest;
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string      /u01/app/oracle/flash_recovery
                                                 _area
db_recovery_file_dest_size           big integer 1G

 

SQL> shutdown immediate;

SQL> startup mount;

SQL> alter database flashback on;
 
Database altered.

SQL> alter database open;
 
Database altered.

SQL> select flashback_on from v$database;
 
FLASHBACK_ON
------------------
YES

 

闪回数据库:
以sys登陆

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

如果没有启用flashback下面蒋查不到 (最早日期)

SQL> select oldest_flashback_scn,oldest_flashback_time from v$flashback_database_log;
 
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_TI
-------------------- -------------------
              919347 2008-07-22 12:09:17


SQL> select sysdate from dual;
 
SYSDATE
-------------------
2008-07-22 14:07:27

 

 


SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.

SQL> startup mount exclusive;

SQL> flashback database to timestamp to_timestamp('2009-07-20 22:11:00','yyyy-mm-dd hh24:mi:ss');
 
Flashback complete.


SQL> alter database open resetlogs; ――用resetlogs打开后将不能再回闪resetlogs之前的时间点
 
Database altered.

SQL> select oldest_flashback_scn,oldest_flashback_time from v$flashback_database_log;
 
OLDEST_FLASHBACK_SCN OLDEST_FL
-------------------- ---------
              919347 22-JUL-08

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值