flashback query
发布时间:2020-12-15 17:59:07 所属栏目:百科 来源:网络整理
导读:目录 1Flashback简介 2闪回查询 flashback query 3获取scn的方法 ? 1Flashback简介 ?? 在Oracle 10g中, Flashback家族分为以下成员: Flashback Database, Flashback Drop,Flashback Query(分Flashback Query,Flashback Version Query, Flashback Transa
目录
1Flashback简介
2闪回查询 flashback query
3获取scn的方法?
在Oracle 10g中, Flashback家族分为以下成员: Flashback Database, Flashback Drop,Flashback Query(分Flashback Query,Flashback Version Query, Flashback Transaction Query 三种) 和Flashback Table。
?Flashback query技术是以Undo segment中的内容为基础的, 因此受限于UNDO_RETENTON参数。要使用flashback 的特性,必须启用自动撤销管理表空间。
?在9i 之前,回滚段的管理和监控是需要dba手工介入的,创建合适的回滚段是件非常耗费dba 精力的事情,需要不断关注oracle 运行状况很长一阵子时间后,不断的调整以确认一段时期内回滚段的大小,一旦回滚段创建的不合适,就极有可能引起性能问题甚至错误,比如ora-1555 就是典型的回滚段设置不合适触发的。
在9i之后的版本中,oracle 为了清晰它的整个概念,取消了回滚段这个说法(实际上并未取消回滚段),而完全以undo 来代替,这也它正好与redo 相对应,一个重做,一个撤销。回滚段可以不再由dba 手工介入,而是完全由它自己在运行时自动分配,这在一定程度上即解放了dba,也确实起到了提高性能的作用,比如采用自动管理表空间就可以最大程序的降低ora-1555发生的机率(注意是降低,不是避免,我们不可能创建一个无限大的回滚段,ora-1555 也并不完全是回滚段造成的,关于ora-01555 的问题这里就不深入讨论了,网上有太多文章描述和介绍该问题及解决方案)
是否起用自动管理的撤销表空间由两个初始化参数决定:
UNDO_MANAGEMENT:值为AUTO 表示使用了自动撤销管理表空间,MANUAL 则表示手动管理。
UNDO_TABLESPACE:当UNDO_MANAGEMENT 值为AUTO 时,该参数用来指定当前的undo 表空间名称。
UNDO表空间的大小,直接影响到flashback query 的查询能力,因为多版本查询所依赖的undo 数据都存储在undo 表空间中,该表空间越大,所能够存储的undo 数据自然也越多,如果该表空间可用空间非常小,别说flashback 了,恐怕正常查询都有可能触发ora-01555。
该参数用来指定undo 记录保存的最长时间,以秒为单位,是个动态参数,完全可以在实例运行时随时修改通常默认是900 秒,也就是15 分钟。
一定要注意,undo_retention 只是指定undo 数据的过期时间,并不是说,undo 中的数据一定会在undo表空间中保存15 分钟,比如说刚一个新事务开始的时候,如果undo 表空间已经被写满,则新事务的数据会自动覆盖已提交事务的数据,而不管这些数据是否已过期,因此呢,这就又关联回了第一点,当你创建一个自动管理的undo 表空间时,还要注意其空间大小,要尽可能保证undo 表空间有足够的存储空间。
同时还要注意,也并不是说,undo_retention 中指定的时间一过,已经提交事务中的数据就立刻无法访问,它只是失效,只要不被别的事务覆盖,它会仍然存在,并可随时被flashback 特性引用。如果你的undo表空间足够大,而数据库又不是那么繁忙,那么其实undo_retention 参数的值并不会影响到你,哪怕你设置成1,只要没有事务去覆盖undo 数据,它就会持续有效。因此呢,这里还是那句话,要注意undo 表空间的大小,保证其有足够的存储空间。
如果一定要保证undo数据的保存有效期,可以为undo 表空间指定Retention Guarantee,指定之后,oracle 对于undo 表空间中未过期的undo 数据不会覆盖,如果有效期未过,但undo表空间不足,需要覆盖旧的undo数据,会报ORA-30036错误。
启动guarantee:
SQL> Alter tablespace undotbs1 retention guarantee;
禁止guarantee:
SQL> Alter tablespace undotbs1 retention noguarantee;
?
Oracle通过undo 数据来确保写不堵塞读,简单的讲,不同的事务在写数据时,会将数据的前映像写入undo 表空间,这样如果同时有其它事务查询该表数据,则可以通过undo 表空间中数据的前映像来构造所需的完整记录集,而不需要等待写入的事务提交或回滚。
? 用法与标准查询非常类似,要通过flashback query 查询undo 中的撤销数据,最简单的方式只需要在标准查询语句的表名后面跟上as of timestamp(基于时间)或as of scn(基于scn)即可。as of timestamp|scn 的语法是自9iR2 后才开始提供支持。
ddl命令会使undo表空间中的撤销数据失效,对执行过ddl操作的表应用flashback query,会触发ora-01466错误。flashback query特性对v$tables,v$tables等动态性能视图无效,但对all_*,
user_*,dba_*等数据字典有效,比如可以通过query dba_source来找回之前版本的procedure.
?
? 同时也适用于dblink.
? ? select * deom tbl@dblink as of scn XXX.
?
SQL> create TABLE flash_table (ID,table_name)
? 2? AS SELECT ROWNUM,table_name
? 3? FROM User_Tables
? 4? WHERE ROWNUM<20;
?
Table created
?
SQL> delete from? flash_table where id<10;
?
9 rows deleted
?
SQL> commit;
?
Commit complete
?
SQL> select * from flash_table ;
?
??????? ID TABLE_NAME
---------- ------------------------------
??????? 10 CONV_ID_LIST_1016
??????? 11 CONV_UNIT_LIST_1016
??????? 12 CONV_TABLE_INDEX_LIST_1016
??????? 13 LOGS_ID_REPAIR
??????? 14 GJ_SQ_USE_LIST
??????? 15 LOGS_SEQ_ERR
??????? 16 LOG_GEN_CONV_TAB
??????? 17 LOGS_UNIT_ERROR
??????? 18 LOGS_REPAIR_ID
??????? 19 LOGS_CONV_PARALLEL
?
10 rows selected
?
SQL> select * from flash_table as of timestamp sysdate-3/1440;
?
select * from flash_table as of timestamp sysdate-3/1440
?
ORA-01466: unable to read data - table definition has changed
此错误表明删除的时间还没有3分钟
SQL> select * from flash_table as of timestamp sysdate-5/1440;
?
??????? ID TABLE_NAME
---------- ------------------------------
???????? 1 CONV_TABLE_LIST_1103
???????? 2 CONV_ID_REPAIR_1103
???????? 3 CONV_ID_LIST_1103
???????? 4 CONV_UNIT_LIST_1103
???????? 5 CONV_TABLE_INDEX_LIST_1103
???????? 6 MB_STAFF_1126
???????? 7 DHM_TMP_SQL_NEW_ID
???????? 8 CONV_TABLE_LIST_1016
???????? 9 CONV_ID_REPAIR_1016
??????? 10 CONV_ID_LIST_1016
??????? 11 CONV_UNIT_LIST_1016
??????? 12 CONV_TABLE_INDEX_LIST_1016
??????? 13 LOGS_ID_REPAIR
??????? 14 GJ_SQ_USE_LIST
??????? 15 LOGS_SEQ_ERR
??????? 16 LOG_GEN_CONV_TAB
??????? 17 LOGS_UNIT_ERROR
??????? 18 LOGS_REPAIR_ID
??????? 19 LOGS_CONV_PARALLEL
?
19 rows selected
?
SQL> insert into flash_table
? 2? select * from flash_table as of timestamp sysdate-5/1440
? 3? where id<10;
commit;
???如遇到主外键关联约束的表的回复,如果使用as of timestamp的方式,可能会由于时间点不统一造成数据的选择或者插入失败,通过as of scn方式能够确保记录处理的时间点一致。
可以和where中的其他条件一起使用:
SELECT?*?from?? ?tb_bm_prod_inst??AS??OF?TIMESTAMP???SYSDATE-3?/1440??WHERE?? serv_code='214331180'?;??
?? 1.SQL> select current_scn from v$database;
?
??? CURRENT_SCN
??? -----------
??? 11357586733
??
?? 2. select dbms_flashback.get_system_change_number fscn from dual;
SQL>? select dbms_flashback.get_system_change_number fscn from dual;
????? FSCN
----------
?? 1882009
?? 3. select timestamp_to_scn(sysdate) from dual;
?
?? TIMESTAMP_TO_SCN(SYSDATE)
?? -------------------------
?????????? 11269857800795
?
select timestamp_to_scn(sysdate) from dual;
?
TIMESTAMP_TO_SCN(SYSDATE)
-------------------------
?????????? 11269857800795
?select count(*) from dgib.tb_wm_plan_rule as of scn? 11269857800795;
?
? COUNT(*)
----------
??? 113092
SQL> select count(*) from dgib.tb_wm_plan_rule as of scn? 11269656800680;
?
? COUNT(*)
----------
??? 113261
?
SQL> select scn_to_timestamp( 11269616800680) from dual;
?
SCN_TO_TIMESTAMP(1126961680068
--------------------------------------------------------------------------------
04-8月 -10 01.46.08.000000000 下午
?
SQL> insert into flashback_tb_wm_plan_rule select * from tb_wm_plaN_rule as of scn 11269616800680;
?
113261 rows inserted
???即使执行flashback query时指定用as of timestamp,oracle也会将其转换为scn.具体的timestamp和scn的对应关系,记录在系统表sys.smon_scn_time;
SQL> desc sys.smon_scn_time;
Name???????? Type????? Nullable Default???????????????????????? Comments
------------ --------- -------- ------------------------------- --------
THREAD?????? NUMBER??? Y????????????????????????????????????????????????
TIME_MP????? NUMBER??? Y????????????????????????????????????????????????
TIME_DP????? DATE????? Y????????????????????????????????????????????????
SCN_WRP????? NUMBER??? Y????????????????????????????????????????????????
SCN_BAS????? NUMBER??? Y????????????????????????????????????????????????
NUM_MAPPINGS NUMBER??? Y????????????????????????????????????????????????
TIM_SCN_MAP? RAW(1200) Y????????????????????????????????????????????????
SCN????????? NUMBER??? Y??????? 0???????????????????????????????????????
ORIG_THREAD? NUMBER??? Y??????? 0 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* for downgrade */?
SQL> select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') from sys.smon_scn_time where rownum<5;
?
?????? SCN TO_CHAR(TIME_DP,'YYYY-MM-DDHH2
---------- ------------------------------
1135554883 2010-11-28 09:31:35
1135554897 2010-11-28 09:41:37
1135554905 2010-11-28 09:46:32
1135554906 2010-11-28 09:46:40
????
每3秒产生一次系统时间与scn的匹配并入smon_scn_time表。
9iR1版本的flashback query,只能使用dbms_flashback包。
SQL> exec dbms_flashback.enable_at_system_change_number(11357590502111);
或者
SQL> exec dbms_flashback.enable_at_time(sysdate-5/1440);
SQL>select * from flash_table;
可以看到前像数据,但没不能保存。因为在应用dbms_flashback包方式时,在disable当前查询状态前,当前session不能执行ddl/dml操作,否则就会提示ora-08182错误。因此应该通过dbms_flashback.disable取消查询状态。
SQL> exec dbms_flashbakc.disable;
如果要保持当前查看到得数据,只能在执行dbms_flashback包之前用游标保存记录。例如:
declare
?? cursor c_tal is select * from flash_table where id<10;--之前误操作,需要找回的记录
?? t_row c_tal%rowtype;
begin
? dbms_flashback.enable_at_system_change_number(11357590502111);
? open c_tal
? dbms_flashbakc.disable;
?loop
? fetch c_tal into t_row;
? exit when c_tal%notfound;
? insert into flash_table valuse(t_row.id,t_row.table_name);
end loop;
close c_tal;
commit;
end;
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |