2013年(350)
分类: Oracle
2013-04-25 11:08:46
2、As of scn的示例
仍以前文中创建的表为例,既然是基于scn的查询,我们首先就需要得到scn,这里我们通过dbms_flashback.get_system_change_number函数来获取当前的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
---------- --------------------
1 A
2 B
3 C
4 D
5 E
6 F
7 G
8 H
9 I
10 J
11 K
12 L
13 M
14 N
15 O
16 P
17 Q
18 R
19 S
20 T
已选择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的方式则只能最近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,会理解的更深刻一些。
===================================