Decode360's Blog

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

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
          ORA_ROWSCN
          ?
          ??? 了解一下10g之后可以新加入的偽劣ORA_ROWSCN,在判斷表的更新時間,是否有記錄被修改的時候比較有用。而且在9i之后,SCN號已經可以和時間互相轉換了,所以使用起來是比較方便的。但是要注意的有幾個事情:
          ?
          ??? 1、默認情況下ORA_ROWSCN以block為單位記錄SCN,如需精確到單一行,則需在建表時加入rowdependencies選項。
          ??? 2、將SCN轉換成timestamp時,太久遠的SCN是無法轉換的,測試了一下我機子上大概能轉一周以內的SCN。
          ??? 3、所有SCN點均為commit的時間,而非dml時間
          ?
          ??? 具體例子就不寫了,轉一篇文看一下就全明白了。
          ?
          ?
          -----------------------------
          關于ORA_ROWSCN

          作者:江楓 | 【轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明】
          地址:
          http://rdc.taobao.com/blog/dba/html/243_about_ora_rowscn.html
          ?
          Oracle10g引入了一個新的ORA_ROWSCN的偽列,可以查詢表中記錄最后變更的SCN。這個新的偽列在某些環境下會非常有用,比如執行樂觀鎖定,或者增量數據抽取的時候。但是,默認情況下,每行記錄的ORA_ROWSCN是基于Block的,除非在建表的時候執行開啟行級跟蹤(create table … rowdependencies)。
          ?
          先來簡單理解一下ORA_ROWSCN的實現原理。我們知道,每個Block在頭部是記錄了該block最近事務的SCN的,所以默認情況下,只需要從block頭部直接獲取這個值就可以了,不需要其他任何的開銷,Oracle就能做到這一點。但是這明顯是不精確的,一個block中會有很多行記錄,每次事務不可能影響到整個block中所有的行,所以這是一個非常不精準的估算值,同一個block的所有記錄的ORA_ROWSCN都會是相同的,基本上沒有多大的使用價值。
          ?
          如果在建表的時候開啟行級跟蹤選項,Oracle則可以為每一行記錄精確的SCN,那么顯然不能再直接從block頭部獲取。要獲得足夠的信息,肯定要付出一定的代價,Oracle必須為每一行實際的存儲這個SCN。所以這個行級跟蹤的選項,只能在建表的時候指定,而不能通過alter table來修改現有的表,否則需要修改每一行記錄的物理存儲格式,代價是可想而知的。
          ?
          簡單的做個實驗就可以知道開啟行級跟蹤以后塊記錄格式的不同。建兩個表,一個norowdependencies(默認),一個rowdependencies,然后分別dump出相應的數據塊:

          create table t1(i int);
          insert into t1 values(1);
          insert into t1 values(2);
          commit;
          create table t2 rowdependencies as select * from t1;
          norowdependencies:
          ?
          block_row_dump:
          tab 0, row 0, @0×1f9a
          tl: 6 fb: –H-FL– lb: 0×1 cc: 1
          col 0: [ 2] c1 02
          tab 0, row 1, @0×1f94
          tl: 6 fb: –H-FL– lb: 0×1 cc: 1
          col 0: [ 2] c1 03
          end_of_block_dump
          ?
          rowdependencies:
          ?
          block_row_dump:
          tab 0, row 0, @0×1f7c
          tl: 12 fb: –H-FL– lb: 0×0 cc: 1
          dscn 0×0000.00029ae4
          col 0: [ 2] c1 02
          tab 0, row 1, @0×1f6d
          tl: 12 fb: –H-FL– lb: 0×0 cc: 1
          dscn 0×0000.00029ae4
          col 0: [ 2] c1 03
          end_of_block_dump
          ?
          得到行的SCN后,通過SCN_TO_TIMESTAMP函數可以轉化為時間:
          ?
          SQL>? select SCN_TO_TIMESTAMP(ora_rowscn) from t2 where rownum<2;
          ?
          SCN_TO_TIMESTAMP(ORA_ROWSCN)
          ---------------------------------------------------------------------------
          06-JAN-09 05.31.20.000000000 PM

          ?
          樂觀鎖和ORA_ROWSCN
          ?
          需要select … for update做悲觀鎖定的時候,通過使用ORA_ROWSCN可以改成樂觀鎖定。一開始select數據的時候將ORA_ROWSCN查出來,修改后如果要寫回數據庫之前再比對下最新的ORA_ROWSCN就可以知道這期間數據是否有發生變化。這個Tom在他的大著《Expert Oracle Database Architecture 9i and 10g Programming Techniques and Solutions 》中也是有提到的。
          ?
          增量數據抽取和ORA_ROWSCN
          ?
          每次抽取后記錄最大的ORA_ROWSCN,下次抽取再基于上一次的SCN來獲得最近修改過的數據即可。在10g之前,很多系統要實現增量數據抽取,要么通過解析日志,要么加觸發器,要么就在表上加一個時間截字段。ORA_ROWSCN其實就是第三種方式,只是這個字段由Oracle來維護,這樣可以避免一些應用繞過時間截去更新其他字段帶來的問題。不過,如果系統中使用了邏輯備庫或者streams等邏輯復制的方案,而數據抽取又是基于邏輯備庫的話,ORA_ROWSCN就可能對抽取后的數據分析有影響了,因為通過這個得到的時間是邏輯備庫上記錄變更的時間,而不是源庫的時間了。當然,如果純粹只是做數據抽取,而不需要使用這個時間來做分析,還是問題不大的,但還是要考慮一旦邏輯備庫出現故障需要重做的,則這個增量抽取要怎么來處理的問題。
          ?
          Metalink上搜一下ORA_ROWSCN可以看到不少相關的bug,所以在生產系統中使用的時候要小心。例如,我在Linux64平臺上的一臺測試庫中,執行以下語句就會碰到ORA-07445的錯誤:
          ?
          SQL> select ora_rowscn from x$bh where rownum<2;
          select ora_rowscn from x$bh where rownum<2
          *
          ERROR at line 1:
          ORA-03113: end-of-file on communication channel
          ?
          ORA-07445: exception encountered: core dump [qkafix()+212]
          [SIGSEGV] [Address not mapped to object] [0x000000004] [] []
          --EOF--
          ?
          ?
          ?
          ?
          ?
          ?
          ?
          posted on 2009-05-24 21:11 decode360 閱讀(204) 評論(0)  編輯  收藏 所屬分類: 07.Oracle
          主站蜘蛛池模板: 闸北区| 前郭尔| 彰化县| 九龙城区| 新昌县| 江源县| 保德县| 长白| 玉山县| 临漳县| 明水县| 涟源市| 南投市| SHOW| 确山县| 定陶县| 大埔县| 德昌县| 平凉市| 灵丘县| 左权县| 武邑县| 尼玛县| 衡南县| 钦州市| 平度市| 论坛| 丹棱县| 济源市| 古交市| 忻城县| 鄂尔多斯市| 成武县| 达日县| 怀化市| 铜川市| 象山县| 夏津县| 都匀市| 尼木县| 河间市|