Decode360's Blog

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

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評(píng)論 :: 0 Trackbacks
          回滾段的學(xué)習(xí)
          ?
          ?
          ??? 說(shuō)實(shí)話至今沒(méi)有用到過(guò)手動(dòng)設(shè)置的回滾段,所以看這部分的內(nèi)容有點(diǎn)像是屠龍之術(shù),僅屬于備用知識(shí)。貌似目前都是直接使用auto用undo表空間而很少有回滾段的操作,但是學(xué)習(xí)一下還是無(wú)妨。
          ?
          一、回滾段的作用:
          ?

          ??? 回滾段用于存放數(shù)據(jù)修改之前的值(也包括數(shù)據(jù)修改前的位置)?;貪L段的頭部包含正在使用的該回滾段事務(wù)的信息。一個(gè)事務(wù)只能使用一個(gè)回滾段來(lái)存放它的回滾信息,而一個(gè)回滾段可以存放多個(gè)事務(wù)的回滾信息。
          ?
            回滾段用于對(duì)數(shù)據(jù)庫(kù)修改時(shí), 保存原有的數(shù)據(jù), 以便稍后可以通過(guò)使用ROLLBACK來(lái)恢復(fù)到修改前的數(shù)據(jù);另外, 回滾段可以為數(shù)據(jù)庫(kù)中的所有進(jìn)程提供讀一致性. 因此, 回滾段設(shè)置的合理與否, 直接影響到數(shù)據(jù)庫(kù)的性能, 在更新密集的OLTP應(yīng)用中,更是如此.
          ?
          ??? 其具體作用有以下幾項(xiàng):
          ?
          ??? 1、事務(wù)回滾:
          ??? 當(dāng)事務(wù)修改表中數(shù)據(jù)的時(shí)候,該數(shù)據(jù)修改前的值(即前影像)會(huì)存放在回滾段中,當(dāng)用戶回滾事務(wù)(ROLLBACK)時(shí),ORACLE將會(huì)利用回滾段中的數(shù)據(jù)前影像來(lái)將修改的數(shù)據(jù)恢復(fù)到原來(lái)的值。
          ?
          ??? 2、事務(wù)恢復(fù):
          ??? 當(dāng)事務(wù)正在處理的時(shí)候,例程失敗,回滾段的信息保存在重做日志文件中,ORACLE將在下次打開數(shù)據(jù)庫(kù)時(shí)利用回滾來(lái)恢復(fù)未提交的數(shù)據(jù)。
          ?
          ??? 3、讀一致性:
          ??? 當(dāng)一個(gè)會(huì)話正在修改數(shù)據(jù)時(shí),其他的會(huì)話將看不到該會(huì)話未提交的修改。而且,當(dāng)一個(gè)語(yǔ)句正在執(zhí)行時(shí),該語(yǔ)句將看不到從該語(yǔ)句開始執(zhí)行后的未提交的修改(語(yǔ)句級(jí)讀一致性)。當(dāng)ORACLE執(zhí)行SELECT語(yǔ)句時(shí),ORACLE依照當(dāng)前的系統(tǒng)改變號(hào)(SYSTEM CHANGE NUMBER-SCN)來(lái)保證任何前于當(dāng)前SCN的未提交的改變不被該語(yǔ)句處理??梢韵胂螅寒?dāng)一個(gè)長(zhǎng)時(shí)間的查詢正在執(zhí)行時(shí),若其他會(huì)話改變了該查詢要查詢的某個(gè)數(shù)據(jù)塊,ORACLE將利用回滾段的數(shù)據(jù)前影像來(lái)構(gòu)造一個(gè)讀一致性視圖。

          ??? 事務(wù)級(jí)的讀一致性:
          ??? ORACLE一般提供SQL語(yǔ)句級(jí)(SQL STATEMENT LEVEL)的讀一致性,可以用以下語(yǔ)句來(lái)實(shí)現(xiàn)事務(wù)級(jí)的讀一致性:
          ??? SET TRANSACTION READ ONLY;
          ??? 或: SET TANNSACTION SERIALIZABLE;
          ??? 以上兩個(gè)語(yǔ)句都將在事務(wù)開始后提供讀一致性。需要注意的是,使用第二個(gè)語(yǔ)句對(duì)數(shù)據(jù)庫(kù)的并發(fā)性和性能將帶來(lái)影響。
          ?
          ?
          二、回滾段的類型:
          ?
          ??? 1、系統(tǒng)回滾段:
          ??? 當(dāng)數(shù)據(jù)庫(kù)創(chuàng)建后,將自動(dòng)創(chuàng)建一個(gè)系統(tǒng)回滾段,它位于SYSTEM表空間,用于處理涉及系統(tǒng)的CataLog的事物(比如大多數(shù)的DDL)。
          ??? 注意:不要把System回滾段放在其他的表空間中,并且應(yīng)該永遠(yuǎn)保持ONLINE狀態(tài)。
          ?
          ??? 2、非系統(tǒng)回滾段:
          ??? 擁有多個(gè)表空間的數(shù)據(jù)庫(kù)至少應(yīng)該有一個(gè)非系統(tǒng)回滾段,用于存放非系統(tǒng)表空間中對(duì)象的數(shù)據(jù)前影像。
          ??? 非系統(tǒng)回滾段又分為私有回滾段和公有回滾段,私有回滾段應(yīng)在參數(shù)文件的ROLLBACK_SEGMENTS參數(shù)中列出,以便例程啟動(dòng)時(shí)自動(dòng)使其ONLINE(也可通過(guò)使用Alter Rollback Segment XXX Online來(lái)使用某一個(gè)回滾段)。公有回滾段一般在OPS(ORACLE并行服務(wù)器)中出現(xiàn),將在例程啟動(dòng)時(shí)自動(dòng)ONLINE。
          ??? 建議將每個(gè)實(shí)例的Private回滾段放置到訪問(wèn)比較快的本地設(shè)備上。
          ?
          ??? 3、DEFERED回滾段:
          ??? 該回滾段在表空間離線(OFFLINE)時(shí)由系統(tǒng)自動(dòng)創(chuàng)建,當(dāng)表空間再次在線(ONLINE)時(shí)由系統(tǒng)自動(dòng)刪除,用于存放表空間離線時(shí)產(chǎn)生的回滾信息。
          ?
          ?
          三、回滾段的使用:
          ?
          ?
          (1) 創(chuàng)建回滾段
          ?

          create rollback segment rb01

          tablespace rbs1

          storage (

          ???????? initial 100 K

          ???????? next 100 K

          ???????? minextents 20

          ???????? maxextents 100

          ???????? optimal 2000 K );


          注意:
          回滾段可以在創(chuàng)建時(shí)指明PRIVATE或PUBLIC,一旦創(chuàng)建將不能修改。
          MINEXTENTS 必須大于等于2
          PCTINCREASE必須是0
          OPTIMAL如果要指定,必須大于等于回滾段的初始大小(由MINEXTENTS指定)
          ?
          建議:
          一般情況下,INITIAL=NEXT
          設(shè)置OPTIMAL參數(shù)來(lái)節(jié)約空間的使用
          不要設(shè)置MAXEXTENTS為UNLIMITED
          回滾段應(yīng)創(chuàng)建在一個(gè)特定的回滾段表空間內(nèi)

          (2) 更改ONLINE/OFFLINE狀態(tài)
          ?

          alter rollback segment rb01 online ;

          alter rollback segment rb01 offline ;


          當(dāng)回滾段創(chuàng)建后,回滾段是離線的,不能被數(shù)據(jù)庫(kù)使用,為了使回滾段被事務(wù)利用,必須將回滾段在線。
          如果有事務(wù)正在使用該回滾段,運(yùn)行offline命令后,回滾段的狀態(tài)將是PENDING OFFLINE。事務(wù)結(jié)束后,狀態(tài)將改為OFFLINE,可以通過(guò)V$ROLLSTAT查詢回滾段的狀態(tài)。

          (3) 更改OPTIMAL參數(shù)
          ?

          alter rollback segment rb01

          storage ( maxextents 200

          ???????? optimal 2048 K );


          (4) 縮小回滾段
          ?

          alter rollback segment rb01 shrink to 2048 K;

          -- OPTIMAL 參數(shù)時(shí) , 縮小到 OPTIMAL

          alter rollback segment rb01 shrink ;

          -- 沒(méi)有 OPTIMAL 參數(shù)時(shí) , 縮小到 MINEXTENTS 所對(duì)應(yīng)的值
            
          (5) 修改INITIAL/NEXT參數(shù)

          ?

          -- 修改 NEXT 時(shí) , 總應(yīng)該同時(shí)修改 INITIAL.

          --INITIAL 參數(shù)無(wú)法直接修改 , 只能先 DROP, 然后再 CREATE.

          drop rollback segment rb01;

          create rollback segment rb01

          tablespace rbs1

          storage ( initial 100 K

          ???????? next 100 K

          ???????? minextents 20

          ???????? maxextents 121

          ???????? optimal 2000 K );


          (6) 在事務(wù)中使用特定的回滾段
          ?

          set transaction use rollback segment rb01;

          ?
          注意:
          1、某個(gè)事務(wù)只能放在一個(gè)回滾段中,事務(wù)不可能分回滾段存放;一個(gè)回滾段可以存儲(chǔ)多個(gè)事務(wù)。
          2、幾個(gè)事務(wù)可以寫在回滾段的同一個(gè)區(qū),一個(gè)事務(wù)也可以寫在回滾段的不同區(qū)。
          3、回滾段的block只能包含一個(gè)事務(wù)的信息。
          4、當(dāng)回滾段區(qū)的所有塊用完而事務(wù)還需要更多的回滾空間時(shí),回滾段的指針將移到下一個(gè)區(qū)。當(dāng)最后一個(gè)區(qū)用完,指針將移到第一個(gè)區(qū)的前面?;貪L段指針移到下一個(gè)區(qū)的前提是下一個(gè)區(qū)沒(méi)有活動(dòng)的事務(wù),同時(shí)指針不能跨區(qū)。當(dāng)下一個(gè)區(qū)正在使用時(shí),事務(wù)將為回滾段分配一個(gè)新的區(qū),這種分配稱為回滾段的擴(kuò)展(extend)?;貪L段將一直擴(kuò)展到該回滾段區(qū)的個(gè)數(shù)到達(dá)回滾段的參數(shù)MAXEXTENTS的值時(shí)為止。
          ?
          ??? 例如:兩個(gè)事務(wù)使用同一個(gè)回滾段,該回滾段有四個(gè)區(qū):
          ??? 1.事務(wù)在進(jìn)行中,它們正在使用回滾段的第三個(gè)區(qū);
          ??? 2.當(dāng)兩個(gè)事務(wù)產(chǎn)生更多的回滾信息,它們將繼續(xù)使用第三個(gè)區(qū);
          ??? 3.當(dāng)?shù)谌齻€(gè)區(qū)滿后,事務(wù)將寫到第四個(gè)區(qū),當(dāng)事務(wù)開始寫到一個(gè)新的區(qū)時(shí),稱為翻轉(zhuǎn)(WRAP);
          ??? 4.當(dāng)?shù)谒膫€(gè)區(qū)用滿時(shí),如果第一個(gè)區(qū)是空閑或非活動(dòng)(使用該區(qū)的所有事務(wù)完成而沒(méi)有活動(dòng)的事務(wù))的,事務(wù)將接著使用第一個(gè)區(qū)。

          (7) 常用的有關(guān)回滾段的系統(tǒng)數(shù)據(jù)字典
          ?

          DBA_ROLLBACK_SEGS? --DBA_SEGMENTS 中的 ROLLBACK 類型

          V$ROLLNAME

          V$ROLLSTAT

          V$TRANSACTION????? --V$SESSION


          回滾段的基本信息, 例:
          SQL>SELECT segment_name,tablespace_name,owner,status FROM dba_rollback_segs;
          ?
          回滾段的統(tǒng)計(jì)信息, 例:
          SQL>SELECT n.name,s.extents,s.rssize,s.optsize,s.hwmsize,s.xacts,s.status
          ? 2 FROM v$rollname n,v$rollstat s
          ? 3 WHERE n.usn=s.usn;
          ?
          回滾段的當(dāng)前活動(dòng)事務(wù),例:
          SQL>SELECT s.username,t.xidusn,t.ubafil,t.ubablk,t.used_ublk
          ? 2 FROM v$session s,v$transaction t
          ? 3 WHERE s.saddr=t.ses_addr;

            USERNAME  XIDUSN   UBAFIL   UBABLK  USED_UBLK
          ??? -------  -------- ----------- ----------- -----------
            SYSTEM     2     2    7      1
            SCOTT      1     2    163     1
            2 rows selected.
          ?
          ?
          三、回滾段的參數(shù)設(shè)置:

          ??? 精確的回滾段的數(shù)量及大小的計(jì)算涉及很多方面:
          ?
          ??? 1、應(yīng)用的類型(OLTP/OLAP/BATCH)
          ??? 2、同時(shí)進(jìn)行的事物的數(shù)量
          ??? 3、DML語(yǔ)句的類型
          ??? 4、每個(gè)事物處理的數(shù)據(jù)量
          ??? 5、……
          ?
          ??? 回滾段使用的建議:
          ?
          ??? 1、OLTP系統(tǒng)應(yīng)使用小但較多的回滾段,每四個(gè)事務(wù)一個(gè)回滾段;每個(gè)回滾段不要超過(guò)十個(gè)事務(wù)。
          ??? 2、OLAP系統(tǒng)/批處理系統(tǒng)應(yīng)使用少量的大回滾段;每個(gè)事務(wù)一個(gè)回滾段。
          ??? 3、OLTP/OLAP混合型系統(tǒng)中, 應(yīng)專門設(shè)置一個(gè)或幾個(gè)大的回滾段, 平時(shí)設(shè)置為OFFLINE, 使用時(shí)通過(guò)使用SET TRANSACTION USE ROLLBACK SEGMENT XXX來(lái)使用它。
          ?????? 這些回滾段應(yīng)使用OPTIMAL參數(shù),以便在不使用時(shí),可以SHRINK到一個(gè)較小的尺寸;
          ??? 3、在很難計(jì)算準(zhǔn)確的數(shù)量、大小時(shí),可用“偏大不偏小”的原則;
          ??? 4、所有的回滾段的INITIAL/NEXT參數(shù)應(yīng)設(shè)為相同, 只有建議3中提到的大回滾段例外;
          ??? 5、不要將回滾段的MAXEXTENTS設(shè)為UNLIMITED, 回滾段所在表空間也不要設(shè)為AUTOEXTEND方式, 否則將會(huì)使得由于某個(gè)不正常的事務(wù)導(dǎo)致整個(gè)數(shù)據(jù)庫(kù)處于失控狀態(tài)。
          ?
          ?
          四、回滾段的常見錯(cuò)誤及解決方法:
          ?
          (1) 回滾段空間不夠
          ???
          ??? ORA-01562 - failed to extend rollback segment number string
            
          ??? 回滾段空間不夠的原因一般有以下幾種情況:
          ??? A. 回滾段所在表空間剩余的空閑空間太小, 無(wú)法分配下一個(gè)EXTENT.
          ??? B. 回滾段擴(kuò)展次數(shù)已經(jīng)達(dá)到MAXEXTENTS限制
          ?
          ??? 解決方法:
          ??? A. 擴(kuò)大回滾段所在表空間
          ??? B. 設(shè)置較大的MAXEXTENTS參數(shù)
          ??? C. 為回滾段設(shè)置OPTIMAL參數(shù)
          ??? D. 用較大的EXTENT參數(shù)重新創(chuàng)建回滾段
          ??? E. 將導(dǎo)致ORA-1562錯(cuò)誤的DML語(yǔ)句改為分段執(zhí)行:

          (2) ORA-01552 cannot use system rollback segment for non-system tablespace 'string'

          ??? 原因: 沒(méi)有可用的非系統(tǒng)回滾段. 分為以下情形:
          ??? A. 除了系統(tǒng)回滾段, 未創(chuàng)建其它回滾段
          ??? B. 只創(chuàng)建了PRIVATE回滾段, 但I(xiàn)NITsid.ORA的ROLLBACK_SEGMENTS中未列出這些回滾段
          ??? C. 創(chuàng)建了PUBLIC回滾段, 但這些回滾段都處于OFFLINE狀態(tài)
          ?
          ??? 解決方法: 根據(jù)以上原因相應(yīng)解決即可
            
          (3) ORA_01555 snapshot too old: rollback segment number string with name "string" too small
          ?
          ??? 原因可分為以下情形:
          ?
          ??? A. 回滾段太少/太小
          ??????? 數(shù)據(jù)庫(kù)中有太多的事務(wù)修改數(shù)據(jù)并提交, 就會(huì)發(fā)生已提交事務(wù)曾使用的空間被重用, 從而造成一個(gè)延續(xù)時(shí)間長(zhǎng)的查詢所請(qǐng)求的數(shù)據(jù)已經(jīng)不在回滾段中.
          ??? 解決方法: 創(chuàng)建更多的回滾段, 為回滾段設(shè)置較大的EXTENT以及較大的MINEXTENTS
          ?
          ??? B. 回滾段被破壞
          ??????? 由于回滾段被破壞, 造成事務(wù)無(wú)法將修改前的內(nèi)容(read-consistent snapshot) 放入回滾段, 也會(huì)產(chǎn)生ORA-01555錯(cuò)誤.
          ??? 解決方法: 將被破壞的回滾段OFFLINE, 刪除重建.
          ?
          ??? C. FETCH ACROSS COMMIT
          ??????? 當(dāng)一個(gè)進(jìn)程打開一個(gè)CURSOR, 然后循環(huán)執(zhí)行FETCH, UPDATE, COMMIT, 如果更新的表與FETCH的是同一個(gè)表, 就很可能發(fā)生ORA-01555錯(cuò)誤.
          ??? 解決方法:
          ??? a. 使用大的回滾段
          ??? b. 減少提交頻率
            ????? 以上兩種方法只能減少該錯(cuò)誤發(fā)生的可能, 不能完全避免. 如果要完全避免, 須從執(zhí)行方法著手, 可以用以下兩種方法:
          ??? c. 建立一個(gè)臨時(shí)表, 存放要更新的表的查詢列(如主鍵及相關(guān)的條件列), 從臨時(shí)表FETCH, 更新原來(lái)的表.
          ??? d. 捕獲ORA-01555錯(cuò)誤, 關(guān)閉并重新打開CURSOR, 繼續(xù)執(zhí)行循環(huán):
          ?
          示例(示例程序的思路來(lái)源自O(shè)RACLE的UTLIP.SQL, 有興趣的朋友可直接閱讀該程序, 位置在RDBMS\ADMIN下, 程序很短, 容易讀):
          DECLARE
          ? LAST_PK NUMBER := 0;
          ? V_THEROWID ROWID;
          ? CURSOR C1 IS
          ??? SELECT ROWID, PK, ... FROM SMPLE
          ??? WHERE PK > LAST_PK
          ??? AND othercondition
          ??? ORDER BY PK;
          BEGIN
          ? OPEN c_SOURCE;
          ? LOOP
          ??? BEGIN
          ????? FETCH C1 INTO v_THEROWID, v_PK;
          ????? EXIT WHEN C1%NOTFOUND;
          ????? EXCEPTION WHEN OTHERS THEN
          ????? IF SQLCODE = -1555 THEN -- snapshot too old, re-execute fetch query
          ??????? CLOSE C1;
          ??????? OPEN c_SOURCE;
          ??????? GOTO NEXTLOOP01555;
          ????? ELSE
          ??????? RAISE;
          ????? END IF;
          ??? END;
          ? LAST_PK := PK;
          ? PROCESS,UPDATE AND COMMIT<>NULL;
          ? END LOOP;
          ? CLOSE C1;
          END;
          ?
          ??? D. 其它原因:
          ??? * Delayed logging block cleanout是ORACLE用來(lái)提高寫性能的一種機(jī)制: 當(dāng)修改操作(INSERT/UPDATE/DELETE)發(fā)生時(shí), ORACLE將原有的內(nèi)容寫入回滾段, 更新每個(gè)數(shù)據(jù)塊的頭部使其指向相應(yīng)的回滾段, 當(dāng)該操作被COMMIT時(shí), ORACLE并不再重新訪問(wèn)一遍所有的數(shù)據(jù)塊來(lái)確認(rèn)所有的修改, 而只是更新位于回滾段頭部的事務(wù)槽來(lái)指明該事務(wù)已被COMMIT, 這使得寫操作可以很快結(jié)束從而提高了性能接下來(lái)的任何訪問(wèn)該操作所修改的數(shù)據(jù)的操作會(huì)使先前的寫操作真正生效, 從而訪問(wèn)到新的值. Delayed logging block cleanout 雖然提高了性能, 但卻可能導(dǎo)致ORA-01555. 這種情況下, 在OPEN/FETCH前對(duì)該表做全表掃描(保證所有的修改被確認(rèn))會(huì)有所幫助.
          ??? * 不適當(dāng)?shù)腛PTIMAL參數(shù): 太小的OPTIMAL參數(shù)會(huì)使回滾段很快被SHRINK, 造成后續(xù)讀取操作訪問(wèn)時(shí), 先前的內(nèi)容已丟失. 仔細(xì)設(shè)計(jì)OPTIMAL參數(shù), 不要讓回滾段過(guò)于頻繁的EXTEND/SHRINK有助于問(wèn)題的解決.
          ??? * DB BLOCK BUFFER太小: 如果讀一致性所請(qǐng)求的塊的先前內(nèi)容在緩沖區(qū)中, 那么就不用去訪問(wèn)回滾段. 而如果緩沖區(qū)太小, 使得先前版本的內(nèi)容在CACHE中的可能性變小, 從而必須頻繁的訪問(wèn)回滾段來(lái)獲取先前的內(nèi)容, 這將大大增大ORA-01555發(fā)生的可能.
          ?
          ?
          posted on 2008-08-31 19:09 decode360 閱讀(141) 評(píng)論(0)  編輯  收藏 所屬分類: 07.Oracle
          主站蜘蛛池模板: 玉溪市| 平湖市| 揭东县| 沾化县| 色达县| 依兰县| 扎囊县| 长垣县| 贡嘎县| 迁安市| 永城市| 犍为县| 海原县| 治多县| 贵定县| 留坝县| 阜康市| 金沙县| 登封市| 吉安县| 英德市| 石首市| 宁城县| 镶黄旗| 临城县| 白河县| 宁都县| 高阳县| 陆丰市| 鸡东县| 台南市| 新化县| 乌拉特后旗| 信宜市| 新巴尔虎右旗| 兴安盟| 焦作市| 金秀| 东乌珠穆沁旗| 那曲县| 曲水县|