开篇我们先用一个实验引出事务:
sys@ORCL> select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction;
no rows selected
没找到相应的事务信息,用hr发起一条事务:
hr@ORCL> select * from p;
ID TEST
---------- -----
2 f
3 g
1 a
hr@ORCL> update p set test='w' where id=1;
1 row updated.
再次查看事务信息:
sys@ORCL> /
XID XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL
---------------- ---------- ---------- ---------- ---------- ----------
02000800E2010000 2 8 482 3339 2
查看hr发起事务所对应的回滚段:
sys@ORCL> select xidusn,sid,username from v$transaction t,v$session s where t.ses_addr=s.saddr;
XIDUSN SID USERNAME
---------- ---------- ------------------------------
2 141 HR
9 158 SCOTT
查看2号回滚段的段名:
sys@ORCL> select * from v$rollname;
USN NAME
---------- ------------------------------
0 SYSTEM
1 _SYSSMU1$
2 _SYSSMU2$
3 _SYSSMU3$
4 _SYSSMU4$
5 _SYSSMU5$
6 _SYSSMU6$
7 _SYSSMU7$
8 _SYSSMU8$
9 _SYSSMU9$
10 _SYSSMU10$
11 rows selected.
然后把2号回滚段的段头dump出来,到udump目录下去找:
sys@ORCL> select header_block,header_file from dba_segments where segment_name='_SYSSMU2$';
HEADER_BLOCK HEADER_FILE
------------ -----------
41 2
sys@ORCL> alter system dump undo header '_SYSSMU2$';
System altered.
查看当前会话的server process的进程编号:
sys@ORCL> select spid from v$process where addr in (select paddr from v$session where sid=(select sid from v$mystat where rownum=1));
SPID
------------
5446
2号undo段头部dump出来的部分内容如下:
Version: 0x01
FREE BLOCK POOL::
uba: 0x00800017.027b.0b ext: 0x2 spc: 0x19d8
uba: 0x00000000.027b.02 ext: 0x2 spc: 0x1f06
uba: 0x00000000.0278.1f ext: 0x10 spc: 0xf54
uba: 0x00000000.0000.00 ext: 0x0 spc: 0x0
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 0x01e8 0x001d 0x0000.0014d967 0x00800016 0x0000.000.00000000 0x00000001 0x00000000 1343716115
0x01 9 0x00 0x01e9 0x002d 0x0000.0014db8f 0x00800017 0x0000.000.00000000 0x00000001 0x00000000 1343717092
0x02 9 0x00 0x01e8 0x0009 0x0000.0014d4b9 0x00800012 0x0000.000.00000000 0x00000001 0x00000000 13437138
这里面有个很重要的概念叫:xid
xid是事务的编号,也是地址,它由三部分组成:
1)使用哪个undo segment header(块号)
2)使用undo segment header里面的事务表的哪一行(行号)
3)是第几次被覆盖(覆盖的次数)
一个事务开始时,会在两个位置,做两件事:
a)在相对空闲的回滚段的段头的事务表(最多47行)标注事务信息,其中包括了xid,uba;并且分配回滚块
b)把要修改的数据块的块头的事务槽(最多255个槽位)上标注事务信息,其中包含了xid,uba
整个过程有四个地方发生了变化:undo segment header,回滚块,数据块的块头,数据块。这四个地方的变化都得到了redo的保护。