|
从9i开始,Oracle还提供了一种新的撤销数据(Undo Data)管理方式,就是使用Oracle自动管理的撤销(Undo)表空间(Automatic Undo Management,通常被缩写为AUM)。
(1)检查empno=7788记录在Buffer Cache中是否存在,如果不存在则读取到Buffer Cahce中;
(2)在回滚表空间的相应回滚段事务表上分配事务槽,这个操作需要记录Redo信息;
(3)从回滚段读入或都在Buffer Cache中创建sal = 3000的前镜像,这需要产生Redo信息并记入Redo Log Buffer;
(4)修改Sal = 4000,这是update的数据变更,需要记入Redo Log Buffer;
(5)当用户提交时,会在Redo Log Buffer记录提交信息,并在回滚段标记该事务为非激活(INACTIVE)。
如果用户回滚(Rollback)事务,则Oracle需要从回滚空间中把前镜像数据读取出来,修改数据缓冲区,完成回滚,这个过程本身也要产生Redo,所以回退这个操作是很昂贵的。
在性能优化中,有一个性能指标称为平均事务回滚率(Rollback per Transaction),用来衡量数据库的提交与回滚效率。
对于insert操作,回滚段只需要记录插入记录的rowid,如果回退,只需将该记录根据rowid删除即可;对于update操作,回滚段只需要记录被更新字段的旧值即可(前镜像),回退时通过旧值即可(前镜像),回退时通过旧值覆盖新值即可完成回滚;对于delete操作,Oracle则必须记录整行的数据,在回滚时,Oracle通过一个反向操作恢复删除的数据。
对于相同数据量的数据操作,通常insert产生最少的Undo,update产生的Undo居中,而delete操作产生的Undo最多。 这也就是我们经常看到的,当一个大的Delete操作失败或都回滚,总是需要很长的时间,并且会有大量的Redo生成。
回滚段在Undo表空间分配,其数据在Buffer Cache内存中的管理方式与用户数据一致,同样按照相同的规则写出到Undo表空间的数据文件上。Undo表空间中的存储空间同样按照Segment来分配和使用。回滚段的作用除了回退事务外,还要参与事务恢复,以及提供读一致性。
并发控制和一致性读
一方面Oracle通过锁定机制实现数据库的并发控制,别一方面通过多版本(Multi-versioning Model)模型来进行并发数据访问。
通过多版本架构,Oracle实现了读取和写入的分离,使用得写入不阻塞读取;读取不阻塞修改。这是Oracle数据库区别于其他数据库的一个重要特征。多版本模型在Oracle数据中是通过一致性读来实现的,一致性读也正是回滚表空间的主要作用之一。
回滚段的前世今生
在Oracle 9i之前,回滚表空间创建之后,Oracle随后创建回滚段供数据库使用,
可以通过如下命令指定使用特定的回滚段:
set transaction use rollback segment <rollback_segment_name>;
在11g中Undo段的命名规则有了进一步变化,现在将回滚段的创建时间戳包含在回滚段名称中。
SYS@ orcl> select segment_name, tablespace_name, status from dba_rollback_segs;
SEGMENT_NAME TABLESPACE_NAME STATUS
------------------------- ------------------------------ ----------------
SYSTEM SYSTEM ONLINE
_SYSSMU10_4131489474$ UNDOTBS1 ONLINE
_SYSSMU9_1735643689$ UNDOTBS1 ONLINE
_SYSSMU8_3901294357$ UNDOTBS1 ONLINE
_SYSSMU7_3517345427$ UNDOTBS1 ONLINE
_SYSSMU6_2897970769$ UNDOTBS1 ONLINE
_SYSSMU5_538557934$ UNDOTBS1 ONLINE
_SYSSMU4_1003442803$ UNDOTBS1 ONLINE
_SYSSMU3_1204390606$ UNDOTBS1 ONLINE
_SYSSMU2_967517682$ UNDOTBS1 ONLINE
_SYSSMU1_592353410$ UNDOTBS1 ONLINE
从Oracle 9i开始,Oracle引入了自动管理的Undo表空间,如果选择使用自动的Undo表空间管理,那么用户不再能够创建或删除回滚段,也不再需要为事务指写回滚段,这一切由Oracle自动进行。
SYS@ orcl> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string undotbs1
在自动管理的Undo表空间下,回滚段的个数是Oracle根据数据库的繁忙程度自动分配或都回收的,数据库创建时缺省初始化10个回滚段。
SYS@ orcl> select * from v$rollname;
USN NAME
---------- ------------------------------
0 SYSTEM
1 _SYSSMU1_592353410$
2 _SYSSMU2_967517682$
3 _SYSSMU3_1204390606$
4 _SYSSMU4_1003442803$
5 _SYSSMU5_538557934$
6 _SYSSMU6_2897970769$
7 _SYSSMU7_3517345427$
8 _SYSSMU8_3901294357$
9 _SYSSMU9_1735643689$
10 _SYSSMU10_4131489474$
在系统繁忙时,可以从数据库的告警日志文件中看到回滚段的动态创建和释放过程
Created Undo Segment _SYSSMU11$
SMON offlining US=11
## 原有Undo表空间的回滚段会逐渐离线,新的表空间Undo段顺序创建
SQL> crreate undo tablespace undotbs2 datafile size 500M
SQL> alter system set undo_tablespace='UNDOTBS2';
Oracle 10g的UNDO_RETENTION管理增强
在AUM模式下,UNDO_RETENTION,默认是一个NO Guaranteed的限制。
从Oracle 10g开始,如果设置undo_retention为0,那么Oracle启用自动调整以满足最长运行查询的需要。
这个特性的引入伴随着几个新的隐含初始化参数:
SYS@ orcl> @GetHidPar
Enter value for par: undo_autotune
NAME VALUE PDESC
------------------------------ --------------- --------------------------------------------------
_undo_autotune TRUE enable auto tuning of undo_retention
SYS@ orcl> @GetHidPar
Enter value for par: collect_undo_stats
NAME VALUE PDESC
------------------------------ --------------- --------------------------------------------------
_collect_undo_stats TRUE Collect Statistics v$undostat
alter tablespace undotbs1 retention guarantee|noguarantee;
SYS@ orcl> select tablespace_name, contents, retention from dba_tablespaces;
TABLESPACE_NAME CONTENTS RETENTION
------------------------------ --------- -----------
SYSTEM PERMANENT NOT APPLY
SYSAUX PERMANENT NOT APPLY
UNDOTBS1 UNDO NOGUARANTEE
TEMP TEMPORARY NOT APPLY
USERS PERMANENT NOT APPLY
在数据文件autoextend off时,设置guarantee时当空间不足时会出现ORA-30036错误,在noguarantee时不会出现错误,这就是GUARANTEE与NOGUARANTEE的不同。
SYS@ orcl> alter database datafile '/oradata/orcl/undotbs01.dbf' autoextend on;
Database altered.
UNDO_RETENTION的内部实现
Oracle在Undo Segment Header上创建了一个Retention Table用于记录相关Undo存储的提交时间,从而实现其保留策略。
SYS@ orcl> delete from t1 where rownum < 3;
2 rows deleted.
SYS@ orcl> select a.usn, a.xacts, b.name from v$rollstat a, v$rollname b where a.usn = b.usn and xacts > 0;
USN XACTS NAME
---------- ---------- ------------------------------
5 1 _SYSSMU5_538557934$
[oracle@rhel5 trace]$ ls -sort | tail -4
4 -rw-r----- 1 oracle 922 Feb 28 16:33 orcl_ckpt_2400.trc
328 -rw-r----- 1 oracle 328236 Feb 28 17:04 alert_orcl.log
4 -rw-r----- 1 oracle 557 Feb 28 17:14 orcl_ora_2459.trm
168 -rw-r----- 1 oracle 163877 Feb 28 17:14 orcl_ora_2459.trc
## undo 数据文件头中的保留表中的数据
Retention Table
-----------------------------------------------------------
Extent Number:0 Commit Time: 1361674810
Extent Number:1 Commit Time: 1361674810
Extent Number:2 Commit Time: 1361683109
Extent Number:3 Commit Time: 1361848168
Extent Number:4 Commit Time: 1361848168
10g In Memory Undo新特性
数据库会在(Shared Pool)开辟独立的内存区域用于存储Undo信息,这样就可避免Undo信息以前在Buffer Cache中的读写操作。IMU中数据通过暂存、整理与收缩之后也可以写出到回滚段,这样的写出提供了有序、批量写的性能提升。
IMU机制与PVRS紧密相关,由于每个IMU Buffer的大小在64~128KB左右,所以仅有特定的小事务可以使用,每个事务会绑定到一个独立空闲的IMU Buffer,同时相关的Redo信息会写入PVRS中,同样每一个IMU Buffer会由一个独立的In Memeory Undo Latch保护,不IMU Buffer或PRVS写满之后,数据库需要写出IMU中的信息。
## 用于控制IMU是否启动的参数
SYS@ orcl> @GetHidPar
Enter value for par: in_memory_undo
NAME VALUE PDESC
------------------------------ --------------- --------------------------------------------------
_in_memory_undo TRUE Make in memory undo for top level transactions
## 系统当前分配的IMU内存
SYS@ orcl> select * from v$sgastat where name = 'KTI-UNDO';
POOL NAME BYTES
------------ ------------------------------ ----------
shared pool KTI-UNDO 2402120
## In Memory Undo池缺少会分配3个,用以提供更好的并发
NAME VALUE PDESC
------------------------------ --------------- --------------------------------------------------
_imu_pools 3 in memory undo pools
## IMU的使用信息
SYS@ orcl> select name, value from v$sysstat where name like '%commits%';
NAME VALUE
------------------------------ -------------
user commits 281
IMU commits 251
SYS@ orcl> select name, gets, misses, immediate_gets, sleeps from v$latch where name like '%undo latch';
NAME GETS MISSES IMMEDIATE_GETS SLEEPS
------------------------------ ---------- ---------- -------------- ----------
In memory undo latch 4887 0 1728 0
Oracle 11g UNDO表空间备份增强
在Oracle 11g中,引入了一个特性RMAN UNDO备份优化。在RMAN备份UNDO表空间时,提交事务的UNDO信息将不再备份,这个特性随RMAN强制启用,有可能一个数据GB的UNDO表空间备份文件的大小公为数百KB。
回滚机制的深入研究
SCOTT@ orcl> select * from emp where empno = 7788;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7788 SCOTT ANALYST 7566 19-APR-87 3000 20
SCOTT@ orcl> update emp set sal = 4000 where empno = 7788;
1 row updated.
SCOTT@ orcl> select * from emp where empno = 7788;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
7788 SCOTT ANALYST 7566 19-APR-87 4000 20
获得事务信息
SYS@ orcl> select xidusn, xidslot, xidsqn, ubafil, ubablk, ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBAREC
---------- ---------- ---------- ---------- ---------- ----------
1 8 668 3 3347 47
SYS@ orcl> select usn, writes, rssize, xacts, hwmsize, wraps from v$rollstat;
USN WRITES RSSIZE XACTS HWMSIZE WRAPS
---------- ---------- ---------- ---------- ---------- ----------
0 8112 385024 0 385024 0
1 171082 1826816 1 1826816 0
2 169458 3268608 0 3268608 0
3 174338 2088960 0 2088960 0
4 152950 2220032 0 2220032 0
5 72022 3268608 0 3268608 0
6 554380 3268608 0 3268608 3
7 577004 3268608 0 3268608 1
8 259354 3268608 0 3268608 0
9 245616 385024 0 385024 5
10 83870 4317184 0 4317184 0
获得回滚段名称并转储段头信息
SCOTT@ orcl> select * from v$rollname where usn = 1;
USN NAME
---------- ------------------------------
1 _SYSSMU1_592353410$
SYS@ orcl> alter system dump undo header '_SYSSMU1_592353410$';
System altered.
-======================
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2602.trc
-======================
获得跟踪文件信息
********************************************************************************
Undo Segment: _SYSSMU1_592353410$ (1)
********************************************************************************
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 13 #blocks: 223
last map 0x00000000 #maps: 0 offset: 4080
Highwater:: 0x00c00d1d ext#: 12 blk#: 29 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 12
Unlocked
Map Header:: next 0x00000000 #extents: 13 obj#: 0 flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x00c00081 length: 7
0x00c00158 length: 8
0x00c00178 length: 8
0x00c000e8 length: 8
0x00c001d8 length: 8
0x00c001e0 length: 8
0x00c00088 length: 8
0x00c000c8 length: 8
0x00c00118 length: 8
0x00c00120 length: 8
0x00c00140 length: 8
0x00c00148 length: 8
0x00c00d00 length: 128
Retention Table
-----------------------------------------------------------
Extent Number:0 Commit Time: 1362128417
Extent Number:1 Commit Time: 1362149020
Extent Number:2 Commit Time: 1362149041
Extent Number:3 Commit Time: 1362149042
Extent Number:4 Commit Time: 1362149046
Extent Number:5 Commit Time: 1362149056
Extent Number:6 Commit Time: 1362149058
Extent Number:7 Commit Time: 1362149061
Extent Number:8 Commit Time: 1362149890
Extent Number:9 Commit Time: 1362150786
Extent Number:10 Commit Time: 1362150786
Extent Number:11 Commit Time: 1362150786
Extent Number:12 Commit Time: 1362150786
TRN CTL:: seq: 0x01ea chd: 0x0003 ctl: 0x0019 inc: 0x00000000 nfb: 0x0001
mgc: 0xb000 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
uba: 0x00c00d13.01ea.2f scn: 0x0000.001a9906
Version: 0x01
FREE BLOCK POOL::
uba: 0x00000000.01ea.2e ext: 0xc spc: 0x21e
uba: 0x00000000.01ea.03 ext: 0xc spc: 0x1eac
uba: 0x00c00d1d.01ea.08 ext: 0xc spc: 0x1ba6
uba: 0x00000000.00db.3f ext: 0x7 spc: 0x8cc
uba: 0x00000000.0000.00 ext: 0x0 spc: 0x0
TRN TBL::
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x00 9 0x00 0x029c 0x000e 0x0000.001a9bef 0x00c00d13 0x0000.000.00000000 0x00000001 0x00000000 1362187705
0x01 9 0x00 0x029c 0x0005 0x0000.001a99a4 0x00c00d0c 0x0000.000.00000000 0x00000001 0x00000000 1362187690
0x02 9 0x00 0x029c 0x000d 0x0000.001a9ad1 0x00c00d12 0x0000.000.00000000 0x00000001 0x00000000 1362187700
0x03 9 0x00 0x029a 0x0021 0x0000.001a991f 0x00c00d09 0x0000.000.00000000 0x00000001 0x00000000 1362187686
0x04 9 0x00 0x029b 0x0011 0x0000.001a9974 0x00c00d10 0x0000.000.00000000 0x00000006 0x00000000 1362187689
0x05 9 0x00 0x029c 0x0013 0x0000.001a99c2 0x00c00d0c 0x0000.000.00000000 0x00000001 0x00000000 1362187692
0x06 9 0x00 0x029c 0x0002 0x0000.001a9ab9 0x00c00d12 0x0000.000.00000000 0x00000001 0x00000000 1362187700
0x07 9 0x00 0x029c 0x0014 0x0000.001a9a1d 0x00c00d13 0x0000.000.00000000 0x00000003 0x00000000 1362187696
0x08 10 0x80 0x029c 0x000c 0x0000.001a988d 0x00c00d13 0x0000.000.00000000 0x00000001 0x00000000 0
0x09 9 0x00 0x029c 0x0018 0x0000.001a9a6a 0x00c00d12 0x0000.000.00000000 0x00000001 0x00000000 1362187698
......
index为数据槽号,state 为10代表的是活动事务
转储前镜像信息
DBA,这个DBA指向的就是包含这个事务的前镜像的数据块地址0x00c00d13,前10位代表文件号,后22位代表数据块。
00000000110000000000110100010011,文件号为3数据块为3347。这从事务表中查询得到的数据完全一致。
SYS@ orcl> select xidusn, xidslot, xidsqn, ubafil, ubablk, ubarec from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBAREC
---------- ---------- ---------- ---------- ---------- ----------
1 8 668 3 3347 47
SYS@ orcl> alter system dump datafile 3 block 3347;
System altered.
-======================
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_5109.trc
-======================
Start dump data blocks tsn: 2 file#:3 minblk 3347 maxblk 3347
Block dump from cache:
Dump of buffer cache at level 4 for tsn=2, rdba=12586259
BH (0x423e81c4) file#: 3 rdba: 0x00c00d13 (3/3347) class: 18 ba: 0x420ee000
set: 3 pool 3 bsz: 8192 bsi: 0 sflg: 2 pwc: 484,28
dbwrid: 0 obj: -1 objn: 0 tsn: 2 afn: 3 hint: f
hash: [0x515b96d0,0x515b96d0] lru: [0x423e8344,0x423e819c]
ckptq: [NULL] fileq: [NULL] objq: [0x3f3f1798,0x3f3f16c4]
st: XCURRENT md: NULL tch: 9
flags: block_written_once redo_since_read
LRBA: [0x0.0.0] LSCN: [0x0.0] HSCN: [0xffff.ffffffff] HSUB: [1]
cr pin refcnt: 0 sh pin refcnt: 0
Block dump from disk:
buffer tsn: 2 rdba: 0x00c00d13 (3/3347)
scn: 0x0000.001aa1c5 seq: 0x01 flg: 0x04 tail: 0xa1c50201
frmt: 0x02 chkval: 0x6573 type: 0x02=KTU UNDO BLOCK
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x00792600 to 0x00794600
792600 0000A202 00C00D13 001AA1C5 04010000 [................]
......
********************************************************************************
UNDO BLK:
xid: 0x0001.008.0000029c seq: 0x1ea cnt: 0x32 irb: 0x32 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f70 0x02 0x1f18 0x03 0x1ec4 0x04 0x1e3c 0x05 0x1dd0
0x06 0x1d64 0x07 0x1bdc 0x08 0x1ab4 0x09 0x19b8 0x0a 0x1930
0x0b 0x18c8 0x0c 0x185c 0x0d 0x1764 0x0e 0x16c4 0x0f 0x1654
0x10 0x15f4 0x11 0x156c 0x12 0x1500 0x13 0x1494 0x14 0x130c
0x15 0x11e4 0x16 0x10e8 0x17 0x1060 0x18 0x0ff4 0x19 0x0f88
0x1a 0x0e90 0x1b 0x0df0 0x1c 0x0d80 0x1d 0x0d20 0x1e 0x0c98
0x1f 0x0c2c 0x20 0x0bc0 0x21 0x0a38 0x22 0x0910 0x23 0x0814
0x24 0x078c 0x25 0x0720 0x26 0x06b4 0x27 0x05bc 0x28 0x051c
0x29 0x04ac 0x2a 0x044c 0x2b 0x03fc 0x2c 0x035c 0x2d 0x02ec
0x2e 0x028c 0x2f 0x01f0 0x30 0x0198 0x31 0x013c 0x32 0x00e0
注意这里的irb: 0x32,irb指的是回滚段中记录的最近未提交变更开始之处,如果开始回滚,这是起始的搜索点。
## 从接下来的信息中找到0x32
*-----------------------------
* Rec #0x32 slt: 0x08 objn: 73181(0x00011ddd) objd: 73181 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x31
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
compat bit: 4 (post-11) padding: 1
op: C uba: 0x00c00d13.01ea.31
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x01000097 hdba: 0x01000092
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 5(0x5) flag: 0x2c lock: 0 ckix: 191
ncol: 8 nnew: 1 size: 1
col 5: [ 3] c2 1d 33
c2 1d 33转换为十进制就是2850。这正好对应了最后更新记录的前镜像。
update emp set sal = 4000 where empno = 7698;
rci 0x31代表的就是UNDO Chain(同一事务中的多次修改,根据Chain链接关联)的下一个偏移量,此处为Ox31。
*-----------------------------
* Rec #0x31 slt: 0x08 objn: 73181(0x00011ddd) objd: 73181 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x30
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
compat bit: 4 (post-11) padding: 1
op: C uba: 0x00c00d13.01ea.30
KDO Op code: URP row dependencies Disabled
xtype: XA flags: 0x00000000 bdba: 0x01000097 hdba: 0x01000092
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 6(0x6) flag: 0x2c lock: 0 ckix: 191
ncol: 8 nnew: 1 size: 1
col 5: [ 3] c2 19 33
c2 19 33为2450,是第二条更新的数据
update emp set sal = 4000 where empno = 7782;
*-----------------------------
* Rec #0x30 slt: 0x08 objn: 73181(0x00011ddd) objd: 73181 tblspc: 4(0x00000004)
* Layer: 11 (Row) opc: 1 rci 0x2f
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
compat bit: 4 (post-11) padding: 1
op: C uba: 0x00c00d13.01ea.2f
KDO Op code: URP row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01000097 hdba: 0x01000092
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 7(0x7) flag: 0x2c lock: 2 ckix: 77
ncol: 8 nnew: 1 size: 0
Vector content:
col 5: [ 2] c2 29
4000,更新为原记录相同的值也会被记录
update emp set sal = 4000 where empno = 7788;
*-----------------------------
* Rec #0x2f slt: 0x08 objn: 73181(0x00011ddd) objd: 73181 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: 0x00000000Ext idx: 0
flg2: 0
*-----------------------------
uba: 0x00c00d13.01ea.2c ctl max scn: 0x0000.001a98dd prv tx scn: 0x0000.001a9906
txn start scn: scn: 0x0000.001a9487 logon user: 84
prev brb: 12586249 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x04 ver: 0x01
compat bit: 4 (post-11) padding: 1
op: L itl: xid: 0x0003.01e.0000033c uba: 0x00c000fb.01d7.03
flg: C--- lkc: 0 scn: 0x0000.0017ef1e
KDO Op code: URP row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01000097 hdba: 0x01000092
itli: 2 ispac: 0 maxfr: 4858
tabn: 0 slot: 7(0x7) flag: 0x2c lock: 0 ckix: 191
ncol: 8 nnew: 1 size: 0
Vector content:
col 5: [ 2] c2 1f
3000,正是每一条更新的记录,所以其Undo Chain的指针为0x00,表示这是最后一条记录。
update emp set sal = 4000 where empno = 7788;
也可以从x$bh中找到这些数据块:
SYS@ orcl> select b.segment_name, a.file#, a.dbarfil, a.dbablk, a.class, a.state
2 from x$bh a, dba_extents b where a.dbarfil = b.relative_fno
3 and b.owner = 'SCOTT' and b.segment_name = 'EMP'
4 and a.dbablk >= b.block_id and a.dbablk < b.block_id + b.blocks;
SEGMENT_NAME FILE# DBARFIL DBABLK CLASS STATE
--------------- ---------- ---------- ---------- ---------- ----------
EMP 4 4 151 1 1
EMP 4 4 151 1 3
EMP 4 4 146 4 3
EMP 4 4 146 4 3
EMP 4 4 146 4 3
class为4的代表的是段头,class为1,块号为151的为数据块,state为3的代表通过一致性读构造出来的
SYS@ orcl> select b.segment_name, a.file#, a.dbarfil, a.dbablk, a.class, a.state,
2 decode(bitand(flag, 1), 0, 'N', 'Y') dirty
3 from x$bh a, dba_extents b where a.dbarfil = b.relative_fno
4 and b.owner = 'SCOTT' and b.segment_name = 'EMP'
5 and a.dbablk >= b.block_id and a.dbablk < b.block_id + b.blocks;
SEGMENT_NAME FILE# DBARFIL DBABLK CLASS STATE D
--------------- ---------- ---------- ---------- ---------- ---------- -
EMP 4 4 147 1 1 N
EMP 4 4 150 1 1 N
EMP 4 4 148 1 1 N
EMP 4 4 151 1 1 Y
EMP 4 4 151 1 3 N
EMP 4 4 146 4 3 N
EMP 4 4 146 4 3 N
EMP 4 4 146 4 3 N
EMP 4 4 146 4 3 N
EMP 4 4 146 4 1 N
EMP 4 4 149 1 1 N
转储数据块信息
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01000097 hdba: 0x01000092
0000 0001 0000 0000 0000 0000 1001 0111
4 151
SYS@ orcl> alter system dump datafile 4 block 151;
System altered.
/u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_6466.trc
Block header dump: 0x01000097
Object id on Block? Y
seg/obj: 0x11ddd csc: 0x00.1aa479 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1000090 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0008.013.00000403 0x00c008d7.01cd.27 C--- 0 scn 0x0000.0017ff06
0x02 0x0001.008.0000029c 0x00c000fb.01ea.32 --- 3 scn 0x0000.0017ef1e
bdba: 0x01000097
tab 0, row 5, @0x1ce8
tl: 41 fb: --H-FL-- lb: 0x02 cc: 8
col 0: [ 3] c2 4d 63
col 1: [ 5] 42 4c 41 4b 45
col 2: [ 7] 4d 41 4e 41 47 45 52
col 3: [ 3] c2 4f 28
col 4: [ 7] 77 b5 05 01 01 01 01
col 5: [ 3] c2 1d 33
col 6: *NULL*
col 7: [ 2] c1 1f
tab 0, row 6, @0x1cbf
tl: 41 fb: --H-FL-- lb: 0x02 cc: 8
col 0: [ 3] c2 4e 53
col 1: [ 5] 43 4c 41 52 4b
col 2: [ 7] 4d 41 4e 41 47 45 52
col 3: [ 3] c2 4f 28
col 4: [ 7] 77 b5 06 09 01 01 01
col 5: [ 3] c2 19 33
col 6: *NULL*
col 7: [ 2] c1 0b
tab 0, row 7, @0x1e4c
tl: 40 fb: --H-FL-- lb: 0x02 cc: 8
col 0: [ 3] c2 4e 59
col 1: [ 5] 53 43 4f 54 54
col 2: [ 7] 41 4e 41 4c 59 53 54
col 3: [ 3] c2 4c 43
col 4: [ 7] 77 bb 04 13 01 01 01
col 5: [ 2] c2 1f
col 6: *NULL*
col 7: [ 2] c1 15
ITL内容主要包括Xid,Uba,Lck
Xid = Undo.Segment.Number + Transaction.Table.Slot.Number + Wrap
8 19 1027
数据块上同样存在指向回滚段的事务信息,0x00c000fb.01ea.32代表文件0x00c000fb,seq:01ea,32为irb信息。
********************************************************************************
UNDO BLK:
xid: 0x0001.008.0000029c seq: 0x1ea cnt: 0x32 irb: 0x32 icl: 0x32 flg: 0x0000
(1)首先当一个事务开始时,需要在回滚段事务表上分配一个事务槽。
(2)在数据块头部获取一个ITL事务槽,该事务槽指向回滚段头的事务槽
(3)在修改数据之前,需要记录前镜像信息,这个信息以UNDO RECORD的形式存储在回滚段中,回滚段头事务槽指向该记录。
(4)锁定修改行,修改行锁定位(lb-lock byte)指向ITL事务槽。
(5)数据修改可以进行。
-- to be continue --
|
|