Oracle Xid UBA

在 Oracle 数据库中,XIDUBA 是事务(Transaction)与回滚(Undo)机制中非常核心的两个概念,通常出现在 块头(block header)数据块转储(block dump) 的信息中。它们是 Oracle 用于追踪和恢复事务一致性的重要内部标识。下面详细解释两者的含义、结构、作用以及它们之间的关系。

block header

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0x0002.00e.0000039b  0x01000e57.00d8.22  C---    0  scn  0x0000000000225c39
0x02   0x0006.00a.0000039f  0x0100044d.00ca.36  ----    1  fsc 0x0001.00000000

undo transaction table

index  state cflags  wrap#    uel         scn            dba            parent-xid    nub     stmt_num    cmt
  ------------------------------------------------------------------------------------------------
   0x00    9    0x00  0x19da  0x0002  0x0000.041e0dbf  0x0140e83e  0x0000.000.00000000  0x00000001   0x00000000  1714104309
   0x01    9    0x00  0x19d9  0x0008  0x0000.041deb1c  0x0140e83a  0x0000.000.00000000  0x00000001   0x00000000  1714103997
   0x02    9    0x00  0x19db  0x0007  0x0000.041e1333  0x0140e83e  0x0000.000.00000000  0x00000001   0x00000000  1714104311
   0x03    9    0x00  0x19c4  0x0020  0x0000.041d9475  0x0140e839  0x0000.000.00000000  0x00000001   0x00000000  1714103733
   0x04    9    0x00  0x19d8  0x000b  0x0000.041d93ff  0x0140e839  0x0000.000.00000000  0x00000001   0x00000000  1714103733

UBA转换

uba: 0x0100044d.00ca.36

with v as (select REPLACEREGEXP_REPLACE ('&uba','0x','',1,1) uba from dual)
select
  v.uba,
  dbms_utility.data_block_address_file(TO_NUMBER(substr(v.uba, 1, instr(v.uba, '.') - 1), 'XXXXXXXX')) file#,
  dbms_utility.data_block_address_block(TO_NUMBER(substr(v.uba, 1, instr(v.uba, '.') - 1), 'XXXXXXXX')) blk#,
  to_number(substr(v.uba,instr(v.uba, '.') + 1,(instr(v.uba, '.', 1, 2) - instr(v.uba, '.') - 1)),'xxxxxxxx') seq#,
  to_number(substr(v.uba, instr(v.uba, '.', 1, 2) + 1), 'xxxxxxxxxx') rec#
 from v;
 

UBA                   FILE#       BLK#       SEQ#       REC#
---------------- ---------- ---------- ---------- ----------
0100044d.00ca.36          4       1101        202         54

XID 转换

xid:  0x0006.00a.0000039f

with v as(select REGEXP_REPLACE ('&id','0x','',1,1) xid from dual)
select
  v.xid,
  to_number(substr(v.xid,1,instr(v.xid,'.')-1),'xxxx') usn#,
  to_number(substr(v.xid,instr(v.xid,'.')+1,(instr(v.xid,'.',1,2)-instr(v.xid,'.')-1)) , 'xxxx') slot#,
  to_number(substr(v.xid,instr(v.xid,'.',1,2)+1) ,'xxxxxxxxxx') seq#
 from v;
 

XID                     USN#      SLOT#       SEQ#
----------------- ---------- ---------- ----------
0006.00a.0000039f          6         10        927

v$transaction

select xidusn,xidslot,xidsqn,ubafil,ubablk,ubasqn,ubarec from v$transaction;		 


    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC
---------- ---------- ---------- ---------- ---------- ---------- ----------
         6         10        927          4       1101        202         54

XID

XID 是 Oracle 数据库中用于唯一标识一个事务的内部标识符(Transaction ID)。在数据库中,每一个事务都有唯一的 XID。

XID 有undo semgment number,slot, seq(又称 wrap#)组成

Undo.Segment.Number+Transaction.Table.Slot.Number+Wrap
字段名称含义
Undo Segment Number (usn)回滚段编号指明该事务使用的 Undo 段是哪一个
Slot (slot)槽号指明事务在 Undo 段事务表中的位置
Sequence (wrap)序列号用于区分同一个 slot 被重复使用的不同事务

Oracle 在一致性读(consistent read)时,根据 XID 查找对应的 Undo 信息。transaction table的 slot(对应index)和seq(对应wrap#).

UBA(Undo Block Address)

UBA 指向一条 Undo 记录(undo record)的具体位置。
Oracle 在数据块的行头(row header)或事务表中保存 UBA,用于回溯该行被修改前的旧值。

数据块中的uba在构造CR块时使用;而事务表中的uba在rollback时使用

事务表中的UBA : 0x00800261.01a1.27 由三部分组成:

1)0x00800261是真正的uba地址; 可以转换出undo 文件号和块号

2)01a1是XIDSQN;

3)27表示是undo记录中的第0x27条记录;dump UBA undo block的 Rec #0x27

Address.Of.Last.Undo.Block.Used(undo block address block_no , undo block address file_no组成)+Sequence+Last.Entry.in.UNDO.Record.Map

UBA(回滚段地址)表示该事务在undo块上被应用的最后一条undo的地址,或者是数据块要回滚的起点

SYS@orcl11g SQL> @dba 100044d

    RFILE#     BLOCK# BIGFILE_BLOCK# DUMP_CMD
---------- ---------- -------------- ---------------------------------------------------------------------------------------------------------------------
         4       1101       16778317 -- alter system dump datafile 4 block 1101

dump undo

UNDO BLK:
 xid: 0x0006.00a.0000039f  seq: 0xca  cnt: 0x36  irb: 0x36  icl: 0x0   flg: 0x0000

 Rec Offset      Rec Offset      Rec Offset      Rec Offset      Rec Offset
---------------------------------------------------------------------------
0x01 0x1f98     0x02 0x1f18     0x03 0x1ea8     0x04 0x1e34     0x05 0x1d88
0x06 0x1ce8     0x07 0x1c60     0x08 0x1bdc     0x09 0x1b88     0x0a 0x1b10
0x0b 0x1a88     0x0c 0x1a04     0x0d 0x19b0     0x0e 0x1938     0x0f 0x18b0
0x10 0x182c     0x11 0x17d8     0x12 0x1760     0x13 0x16d8     0x14 0x1674
0x15 0x1630     0x16 0x15dc     0x17 0x1530     0x18 0x14b8     0x19 0x1450
0x1a 0x13a4     0x1b 0x133c     0x1c 0x12d4     0x1d 0x124c     0x1e 0x11d8
0x1f 0x1138     0x20 0x10b0     0x21 0x103c     0x22 0x0fb4     0x23 0x0f54
0x24 0x0ec8     0x25 0x0e68     0x26 0x0dbc     0x27 0x0d4c     0x28 0x0cdc
0x29 0x0c78     0x2a 0x0c14     0x2b 0x0bb0     0x2c 0x0aa4     0x2d 0x0a38
0x2e 0x09bc     0x2f 0x0950     0x30 0x08d4     0x31 0x0890     0x32 0x0834
0x33 0x07b4     0x34 0x0758     0x35 0x06d8     0x36 0x064c

--xid 事务id
--cnt 回滚段的数量,0x36=54
--irb 表示回滚段的开始REC (record)
*-----------------------------
* Rec #0x36  slt: 0x0a  objn: 73300(0x00011e54)  objd: 73300  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
*-----------------------------

Rec #0x36  slt: 0x0a =10 


slt对应transaction中的XIDSLOT

XID 与 UBA 的关系

项目XIDUBA
作用标识一个事务指向一次具体的回滚记录
范围事务级别行修改级别
位置在 Undo 段头(事务表)中记录在数据块的行头中记录
功能用于标识事务与恢复关系用于指向旧版本数据
关系总结:
一个事务(XID)会有多个 UBA;
每个修改操作(行级)对应一个 UBA;
Oracle 通过 XID 找到事务,再通过 UBA 找到每条修改记录的 Undo 信息。

事务的流程:

1.分配一个回滚段
2.在回滚段事务表中分配一个事务槽
3.分配undo block
4.更新数据块上的ITL事务槽
5.把前镜像记录在undo block内
6.更改数据块的内容

由于Delayed Block Cleanout的存在,Oracle在读一个block时,如果ITL事务槽存在活动事务,那么Oracle必须根据相应的xid找到
相应的回滚段以判断事务状态.