概要:通过一普通用户对一个表的更改来学习flashback的使用。本实验通过调用SCN和时间戳timestamp两个关键点来还原数据。需要说明的是SCN还原比较方便,而时间戳因为格式有时候不好把握还原比较费力,但可以使用函数to_timestamp()。
第一步:普通用户登录,创建一测试表并对其中测试数据进行更新
SQL> conn scott/m1234;
已连接。
创建表emp1,并对其中一数据更新。
SQL> create table emp1 as select * from emp;
SQL> select * from emp1;
0 abc 1 22 1999-12-01 00:00:00 1000
SQL> update emp1
2 set job='clerk' where empno=0;
已更新 1 行。
SQL> select * from emp1;
0 abc clerk 22 1999-12-01 00:00:00 1000
SQL> commit;
提交完成。
第二步:修改时间格式,输出SCN.这里需要注意:一个是SCN必须声明(variable scn number),而是必须有执行权限(grant execute on dbms_flashback to scott;),否则会报如下错:
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
会话已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2010-12-10 09:10:01
SQL> set linesize 300;
SQL> exec:scn:=dbms_flashback.get_system_change_number();
SP2-0552: 未声明绑定变量 "SCN"。
SQL> exec:scn:=dbms_flashback.get_system_change_number();
SP2-0552: 未声明绑定变量 "SCN"。
SQL> variable scn number;
SQL> exec:scn:=dbms_flashback.get_system_change_number();
BEGIN :scn:=dbms_flashback.get_system_change_number(); END;
*
第 1 行出现错误:
ORA-06550: 第 1 行, 第 14 列:
PLS-00201: 必须声明标识符 'DBMS_FLASHBACK'
ORA-06550: 第 1 行, 第 7 列:
PL/SQL: Statement ignored
正确做法:
SQL> conn sys/m1234 as sysdba;
已连接。
SQL> grant execute on dbms_flashback to scott;
授权成功。
SQL> conn scott/m1234;
已连接。
SQL> exec:scn:=dbms_flashback.get_system_change_number();
PL/SQL 过程已成功完成。
SQL> print scn;
SCN
-----------------
2129455
第三步,多次寻找SCN,寻找最佳的。
SQL> select * from emp1 as of scn 2129400;
0 abc clerk 22 01-12月-99 1000 90
SQL> select * from emp1 as of scn 2129000;
0 abc clerk 22 01-12月-99 1000 90
SQL> select * from emp1 as of scn 2128000;
0 abc 1 22 01-12月-99 1000 90
第四步,还原数据。本来可以通过SCN还原的,但本次为了学习时间戳timestamp还原,改用timestamp还原。
先选择还原时间,选最佳时间,但老是格式不正确!
SQL> select scn_to_timestamp( 2128000) time from dual;
TIME
---------------------------------------------------------------------------
10-12月-10 09.09.11.000000000 上午
SQL> select * from emp1 as of timestamp 10-12月-10 09.09.11.000000000 上午;
select * from emp1 as of timestamp 10-12月-10 09.09.11.000000000 上午
*
第 1 行出现错误:
ORA-00933: SQL 命令未正确结束
SQL> select * from emp1 as of timestamp('2010-12-10 09:10:01','yyyy-mm-dd hh24:mi:ss');
select * from emp1 as of timestamp('2010-12-10 09:10:01','yyyy-mm-dd hh24:mi:ss')
SQL> select * from emp1 as of timestamp 2010-12-10 09:10:01;
SP2-0552: 未声明绑定变量 "10"。
查一小时前数据
SQL> select * from emp1 as of timestamp(systimestamp - interval'3600' second);
0 abc 1 22 01-12月-99 1000 90
查90分钟前数据。底下这个方式简单点
SQL> select * from emp1 as of timestamp systimestamp- 90/1440 ; //
0 abc 1 22 01-12月-99 1000 90
开始还原:
SQL> flashback table emp1 to timestamp systimestamp -90/1440;
flashback table emp1 to timestamp systimestamp -90/1440
*
第 1 行出现错误:
ORA-08189: 因为未启用行移动功能, 不能闪回表
需要启动行移动功能,为什么呢?因为此处使用的是DML操作恢复数据,不能保证rowid不变,所以要启动移动功能。
SQL> alter table emp1 enable row movement;
表已更改。
SQL> flashback table emp1 to timestamp systimestamp -90/1440;
闪回完成。
SQL> select * from emp1;
0 abc 1 22 01-12月-99 1000 90
补:
简单示范一下两函数间的转换,这个是从Oracle 10g开始的,timestamp_to_scn用于时间到SCN的转换,scn_to_timestamp用于SCN 到时间的转换。如下:
SQL> select timestamp_to_scn (to_timestamp('2010-12-10 14:43:40','yyyy-mm-dd hh24:mi:ss')) scn from dual;
SCN
----------
2132766
SQL> select scn_to_timestamp(2132766) from dual;
SCN_TO_TIMESTAMP(2132766)
---------------------------------------------------------------------------
10-12月-10 02.43.38.000000000 下午
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/22528444/viewspace-681609/ ,如需转载,请注明出处,否则将追究法律责任。