Oracle的闪回技术允许我们查看一个对象之前的状态,而不用做基于时间点的不完全恢复,使用这种技术我们可以:
a) 查看当前状态以前的数据
b) 查看数据库的修改历史
c) 把表或表数据恢复到以前的某个时间
d) 自动跟踪并归档事物数据的修改
e) 在线回滚事务
闪回技术是依赖UNDO数据的,UNDO数据是被持久化到磁盘上的,即使数据库重启,他也能保留,保留时间受undo_retention影响,UNDO数据还有以下作用:
a) Rollbacktransaction
b) 恢复失败事物
c) 构造一致读
在开发中经常用到的闪回技术有
a) Flashbackup query(依赖UNDO)
b) Flashback versionquery(依赖UNDO)
c) Flashbacktransaction query(依赖UNDO)
对于DBA来说用到的闪回技术有:
a) Flashback table(依赖UNDO)
b) Flashback drop (依赖回收站)
c) Flashback database(依赖flashback log)
开发相关的闪回依赖UNDO数据,并且要使用AUM(automatic undo management),除了配置足够大的UNDO表空间,还要注意如下参数的配置:UNDO_MANAGEMENTUNDO_TABLESPACE UNDO_RETENTION;对于固定尺寸的UNDO表空间,oracle会自动调整以适应undo数据的保留时间,对于自动扩展的UNDO表空间,oracle会保证数据保留时间大于最长时间查询或UNDO_RETENTION参数指定的值。UNDO_RETENTION并不一定保证UNDO的数据不被覆盖,如果要硬性指定则需要把RETENTIONGUARANTEE的特性打开:
SQL> alter tablespaceundotbs1 retention guarantee;
表空间已更改
SQL> alter tablespace undotbs1retention noguarantee;s
表空间已更改。
FlashbackQuery演示:
SQL> select *from t;
IDMSG
---------- ----------
1aaa
2bbb
3ccc
SQL> select current_scnfrom v$database;
CURRENT_SCN
-----------
2226411
SQL> delete from t;
已删除 3行。
SQL> commit;
提交完成。
SQL> select * from t;
未选定行
SQL> select * from t as ofscn 2226411;
ID MSG
---------- ----------
1 aaa
2 bbb
3 ccc
SQL> select * from t as oftimestamp(systimestamp - interval '60' second);
未选定行
SQL> select * from t as oftimestamp(systimestamp - interval '70' second);
未选定行
SQL> select * from t as oftimestamp(systimestamp - interval '80' second);
未选定行
SQL> select * from t as oftimestamp(systimestamp - interval '100' second);
ID MSG
---------- ----------
1 aaa
2 bbb
3 ccc
FlashbackVersion Query演示:
这种查询可以查看表内指定时间段内经历了哪些版本,实际是利用了oracle的伪列,查询语法如下:
VERSIONS {BETWEEN{SCN | TIMESTAMP} start AND end}
SQL> l
1 SELECTversions_startscn,
2 versions_starttime,
3 versions_endscn,
4 versions_endtime,
5 versions_xid,
6 versions_operation,
7 id,
8 msg
9 FROM lihm.t
10* VERSIONS BETWEENSCN MINVALUE AND MAXVALUE
SQL> /
VERSIONS_STARTSCNVERSIONS_STARTTIME VERSIONS_ENDSCNVERSIONS_ENDTIME VERSIONS_XID VE ID MSG
------------------------------------- --------------- -------------------- ---------------- ------------ -----
22270452013-08-14 11:36:21 03000F001A070000 I 3 ccc
22264212013-08-14 11:15:07 020010003F070000 D 3 ccc
22264212013-08-14 11:15:07 020010003F070000 D 2 bbb
22264212013-08-14 11:15:07 020010003F070000 D 1 aaa
22263772013-08-14 11:13:49 22264212013-08-14 11:15:07 06000400E6070000 I 3 ccc
22263772013-08-14 11:13:49 22264212013-08-14 11:15:07 06000400E6070000 I 2 bbb
22263772013-08-14 11:13:49 22264212013-08-14 11:15:07 06000400E6070000 I 1 aaa
可以看到在2013-08-14 11:13:49到2013-08-14 11:15:07插入了三条数据,然后删除了这三条,最后插入一条数据。
FlashbackTransaction Query演示:
闪回事物查询可以查找出历史事物的数据,或指定时间段内所有事物的数据,并且oracle提供了与原事物逻辑相反的SQL用来还原数据,要使用该种闪回特性必须把附加日志功能打开:
SQL>ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
禁用附加日志功能:
SQL>ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;
SQL> ALTER DATABASE ADDSUPPLEMENTAL LOG DATA;
数据库已更改。
SQL> delete from lihm.twhere id=2;
已删除 1行。
SQL> l
1 SELECTversions_xid,
2 versions_operation,
3 id,
4 msg
5 FROM lihm.t
6* VERSIONS BETWEENSCN MINVALUE AND MAXVALUE
SQL> /
VERSIONS_XID VE ID MSG
---------------- ------------ -----
02000F0040070000 D 2 bbb
06000E00E8070000 D 1 aaa
09000300D3070000 I 4 ddd
09000300D3070000 I 2 bbb
09000300D3070000 I 1 aaa
3 ccc
可以看到删除是的XID为02000F0040070000,使用闪回服务查询找出修复数据的SQL:
SQL> l
1 select xid,operation, undo_sql
2 from FLASHBACK_TRANSACTION_QUERY
3* where XID ='02000F0040070000'
SQL> /
XID OPERATION UNDO_SQL
---------------- ------------------------------
02000F0040070000DELETE insert into"LIHM"."
T"("ID","MSG")value
s ('2','bbb');
02000F0040070000 BEGIN
使用这个UNDO_SQL我们就可以还原以前的数据。
DBMS_FLASHBACK的使用
DBMS_FLASHBACK包允许我们回到过去某个时间(穿越到过去)执行查询,这种方式给书写SQL带来了方便,我们可以不用加AS OF之类的字句了,使用也比较简单
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
2271358
SQL> select * from t;
ID MSG
---------- ----------
1 aaa
2 bbb
3 ccc
-1 xyz
-1 xyz
-1 xyz
已选择 6 行。
SQL> delete from t where id=-1;
已删除 3 行。
SQL> commit;
提交完成。
SQL> select * from t;
ID MSG
---------- ----------
1 aaa
2 bbb
3 ccc
SQL> exec dbms_flashback.ENABLE_AT_SYSTEM_CHANGE_NUMBER(2271358);
SQL>
SQL> select * from t;
ID MSG
---------- ----------
1 aaa
2 bbb
3 ccc
SQL> EXEC dbms_flashback.ENABLE_AT_SYSTEM_CHANGE_NUMBER(2271358);
PL/SQL 过程已成功完成。
SQL> select * from t;
ID MSG
---------- ----------
1 aaa
2 bbb
3 ccc
-1 xyz
-1 xyz
-1 xyz
已选择 6 行。
SQL> EXEC dbms_flashback.disable;
PL/SQL 过程已成功完成。
SQL> select * from t;
ID MSG
---------- ----------
1 aaa
2 bbb
3 ccc