闪回
1 开启闪回
1. 记录当前时间或SCN
在数据库变动前记录时间或SCN
SQL> select to_char(sysdate,'YYYY-MM-DD HH24:mi:ss') from dual;
SQL> select current_scn from v$database;
2.开启闪回
开启闪回需要数据库在归档模型下,所以首先需要开启归档。并且在mount状态下。
首先查看是否开启闪回:
SQL> select flashback_on from V$database;
FLASHBACK_ON
------------------
NO
如果已经开启了闪回,无须执行下面的操作。
SQL> alter system set db_recovery_file_dest_size=30G scope=both;
SQL> alter system set db_recovery_file_dest='/u01/flashback' scope=both;
SQL> shutdown immediate
SQL> startup mount
SQL> alter database archivelog;
SQL> alter database flashback on;
SQL> alter database open;
再进行确认:
SQL> select flashback_on from V$database;
FLASHBACK_ON
------------------
YES
2 DROP闪回:
system表空间里的表,索引,约束被删除,不放在回收站,不能闪回
Oracle10g以后,当我们删除表时,默认Oracle只是在数据库字典里面对被删的表的进行了重命名,并没有真正的把表删除。
回收站(recyclebin):用来维护表被删除前的名字与删除后系统生成的名字之间的对应关系的数据字典,表上的相关对象(索引、触发器等)也会一并进入回收站。
SYS@ora11g>show parameter recyclebin
NAME TYPE VALUE
----------------------- ----------- ------------------------------
recyclebin string on
SQL> alter system set recyclebin=off scope=spfile;
SQL> alter system set recyclebin=on,scope=spfile;
SQL> alter session set recyclebin=off,scope=spfile;
SQL> alter session set recyclebin=on,scope=spfile;
SYS@ora11g>show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
T1 BIN$7mwwGMzzQB7gQKjAZAp57A==$0 TABLE 2013-12-26:15:47:48
T1 BIN$7mwwGMzyQB7gQKjAZAp57A==$0 TABLE 2013-12-26:15:47:22
T2 BIN$7mwwGMz0QB7gQKjAZAp57A==$0 TABLE 2013-12-26:15:48:09
可以查询回收站的东西
select * from "BIN$7mwwGMzzQB7gQKjAZAp57A==$0 ";
如果误对表做了drop操作,可用下面的方法闪回
SQL>flashback table t1 to before drop;
SQL>flashback table t1 to before drop rename to TE;
SQL>flashback table "BIN$7mwwGMzzQB7gQKjAZAp57A==$0"to before drop;
--闪回表后表的索引也会回来,但是索引名还是在recyclebin中显示的名字,所以使用 alterindex“ bin$xxx” rename to xxxx命令修改索引名称。
SQL>alter index "BIN$s6TKiw4uafDgRAAVF3jtoA==$0"rename to PK_PC_STIM_INJ_ENHANCE_MON
SYS@ora11g>select owner,tablespace_name,table_name,flash_cache,partitioned,status from dba_tables where table_name='TE';
OWNER TABLESPACE_NAME TABLE_NAME FLASH_C PAR STATUS
-------------------------------------------- ------------------------------ ------- --- --------
SYS USERS TE DEFAULT NO VALID
select table_name,index_name,constraint_name,constraint_type from user_constraints where table_name='T4';
select table_name,column_name,constraint_name from user_cons_columns where table_name='T4';
SYS@ora11g>select tablespace_name,table_name,index_name,index_type from user_indexes where table_name='T4';
TABLESPACE_NAME TABLE_NAME INDEX_NAME INDEX_TYPE
------------------------------ ------------------------------ ------------------------------ ---------------------------
SYSTEM T4 BIN$7mwwGMz1QB7gQKjAZAp57A==$0 NORMAL
SYS@ora11g>select tablespace_name,table_name,index_name,index_type from user_indexes where table_name='T5';
TABLESPACE_NAME TABLE_NAME INDEX_NAME INDEX_TYPE
------------------------------ ------------------------------ ------------------------------ ---------------------------
USERS T5 BIN$7mwwGMz3QB7gQKjAZAp57A==$0 NORMAL
系统表空间的索引、约束不能闪回
SYS@ora11g>alter index "BIN$7mwwGMz3QB7gQKjAZAp57A==$0" rename to empno_inx;
Index altered.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3 闪回表
用的是undo,查询过去某个时刻表的数据的情况,一旦确认某个时刻的数据满足我们的需求以后,可以根据这个时间执行闪回表。
SYS@ora11g>show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900单位是秒
undo_tablespace string UNDOTBS1
ORA-08189: 因为未启用行移动功能, 不能闪回表,需要先执行一个命令:
ALTER TABLE dept ENABLE ROW MOVEMENT;
SQL >FLASHBACK TABLE dept TO timestamp to_timestamp('2013-07-05 08:00:00','yyyy-mm-ddhh24:mi:ss');
SQL >FLASHBACK TABLE dept TO SCN 133456;
语法一:
select * from dept
VERSIONS BETWEEN TIMESTAMP SYSTIMESTAMP
- INTERVAL '1' DAY AND SYSTIMESTAMP -INTERVAL '1' HOUR;
语法二:
select * from dept as of timestamp
to_timestamp('2013-08-25 21:12:46','yyyy-mm-dd HH24:MI:SS');
语法三:
select * from dept as of scn 13081009;
语法四:
select * from
flashback_transaction_query a where a.table_name='DEPT';
附注:interval用法
Oracle语法:
INTERVAL '{ integer | integer time_expr | time_expr }' { { DAY | HOUR | MINUTE } [ ( leading_precision ) ] | SECOND [ ( leading_precision
[, fractional_seconds_precision ] ) ] } [ TO { DAY | HOUR | MINUTE | SECOND [ (fractional_seconds_precision) ] } ]
leading_precision值的范围是0到9, 默认是2. time_expr的格式为:HH[:MI[:SS[.n]]] or MI[:SS[.n]] or SS[.n], n表示微秒.
该类型与INTERVAL YEAR TO MONTH有很多相似的地方,建议先看INTERVAL YEAR TO MONTH再看该文.
INTERVAL '20' DAY - INTERVAL '240' HOUR = INTERVAL '10-0' DAY TO SECOND
表示: 20天 - 240小时 = 10天0秒
INTERVAL '30.12345' SECOND(2,4)
表示: 30.1235秒, 因为该地方秒的后面精度设置为4, 要进行四舍五入.
查询tableA中10分钟前的数据(闪回查询,前提:undo没有被覆盖..如果undo被覆盖,查询会失败)
Select * From table dept As Of Timestamp (systimestamp - Interval '10' minute);