概述
一、我们来看一个DML语句的处理过程描述
update undotest set object_type='VIEW' where object_type='PROCEDURE';
- 检查shared pool中是否存在相同的语句,如果存在,重用执行计划,执行扫描运算,如果不存在,执行硬解析生成执行计划
- 根据执行计划中的扫描运算,检查undotest表中的相关数据块是否存在buffer cache中,如果不存在则读取到内存中
- 检查数据块中符合object_type='PROCEDURE'条件的记录,如果没有符合条件的行记录,则结束语句,如果存在则进入下一步
- 以当前模式(current)获取符合object_type='PROCEDURE'条件的数据块,准备进行更新
- 在回滚表空间的相应回滚段头的事务表上分配事务槽,这个动作需要记录redo日志
- 从回滚段数据块上创建object_type='PROCEDURE'的前映像数据,这个动作也要记录redo日志
- 修改object_type='VIEW' ,这是DML操作的数据变更,而需要记录redo日志
- 用户提交时,在redo日志中记录提交信息,将回滚段头上的事务表和回滚段数据块标记为非活动,清除修改数据块上的事务信息(也可能延迟清除)。同时必须确保整个事务的redp日志写到磁盘上的日志文件
注意:如果最后用户回滚了事务,oracle从回滚段中将前映像数据提取出来,覆盖被更新的数据块。这个回滚动作本身也需要产生redo日志,因此,我们要知道回滚的代价非常昂贵。
二、不同的DML操作,UNDO BLOCK中保存的前映像内容
- INSERT操作,UNDO中只需要保存插入记录的rowid,如果需要回退,通过保存的rowid进行删除即可(后面有案例)
- UPDATE操作,UNDO中只需要记录被更新字段的旧值,如果需要回退,只需要通过旧值覆盖更新后的值即可。
- DELETE操作,UNDO中必须记录整行的数据,如果需要回退,只需要将这整行的数据重新插入至表中即可。
备注:本文章只对INSERT操作,UNDO中保存的内容进行测试,至于UPDATE、DELETE操作,实验方法基本一致,这里就不再累赘
示例
1.开启事务
SQL
>
create
table tt
as
select object_name,object_id
from dba_objects;
Table created.
SQL > insert into tt values( 'dddddd', 1233456); --执行insert操作
1 row created.
Table created.
SQL > insert into tt values( 'dddddd', 1233456); --执行insert操作
1 row created.
2.检查事务信息和其他一些事务信息
SQL > select HEADER_FILE,HEADER_BLOCK from dba_segments a where segment_name = 'TT';
HEADER_FILE HEADER_BLOCK
- - - - - - - - - - - - - - - - - - - - - - -
4 810
SQL > SELECT
2 dbms_rowid.rowid_object(rowid) object_id,
3 dbms_rowid.rowid_relative_fno(rowid) REL_FNO,
4 dbms_rowid.rowid_block_number(rowid) BLOCKNO,
5 dbms_rowid.rowid_row_number(rowid) ROWNO,rowid,object_name
6 FROM tt WHERE object_name = 'dddddd';
OBJECT_ID REL_FNO BLOCKNO ROWNO ROWID
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OBJECT_NAME
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
73430 4 1150 0 AAAR7WAAEAAAAR +AAA
dddddd
SQL > select xidusn,xidslot,xidsqn,ubablk,ubafil,ubarec,to_char(start_scnw, 'xxxxxxxx') start_scnw,
2 to_char(start_scnb, 'xxxxxxxx') start_scnb, start_scnb +start_scnw *power( 2, 32) start_scn
3 from v$ transaction;
XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL UBAREC START_SCNW START_SCNB START_SCN
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5 21 960 1466 3 7 0 f5520 1004832
根据上面查询获取的事务信息,dump insert事务undo 段头和undo 块
SQL > select HEADER_FILE,HEADER_BLOCK from dba_segments a where segment_name = 'TT';
HEADER_FILE HEADER_BLOCK
- - - - - - - - - - - - - - - - - - - - - - -
4 810
SQL > SELECT
2 dbms_rowid.rowid_object(rowid) object_id,
3 dbms_rowid.rowid_relative_fno(rowid) REL_FNO,
4 dbms_rowid.rowid_block_number(rowid) BLOCKNO,
5 dbms_rowid.rowid_row_number(rowid) ROWNO,rowid,object_name
6 FROM tt WHERE object_name = 'dddddd';
OBJECT_ID REL_FNO BLOCKNO ROWNO ROWID
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OBJECT_NAME
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
73430 4 1150 0 AAAR7WAAEAAAAR +AAA
dddddd
SQL > select xidusn,xidslot,xidsqn,ubablk,ubafil,ubarec,to_char(start_scnw, 'xxxxxxxx') start_scnw,
2 to_char(start_scnb, 'xxxxxxxx') start_scnb, start_scnb +start_scnw *power( 2, 32) start_scn
3 from v$ transaction;
XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL UBAREC START_SCNW START_SCNB START_SCN
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5 21 960 1466 3 7 0 f5520 1004832
根据上面查询获取的事务信息,dump insert事务undo 段头和undo 块
SQL
>
select
name
from v$rollname
where usn
=
5;
NAME
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_SYSSMU5_1527469038$
NAME
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_SYSSMU5_1527469038$
3.dump undo 段头和undo 块
SQL > oradebug setmypid;
Statement processed.
SQL > oradebug tracefile_name
/u01 /oracle /diag /rdbms /test /test /trace /test_ora_604.trc
SQL > alter system dump undo header '_SYSSMU5_1527469038$';
System altered.
SQL > alter system dump datafile 3 block 1466;
System altered.
UNDO BLK:
xid: 0x0005. 015. 000003c0 seq: 0x12c cnt: 0x7 irb: 0x7 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x01 0x1fa4 0x02 0x1f48 0x03 0x1ecc 0x04 0x1e70 0x05 0x1df4
0x06 0x1d90 0x07 0x1d20
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Rec #0x7 slt: 0x15 objn: 73430(0x00011ed6) objd: 73430 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: 0x00c005b9. 012c. 2d ctl max scn: 0x0000.000f4ed4 prv tx scn: 0x0000.000f4ee0
txn start scn: scn: 0x0000.000f53a9 logon user: 85
prev brb: 12584373 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
compat bit: 4 (post - 11) padding: 1
op: Z
KDO Op code: DRP row dependencies Disabled --DRP操作完成回滚
xtype: XA flags: 0x00000000 bdba: 0x0100047e hdba: 0x0100032a --bdba表示block address hdba 代表sgment header address
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) - - - - - - - - - 这个slot表示这一行数据在数据块中的行地址(行序列)
其中bdba表示file 4,block 1150 ,hdba表示file 4,block 810 与我们上面查询出来的地址相符。
SQL > oradebug setmypid;
Statement processed.
SQL > oradebug tracefile_name
/u01 /oracle /diag /rdbms /test /test /trace /test_ora_604.trc
SQL > alter system dump undo header '_SYSSMU5_1527469038$';
System altered.
SQL > alter system dump datafile 3 block 1466;
System altered.
UNDO BLK:
xid: 0x0005. 015. 000003c0 seq: 0x12c cnt: 0x7 irb: 0x7 icl: 0x0 flg: 0x0000
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0x01 0x1fa4 0x02 0x1f48 0x03 0x1ecc 0x04 0x1e70 0x05 0x1df4
0x06 0x1d90 0x07 0x1d20
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Rec #0x7 slt: 0x15 objn: 73430(0x00011ed6) objd: 73430 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: 0x00c005b9. 012c. 2d ctl max scn: 0x0000.000f4ed4 prv tx scn: 0x0000.000f4ee0
txn start scn: scn: 0x0000.000f53a9 logon user: 85
prev brb: 12584373 prev bcl: 0
KDO undo record:
KTB Redo
op: 0x03 ver: 0x01
compat bit: 4 (post - 11) padding: 1
op: Z
KDO Op code: DRP row dependencies Disabled --DRP操作完成回滚
xtype: XA flags: 0x00000000 bdba: 0x0100047e hdba: 0x0100032a --bdba表示block address hdba 代表sgment header address
itli: 1 ispac: 0 maxfr: 4858
tabn: 0 slot: 0(0x0) - - - - - - - - - 这个slot表示这一行数据在数据块中的行地址(行序列)
其中bdba表示file 4,block 1150 ,hdba表示file 4,block 810 与我们上面查询出来的地址相符。
我们可以看到,undo块中并没有直接保存rowid信息,但是oracle完全可以根据上面的几个信息(bdba,slot,objd)定位回滚时需要删除的具体数据,因此对于Insert操作,ORACLE只需保留上述信息,即可完成回滚操作
三、基本概念和名词解释
- UBA: Undo block address
- RBA: Redo block address
- Dba: Data block address
- Rdba: Root dba
- Xid: Transaction ID
- ITL: Interested Transaction List 保存在数据块的头部(事务信息部分),包含XID,UBA,LCK,FLG等重要信息
Transaction Identifiers
Transaction identifiers (XID) uniquely identify a transaction within the system; they are used within the Interested Transaction List (ITL) of the data block.
A transaction identifier consists of:
- Undo segment number 即v$rollname中的usn
- Transaction table slot number 对应回滚段头中回滚事务表的第几条记录
- Sequence number or wrap#
XID = usn# . slot# . wrap#
Undo Block Address
The undo block address (UBA) uniquely identifies the undo block for a given transaction; it is found within the ITL of the data block.
A UBA consists of:
- Data block address (DBA) of the block 前映像undo 块地址
- The sequence number of the block 序列号
- The record number within the block undo记录的开始地址(针对该块)
UBA = DBA. seq#. rec#
最后
以上就是朴素汽车为你收集整理的数据库回滚机制(RollBack)的实现的全部内容,希望文章能够帮你解决数据库回滚机制(RollBack)的实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复