1
关于undo
作用
Oracle
数据库使用undo维护事务操作的记录,undo作用如下所示,
l
Roll back an active transaction
l
Recover a terminated transaction
l
Provide read consistency
l
Perform some logical flashback operations
深入理解Oracle数据库undo原理对于数据库异常恢复、性能优化具有重要意义。
2
关于oracle
中的事务
事务是包含一个或多个SQL语句的逻辑原子单元。事务对SQL语句进行分组,使
全部提交或全部回滚。Oracle数据库为每个事务分配一个称为transaction ID(XID)的惟一标识符。所有Oracle事务都遵循数据库事务的基本属性,即ACID属性。ACID解析如下:
Atomicity
:
事务的所有任务
要么全部提交,要么全部回滚
。
Consistency
:
事务将数据库从一个一致的状态修改为另一个一致的状态。
Isolation
:
在提交事务之前,事务的
变更对其他事务是不可见的。
Durability
:
提交的事务所做的变更是永久性的。
3
多个dml
是一个事务还是多个事务?
3.1
测试表信息
SYS@source>select * from orastar.undo_test;
C1 C2
------------------------------ ------------------------------
4 1234
2 12
SYS@source>desc orastar.redo_test9
Name Null? Type
----------------------------------------- -------- ----------------------------
C1 CHAR(10)
C2 CHAR(10)
3.2
同一session
多个dml
操作
session 1:
update orastar.undo_test set c2='1111' where c1=4;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC USED_UBLK USED_UREC
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
7 26 354 2 52 384 11 1 1
select xidusn,
xidslot,
xidsqn,
ubafil,
ubablk,
ubasqn,
ubarec,
used_ublk,
used_urec
from v$transaction;
update orastar.undo_test set c2='3333' where c1=3;
select xidusn,
xidslot,
xidsqn,
ubafil,
ubablk,
ubasqn,
ubarec,
used_ublk,
used_urec
from v$transaction;
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC USED_UBLK USED_UREC
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
7 26 354 2 52 384 12 1 2
3.3
不同session
多个dml
操作
session 1:
update orastar.undo_test set c2='1111' where c1=4;
session 2:
update orastar.undo_test set c2='3333' where c1=3;
session3: 查询v$transaction信息:
XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC USED_UBLK USED_UREC
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
5 37 325 2 1605 352 14 1 1
4 47 340 2 533 432 20 1 1
3.4
小结
同一session中多个dml为同一事务,不同session中多个dml为不同事务。
4
深入解析undo
段分配规则
当Oracle数据库undo剩余空间小于100%时,Oracle为每个事务分配一个新的回滚段,初始为2个extent各8 blocks;
4.1
2M undo
测试结果
每个回滚段初始16 个blocks,合计128K,2M空间最多可生成16个回滚段,当生成第15个回滚段时开始回滚段重用,因此当UNDO表空间剩余空间小于100%时会一直创建新的回滚段,尽可能为每一个事务分配一个新的回滚段。
4.2
3M undo
测试结果
根据2M undo的测试结果,推测3M undo在前23个事务都会创建新的回滚段,当开始第24个事务时,不会再创建回滚段,而是会和某事务共用某个已经存在的回滚段,测试结果和推测一致。
5
深入解析
Tx Header
Tx Header
由固定部分和可变部分组成。固定部分包含事务块头和一个描述符ITL
。变量部分由零个或多个描述符itl
组成,
通过dump
数据块的方式,分析其内部结构:
查询数据物理块信息:
SYS@source>select rowid,
2 dbms_rowid.rowid_object(rowid) object_id,
3 dbms_rowid.rowid_relative_fno(rowid) file_id,
4 dbms_rowid.rowid_block_number(rowid) block_id,
5 dbms_rowid.rowid_row_number(rowid) num
6 from orastar.undo_test;
ROWID OBJECT_ID FILE_ID BLOCK_ID NUM
------------------ ---------- ---------- ---------- ----------
AAAMyDAAFAAAABkAAA 52355 5 100 0
AAAMyDAAFAAAABkAAB 52355 5 100 1
AAAMyDAAFAAAABkAAC 52355 5 100 2
修改记录产生事务:
update orastar.undo_test set c2='66666' where c1=4;
dump 数据块信息:
alter session set tracefile_identifier='undo_01';
oradebug setmypid
alter system dump datafile 5 block 100;
oradebug close_trace
oradebug tracefile_name
csc: 0x00.b6376 --
块清除
scn
itc: 3 --
ITL
数量
flg: E --
大写的“
O
”表示
Block is on free list
ITL
各字段含义如下所示,
6
深入解析XID
事务标识符
(XID)
惟一地标识系统中的事务,结构如下所示,
XID = usn# (2 bytes). slot# (2 bytes). wrap#/sqn(4 bytes)
usn: Undo segment number
slot: Transaction table slot number
wrap: Sequence number or wrap#
使用
bbed
查看
xid
内部结构如下所示,
查询事务信息
select xidusn,
xidslot,
xidsqn,
ubafil,
ubablk,
ubasqn,
ubarec,
used_ublk,
used_urec
from v$transaction order by 1;
查询回滚段信息
select * from v$rollname;
dump95
号回滚段:
alter session set tracefile_identifier='undo_02';
oradebug setmypid
alter system dump undo header '_SYSSMU95$';
oradebug close_trace
oradebug tracefile_name
State
:
9
表示:Inactive, no local Tx
10
表示:Active, begin local Tx
7
深入解析UBA
UBA
惟一地标识给定事务的
undo block
。包含在
ITL
中,
UBA = DBA(4 bytes). seq#(2 bytes). rec#(2 bytes)
dba: Data block address (DBA) of the block
seq: The sequence number of the block
rec: The record number within the block
使用
bbed
查看
UBA
内部结构如下所示,
YS@source>select dbms_utility.data_block_address_file(TO_NUMBER('01c0011c', 'XXXXXXXX')) file_id,
dbms_utility.data_block_address_block(TO_NUMBER('01c0011c', 'XXXXXXXX')) block_id from dual; 2
FILE_ID BLOCK_ID
---------- ----------
7 284
8
说明
以上内容为个人多次测试结果,由于个人原因,如有分析不足之处还请见谅及指正,谢谢。