日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

在Oracle中如何让SELECT查询绕过UNDO

發布時間:2025/4/5 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Oracle中如何让SELECT查询绕过UNDO 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
是否有想過如何在Oracle中實現臟讀(dirty read),在Oracle官方文檔或者Asktom的時候顯然會提到Oracle是不實現臟讀的, 總是有undo來提供數據塊的前鏡像(before image)以維護一致性Consistent, 通過正常途徑我們幾乎不可能破壞Oracle中查詢的一致性來實現臟讀。 ? 是否真的無計可施? 非也,非也,Oracle作為一個高度復雜而又可控的RDBMS,仍是有很多空子可以鉆的。 ? 我們先來介紹以下的2個隱藏參數: _offline_rollback_segments or _corrupted_rollback_segments 這2個隱藏參數對于熟悉Oracle數據庫異?;謴突蛘呓鉀QORA-600[4XXX]問題有經驗的同學來說肯定不陌生,因為這2個參數是針對Undo存在Corruption訛誤時忽略問題的有力工具,而大家對這2個參數實際起到的作用有多少認識呢? ? 我們可能在以下幾種場景中用到_offline_rollback_segments 和 _corrupted_rollback_segments 這2個隱藏參數:
  • 強制打開數據庫(FORCE OPEN DATABASE)
  • 控制一致性讀和延遲塊清除(consistent read & delayed block cleanout)
  • 強制刪除某個rollback segment回滾段
? 但是請注意:千萬不要在沒有Oracle專家建議的情況下,在產品環境設置以上這2個隱藏參數,可能造成數據邏輯訛誤等影響!! ? _offline_rollback_segments 和 _corrupted_rollback_segments 均會造成的實例行為變化:
  • 以上2個參數所列出的Undo Segments(撤銷段/回滾段)將不會被在線使用online
  • 在UNDO$數據字典基表中將體現為OFFLINE的記錄
  • 在實例instance的生命周期中將不會再給新的事務分配使用
  • 參數所列出的Undo Segments列表上的活躍事務active transaction將即不被回滾亦不被標記為dead以便SMON去回滾(了解你所不知道的SMON功能(五):Recover Dead transaction)
? _OFFLINE_ROLLBACK_SEGMENTS(offline undo segment list)隱藏參數(hidden parameter)的獨有作用:
  • 在實例startup啟動并open database的階段仍將讀取_OFFLINE_ROLLBACK_SEGMENTS所列出的Undo segments(撤銷段/回滾段),若訪問這些undo segments出現了問題則將在alert.log和其他TRACE中體現出來,但不影響實際的startup進程
    • 若查詢數據塊發現活躍的事務,并ITL指向對應的undo segments則:
    • 若讀取undo segments的transaction table事務表發現事務已提交則做數據塊的清除
    • 若讀取發現事務仍活動未commit,則生成一個CR塊拷貝
    • 若讀取該undo segments存在問題(可能是corrupted訛誤,可能是missed丟失)則產生一個錯誤并寫出到alert.log,查詢將異常終止
  • 若DML更新相關的數據塊會導致服務進程為了恢復活躍事務而進入死循環消耗大量CPU,解決方法是通過可以進行的查詢工作重建相關表
? _CORRUPTED_ROLLBACK_SEGMENTS(corrupted undo segment list)隱藏參數所獨有的功能:
  • 在實例啟動startup并open database的階段_CORRUPTED_ROLLBACK_SEGMENTS所列出的undo segments(撤銷段/回滾段)將不會被訪問讀取
  • 所有指向這些被_CORRUPTED_ROLLBACK_SEGMENTS列出的undo segments的事務都被認為已經提交了commit,和這個undo segments已經被drop時類似
    • 這將導致嚴重的邏輯訛誤
    • 如果數據字典上有活躍事務那么將更糟糕,數據字典邏輯訛誤會造成數據庫管理問題
    • 如果bootstrap自舉核心對象有活躍事務,那么將無法忽略錯誤ORA-00704: bootstrap process failure錯誤,導致無法強制打開數據庫(見拙作Oracle數據恢復:解決ORA-00600:[4000] ORA-00704: bootstrap process failure錯誤一例)
  • 衷心地建議用_CORRUPTED_ROLLBACK_SEGMENTS這個參數打開數據庫后導出數據并重建數據庫,這個參數使用的后遺癥可能很頑固
  • Oracle公司內部有叫做TXChecker的工具可以檢查問題事務
? 好了了解了以上2個參數之后,你將不難明白下面演示如何通過_CORRUPTED_ROLLBACK_SEGMENTS隱藏參數讓SELECT查詢繞過UNDO實現臟讀的過程: ? SQL> alter system set event= '10513 trace name context forever, level 2' scope=spfile;System altered.SQL> alter system set "_in_memory_undo"=false scope=spfile;System altered.10513 level 2 event可以禁止SMON 回滾rollback 死事務 dead transaction _in_memory_undo 禁用 in memory undo 特性SQL> startup force; ORACLE instance started.Total System Global Area 3140026368 bytes Fixed Size 2232472 bytes Variable Size 1795166056 bytes Database Buffers 1325400064 bytes Redo Buffers 17227776 bytes Database mounted. Database opened.session A:SQL> conn maclean/maclean Connected.SQL> create table maclean tablespace users as select 1 t1 from dual connect by level exec dbms_stats.gather_table_stats('','MACLEAN');PL/SQL procedure successfully completed.SQL> set autotrace on; SQL> select sum(t1) from maclean;SUM(T1) ----------501Execution Plan ---------------------------------------------------------- Plan hash value: 1679547536------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 3 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 3 | | | | 2 | TABLE ACCESS FULL| MACLEAN | 501 | 1503 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------Statistics ----------------------------------------------------------1 recursive calls0 db block gets3 consistent gets0 physical reads0 redo size515 bytes sent via SQL*Net to client492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processe在沒有活躍事務的情況下,直接讀取current block, 全表掃描一致性讀,consistent gets只要3次 SQL> update maclean set t1=0;501 rows updated.SQL> alter system checkpoint;System altered.這里session A不commit;另開一個 session:SQL> conn maclean/maclean Connected. SQL> SQL> set autotrace on; SQL> select sum(t1) from maclean;SUM(T1) ----------501Execution Plan ---------------------------------------------------------- Plan hash value: 1679547536------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 3 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 3 | | | | 2 | TABLE ACCESS FULL| MACLEAN | 501 | 1503 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------Statistics ----------------------------------------------------------0 recursive calls0 db block gets505 consistent gets0 physical reads108 redo size515 bytes sent via SQL*Net to client492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed為了一致性讀 上面的查詢需要通過undo構造CR塊,這導致consistent gets上升到 505[oracle@vrh8 ~]$ ps -ef|grep LOCAL=YES |grep -v grep oracle 5841 5839 0 09:17 ? 00:00:00 oracleG10R25 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))[oracle@vrh8 ~]$ kill -9 5841殺掉session A對應的Server Process服務進程,這導致dead transaction 但是不被smon回滾select ktuxeusn,to_char(sysdate, 'DD-MON-YYYY HH24:MI:SS') "Time",ktuxesiz,ktuxestafrom x$ktuxewhere ktuxecfl = 'DEAD';KTUXEUSN Time KTUXESIZ KTUXESTA ---------- -------------------- ---------- ----------------2 06-AUG-2012 09:20:45 7 ACTIVE此時有1個active rollback segment SQL> conn maclean/maclean Connected.SQL> set autotrace on;SQL> select sum(t1) from maclean;SUM(T1) ----------501Execution Plan ---------------------------------------------------------- Plan hash value: 1679547536------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 3 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 3 | | | | 2 | TABLE ACCESS FULL| MACLEAN | 501 | 1503 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------Statistics ----------------------------------------------------------0 recursive calls0 db block gets411 consistent gets0 physical reads108 redo size515 bytes sent via SQL*Net to client492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed到上面為止 雖然通過kill進程 和禁止smon 回滾dead transaction , 形成了一個不回滾的死事務 但是仍通過undo實現了一致性讀找出當前active的rollback segment的名字SQL> select segment_name from dba_rollback_segs where segment_id=2;SEGMENT_NAME ------------------------------ _SYSSMU2$SQL> alter system set "_corrupted_rollback_segments"='_SYSSMU2$' scope=spfile;System altered.用 _corrupted_rollback_segments 廢掉 上面的2個rollback segment, 這將導致無法提供undo SQL> startup force; ORACLE instance started.Total System Global Area 3140026368 bytes Fixed Size 2232472 bytes Variable Size 1795166056 bytes Database Buffers 1325400064 bytes Redo Buffers 17227776 bytes Database mounted. Database opened.SQL> conn maclean/maclean Connected.SQL> set autotrace on;SQL> select sum(t1) from maclean;SUM(T1) ----------94Execution Plan ---------------------------------------------------------- Plan hash value: 1679547536------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 3 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 3 | | | | 2 | TABLE ACCESS FULL| MACLEAN | 501 | 1503 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------Statistics ----------------------------------------------------------228 recursive calls0 db block gets29 consistent gets5 physical reads116 redo size514 bytes sent via SQL*Net to client492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client4 sorts (memory)0 sorts (disk)1 rows processedSQL> /SUM(T1) ----------94Execution Plan ---------------------------------------------------------- Plan hash value: 1679547536------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | 3 | 3 (0)| 00:00:01 | | 1 | SORT AGGREGATE | | 1 | 3 | | | | 2 | TABLE ACCESS FULL| MACLEAN | 501 | 1503 | 3 (0)| 00:00:01 | ------------------------------------------------------------------------------Statistics ----------------------------------------------------------0 recursive calls0 db block gets3 consistent gets0 physical reads0 redo size514 bytes sent via SQL*Net to client492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed ? ? 以上可以看到 consistent gets下降到3,服務進程讀取數據塊發現存在活躍事務,但是ITL指向的UNDO SEGMENTS在_corrupted_rollback_segments的列表中,所以直接認為該事務已經COMMIT提交,以便繞過UNDO。 這里實現了臟讀,雖然通過上述方法去實現臟讀在產品環境中沒有實際收益(有部分數據庫軟件允許臟讀來做統計信息收集),破壞了一致性且需要設置需重啟實例的 隱藏參數 , 僅供參考。

總結

以上是生活随笔為你收集整理的在Oracle中如何让SELECT查询绕过UNDO的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。