在 Oracle 数据库中,XID 和 UBA 是事务(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 的关系
| 项目 | XID | UBA |
|---|---|---|
| 作用 | 标识一个事务 | 指向一次具体的回滚记录 |
| 范围 | 事务级别 | 行修改级别 |
| 位置 | 在 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找到
相应的回滚段以判断事务状态.