oracle實驗記錄 (oracle 10G 詳細分析undo)
undo資料存undo tablespace,讀入buffer cache,管理規則也是按buffer cache管理(寫出)
oracle預設啟動時候分配10個rollback segment(非system rollback segment)
SQL> select name from v$rollstat a ,v$rollname b where a.usn=b.usn;
NAME
------------------------------
SYSTEM
_SYSSMU1$
_SYSSMU2$
_SYSSMU3$
_SYSSMU4$
_SYSSMU5$
_SYSSMU6$
_SYSSMU7$
_SYSSMU8$
_SYSSMU9$
_SYSSMU10$
已選擇11行。
undo_retention:控制事務commit以後資訊保留時間(是一個建議性引數)S為單位
如果設定為0那麼oracle將啟動動態調整,當undo space足夠時 ,會將undo資訊的保留時間與當前執行時間最長的那個查詢所需要的時間相同(並且以900s為最低值).
Autotune of undo retention is turned on.
SQL> show parameter undo_reten
NAME TYPE
------------------------------------ -------------------------------
VALUE
------------------------------
undo_retention integer
900
10G R2 DEFAULT 900s
兩個隱藏引數控制
_undo_autotune TRUE TRUE FALSE
FALSE
enable auto tuning of undo_retention(是否開啟自動調整undo_retention)
_collect_undo_stats TRUE TRUE FALSE
FALSE
Collect Statistics v$undostat (從v$undostat收集統計資訊用於調整 預設是每30秒收集一次)
undo_retention 是noguarantee 意思當undo空間不足時還是會換出去
具體undo block有4種狀態
1.active表示使用這個undo block的 transaction還未提交
2.inactive:undo block上沒有活動事務,可以被覆蓋(但是未過期expired)
3.expired:undo block狀態為inactive的時間 超過了undo_retention
4.free:空的
AUM時候
事務使用undo segment可在不同的undo segment之間動態交換undo 空間(交換extents),當一個transaction需要更多undo空間時,首先會重用當前使用的undo segment裡可用空間,如果沒有按下面步驟獲取undo
1.獲取undo tablespace 中可用free extent
2.獲取其它rollback segment 中expired的extent
3.如果datafile 有autoextend on,那麼自動擴充套件
4.若沒開autoextend on,那麼用狀態為inactive的undo block,如果 還是不足,則報錯,
順序為 : free-expired-autoextend on-inactive
關於undo datafile autoextend on ,如果undo space不夠 oracle會先儘可能使用undo space中free ,expried的 不會馬上 擴充套件空間,除非當要覆蓋的資料是在900s之內的,才會去擴充套件空間
10g 對tablespace多了guarantee選項,保證inactive的 undo block不會被覆蓋
alter tablespace UNDOTBS1 guarantee
dml操作產生undo比較
insert 操作將記錄 rowid
SQL> create table t1 ( a varchar2(10), b varchar2(10));
表已建立。
SQL> insert into t1 values('a','a');
已建立 1 行。
SQL> select object_id from dba_objects where object_name='T1';
OBJECT_ID
----------
54556
SQL> select file#,block# ,rowid from (select dbms_rowid.rowid_relative_fno(rowid
) file#,dbms_rowid.rowid_block_number(rowid) block# ,rowid from T1);
FILE# BLOCK# ROWID
---------- ---------- ------------------
4 2500 AAANUcAAEAAAAnEAAA
SQL> select xidusn ,ubafil,UBABLK from v$transaction;
XIDUSN UBAFIL UBABLK
---------- ---------- ----------
2 2 750
SQL> alter system dump datafile 2 block 750;
系統已更改。
* Rec #0x15 slt: 0x11 objn: 54556(0x0000d51c) objd: 54556 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x008002ee.04f3.14 ctl max scn: 0x0000.004f1084 prv tx scn: 0x0000.004f1092
txn start scn: scn: 0x0000.004fbcb1 logon user: 61
prev brb: 8389354 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
KDO Op code: DRP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x010009c4 hdba: 0x010009c3
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0)
End dump data blocks tsn: 1 file#: 2 minblk 750 maxblk 750
SQL> commit;
提交完成。
update將記錄修改欄位的前映象
SQL> update t1 set a='aa';
已更新 1 行。
SQL> select xidusn ,ubafil,UBABLK from v$transaction;
XIDUSN UBAFIL UBABLK
---------- ---------- ----------
10 2 158
SQL> alter system dump datafile 2 block 158;
系統已更改。
* Rec #0xb slt: 0x0e objn: 54556(0x0000d51c) objd: 54556 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x0080009e.0499.08 ctl max scn: 0x0000.004f6a4f prv tx scn: 0x0000.004f6a83
txn start scn: scn: 0x0000.004fbf43 logon user: 61
prev brb: 8388764 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
KDO Op code: URP row dependencies Disabled( URP 一個update 操作)
xtype: XA flags: 0x00000000 bdba: 0x010009c4 hdba: 0x010009c3
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 9
ncol: 2 nnew: 1 size: -1
col 0: [ 1] 61~~~~~~~~~修改欄位值前映象
SQL> select chr(to_number(61,'xxx')) from dual;
CH
--
a
delete操作記錄整行內容 (所以 delete產生undo最多,相對的redo最多)
SQL> select xidusn ,ubafil,UBABLK from v$transaction;
XIDUSN UBAFIL UBABLK
---------- ---------- ----------
10 2 158
SQL> alter system dump datafile 2 block 158;
系統已更改。
SQL>
* Rec #0xd slt: 0x0e objn: 54556(0x0000d51c) objd: 54556 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x0c
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
op: C uba: 0x0080009e.0499.0c
KDO Op code: IRP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x010009c4 hdba: 0x010009c3
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) size/delt: 8
fb: --H-FL-- lb: 0x2 cc: 2
null: --
col 0: [ 2] 61 61~~~修改行前映象
col 1: [ 1] 61~~修改行前映象
End dump data blocks tsn: 1 file#: 2 minblk 158 maxblk 158
總結:delete 產生UNDO 最多 ,相對應的redo也就最多
關於system tablespace中的 system 還原段
這個還原段是在create database 時建立的 ,存在system tablespace,只對system 中物件所做更改
SQL> select distinct segment_type from user_segments where tablespace_name='SYST
EM';
SEGMENT_TYPE
------------------
INDEX
TABLE
LOBINDEX
LOBSEGMENT
CLUSTER
NESTED TABLE
ROLLBACK
已選擇7行。
SQL> select segment_name,segment_type,tablespace_name from user_segments where s
egment_type like '%ROLLBACK%';
SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME
------------------------------ ------------------ ------------------------------
SYSTEM ROLLBACK SYSTEM
SQL> shutdown immediate;
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE 例程已經關閉。
SQL>
SQL> startup mount
ORA-32004: obsolete and/or deprecated parameter(s) specified
ORACLE 例程已經啟動。
Total System Global Area 289406976 bytes
Fixed Size 1248576 bytes
Variable Size 104858304 bytes
Database Buffers 176160768 bytes
Redo Buffers 7139328 bytes
資料庫裝載完畢。
SQL> alter database datafile 2 offline; 將undo檔案offline
資料庫已更改。
SQL> alter database open;~~~database可以正常open
資料庫已更改。
SQL> show user
USER 為 "SYS"
SQL> create table t1(a int);
表已建立。
SQL> insert into t1 values(1);
已建立 1 行。
SQL> commit;
提交完成。
SQL> delete from t1;
已刪除 1 行。
SQL> rollback
2 ;
回退已完成。
SQL> select * from t1;
A
----------
1
SQL> select tablespace_name from user_tables where table_name='T1';
TABLESPACE_NAME
------------------------------
SYSTEM
在system tablespace 建立物件 ,DML操作都是正常的,所用undo為system rollback segment
SQL> select usn,status from v$rollstat; 檢視當前所有回滾段狀態
USN STATUS
---------- ---------------
0 ONLINE
SQL> desc v$rollname;
名稱 是否為空? 型別
----------------------------------------- -------- ----------------------------
USN NUMBER
NAME NOT NULL VARCHAR2(30)
SQL> select name from v$rollname where usn=0;
NAME
------------------------------
SYSTEM
只有system rollback segment是online的
SQL> conn xh/a831115
已連線。
SQL> select count(*) from t1;
COUNT(*)
----------
10000
SQL> delete from t1;
delete from t1
*
第 1 行出現錯誤:
ORA-01552: 非系統表空間 'USERS' 不能使用系統回退段
可以看到 其它如果dml 其他tablespace的物件 那麼需要擁有非系統回滾段(undo tablespace),system rollback segment只針對system tablespace中物件
SQL> alter database datafile 2 online;
資料庫已更改。
SQL> delete from t1;
已刪除10000行。
SQL> rollback;
回退已完成。
SQL>
針對DML語句來說,只要資料塊發生了變化,oracle會將修改前的資料保留下來儲存在rollback segment中(rollback segment存在undo tablespace中),兩種方式管理undo tablespace 自動(AUM AUTOMATIC UNDO MANAGEMENT),手動(mum manual undo management)
SQL> show parameter undo
NAME TYPE
------------------------------------ --------------------------------
VALUE
------------------------------
undo_management string~~~管理模式
AUTO
undo_retention integer
900
undo_tablespace string~~~undo tablespace
UNDOTBS1
SQL>
oracle推薦使用自動管理
undo使用的具體過程:
一條DML 比如update t1 set b='c' where a='a'
1.在shared pool中解析生成執行計劃
2.由執行計劃得出a='a'記錄在file 4 ,block 5中
3.在buffer cache中 找到 可用的undo blk,如果buffer cache中不存在則從undo tablespace中找一個可用undo block調入buffer cache(physical read )比如file 2 block 22,並且在相應的undo segment header中 trn tab中分配一個事務槽(這將會產生redo )
4.將改變前值放入file 2 block 22中
5.由於undo塊改變了將產生redo(redo有保護undo的作用)
6.在buffer cache中找file 4 block 5如果沒找到從buffer cache中調入(physical read )
7.將改變後的值 放入 file 4,block 5
8.由於file 4 ,block 5 發生了變化所以會產生redo
9.返回資訊,操作權給使用者
10.commit時 LGWR 將上面生成的redo寫入online redo file ,在file 4,block 5 ,file 2 block 22塊頭記錄事務狀態標記,設定為已提交,事務表記錄狀態為state 9
(注意上面 file 4,block 5, file 2 block 22 就是 dirty block了 他們並不隨commit而寫入datafile,只有在dirty block數量達到一定的觸發條件時才寫入 屬於incremental checkpoint或者full checkpoint的 時候,即使使用者未commit,那麼對應的dirty block也會寫入datafile )
11.事務只要commit or rollback那麼該事務所使用的undo就可以被其它事務覆蓋
實驗:
SQL> show user
USER 為 "XH"
SQL> create table t1 (a varchar2(10));
表已建立。
SQL> insert into t1 values('a');
已建立 1 行。
SQL> commit;
提交完成。
SQL> select * from t1;
A
----------
a
SQL> select file#,block# from (select dbms_rowid.rowid_relative_fno(rowid) file#
,dbms_rowid.rowid_block_number(rowid) block# from xh.t1);
FILE# BLOCK#
---------- ----------
4 2599
SQL> alter system flush shared_pool;
系統已更改。
SQL> alter system flush buffer_cache;
系統已更改。
SQL> select file#,block#,dirty from v$bh where file#=2 or (file#=4 and block#=2
599);
FILE# BLOCK# D
---------- ---------- -
2 618 Y
2 2757 Y
2 105 N
2 121 N
2 82 N
2 137 N
2 137 Y
2 9 N
2 153 N
2 153 N
2 2292 N
FILE# BLOCK# D
---------- ---------- -
2 25 N
2 25 N
2 3062 Y
2 2096 N
2 41 N
2 41 Y
2 617 N
2 83 N
2 2756 N
2 2 N
2 2 N
FILE# BLOCK# D
---------- ---------- -
2 57 Y
2 3272 N
2 2628 N
2 73 N
2 73 N
2 89 N
2 89 N
已選擇29行。
現在buffer cache中沒有 file 4 block 2
SQL> update t1 set a='b'; 進行dml操作
已更新 1 行。
SQL> select file#,block#,dirty from v$bh where file#=2 or (file#=4 and block#=2
599);
FILE# BLOCK# D
---------- ---------- -
.......................
4 2599 Y~~~~對應的t1 的file ,block從disk讀入buffer cache(physiacl read)修改並且標記為dirty
'''''''''''''''''''''''
FILE# BLOCK# D
---------- ---------- -
2 3272 Y~~~~使用的 undo file block 標記為dirty
..........................
SQL> select xidusn, XIDSLOT, XIDSQN,UBAFIL,UBABLK,UBASQN,UBAREC from v$transacti
on;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
2 0 1493 2 3272 1277 51
XIDUSN NUMBER Undo segment number
XIDSLOT NUMBER Slot number
XIDSQN NUMBER Sequence number
UBAFIL NUMBER Undo block address (UBA) filenum
UBABLK NUMBER UBA block number
UBAREC NUMBER UBA record number
使用file 2 block 3272 剛才的 查詢這個塊在 buffer cache中 所以這次就是 邏輯讀
SQL> select * from v$rollname where usn=2;
USN NAME
---------- ------------------------------
2 _SYSSMU2$
SQL> select header_block,header_file from dba_segments where segment_name='_SYSS
MU2$';
HEADER_BLOCK HEADER_FILE
------------ -----------
25 2
SQL> select object_id from dba_objects where object_name='T1' and wner='XH';
OBJECT_ID
----------
54666
SQL> select usn,writes,rssize,xacts from v$rollstat where usn=2
2 ;
USN WRITES RSSIZE XACTS
---------- ---------- ---------- ----------
2 1344 5365760 1
XACTS NUMBER Number of active transactions
WRITES NUMBER Number of bytes written to the rollback segment
RSSIZE NUMBER Size (in bytes) of the rollback segment. This value differs by the number of bytes in one database block from the value of the BYTES column of the ALL/DBA/USER_SEGMENTS views.
可以看到 update 這個操作的事務使用的是編號為2的rollback segment ,這個rollback segment中有一個 活動事務(就是update這個操作的)
SQL> alter system dump datafile 2 block 3272;
系統已更改。
SQL> alter system dump datafile 4 block 2599;
系統已更改。
SQL> alter system dump undo header '_SYSSMU2$';
系統已更改。
SQL> select group#,status from v$log;
GROUP# STATUS
---------- ----------------
1 CURRENT
2 INACTIVE
3 INACTIVE
SQL> select group#,member from v$logfile;
GROUP#
----------
MEMBER
--------------------------------------------------------------------------------
3
F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\REDO03.LOG
2
F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\REDO02.LOG
1
F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\REDO01.LOG
SQL> alter system dump logfile 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\REDO01.L
OG';
系統已更改。
通過dump 分析下undo機制
首先是 file 2 block 3272這個undo block
Start dump data blocks tsn: 1 file#: 2 minblk 3272 maxblk 3272
buffer tsn: 1 rdba: 0x00800cc8 (2/3272)
scn: 0x0000.0050bff7 seq: 0x01 flg: 0x04 tail: 0xbff70201
frmt: 0x02 chkval: 0x3a46 type: 0x02=KTU UNDO BLOCK
這部分是 塊的基本資訊 塊地址(rdba: 0x00800cc8 ),型別等 (0x02=KTU UNDO BLOCK)
............................................
UNDO BLK:
xid: 0x0002.000.000005d5 seq: 0x4fd cnt: 0x33 irb: 0x33 icl: 0x0 flg: 0x0000
xid: 0x0002.000.000005d5 :記錄在這個塊上最新事務的資訊(分3段,回滾段編號,slot號,序列號)
與v$transaction中 XIDUSN XIDSLOT XIDSQN 對應(2,0,1493)
SQL> select to_number('2','xxxxx') from dual;
TO_NUMBER('2','XXXXX')
----------------------
2
SQL> select to_number('5d5','xxxxx') from dual;
TO_NUMBER('5D5','XXXXX')
------------------------
1493
irb:0x33 中記錄的是最近未提交變更的開始處及最後一次更改處,如果rollback這個是起點
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
................
0x33 0x020c
偏移量資訊 最後這個是0x33
用0x33往下找
找到事務所使用的undo block
* Rec #0x33 slt: 0x00 objn: 54666(0x0000d58a) objd: 54666 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x00800cc8.04fd.31 ctl max scn: 0x0000.0050bbf6 prv tx scn: 0x0000.0050bbf8
txn start scn: scn: 0x0000.00000000 logon user: 61
prev brb: 8391879 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
Array Update of 1 rows: ~~~~~資訊更新一行
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 10
ncol: 1 nnew: 1 size: 0
KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01000a27 hdba: 0x01000a23
itli: 2 ispac: 0 maxfr: 4858
vect = 0
col 0: [ 1] 61~~~~~~~~~~~存的舊值
SQL> select chr(to_number('61','xxxxx')) from dual;
CH
--
a
rci 0x00 :代表同一個事務的關聯修改,rollback時用這個迴圈往下找修改值,找到回滾之處
(undo chain) 實驗中 只修改了一次 ,所以為0表示這是最後一條修改記錄
分析下表塊 file 4 block 2599
Start dump data blocks tsn: 4 file#: 4 minblk 2599 maxblk 2599
buffer tsn: 4 rdba: 0x01000a27 (4/2599)
scn: 0x0000.0050bff7 seq: 0x01 flg: 0x04 tail: 0xbff70601
frmt: 0x02 chkval: 0x4463 type: 0x06=trans data
Object id on Block? Y
seg/obj: 0xd58a csc: 0x00.50bf51 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1000a21 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0006.01d.000005e6 0x00800a44.03f0.36 C--- 0 scn 0x0000.0050be9e
0x02 0x0002.000.000005d5 0x00800cc8.04fd.33 ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0x7c12264
===============
tsiz: 0x1f98
hsiz: 0x14
pbl: 0x07c12264
bdba: 0x01000a27
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f93
avsp=0x1f7b
tosp=0x1f7b
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f93
block_row_dump:
tab 0, row 0, @0x1f93
tl: 5 fb: --H-FL-- lb: 0x2 cc: 1
col 0: [ 1] 62
end_of_block_dump
End dump data blocks tsn: 4 file#: 4 minblk 2599 maxblk 2599
這裡主要看itl資訊 事務槽(defalut 2個 )
Itl Xid Uba Flag Lck Scn/Fsc
0x02 0x0002.000.000005d5 0x00800cc8.04fd.33 ---- 1 fsc 0x0000.00000000
xid: 回滾段編號+slot號+序列號 (與v$transaction中 XIDUSN XIDSLOT XIDSQN 對應(2,0,1493))
uba 0x00800cc8.04fd.33:也是分3段,回滾段塊地址(800cc8),回滾塊序號(4fd)對應v$transaction中 UBASQN(1227) ,undo chain(irb)(0X33), 將指向具體使用的undo block
SQL> variable file# number;
SQL> variable blk# number;
SQL> execute :file#:=dbms_utility.data_block_address_file(to_number('800cc8','xx
xxxx'));
PL/SQL 過程已成功完成。
SQL> execute :blk#:=dbms_utility.data_block_address_block(to_number('800cc8','xx
xxxx'));
PL/SQL 過程已成功完成。
SQL> print blk#
BLK#
----------
3272
SQL> print file#
FILE#
----------
2
Lck :表示 transaction修改的行數,這些行被lock住
Scn/Fsc:transaction的scn資訊, SCN表示commit scn, fsc表示fast commit fsc 的scn
Flag :標記共4位c---表示已經提交,----表示未提交
tl: 5 fb: --H-FL-- lb: 0x2 (lb鎖定位資訊指向 0x02 itl) cc: 1(1列)
col 0: [ 1] 62~~~~新值b
事務表資訊
********************************************************************************
Undo Segment: _SYSSMU2$ (2)
********************************************************************************
Extent Control Header
Retention Table
-----------------------------------------------------------
Extent Number:0 Commit Time: 1256609738
Extent Number:1 Commit Time: 1256609738
Extent Number:2 Commit Time: 1256609738
Extent Number:3 Commit Time: 1256609738
Extent Number:4 Commit Time: 1256609738
Extent Number:5 Commit Time: 1256609738
Extent Number:6 Commit Time: 1256609738
以上這部分就是undo_retention使用的部分
TRN CTL:: seq: 0x04fd chd: 0x001c ctl: 0x0006 inc: 0x00000000 nfb: 0x0000
mgc: 0x8201 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
uba: 0x00800cc8.04fd.33 scn: 0x0000.0050bbf8(control scn)
其中事務表控制資訊最新uba資訊 就是 file 2 block 3272
TRN TBL::(transaction table )
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x00 10 0x80 0x05d5 0x0004 0x0000.0050bf73 0x00800cc8 0x0000.000.00000000 0x00000001 0x00000000 0
index 就是 v$transaction.xidslot資訊為0 ,index為0x00
找到了update存transaction table中的資訊身體state資訊10表示活動事務
SQL> commit;~~~~~提交後
提交完成。
SQL> alter system dump datafile 2 block 3272;
系統已更改。
SQL> alter system dump datafile 4 block 2599;
系統已更改。
SQL> alter system dump undo header '_SYSSMU2$';
系統已更改。
undo file 2 block 3272~~~undo 資料塊
Start dump data blocks tsn: 1 file#: 2 minblk 3272 maxblk 3272
buffer tsn: 1 rdba: 0x00800cc8 (2/3272)
scn: 0x0000.0050bff7 seq: 0x01 flg: 0x04 tail: 0xbff70201
frmt: 0x02 chkval: 0x3a46 type: 0x02=KTU UNDO BLOCK
Hex dump of block: st=0, typ_found=1
UNDO BLK:
xid: 0x0002.000.000005d5 seq: 0x4fd cnt: 0x33 irb: 0x33 icl: 0x0 flg: 0x0000
* Rec #0x33 slt: 0x00 objn: 54666(0x0000d58a) objd: 54666 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x00800cc8.04fd.31 ctl max scn: 0x0000.0050bbf6 prv tx scn: 0x0000.0050bbf8
txn start scn: scn: 0x0000.00000000 logon user: 61
prev brb: 8391879 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
op: Z
Array Update of 1 rows:
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 10
ncol: 1 nnew: 1 size: 0
KDO Op code: 21 row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01000a27 hdba: 0x01000a23
itli: 2 ispac: 0 maxfr: 4858
vect = 0
col 0: [ 1] 61
首先undo block不會有任何變化
data block~~表資料塊
seg/obj: 0xd58a csc: 0x00.50bf51 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1000a21 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0006.01d.000005e6 0x00800a44.03f0.36 C--- 0 scn 0x0000.0050be9e
0x02 0x0002.000.000005d5 0x00800cc8.04fd.33 --U- 1 fsc 0x0000.0050db99
data_block_dump,data header at 0x7be2264
===============
tsiz: 0x1f98
hsiz: 0x14
pbl: 0x07be2264
bdba: 0x01000a27
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f93
avsp=0x1f7b
tosp=0x1f7b
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f93
block_row_dump:
tab 0, row 0, @0x1f93
tl: 5 fb: --H-FL-- lb: 0x2 cc: 1
col 0: [ 1] 62
end_of_block_dump
End dump data blocks tsn: 4 file#: 4 minblk 2599 maxblk 2599
0x02 0x0002.000.000005d5 0x00800cc8.04fd.33 --U- 1 fsc 0x0000.0050db99
flag:--u-表示使用者已經提交,之後 如果與該塊有關的事務再提交 則 這個itl flag變為c---,以前c---的變為----
回滾段頭 事務表:
Undo Segment: _SYSSMU2$ (2)
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x00 9 0x00 0x05d5 0xffff 0x0000.0050db99 0x00800cc8 0x0000.000.00000000 0x00000001 0x00000000 1256621655
state變為9表示已經 提交
整體transaction過程:
1.事務開始時,在undo segment header (trn tab)中分配一個INDEX(SLOT)
2.在表所在的資料塊頭獲取一個itl,指向undo segment header的index(用ITL中 XID中slot資訊)
3.在修改資料前記錄前映象undo record形式存在undo segment undo block中,undo segment header中 trn tab(中index,dba )指向該記錄
4.lock修改的行(lb-lock bytes)指向block中 itl
5.資料修改
關於塊中itl
SQL> create table t2 (a int, b int);
表已建立。
1 declare
2 begin
3 for i in 1..20 loop
4 insert into t2 values(i,i+1);
5 end loop;
6 commit;
7* end;
SQL> /
PL/SQL 過程已成功完成。
SQL> select distinct block# from (select dbms_rowid.rowid_relative_fno(rowid) fi
le#,dbms_rowid.rowid_block_number(rowid) block# from xh.t2);
BLOCK#
----------
2632
SQL>
SQL> update xh.t2 set b=23 where a=1;
已更新 1 行。
SQL> update xh.t2 set b=24 where a=2;
已更新 1 行。
SQL> update xh.t2 set b=25 where a=3;
已更新 1 行。
SQL> alter system dump datafile 4 block 2632;
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.002.000004b1 0x00800989.04b0.06 ---- 1 fsc 0x0000.00000000
0x02 0x0006.028.00000604 0x00800a20.03fc.26 ---- 1 fsc 0x0000.00000000
0x03 0x0008.00f.000005e5 0x00800093.058f.20 ---- 1 fsc 0x0000.00000000
3個不同的session更新 產生3個 事務 且都未提交oracle會自動擴充套件itl
SQL> select max_trans from all_tables where table_name='T2';
MAX_TRANS
----------
255
最多可以擴充套件到255個itl ,可以 擴充套件但會對效能有影響,可以建表時指定 多個 create table name (id number) initrans 3;
SQL> create table t2 (a int ) initrans 3;
表已建立。
SQL> insert into t2 values(1);
已建立 1 行。
SQL> commit;
提交完成。
SQL> select file#,block# from (select dbms_rowid.rowid_relative_fno(rowid) file#
,dbms_rowid.rowid_block_number(rowid) block# from t2);
FILE# BLOCK#
---------- ----------
1 64554
SQL> alter system dump datafile 1 block 64554;
系統已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0003.027.000005f5 0x00800aba.0388.34 --U- 1 fsc 0x0000.0053d9b9
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
0x03 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
undo主要作用
1.consistent read(包括flashback query,flashback drop)
2.instance recovery
3.rollback transaction
讀一致性 就是當select 發出的時候 ,其結果是固定
當block上有 LOCK, flashback query < current block scn,cursor scn< current block scn 會構造cr塊來保證consistent read
過程:
當select 時(一個長時間select ) 時間是8:00 scn為111,8:10 一個SESSION 更新了 一個塊 提交了(select 還未查到獲取這個塊)這個UPDATE會在更新塊ITL中記錄提交時最新的SCN/FSN ,儲存指向一個undo block的指標(UBA),8:15一個session更新了同樣的塊提交了(select 還未查到獲取這個塊),這個UPDATE會在更新塊ITL中記錄提交時最新的SCN/FSN,儲存指向一個undo block的指標(UBA),8:20 一個session第3次更新了同樣的block並且提交了 ,這時候出現一個問題 data block中 ITL 最早第一個更新的 資訊 將被覆蓋被覆蓋的ITL 資訊記載到最新ILT資訊中UBA指向的undo block中,此時查詢語句要 讀取這個塊那麼發現查詢的 SCN
SQL> select file#,block# from (select dbms_rowid.rowid_relative_fno(rowid) file#
,dbms_rowid.rowid_block_number(rowid) block# from xh.t1);
FILE# BLOCK#
---------- ----------
4 2612
SQL> select data_object_id,owner from all_objects where object_name='T1';
DATA_OBJECT_ID OWNER
-------------- ------------------------------
54727 XH
SQL> select * from t1;
A B
---------- ----------
d a
看下現在塊的結構
SQL> alter system dump datafile 4 block 2612;
系統已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.013.000005ef 0x008000d8.05a0.25 C--- 0 scn 0x0000.005361b3
0x02 0x0003.005.000005e5 0x0080042e.0387.0c --U- 1 fsc 0x0000.00536254
block_row_dump:
tab 0, row 0, @0x1f42
tl: 7 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 1] 64~~~~~~~~~~值d
col 1: [ 1] 61~~~~~~~~~值得a
end_of_block_dump
End dump data blocks tsn: 4 file#: 4 minblk 2612 maxblk 2612
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
5464707
SQL> update t1 set a='e';
已更新 1 行。
SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK
---------- ---------- ---------- ---------- ----------
9 29 1568 2 17587
SQL> alter system dump datafile 4 block 2612;
系統已更改。
SQL> alter system dump datafile 2 block 17587;
系統已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0009.01d.00000620 0x008044b3.0229.17 ---- 1 fsc 0x0000.00000000~~~~被覆蓋了
0x02 0x0003.005.000005e5 0x0080042e.0387.0c C--- 0 scn 0x0000.00536254
data_block_dump,data header at 0x74a2264
===============
tab 0, row 0, @0x1f42
tl: 7 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 1] 65~~~~~~~~~~~~~~~~~e
col 1: [ 1] 61~~~~~~~~~~~~~~~~~a
* Rec #0x17 slt: 0x1d objn: 54727(0x0000d5c7) objd: 54727 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x008044b3.0229.16 ctl max scn: 0x0000.00535d48 prv tx scn: 0x0000.00535d98
txn start scn: scn: 0x0000.005362f1 logon user: 61
prev brb: 8406192 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
op: L itl: xid: 0x0008.013.000005ef uba: 0x008000d8.05a0.25( 這塊itl .xid ,uba ,scn整個是被覆蓋itl的資訊)
flg: C--- lkc: 0 scn: 0x0000.005361b3
KDO Op code: URP row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01000a34 hdba: 0x01000a33
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 7
ncol: 2 nnew: 1 size: 0
Vector content:
col 0: [ 1] 64~~~~~~~值d
SQL> commit
2 ;
提交完成。
SQL> update t1 set a='ee';
已更新 1 行。
SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK
---------- ---------- ---------- ---------- ----------
9 8 1570 2 17590
SQL> alter system dump datafile 4 block 2612;
系統已更改。
SQL> alter system dump datafile 2 block 17590;
系統已更改。
SQL>
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0009.01d.00000620 0x008044b3.0229.17 C--- 0 scn 0x0000.0053637d
0x02 0x0009.008.00000622 0x008044b6.0229.31 ---- 1 fsc 0x0000.00000000(0x0080042e.0387.0c被覆蓋)
tab 0, row 0, @0x1f3a
tl: 8 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] 65 65~~~~~~~~~~~~~~ee
col 1: [ 1] 61~~~~~~~~~~~~~~~~~~~~~~~~~~~~a
* Rec #0x31 slt: 0x08 objn: 54727(0x0000d5c7) objd: 54727 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x008044b6.0229.2f ctl max scn: 0x0000.0053615a prv tx scn: 0x0000.00536174
txn start scn: scn: 0x0000.00536a86 logon user: 61
prev brb: 8406194 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
op: L itl: xid: 0x0003.005.000005e5 uba: 0x0080042e.0387.0c (被覆蓋itl資訊)
flg: C--- lkc: 0 scn: 0x0000.00536254
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x01000a34 hdba: 0x01000a33
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 7
ncol: 2 nnew: 1 size: -1
col 0: [ 1] 65~~~~~~~~~~~~~~~~~~~~值e
SQL> commit;
提交完成。
SQL>
SQL> update t1 set a='eee';
已更新 1 行。
SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK
---------- ---------- ---------- ---------- ----------
8 10 1520 2 126
SQL> alter system dump datafile 4 block 2612;
系統已更改。
SQL> alter system dump datafile 2 block 126;
系統已更改。
SQL>
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.00a.000005f0 0x0080007e.05a2.06 ---- 1 fsc 0x0000.00000000(0x008044b3.0229.17被覆蓋)
0x02 0x0009.008.00000622 0x008044b6.0229.31 C--- 0 scn 0x0000.00536af8
data_block_dump,data header at 0x74a2264
===============
tl: 9 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 3] 65 65 65~~~eee
col 1: [ 1] 61~~a
* Rec #0x6 slt: 0x0a objn: 54727(0x0000d5c7) objd: 54727 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x00
Undo type: Regular undo Begin trans Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
uba: 0x0080007e.05a2.05 ctl max scn: 0x0000.00536276 prv tx scn: 0x0000.0053628a
txn start scn: scn: 0x0000.00536afd logon user: 61
prev brb: 8388824 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
op: L itl: xid: 0x0009.01d.00000620 uba: 0x008044b3.0229.17 (被覆蓋itl資訊)
flg: C--- lkc: 0 scn: 0x0000.0053637d
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x01000a34 hdba: 0x01000a33
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) flag: 0x2c lock: 0 ckix: 7
ncol: 2 nnew: 1 size: -1
col 0: [ 2] 65 65~ee
現在select檢視到 這個塊了 FILE 4 BLOCK 2612 ,QUERY SCN 是 5464707 發現itl中有未提交事務(從lck , LB, Scn/Fsc判斷),開始構造cr塊,
當前block中 狀態資訊
0x01 0x0008.00a.000005f0 0x0080007e.05a2.06 ---- 1 fsc 0x0000.00000000
0x02 0x0009.008.00000622 0x008044b6.0229.31 C--- 0 scn 0x0000.00536af8
通過itl中 uba(0x0080007e.05a2.06 ) 找到file 2 block 126 ,發現其中記載的被覆蓋 itl資訊itl: xid: 0x0009.01d.00000620 uba: 0x008044b3.0229.17 SCN為
SQL> select to_number('53637d','xxxxxxx') from dual;
TO_NUMBER('53637D','XXXXXXX')
-----------------------------
5464957~~~~~~~~~比query scn還要大
,那麼 繼續回溯用從file 2 block 126中記載的被覆蓋ITL中的undo block address回溯( uba: 0x008044b3.0229.17 )到file 2,block 17587
這個undo block(file 2 block 17587)中 記載覆蓋上一個itl的資訊
itl: xid: 0x0008.013.000005ef uba: 0x008000d8.05a0.25 scn: 0x0000.005361b3
記錄的undo 值 是
Vector content:
col 0: [ 1] 64~~~~~~~值d
SQL> select to_number('5361b3','xxxxxxx') from dual;
TO_NUMBER('5361B3','XXXXXXX')
-----------------------------
5464499~~~~~~~~~~~~~~~發現這個 SCN 比 query scn要小
那麼將使用這個 itl資訊
並使用undo file 2 block 17587 中記錄的 值(將 舊值D 替換掉新值ee) 與當前塊構造cr塊
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.013.000005ef 0x008000d8.05a0.25 C--- 0 scn 0x0000.005361b3~~~~第一個itl slot出來了,值也替換掉了
但 當前塊中 還有 這個itl資訊
0x02 0x0009.008.00000622 0x008044b6.0229.31 C--- scn 0x0000.00536af8
它的scn>query scn
SQL> select to_number('536af8','xxxxxxx') from dual;
TO_NUMBER('536AF8','XXXXXXX')
-----------------------------
5466872>query scn
通過uba (0x008044b6.0229.31 )找到 undo block file 2,block 17590;
這個塊 包含 被覆蓋的 itl資訊 為op: L itl: xid: 0x0003.005.000005e5 uba: 0x0080042e.0387.0c (被覆蓋itl資訊)
flg: C--- lkc: 0 scn: 0x0000.00536254
SQL> select to_number('536254','xxxxxx') from dual;
TO_NUMBER('536254','XXXXXX')
----------------------------
5464660 ~~~~~~~~~~query scn(5464707) 要小
這個undo block (2,17950)中值記錄為e ,orcle對只會使用這個undo塊中記錄的被覆蓋itl的資訊構造cr,而不會使用這個undo塊中值資訊構造cr(oracle會使用undo block中儲存 被覆蓋itl資訊中 SCN最接近 query scn的 undo block中記錄的 值 )
那麼 最終 將構造出一個consistent read block ,
這個CR塊 在buffer中 file# 是4 BLOCK#是 2612,在buffer cache中 hash value一樣,所以掛在 同一個hash cache buffer chain
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.013.000005ef 0x008000d8.05a0.25 C--- 0 scn 0x0000.005361b3
0x02 0x0003.005.000005e5 0x0080042e.0387.0c C--- 1 fsc 0x0000.00536254
block_row_dump:
tab 0, row 0, @0x1f42
tl: 7 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 1] 64~~~~~~~~~~值d
col 1: [ 1] 61~~~~~~~~~值a
end_of_block_dump
cr塊數量
SQL> set linesize 132
SQL> column name format a30
SQL> column value format a25
SQL> select
2 x.ksppinm name,
3 y.ksppstvl value,
4 y.ksppstdf isdefault,
5 decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE') ismod,
6 decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE') isadj,x. KSPPDESC
7 from
8 sys.x$ksppi x,
9 sys.x$ksppcv y
10 where
11 x.inst_id = userenv('Instance') and
12 y.inst_id = userenv('Instance') and
13 x.indx = y.indx and
14 x.ksppinm like '%_&par%'
15 order by
16 translate(x.ksppinm, ' _', ' ')
17 /
輸入 par 的值: db_block_max_cr
原值 14: x.ksppinm like '%_&par%'
新值 14: x.ksppinm like '%_db_block_max_cr%'
NAME VALUE ISDEFAULT ISMOD
ISADJ
------------------------------ ------------------------- --------- -------------
------------------- --------------------------------
KSPPDESC
--------------------------------------------------------------------------------
----------------------------------------------------
_db_block_max_cr_dba 6 TRUE FALSE
FALSE
Maximum Allowed Number of CR buffers per dba
預設同一個datablock可以有 6個CR block
SQL> select file#,block# from (select dbms_rowid.rowid_relative_fno(rowid) file#
,dbms_rowid.rowid_block_number(rowid) block# from t2);
FILE# BLOCK#
---------- ----------
1 64554
SQL> select file#,block#,status from v$bh where file#=1 and block#=64554;
FILE# BLOCK# STATUS
---------- ---------- -------
1 64554 free
SQL> update t2 set a=2;
已更新 1 行。
SQL> select file#,block#,status from v$bh where file#=1 and block#=64554;
FILE# BLOCK# STATUS
---------- ---------- -------
1 64554 free
1 64554 cr
1 64554 xcur
這個UPDATE 產生一個CR塊 ,和一個當前模式的塊,未commit
SQL> select * from t2;
A
----------
3
~~多次查詢
SQL> select file#,block#,status from v$bh where file#=1 and block#=64554;
FILE# BLOCK# STATUS
---------- ---------- -------
1 64554 free
1 64554 xcur
1 64554 cr
1 64554 cr
1 64554 cr
1 64554 cr
1 64554 cr
1 64554 cr
已選擇8行。
已選擇8行。~~~~~~~~~~~~~~~·可以看到最多就 構建6個 cr塊,超過後 覆蓋以前的CR塊 繼續構建,cr塊是不會讓其它session共享的 (因為每次查詢的scn不一樣,而且也許事務也在對塊有不同的修改)
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
oracle 10g IMU(IN MEMORY UNDO )
修改資料時UNDO寫到BUFFER CACHE中(產生redo) 然後 按BUFFER CACHE 管理方法 被DBWN 程式將undo寫到undo segment 上,當產生cr塊或rollback操作時 ,undo blk要從undo segment 讀入buffer cache,可能會產生大量consistent get or physical reads
IN MEMROY UNDO (用於控制UNDO產生redo及其從buffer cache寫回disk) shared pool中開獨立記憶體區,存undo 資訊(避免在 buffer cache中進行讀寫操作 減少redo生成)
減少了undo segment的操作,IMU中資料暫存整理收縮後批量寫入undo segment
**imu 與redo 的private redolog strands(zero-copy redo)是緊密相關的,IMU在shared pool中 buffer 64-128K(與 private redolog strands一樣 ),所以只有特定的小事務才可以放入 產生修改變化時候相關redo寫入pvrs(等於都是在shared pool中操作,UNDO,REDO還是對應的),每個transaction 繫結一個獨立的free space(每個獨立IMU 空間由in memory undo latch保護)當 imu buffer,pvrs滿後,oracle會寫出imu中資訊到 undo segment ,pvrs中redo到 online redo log file,RAC不支援IMU特性
SQL> select * from v$sgastat where nAme like '%KTI%'
2 ;
POOL NAME BYTES
------------ ------------------------------ ----------
shared pool KTI-UNDO 1235304~~~~分配imu記憶體
shared pool KTI pool states 20
shared pool KTI latch structure 1872
shared pool KTI latches 288
SQL> select name,gets from v$latch_children where name like '%undo latch';
NAME GETS
------------------------------ ----------
In memory undo latch 2845
In memory undo latch 8261
In memory undo latch 929
In memory undo latch 1214
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
NAME GETS
------------------------------ ----------
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
In memory undo latch 0
已選擇18行。
獨立的in memory undo latch
控制imu的隱藏引數
_in_memory_undo default true Make in memory undo for top level transactions 是否起用imu
_imu_pools default 3 in memory undo pools 預設分3個pool
_recursive_imu_transactions default false recursive transactions may be IMU 遞迴事務是否使用IMU
_db_writer_flush_imu default TRUE If FALSE, DBWR will not downgrade IMU txns for AGING 將IMU TRANSACTION 降級為正常事務執行在undo segment的寫出操作
IMU 總體資訊
SQL> select name,to_number(value,'xxxxxxxx') from v$sysstat where name like '%I
MU%';
NAME TO_NUMBER(VALUE,'XXXXXXXX')
------------------------------ ---------------------------
IMU commits 4119~~提交次數
IMU Flushes 40~~重新整理次數
IMU contention 0
IMU recursive-transaction flus 1
h
IMU undo retention flush 0
IMU ktichg flush 0
IMU bind flushes 0
IMU mbu flush 0
IMU pool not allocated 0
NAME TO_NUMBER(VALUE,'XXXXXXXX')
------------------------------ ---------------------------
IMU CR rollbacks 0
IMU undo allocation size 37896594
IMU Redo allocation size 1644694
IMU- failed to get a private s 0
trand
已選擇13行。
關於ora-01555
常見原因就是 當一個select 的SCN 小於一個更新操作的 SCN 那麼需要構造CR塊,如果這個查詢完成的時間 大於這個UPDATE 提交時間 那麼該塊的前映象有可能被覆蓋,如果這個UPDATE 事務是 fast block clean 那麼當 構造cr塊時 回滾段資訊已經被覆蓋 資訊不可用,那麼造成ora-01555
SQL> create undo tablespace undotbs2 datafile 'e:\datafile\undotbs2.dbf' size 10m
;
表空間已建立。
SQL> show parameter undo_tablespace
NAME TYPE
------------------------------------ --------------------------------
VALUE
------------------------------
undo_tablespace string
UNDOTBS1
SQL> select usn,xacts,status from v$rollstat;
USN XACTS STATUS
---------- ---------- ---------------
0 0 ONLINE
1 0 ONLINE
2 0 ONLINE
3 0 ONLINE
4 0 ONLINE
5 0 ONLINE
6 0 ONLINE
7 0 ONLINE
8 0 ONLINE
9 0 ONLINE
10 0 ONLINE
已選擇11行。
SQL> alter system set undo_tablespace='UNDOTBS2';
系統已更改。
SQL> select usn,xacts,status from v$rollstat;
USN XACTS STATUS
---------- ---------- ---------------
0 0 ONLINE~~~~~~~~~system undo segment
11 0 ONLINE
12 0 ONLINE
13 0 ONLINE
14 0 ONLINE
15 0 ONLINE
16 0 ONLINE
17 0 ONLINE
已選擇8行。~~~~可以看到已經切換成最新的UNDO tablespace了
SQL> select segment_name,status,tablespace_name from dba_rollback_segs;
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
SYSTEM ONLINE SYSTEM
_SYSSMU1$ OFFLINE UNDOTBS1
_SYSSMU2$ OFFLINE UNDOTBS1
_SYSSMU3$ OFFLINE UNDOTBS1
_SYSSMU4$ OFFLINE UNDOTBS1
_SYSSMU5$ OFFLINE UNDOTBS1
_SYSSMU6$ OFFLINE UNDOTBS1
_SYSSMU7$ OFFLINE UNDOTBS1
_SYSSMU8$ OFFLINE UNDOTBS1
_SYSSMU9$ OFFLINE UNDOTBS1
_SYSSMU10$ OFFLINE UNDOTBS1
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
_SYSSMU11$ ONLINE UNDOTBS2
_SYSSMU12$ ONLINE UNDOTBS2
_SYSSMU13$ ONLINE UNDOTBS2
_SYSSMU14$ ONLINE UNDOTBS2
_SYSSMU15$ ONLINE UNDOTBS2
_SYSSMU16$ ONLINE UNDOTBS2
_SYSSMU17$ ONLINE UNDOTBS2
已選擇18行。
SQL> conn xh/a831115
已連線。
SQL> show user
USER 為 "XH"
SQL> create table ts(a char(2000), b char(2000), c char(2000));
表已建立。
SQL> declare
2 begin
3 for i in 1..20 loop
4 insert into ts values('a','a','a');
5 end loop;
6 commit;
7 end;
8 /
PL/SQL 過程已成功完成。
SQL> select file#,block# ,rowid from (select dbms_rowid.rowid_relative_fno(rowi
d) file#,dbms_rowid.rowid_block_number(rowid) block# ,rowid from TS);
FILE# BLOCK# ROWID
---------- ---------- ------------------
4 2764 AAANcIAAEAAAArMAAA
4 2765 AAANcIAAEAAAArNAAA
4 2766 AAANcIAAEAAAArOAAA
4 2767 AAANcIAAEAAAArPAAA
4 2768 AAANcIAAEAAAArQAAA
4 2769 AAANcIAAEAAAArRAAA
4 2770 AAANcIAAEAAAArSAAA
4 2771 AAANcIAAEAAAArTAAA
4 2772 AAANcIAAEAAAArUAAA
4 2773 AAANcIAAEAAAArVAAA
4 2774 AAANcIAAEAAAArWAAA
FILE# BLOCK# ROWID
---------- ---------- ------------------
4 2775 AAANcIAAEAAAArXAAA
4 2776 AAANcIAAEAAAArYAAA
4 2778 AAANcIAAEAAAAraAAA
4 2779 AAANcIAAEAAAArbAAA
4 2780 AAANcIAAEAAAArcAAA
4 2781 AAANcIAAEAAAArdAAA
4 2782 AAANcIAAEAAAAreAAA
4 2783 AAANcIAAEAAAArfAAA
4 2784 AAANcIAAEAAAArgAAA
SQL> show user
USER 為 "XH"
SQL> select distinct sid from v$mystat;
SID
----------
143
SQL> var a refcursor
SQL> exec open :a for select * from xh.ts;
PL/SQL 過程已成功完成。
SQL> ed
已寫入 file afiedt.buf
1 declare
2 begin
3 for i in 1..1000 loop
4 update xh.ts set a='aa';
5 commit;
6 end loop;
7* end;
SQL> /
PL/SQL 過程已成功完成。
SQL> print a
ERROR:
ORA-01555: 快照過舊: 回退段號 16 (名稱為 "_SYSSMU16$") 過小
oracle 按照前面的回溯方法 製造cr塊,但 製造CR塊 時需要的undo資訊 已經被覆蓋了 (可以理解為所有undo block中記載被覆蓋的ITL資訊中SCN 都比查詢的大)
alert.log中會記載詳細資訊
ORA-01555 caused by SQL statement below (SQL ID: 8f9xxvtdbyaf6, Query Duration=138 sec, SCN: 0x0000.0054f00f):
Fri Oct 30 20:41:28 2009
SELECT * FROM XH.TS
SQL> select sql_text from v$sqlarea where sql_id='8f9xxvtdbyaf6';
SQL_TEXT
--------------------------------------------------------------------------------
SELECT * FROM XH.TS
SQL> select sid ,username from v$session where sql_hash_value=1522477510 or PREV
_HASH_VALUE=1522477510;
SID USERNAME
---------- ------------------------------
143 XH
errorstack 跟蹤ora-01555
SQL> alter system set events'1555 trace name errorstack level 4';,跟蹤資訊01555
第2種情況
delayed block cleanout 與ora-01555
tom 對於 延遲塊清除造成ora-01555的解釋
塊清除是導致ORA-01555錯誤錯誤的原因,儘管很難完全杜絕,不過好在畢竟並不多見,因為可能出現塊清除的情況不常發生(至少在Oracle8i及 以上版本中是這樣)。我們已經討論過塊清除機制,不過這裡可以做一個總結:在塊清除過程中,如果一個塊已被修改,下一個會話訪問這個塊時,可能必須檢視最 後一個修改這個塊的事務是否還是活動的。一旦確定該事務不再活動,就會完成塊清除,這樣另一個會話訪問這個塊時就不必再歷經同樣的過程。要完成塊清除,Oracle會從塊首部確定前一個事務所用的undo段,然後確定從undo首部能不能看出這個塊是否已經提交。可以用以下兩種方式完成這種確認。一種方式是Oracle可以確定這個事務很久以前就已經提交,它在undo段事務表中的事務槽已經被覆蓋。另一種情況是COMMIT SCN還在undo段的事務表中,這說明事務只是稍早前剛提交,其事務槽尚未被覆蓋。
要從一個延遲的塊清除收到ORA-01555錯誤,以下條件都必須滿足:
1. 首先做了一個修改並COMMIT,塊沒有自動清理(即沒有自動完成“提交清除”,例如修改了太多的塊,在SGA塊緩衝區快取的10%中放不下)。
2. 其他會話沒有接觸這些塊,而且在我們這個“倒黴”的查詢(稍後顯示)命中這些塊之前,任何會話都不會接觸它們。
3. 開始一個長時間執行的查詢。這個查詢最後會讀其中的一些塊。這個查詢從SCN t1開始,這就是讀一致SCN,必須將資料回滾到這一點來得到讀一致性。開始查詢時,上述修改事務的事務條目還在undo段的事務表中。
4. 查詢期間,系統中執行了多個提交。執行事務沒有接觸執行已修改的塊(如果確實接觸到,也就不存在問題了)。
5.由於出現了大量的COMMIT,undo段中的事務表要回繞並重用事務槽。最重要的是,將迴圈地重用原來修改事務的事務條目。另外,系統重用了undo段的區段,以避免對undo段首部塊本身的一致讀。
6.此外,由於提交太多,undo段中記錄的最低SCN現在超過了t1(高於查詢的讀一致SCN)。
如果查詢到達某個塊,而這個塊在查詢開始之前已經修改並提交,就會遇到麻煩。正常情況下 會回到,到塊所指的undo段,找到修改了這個塊的事務的狀態(換句話說,它會找到事務的COMMIT SCN)。如果這個COMMIT SCN小於t1,查詢就可以使用這個塊。如果該事務的COMMIT SCN大於t1,查詢就必須回滾這個塊。不過,問題是,在這種特殊的情況下,查詢無法確定塊的COMMIT SCN是大於還是小於t1。相應地,不清楚查詢能否使用這個塊映像。這就導致了ORA-01555錯誤。
個人總結:簡單說 如果update 提交方式是delayed block cleanout,那麼undo segement header 中的trn tab已經被重用,將造成無法判斷select 與update時間的前後關係,select到這個塊時候發現 塊中有未提交事務的資訊,將去對應的事務表中判斷這個未提交事務的狀態(是否提交) 事務表覆蓋了就無法判斷狀態了,如果可以判斷出 select scn>update scn,這樣select可以直接使用這個塊,如果select scn< update scn那麼將構造cr塊,現在問題就是無法判斷 是哪種情況
關於塊清除
若一個transcation 修改不超過10%的buffer cache 提交時,oracle將做fast commit cleanout,如果修改超過了10%的buffer cache 提交時,超過的10%的部分將執行delayed block cleanout
在事務commit前修改資料(dirty buffer)若已寫入datafile,當事務提交時候oracle 並不會把已經寫入datafile的來做cleanout,下次讀取時在清除 進行delayed block cleanout,這是一種對效能的優化,減少physiace read,但delayed block cleanout時並不讀入修改的data block,但是會讀入 使用回滾段的 undo segment header block,修改其中的事務表(trn tab)將事務標記為提交,下次另一個事務再次讀入這個data block時發現沒有提交 會先檢視itl xid找到 事務表 看是否提交過,然後做延遲塊清除(如果是select 時候 讀入這個 block 會產生 redo)清除塊中itl資訊和鎖資訊
主要看下塊清除
undo block和修改的data block 未commit前 已經寫回 datafile, 此時commit,延遲塊清除產生,data block不會被從datafile讀入buffer cache,但是undo segment header block會讀入buffer cache修改事務表
SQL> select * from test;
A
----------
9
9
SQL> select file#,block# from (select dbms_rowid.rowid_relative_fno(rowid) file#
,dbms_rowid.rowid_block_number(rowid) block# from test);
FILE# BLOCK#
---------- ----------
6 50
6 50
SQL> update test set a=9;
2 rows updated.
SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK
---------- ---------- ---------- ---------- ----------
4 25 407 2 1630
SQL> select name from v$rollname where usn=4;
NAME
------------------------------
_SYSSMU4$
SQL> alter system dump datafile 6 block 50;
System altered.
SQL> alter system dump undo header '_SYSSMU4$';
System altered.
buffer tsn: 7 rdba: 0x01800032 (6/50)
scn: 0x0000.00277541 seq: 0x01 flg: 0x04 tail: 0x75410601
frmt: 0x02 chkval: 0x2ff4 type: 0x06=trans data
Block header dump: 0x01800032
Object id on Block? Y
seg/obj: 0xc972 csc: 0x00.23b1db itc: 2 flg: O typ: 1 - DATA
fsl: 0 fnx: 0x0 ver: 0x01
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0004.019.00000197 0x0080065e.0229.0e ---- 2 fsc 0x0000.00000000
0x02 0x0009.022.000001b7 0x0080008c.0250.63 C--- 0 scn 0x0000.0023916f
tab 0, row 0, @0x1f9a
tl: 6 fb: --H-FL-- lb: 0x1 cc: 1
col 0: [ 2] c1 0a
tab 0, row 1, @0x1f94
tl: 6 fb: --H-FL-- lb: 0x1 cc: 1
col 0: [ 2] c1 0a
end_of_block_dump
~~~~~~~~~~~~~~~~~~~~~~未commit時候塊中資訊
SQL> variable file# number;
SQL> variable blk# number;
uba:0x0080065e.0229.0e 找到這個事務使用的undo block
SQL> execute :file#:=dbms_utility.data_block_address_file(to_number('80065e','xx
xxxxx'));
PL/SQL procedure successfully completed.
SQL> execute :blk#:=dbms_utility.data_block_address_block(to_number('80065e','xx
xxxxx'));
PL/SQL procedure successfully completed.
SQL> print file#
FILE#
----------
2
SQL> print blk#
BLK#
----------
1630
SQL> select file_id,block_id from dba_extents where segment_name='_SYSSMU4$';
FILE_ID BLOCK_ID
---------- ----------
2 57~~~~~~~~undo segment header 存trn tab(事務表)
2 17
2 1545
SQL> select file#,block#,class#,status from v$bh where file# in(6,2) and block#
in(1630,57,17,1545,50);
FILE# BLOCK# CLASS# STATUS
---------- ---------- ---------- -------
2 57 23 xcur
6 50 1 cr
6 50 1 xcur
2 1630 24 xcur
SQL> alter system flush buffer_cache;~~~事務未提交時,強制將dirty buffer 重新整理到disk
System altered.
SQL> select file#,block#,class#,status ,dirty from v$bh where file# in(6,2) and
block# in(1630,57,17,1545,50);
FILE# BLOCK# CLASS# STATUS D
---------- ---------- ---------- ------- -
2 57 23 free N
6 50 1 free N
6 50 1 free N
2 1630 24 free N
SQL> commit;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~此時執行update 的 session commit,這是一個delayed block cleanout
Commit complete.
QL> /
FILE# BLOCK# CLASS# STATUS D
--------- ---------- ---------- ------- -
2 57 23 free N
2 57 23 xcur Y~~~~~~~~~~~~~~~~~~~~~~~~~~buffer cache中讀入 undo header了 修改了 undo header tran tab
6 50 1 free N~~~~~~~~~~data block沒有讀入buffer cache
6 50 1 free N
2 1630 24 free N~~~~~~~~~~undo block也沒讀入buffer cache
SQL> select * from test;~~~~此時另一個SESSION 查詢,產生delayed block cleanout
A
----------
9
9
SQL> /
FILE# BLOCK# CLASS# STATUS D
---------- ---------- ---------- ------- -
2 57 23 free N
2 57 23 xcur Y~~~~~~~~~~~~~~~~~
6 50 1 free N
6 50 1 free N
6 50 1 xcur Y~~~~~~~~~~~~~~~~~~讀入data block 產生delayed block cleanout
2 1630 24 free N
通過轉儲分析下
SQL> conn xh/a831115
已連線。
SQL> desc t1;
名稱 是否為
空? 型別
------------------------------------------------------------------------ ------
-- -------------------------------------------------
A
VARCHAR2(10)
B
VARCHAR2(10)
SQL> update t1 set a='f';
已更新 1 行。
SQL> select file#,block# from (select dbms_rowid.rowid_relative_fno(rowid) file#
,dbms_rowid.rowid_block_number(rowid) block# from t1);
FILE# BLOCK#
---------- ----------
4 2612
SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK
---------- ---------- ---------- ---------- ----------
15 38 44 11 77
SQL> select name from v$rollname where usn=15;
NAME
------------------------------
_SYSSMU15$
SQL> alter system dump datafile 4 block 2612;
系統已更改。
SQL> alter system dump undo header '_SYSSMU15$';
系統已更改。
data block中
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.00a.000005f0 0x0080007e.05a2.06 C--- 0 scn 0x0000.00537e75
0x02 0x000f.026.0000002c 0x02c0004d.027d.1b ---- 1 fsc 0x0000.00000000
data_block_dump,data header at 0x94f2264
tosp=0x1f7b
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f2a
block_row_dump:
tab 0, row 0, @0x1f2a
tl: 7 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 1] 66
col 1: [ 1] 61
undo segment header 中
TRN TBL::
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
0x26 10 0x80 0x002c 0x0000 0x0000.0055bdcc 0x02c0004d 0x0000.000.00000000 0x00000001 0x00000000 0
SQL> select to_number('26','xxxx') from dual;
TO_NUMBER('26','XXXX')
----------------------
38~~~38好slot(與 v$transaction中 XIDslot一樣 )
SQL> alter system flush buffer_cache;
系統已更改。
SQL> commit;~~~update transaction提交
提交完成。
SQL>
SQL> alter system dump datafile 4 block 2612;
系統已更改。
SQL> alter system dump undo header '_SYSSMU15$';
系統已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.00a.000005f0 0x0080007e.05a2.06 C--- 0 scn 0x0000.00537e75
0x02 0x000f.026.0000002c 0x02c0004d.027d.1b ---- 1 fsc 0x0000.00000000~~~看 到 itl資訊 沒 清除
data_block_dump,data header at 0x94f2264
===============
..........
block_row_dump:
tab 0, row 0, @0x1f2a
tl: 7 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 1] 66
col 1: [ 1] 61
TRN TBL::
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
0x26 9 0x00 0x002c 0x002d 0x0000.0055c0ae 0x02c0004d 0x0000.000.00000000 0x00000001 0x00000000 1256981843
~~~看 到 undo segment header 中 trn tbl 已經記錄為 提交 state 為 9
SQL> set autotrace trace statistics
SQL> select * from xh.t1;~~另一session查詢
統計資訊
----------------------------------------------------------
24 recursive calls
0 db block gets
11 consistent gets
8 physical reads~~~從disk讀回buffer cache產生 物理讀
116 redo size~~~~~~~~~~產生redo
457 bytes sent via SQL*Net to client
385 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> alter system dump datafile 4 block 2612;
系統已更改。
SQL> alter system dump undo header '_SYSSMU15$';
系統已更改。
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.00a.000005f0 0x0080007e.05a2.06 C--- 0 scn 0x0000.00537e75~~~flag改變
0x02 0x000f.026.0000002c 0x02c0004d.027d.1b C--- 0 scn 0x0000.0055c0ae
data_block_dump,data header at 0x94f2264
===============
tsiz: 0x1f98
hsiz: 0x14
pbl: 0x094f2264
bdba: 0x01000a34
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f2a
avsp=0x1f7b
tosp=0x1f7b
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f2a
block_row_dump:
tab 0, row 0, @0x1f2a
tl: 7 fb: --H-FL-- lb: 0x0 cc: 2~~~~~~LB 原來指向0x01的lock標記清除(lock修改的行(lb-lock bytes)指向block中 itl)
col 0: [ 1] 66
col 1: [ 1] 61
end_of_block_dump
以上就是 delayed block cleanout時 資料結構
關於undo的 恢復
有備份且archive log mode 下 undo tablespace的恢復與恢復普通tablespace並沒有區別,無論損壞時UNDO TABLESPACE中是否存在活動事務;
SQL> show parameter undo_tablespace
NAME TYPE
------------------------------------ --------------------------------
VALUE
------------------------------
undo_tablespace string
UNDOTBS1
SQL> select segment_name,status,tablespace_name from dba_rollback_segs;
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
SYSTEM ONLINE SYSTEM
_SYSSMU1$ ONLINE UNDOTBS1
_SYSSMU2$ ONLINE UNDOTBS1
_SYSSMU3$ ONLINE UNDOTBS1
_SYSSMU4$ ONLINE UNDOTBS1
_SYSSMU5$ ONLINE UNDOTBS1
_SYSSMU6$ ONLINE UNDOTBS1
_SYSSMU7$ ONLINE UNDOTBS1
_SYSSMU8$ ONLINE UNDOTBS1
_SYSSMU9$ ONLINE UNDOTBS1
_SYSSMU10$ ONLINE UNDOTBS1
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- ------------------------------
_SYSSMU11$ OFFLINE UNDOTBS2
_SYSSMU12$ OFFLINE UNDOTBS2
_SYSSMU13$ OFFLINE UNDOTBS2
_SYSSMU14$ OFFLINE UNDOTBS2
_SYSSMU15$ OFFLINE UNDOTBS2
_SYSSMU16$ OFFLINE UNDOTBS2
_SYSSMU17$ OFFLINE UNDOTBS2
已選擇18行。
RMAN> list backup of database;
RMAN> backup datafile 2;
啟動 backup 於 01-11月-09
使用通道 ORA_DISK_1
通道 ORA_DISK_1: 啟動全部資料檔案備份集
通道 ORA_DISK_1: 正在指定備份集中的資料檔案
輸入資料檔案 fno=00002 name=F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\UNDOTBS01.DB
F
通道 ORA_DISK_1: 正在啟動段 1 於 01-11月-09
通道 ORA_DISK_1: 已完成段 1 於 01-11月-09
段控制程式碼=F:\ORACLE\PRODUCT\10.2.0\FLASH_RECOVERY_AREA\XHTEST\BACKUPSET\2009_11_01\
O1_MF_NNNDF_TAG20091101T152506_5GTFYNYR_.BKP 標記=TAG20091101T152506 註釋=NONE
通道 ORA_DISK_1: 備份集已完成, 經過時間:00:00:26
完成 backup 於 01-11月-09
啟動 Control File and SPFILE Autobackup 於 01-11月-09
段 handle=F:\ORACLE\PRODUCT\10.2.0\FLASH_RECOVERY_AREA\XHTEST\AUTOBACKUP\2009_11
_01\O1_MF_S_701796332_5GTFZF3F_.BKP comment=NONE
完成 Control File and SPFILE Autobackup 於 01-11月-09
SQL> col tablespace_name format a20
SQL> col file_name format a40
SQL> select tablespace_name,file_name from dba_data_files;
TABLESPACE_NAME FILE_NAME
-------------------- ----------------------------------------
USERS F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\
USERS01.DBF
SYSAUX F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\
SYSAUX01.DBF
UNDOTBS1 F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\
UNDOTBS01.DBF
SYSTEM F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\
SYSTEM01.DBF
TABLESPACE_NAME FILE_NAME
-------------------- ----------------------------------------
EXAMPLE F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\
EXAMPLE01.DBF
TEST E:\DATAFILE\TEST.DBF
SSS E:\DATAFILE\SSS.DBF
SS E:\DATAFILE\SS.DBF
MYT E:\DATAFILE\MYT.DBF
UNDO2 E:\DATAFILE\UNDO2.DBF
UNDOTBS2 E:\DATAFILE\UNDOTBS2.DBF
已選擇11行。
SQL>
SQL> select usn,writes,rssize,xacts from v$rollstat
2 ;
USN WRITES RSSIZE XACTS
---------- ---------- ---------- ----------
0 12184 385024 0
1 9280 6414336 0
2 402 5365760 0
3 2078 2416640 0
4 5860 253952 0
5 984 253952 0
6 1466 319488 0
7 2428 3268608 0
8 670 319488 0
9 5742 1171456 0
10 1406 2416640 0
已選擇11行。~~~沒有存在活動事務
SQL> shutdown immediate;
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE 例程已經關閉。
SQL> host del F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\UNDOTBS01.DBF
SQL> startup
ORA-32004: obsolete and/or deprecated parameter(s) specified
ORACLE 例程已經啟動。
Total System Global Area 289406976 bytes
Fixed Size 1248576 bytes
Variable Size 83886784 bytes
Database Buffers 197132288 bytes
Redo Buffers 7139328 bytes
資料庫裝載完畢。
ORA-01157: 無法標識/鎖定資料檔案 2 - 請參閱 DBWR 跟蹤檔案
ORA-01110: 資料檔案 2: 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\UNDOTBS01.DBF'
SQL> alter database datafile 2 offline;
資料庫已更改。
SQL> alter database open;
資料庫已更改。
RMAN> run{restore datafile 2;
2> recover datafile 2;}
啟動 restore 於 01-11月-09
使用目標資料庫控制檔案替代恢復目錄
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: sid=148 devtype=DISK
通道 ORA_DISK_1: 正在開始恢復資料檔案備份集
通道 ORA_DISK_1: 正在指定從備份集恢復的資料檔案
正將資料檔案00002恢復到F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\UNDOTBS01.DBF
通道 ORA_DISK_1: 正在讀取備份段 F:\ORACLE\PRODUCT\10.2.0\FLASH_RECOVERY_AREA\XHT
EST\BACKUPSET\2009_11_01\O1_MF_NNNDF_TAG20091101T152506_5GTFYNYR_.BKP
通道 ORA_DISK_1: 已恢復備份段 1
段控制程式碼 = F:\ORACLE\PRODUCT\10.2.0\FLASH_RECOVERY_AREA\XHTEST\BACKUPSET\2009_11_0
1\O1_MF_NNNDF_TAG20091101T152506_5GTFYNYR_.BKP 標記 = TAG20091101T152506
通道 ORA_DISK_1: 恢復完成, 用時: 00:00:26
完成 restore 於 01-11月-09
啟動 recover 於 01-11月-09
使用通道 ORA_DISK_1
正在開始介質的恢復
介質恢復完成, 用時: 00:00:01
完成 recover 於 01-11月-09
SQL> alter database datafile 2 online;
資料庫已更改。
另外 如果undo tablespace 沒有備份,但損壞時所有undo segment 中沒有活動事務那麼可以通過create 一個新的undo tablespace,修改undo_tablespace引數 既可
情況 2 不存在備份,或archive log 不全,且undo tablespace undo segment中存在活動事務
SQL> conn xh/a831115
已連線。
SQL> update t1 set a='bbbb';~~~未提交
已更新 1 行。
SQL> select segment_name,status,tablespace_name from dba_rollback_segs;
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- --------------------
SYSTEM ONLINE SYSTEM
_SYSSMU1$ ONLINE UNDOTBS1
_SYSSMU2$ OFFLINE UNDOTBS1
_SYSSMU3$ OFFLINE UNDOTBS1
_SYSSMU4$ OFFLINE UNDOTBS1
_SYSSMU5$ OFFLINE UNDOTBS1
_SYSSMU6$ OFFLINE UNDOTBS1
_SYSSMU7$ OFFLINE UNDOTBS1
_SYSSMU8$ OFFLINE UNDOTBS1
_SYSSMU9$ OFFLINE UNDOTBS1
_SYSSMU10$ OFFLINE UNDOTBS1
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- --------------------
_SYSSMU11$ OFFLINE UNDOTBS2
_SYSSMU12$ OFFLINE UNDOTBS2
_SYSSMU13$ OFFLINE UNDOTBS2
_SYSSMU14$ OFFLINE UNDOTBS2
_SYSSMU15$ OFFLINE UNDOTBS2
_SYSSMU16$ OFFLINE UNDOTBS2
_SYSSMU17$ OFFLINE UNDOTBS2
已選擇18行。
SQL> select usn,writes,rssize,xacts from v$rollstat;
USN WRITES RSSIZE XACTS
---------- ---------- ---------- ----------
0 26674 385024 0
1 382 6414336 1
SQL> conn / as sysdba
已連線。
SQL> shutdown abort
ORACLE 例程已經關閉。
SQL> host del F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\UNDOTBS01.DBF
SQL> startup
ORA-32004: obsolete and/or deprecated parameter(s) specified
ORACLE 例程已經啟動。
Total System Global Area 289406976 bytes
Fixed Size 1248576 bytes
Variable Size 83886784 bytes
Database Buffers 197132288 bytes
Redo Buffers 7139328 bytes
資料庫裝載完畢。
ORA-01157: 無法標識/鎖定資料檔案 2 - 請參閱 DBWR 跟蹤檔案
ORA-01110: 資料檔案 2: 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\UNDOTBS01.DBF'
SQL> alter database datafile 2 offline;
資料庫已更改。
SQL> alter database open;
資料庫已更改。
SQL> select usn,writes,rssize,xacts from v$rollstat;
USN WRITES RSSIZE XACTS
---------- ---------- ---------- ----------
0 4016 385024 0
SQL> select segment_name,status,tablespace_name from dba_rollback_segs;
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- --------------------
SYSTEM ONLINE SYSTEM
_SYSSMU1$ NEEDS RECOVERY UNDOTBS1*******
_SYSSMU2$ NEEDS RECOVERY UNDOTBS1*******
_SYSSMU3$ OFFLINE UNDOTBS1
_SYSSMU4$ OFFLINE UNDOTBS1
_SYSSMU5$ OFFLINE UNDOTBS1
_SYSSMU6$ OFFLINE UNDOTBS1
_SYSSMU7$ OFFLINE UNDOTBS1
_SYSSMU8$ OFFLINE UNDOTBS1
_SYSSMU9$ OFFLINE UNDOTBS1
_SYSSMU10$ OFFLINE UNDOTBS1
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- --------------------
_SYSSMU11$ OFFLINE UNDOTBS2
_SYSSMU12$ OFFLINE UNDOTBS2
_SYSSMU13$ OFFLINE UNDOTBS2
_SYSSMU14$ OFFLINE UNDOTBS2
_SYSSMU15$ OFFLINE UNDOTBS2
_SYSSMU16$ OFFLINE UNDOTBS2
_SYSSMU17$ OFFLINE UNDOTBS2
SQL> alter system set undo_tablespace='UNDOTBS2';
系統已更改。
SQL> select usn,writes,rssize,xacts from v$rollstat;
USN WRITES RSSIZE XACTS
---------- ---------- ---------- ----------
0 7572 385024 0
11 0 1105920 0
12 0 3399680 0
13 0 1433600 0
14 0 1564672 0
15 0 909312 0
16 0 1302528 0
17 0 581632 0
已選擇8行。
SQL> select segment_name,status,tablespace_name from dba_rollback_segs;
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- --------------------
SYSTEM ONLINE SYSTEM
_SYSSMU1$ NEEDS RECOVERY UNDOTBS1
_SYSSMU2$ NEEDS RECOVERY UNDOTBS1
_SYSSMU3$ OFFLINE UNDOTBS1
_SYSSMU4$ OFFLINE UNDOTBS1
_SYSSMU5$ OFFLINE UNDOTBS1
_SYSSMU6$ OFFLINE UNDOTBS1
_SYSSMU7$ OFFLINE UNDOTBS1
_SYSSMU8$ OFFLINE UNDOTBS1
_SYSSMU9$ OFFLINE UNDOTBS1
_SYSSMU10$ OFFLINE UNDOTBS1
SEGMENT_NAME STATUS TABLESPACE_NAME
------------------------------ ---------------- --------------------
_SYSSMU11$ ONLINE UNDOTBS2
_SYSSMU12$ ONLINE UNDOTBS2
_SYSSMU13$ ONLINE UNDOTBS2
_SYSSMU14$ ONLINE UNDOTBS2
_SYSSMU15$ ONLINE UNDOTBS2
_SYSSMU16$ ONLINE UNDOTBS2
_SYSSMU17$ ONLINE UNDOTBS2
已選擇18行。
SQL> update t2 set a=555;~~~其他操作可以 正常進行~~使用新的undo tablespace
已更新 1 行。
SQL> select usn,writes,rssize,xacts from v$rollstat;
USN WRITES RSSIZE XACTS
---------- ---------- ---------- ----------
0 9604 385024 0
11 11246 1105920 0
12 14362 3399680 1
13 110766 1630208 0
14 8316 1499136 0
15 15094 909312 0
16 53506 1236992 0
17 7964 581632 0
已選擇8行。
SQL> select * from xh.t1;
select * from xh.t1
*
第 1 行出現錯誤:
ORA-00376: 此時無法讀取檔案 2
ORA-01110: 資料檔案 2: 'F:\ORACLE\PRODUCT\10.2.0\ORADATA\XHTEST\UNDOTBS01.DBF'
此時 這個表經歷了instance recover 現在需要rollback階段,但使用的undo 資訊沒有了
SQL> drop tablespace undotbs1 including contents and datafiles;
drop tablespace undotbs1 including contents and datafiles
*
第 1 行出現錯誤:
ORA-01548: 已找到活動回退段 '_SYSSMU1$', 終止刪除表空間(且存在活動事務的話 ,不許刪除)
SQL> alter system set "_offline_rollback_segments"="_SYSSMU1$","_SYSSMU2$" scope
=spfile;
系統已更改。
SQL> alter system set undo_management='MANUAL' scope=spfile;
系統已更改。
SQL> startup force
ORA-32004: obsolete and/or deprecated parameter(s) specified
ORACLE 例程已經啟動。
Total System Global Area 289406976 bytes
Fixed Size 1248576 bytes
Variable Size 83886784 bytes
Database Buffers 197132288 bytes
Redo Buffers 7139328 bytes
資料庫裝載完畢。
資料庫已經開啟。
SQL> drop rollback segment "_SYSSMU1$";
回退段已刪除。
SQL> drop rollback segment "_SYSSMU2$";
回退段已刪除。
SQL> drop tablespace undotbs1 including contents and datafiles;
表空間已刪除。
SQL> select * from xh.t1;
A B
---------- ----------~~~~~~~~~~~
bbbb a
可以看到 未提交的事務 變成已經提交了,造成 資料不一致,主要是instanc recover時 先是前滾階段,應用所有redo,包括提交 未提交的,然後open後進行後滾,此時後滾需要的undo資訊沒了,所以 無法完成,資料不一致.
SQL> alter system set undo_management='AUTO' scope=spfile;
系統已更改。
另外 也可以用
_corrupted_rollback_segments這個隱藏引數,與上面過程是一樣的
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12020513/viewspace-617904/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle Redo and UndoOracle Redo
- Oracle從10g升級到11g詳細步驟Oracle
- Oracle 10g expdp attach引數體驗Oracle 10g
- oracle undo分配規則Oracle
- Oracle OCP(48):UNDO TABLESPACEOracle
- oracle的redo和undoOracle
- 19_深入解析Oracle undo原理(3)_ktuxe詳解OracleUX
- 20_深入解析Oracle undo原理(4)_ktuxc詳解OracleUX
- oracle 10g flashback databaseOracle 10gDatabase
- Oracle常見UNDO等待事件Oracle事件
- 關於oracle中的undoOracle
- 【REDO】Oracle redo undo 學習Oracle Redo
- 【SCN】Oracle SCN 詳細介紹Oracle
- Scheduler in Oracle Database 10g(轉)OracleDatabase
- Oracle 10g 下載地址Oracle 10g
- oracle 10G特性之awrOracle 10g
- Oracle 面試寶典-UNDO篇Oracle面試
- Oracle Partition 分割槽詳細總結Oracle
- oracle 大頁配置詳細介紹Oracle
- Oracle SCN機制詳細解讀Oracle
- Oracle實驗(04):floatOracle
- ISO 映象安裝oracle 10gOracle 10g
- Oracle 10g RAC故障處理Oracle 10g
- Oracle 10g 增刪節點Oracle 10g
- 驗證Oracle 10g線上整理碎片索引是否失效過程Oracle 10g索引
- 理論+實驗 詳解Oracle安裝部署過程Oracle
- Oracle 12c 新特性之臨時Undo--temp_undo_enabledOracle
- Oracle記憶體結構(二)----Shared Pool的詳細資訊(轉)Oracle記憶體
- Oracle記憶體結構(三)----Process Memory的詳細資訊(轉)Oracle記憶體
- 17_深入解析Oracle undo原理(1)_transactionOracle
- ORACLE線上切換undo表空間Oracle
- 【UNDO】Oracle系統回滾段說明Oracle
- 【BUILD_ORACLE】Oracle RAC配置ASM Filter Driver(ASMFD)(二)詳細配置步驟UIOracleASMFilter
- oracle rac監控oswatch詳細使用教學Oracle
- oracle 12c rac 詳細部署教程(二)Oracle
- Docker安裝Oracle 19c 詳細教程DockerOracle
- oracle 12c rac 詳細部署教程(一)Oracle
- Oracle實驗(01):字元 & 位元組Oracle字元
- Oracle實驗(03):number的使用Oracle