?
??? 回滾段用于存放數(shù)據(jù)修改之前的值(也包括數(shù)據(jù)修改前的位置)?;貪L段的頭部包含正在使用的該回滾段事務(wù)的信息。一個(gè)事務(wù)只能使用一個(gè)回滾段來(lái)存放它的回滾信息,而一個(gè)回滾段可以存放多個(gè)事務(wù)的回滾信息。
??? 事務(wù)級(jí)的讀一致性:
??? SET TRANSACTION READ ONLY;
create
rollback
segment
rb01
tablespace
rbs1
storage
(
????????
initial
100
K
????????
next
100
K
????????
minextents
20
????????
maxextents
100
????????
optimal
2000
K );
注意:
(2) 更改ONLINE/OFFLINE狀態(tài)
alter
rollback
segment
rb01
online
;
alter rollback segment rb01 offline ;
當(dāng)回滾段創(chuàng)建后,回滾段是離線的,不能被數(shù)據(jù)庫(kù)使用,為了使回滾段被事務(wù)利用,必須將回滾段在線。
(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;
(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;
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;
? 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ù)量及大小的計(jì)算涉及很多方面:
??? 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)使用它。
??? 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)。
???
??? 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)
??????? 數(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):
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;