Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評(píng)論 :: 0 Trackbacks
          9i Flashback 簡(jiǎn)介
          ?
          ??? 不得不說(shuō),F(xiàn)lashback是我接觸到的Oracle最好的一個(gè)特性,簡(jiǎn)單易用,真是居家旅行的必備良藥啊。原本以為只有10g才有這個(gè)功能,沒(méi)想到今天發(fā)現(xiàn)9i就有了,所以專門(mén)來(lái)介紹一下在9i下面的flashback的操作。
          ?
          1、原理
          ?
          ??? 當(dāng)數(shù)據(jù)UPDATE或DELETE時(shí),原來(lái)的數(shù)據(jù)會(huì)保存在UNDO表空間中,保存的最少時(shí)間是UNDO_RETENTION。實(shí)際的保存時(shí)間與UNDO表空間的大小和數(shù)據(jù)更改的繁忙程度相關(guān)。UNDO_RETENTION的參數(shù)(單位為秒)指定Oracle保存用于FlashBack查詢的UNDO映像的時(shí)間。一般你可以將這個(gè)值設(shè)為一整天(864000秒),這樣你就能看到前一天全天的映像。當(dāng)然,你的在線UNDO日志必須足夠大,大到足以能保存一整天的UNDO日志數(shù)據(jù),對(duì)于繁忙的Oracle系統(tǒng),這個(gè)數(shù)值可以達(dá)到很大。
          ?
          2、一些限制
          ?
          ??? * 服務(wù)器必須配置成使用自動(dòng) undo管理。
          ??? * 在使用FlashBack查詢時(shí)不能使用DDL或者DML。
          ??? * FlashBack不取消DDL操作,例如DROP命令。
          ?
          ??? 數(shù)據(jù)庫(kù)管理員做一些必要的設(shè)置之后,一般用戶才能使用Flashback查詢功能:
          ??? SQL> ALTER SYSTEM SET UNDO_MANAGEMENT=AUTO
          ??? SQL> ALTER SYSTEM SET UNDO_RETENTION=86400
          ??? SQL> GRANT EXECUTE ON DBMS_FLASHBACK TO USERNAME;
          ?
          3、獲得SCN或時(shí)間點(diǎn)
          ?
          ??? 在FlashBack時(shí),可以嘗試多個(gè)SCN,獲取最佳值。
          ??? 如果能得知具體時(shí)間,那么可以獲得準(zhǔn)確的數(shù)據(jù)閃回。
          ??? SQL> alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS';
          ??? SQL> select sysdate from v$database;
          ?
          ??? 可通過(guò)以下方法獲取SCN,但是不知為什么,兩種方法獲得的 SCN不一樣
          ??? SQL> select dbms_flashback.get_system_change_number scn from dual;
          ??? SQL> select max(ktuxescnw * power(2,32) + ktuxescnb) SCN from x$ktuxe;
          ?
          4、啟用或禁用flashback查詢
          ?
          使用系統(tǒng)改變數(shù)(SCN)或者真實(shí)時(shí)間來(lái)指定FlashBack的時(shí)間點(diǎn)來(lái)獲取數(shù)據(jù)映象。
          ?
          方法一:
          SQL> select * from [TABLE] as of scn 129292;
          SQL> select * from [TABLE] as of timestamp to_timestamp('時(shí)間','時(shí)間格式');
          SQL> select * from [TABLE] as of timestamp to_timestamp('2007-12-18 08:40:00','YYYY-MM-DD HH24:MI:SS');
          ?
          方法二:
          啟用:
          SQL> exec dbms_flashback.enable_at_system_change_number(112112);
          SQL> exec dbms_flashback.enable_at_time('28-AUG-02 11:00:00');
          啟用后看到的只是閃回的結(jié)果,實(shí)際上并未恢復(fù)數(shù)據(jù)。且閃回狀態(tài)下不能做DML操作。可以先恢復(fù)到一個(gè)臨時(shí)表中。見(jiàn)示例。
          ?
          禁用:
          SQL> exec dbms_flashback.disable();
          ?
          5、示例:
          ?
          declare
          ? cursor c1 is
          ??? select * from scott.emp_temp;
          ? r_c1 scott.e%rowt ype;
          begin
          ? loop
          ??? dbms_flashback.enable_at_system_change_number(49570);
          ??? if c1%isopen = false then
          ????? open c1;
          ??? end if;
          ??? fetch c1
          ????? into r_c1;
          ??? dbms_flashback.disable();
          ??? exit when c1%notfound;
          ??? update scott.emp_temp set sal = r_c1.sal where empno = r_c1.empno;
          ??? commit;
          ? end loop;
          ? exec dbms_flashback.disable();
          ? close c1;
          end;
          /
          ?
          ?
          ?
          轉(zhuǎn)一篇的yangtingkun文章:
          ====================================================================================================
          ?
          Oracle9i使用閃回操作
          ===========================================================
          作者: yangtingkun(
          http://yangtingkun.itpub.net )
          發(fā)表于: 2005.01.24 23:23
          分類: ORACLE
          出處:
          http://yangtingkun.itpub.net/post/468/15464
          ---------------------------------------------------------------
          ?
          ??? 從9i開(kāi)始,Oracle提供了閃回(FLASHBACK)功能。即查找當(dāng)前時(shí)間之前的某個(gè)時(shí)間點(diǎn)系統(tǒng)或表的狀態(tài)。
          ??? 可以閃回的最大時(shí)間和回滾空間有關(guān)。如果使用了自動(dòng)管理回滾表空間,那么UNDO_RETENTION給出了閃回支持的最小時(shí)間。也就是說(shuō),F(xiàn)LASHBACK最少可以支持UNDO_RETENTION給出的時(shí)間,如果系統(tǒng)比較閑,則可以閃回更長(zhǎng)的時(shí)間。(當(dāng)然,如果回滾表空間的空間分配不足,當(dāng)系統(tǒng)處于忙時(shí),有可能重用還沒(méi)有達(dá)到UNDO_RETENTION時(shí)間限制的數(shù)據(jù)的空間)
          ??? 使用閃回的一個(gè)前提是表不能進(jìn)行DDL操作。不但不能對(duì)DDL操作進(jìn)行回閃,而且,也無(wú)法閃回到DDL操作以前的數(shù)據(jù)了。
          ?
          ??? Oracle提供兩種方法支持閃回:
          ?
          ??? 一種是使用DBMS_FLASHBACK包,這是SESSION級(jí)的回閃。執(zhí)行DBMS_FLASHBACK包的ENABLE_AT_TIME或者ENABLE_AT_SYSTEM_CHANGE_NUMBER過(guò)程后,當(dāng)前session處于閃回狀態(tài),此時(shí)任何的查詢返回的是ENABLE_AT_TIME指定的時(shí)間點(diǎn)或ENABLE_AT_SYSTEM_CHANGE_NUMBER指定的SCN的時(shí)刻對(duì)應(yīng)的狀態(tài)。當(dāng)執(zhí)行DISABLE過(guò)程后,系統(tǒng)恢復(fù)到當(dāng)前狀態(tài)。
          ??? 這種方法是SESSION級(jí)別,此后對(duì)任何表的任意的查詢語(yǔ)句都返回以前某個(gè)時(shí)間點(diǎn)的結(jié)果。不過(guò)缺點(diǎn)是閃回狀態(tài)下,不支持DML語(yǔ)句。如果用以前的某個(gè)時(shí)間點(diǎn)的數(shù)據(jù)恢復(fù)當(dāng)前數(shù)據(jù),則必須ENABLE_AT_TIME后,打開(kāi)一個(gè)游標(biāo),然后DIABLE閃回狀態(tài),然后從游標(biāo)中讀取數(shù)據(jù)并插入到當(dāng)前表中。
          ?
          ??? 第二種方式是采用AS OF語(yǔ)句,這是語(yǔ)句級(jí)的回閃。AS OF后面可以跟TIMESTAMP或SCN。通過(guò)在查詢表后面直接加AS OF時(shí)間點(diǎn)的方式,可以查詢到那一時(shí)刻的數(shù)據(jù)。這種方法直觀方便,使用于恢復(fù)個(gè)別表,或?qū)δ硞€(gè)表提供基于時(shí)間點(diǎn)的訪問(wèn)。
          ?
          ??? 下面給出一個(gè)例子:
          ?
          SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
          ?
          會(huì)話已更改。
          ?
          SQL> create table t (id number, name varchar2(30));
          ?
          表已創(chuàng)建。
          ?
          SQL> insert into t values (1, 'yangtingkun');
          ?
          已創(chuàng)建 1 行。
          ?
          SQL> commit;
          ?
          提交完成。
          ?
          SQL> select sysdate from dual;
          ?
          SYSDATE
          -------------------
          2005-01-24 23:21:23
          ?
          SQL> commit;
          ?
          提交完成。
          ?
          SQL> select sysdate from dual;
          ?
          SYSDATE
          -------------------
          2005-01-24 23:26:05
          ?
          SQL> delete t;
          ?
          已刪除 1 行。
          ?
          SQL> commit;
          ?
          提交完成。
          ?
          SQL> exec dbms_flashback.enable_at_time(to_timestamp('2005-1-24 23:26:5', 'yyyy-mm-dd hh24:mi:ss'))
          ?
          PL/SQL 過(guò)程已成功完成。
          ?
          SQL> select * from t;
          ?
          ??????? ID NAME
          ---------- ------------------------------
          ???????? 1 yangtingkun
          ?
          SQL> exec dbms_flashback.disable
          ?
          PL/SQL 過(guò)程已成功完成。
          ?
          SQL> select * from t;
          ?
          未選定行
          ?
          SQL> select * from t as of timestamp to_timestamp('2005-1-24 23:26:5', 'yyyy-mm-dd hh24:mi:ss');
          ?
          ??????? ID NAME
          ---------- ------------------------------
          ???????? 1 yangtingkun
          ?

          ??? 上面給出了通過(guò)兩種方法實(shí)現(xiàn)回閃查詢的方法。在上面的例子中,我在執(zhí)行insert命令和delete命令直接間隔了5分鐘左右,且提交了一些空事務(wù)。這樣做的原因是由于Oracle把時(shí)間點(diǎn)映射到SCN上,大約每5分鐘左右映射依次。因此兩個(gè)操作間隔5分鐘,且保證兩個(gè)操作間SCN發(fā)生了變化,從而使Oracle可以將timestamp正確的映射到不同的SCN上。
          ?
          ??? 下面給出兩種不同方法是如何實(shí)現(xiàn)數(shù)據(jù)恢復(fù)的。
          ?
          SQL> select * from t;
          ?
          未選定行
          ?
          SQL> declare
          ? 2?? cursor c is select * from t;
          ? 3?? v_record c%rowtype;
          ? 4? begin
          ? 5?? dbms_flashback.enable_at_time(to_timestamp('2005-1-24 23:26:5', 'yyyy-mm-dd hh24:mi:ss'));
          ? 6?? open c;
          ? 7?? dbms_flashback.disable;
          ? 8?? loop
          ? 9??? fetch c into v_record;
          10??? exit when c%NOTFOUND;
          11??? insert into t values (v_record.id, v_record.name);
          12?? end loop;
          13?? close c;
          14? end;
          15? /
          ?
          PL/SQL 過(guò)程已成功完成。
          ?
          SQL> select * from t;
          ?
          ??????? ID NAME
          ---------- ------------------------------
          ???????? 1 yangtingkun
          ?
          SQL> rollback;
          ?
          回退已完成。
          ?
          SQL> select * from t;
          ?
          未選定行
          ?
          SQL> insert into t
          ? 2? select * from t as of timestamp to_timestamp('2005-1-24 23:26:5', 'yyyy-mm-dd hh24:mi:ss');
          ?
          已創(chuàng)建 1 行。
          ?
          SQL> select * from t;
          ?
          ??????? ID NAME
          ---------- ------------------------------
          ???????? 1 yangtingkun
          posted on 2009-02-10 22:47 decode360 閱讀(231) 評(píng)論(0)  編輯  收藏 所屬分類: 07.Oracle
          主站蜘蛛池模板: 临洮县| 通山县| 望江县| 汝南县| 富裕县| 板桥市| 仁布县| 读书| 铁岭县| 右玉县| 黑龙江省| 台州市| 射洪县| 石渠县| 雷州市| 马鞍山市| 泌阳县| 利津县| 长治县| 同心县| 雅安市| 连城县| 西贡区| 舞钢市| 德令哈市| 洪雅县| 吕梁市| 安乡县| 乌兰浩特市| 青海省| 曲靖市| 马边| 海盐县| 汝阳县| 开江县| 万源市| 武鸣县| 安多县| 平南县| 乐陵市| 分宜县|