首页 > 代码库 > oracle_事务与undo块
oracle_事务与undo块
1.事务(transaction)
1.1事务的概念
事务是若干操作的集合,集合中的操作看作程一个整体,要么都完成,要么都取消。
1.2事务的属性
Atomicity(原子性) 事务是一个整体,一起完成,一起取消。
Consistency(一致性) 事务将数据从一种一致状态转变为下一种一致状态。(指的是修改前与修改后吗?留疑)
Isolation(隔离性) 一个事物的影响在该事物提交前对其他事务都不可见。(由undo表空间完成)
Durability(永久性) 事务一旦提交,结果是永久的。(通过重做日志机制,达到的效果。而不是直接写入磁盘。)
1.3事务的控制操作
和sql server不同,Oracle没有专门的开始事务控制语句。
在修改数据语句之前,Oracle会自动添加一个隐式的开始事务语句。
1.3.1事务操作语句
commit --提交语句。commit会结束你的事务,并把事务做的修改永久化。
rollback --回滚语句。rollback会结束事务,并撤销未提交的事务。
savepoint <savepoint_name> --容许在事务中做一个保存标记点。(一个事务中可以有多个savepoint)
rollback to <savepoint_name> --与上面savepoint一起使用,可以rollback到这个点。
实验:
SQL> select * from scott.emp where empno in(7369,7499,7521);
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12月-80 1000 20
7499 ALLEN SALESMAN 7698 20-2月 -81 200 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
SQL> update scott.emp set sal=800 where empno=7369;
已更新 1 行。
SQL> update scott.emp set sal=500 where empno=7499;
已更新 1 行。
SQL> savepoint t1;
保存点已创建。
SQL> update scott.emp set sal=1000 where empno=7521;
已更新 1 行。
SQL> rollback to t1;
回退已完成。
SQL> select * from scott.emp where empno in(7369,7499,7521);
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12月-80 800 20
7499 ALLEN SALESMAN 7698 20-2月 -81 500 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
--可以看到前两个update已修改,只是rollback到了savepoint。
SQL> rollback;
回退已完成。
SQL> select * from scott.emp where empno in(7369,7499,7521);
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
7369 SMITH CLERK 7902 17-12月-80 1000 20
7499 ALLEN SALESMAN 7698 20-2月 -81 200 300 30
7521 WARD SALESMAN 7698 22-2月 -81 1250 500 30
--这下全部撤销。
--小总结:一个事物中,savepoint可以多个;rollback可以多次撤销。
1.4事务与undo表空间
Oracle中undo的作用主要有两个:第一是回滚事务,第二是产生一致性读。
XID=usn#:slot#:wrap# --transaction identifiers(XID--事务ID)
usn rollback segment number 回滚段序号
slot transaction table slot number 事务表槽号
wrap sequence number or wrap# 被覆盖次数
UBA=DBA:seq#:rec#: --undo block address(undo块地址)
DBA data block address of the undo block 回滚块地址
seq# the sequence number of the block 覆盖次数
rec# the record number within the block 块中的第几行
ITL --Interested Transaction List 事务槽
1.4.1一个事务的操作流程。
我们可以通过下图,系统了解下事务的执行流程。
1.一个事务先在shared Pool解析。(以硬解析为例)
2.在buffer cache中寻找事务所需要的块。
3.数据块读入buffer cahce。
4.产生重做日志信息,记日志。
5.为事务建立undo段。
6.事务修改数据块的详细步骤。
6.1事务开始,必须首先在data block中分配ITL(事务槽),ITL中记录了事务ID(XID),XID由三部分内容组成:
XIDUSN(回滚段号),XIDSLOT(回滚段槽号),XIDSQN(覆盖次数)。
6.2分配对应的undo块,用于保存修改之前data block的数据。data block的ITL和undo block的ITL都记录着相同的UBA block address)
6.3在Undo segment header中的事务表中,记录所有回滚块上的事务信息,每个事务都会占据了一个回滚槽。
XID指向data block。
UBA指向事务回滚信息的开始位置。undo块存储是一个链表结构,只要找到最先开始回滚的块,就能依次回滚整个事务。
小结undo的内容:
1.为事务建立undo段。
2.在数据块的ITL中存储XID,UBA.
3.在undo表头中存储相对应的数据 块的XID,UBA.
4.建立undo块,存储数据块镜像。数据块中的UBA指向undo块。同样有xid,uba。
1.4.2.1.实验说明。
第6步,dump出了undo段头信息。
第8步,dump出来data block中ITL的信息。
第10步,dump出了undo block中信息。
证明--下面一张根据这次事务所作的图,结合图理解
undo 段表中记录着每一个事务的XID和UBA ---实验中用红色字体标注出XID,UBA
data block中ITL的XID指向undo段头
undo 段头中的UBA指向undo block
1.4.3实验开始
1.触发一个事务。
SQL> update scott.emp set sal=800 where empno=7369;
已更新 1 行。
SQL> update scott.emp set sal=800 where empno=7369;
已更新 1 行。
SQL> update scott.emp set sal=800 where empno=7369;
已更新 1 行。
2.查询事务的XID,回滚段序号,事务表序号,覆盖次数,undo块,undo文件号。
SQL> select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction;
XID XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL
---------------- ---------- ---------- ---------- ---------- ----------
04001300F3070000 4 19 2035 24247 5
3.通过回滚段序号,可以查到对应的回滚段。(XIDUSN=4,所以该事物的回滚段是_SYSSMU4_3587866380$)
SQL> select * from v$rollname;
USN NAME CON_ID
---------- ------------------------------ ----------
0 SYSTEM 0
1 _SYSSMU1_2129601957$ 0
2 _SYSSMU2_4159822658$ 0
3 _SYSSMU3_2248346778$ 0
4 _SYSSMU4_3587866380$ 0
5 _SYSSMU5_2367258232$ 0
6 _SYSSMU6_3229781354$ 0
7 _SYSSMU7_2293707892$ 0
8 _SYSSMU8_1104184495$ 0
9 _SYSSMU9_376956797$ 0
10 _SYSSMU10_2767132874$ 0
已选择 11 行。
4.dump出该undo段块头。
SQL> alter system dump undo header ‘_SYSSMU4_3587866380$‘;
系统已更改。
5.跟踪着转储文件的位置。
SQL> select * from v$diag_info where name=‘Default Trace File‘;
INST_ID NAME VALUE CON_ID
---------- ------------------------- ---------------------------------------------------------------------- ----------
1 Default Trace File F:APPADMINISTRATORdiag dbmsyzhyzh raceyzh_ora_1604.trc 0
6.详细看undo段块头的信息,(篇幅很长。) (图rollback segment header block,结合图理解)
*** 2014-12-18 20:14:33.420
********************************************************************************
Undo Segment: _SYSSMU4_3587866380$ (4)
********************************************************************************
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 5 #blocks: 655
last map 0x00000000 #maps: 0 offset: 4080
Highwater:: 0x01405eb7 ext#: 4 blk#: 55 ext size: 256
#blocks in seg. hdr‘s freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 4
Unlocked
Map Header:: next 0x00000000 #extents: 5 obj#: 0 flag: 0x40000000
********************************************************************************
先一部分一部分来看。
#extents: 5 --这个undo段共有5个区。
#blocks: 655 --有655可用块。
ext#: 4 --这个事务发生在第五个区上。(从0开始)
blk#: 55 --这个事务发生在第55个快上。
ext size: 256 --第5个区还有256个块可用。
Highwater:: 0x01405eb7 --段头的下一块。
********************************************************************************
Extent Map
-----------------------------------------------------------------
0x014000b1 length: 7
0x014000b8 length: 8
0x01402380 length: 128
0x01405500 length: 256
0x01405e80 length: 256
********************************************************************************
代表各个区的各有多少undo块。
********************************************************************************
Retention Table
-----------------------------------------------------------
Extent Number:0 Commit Time: 1418211204
Extent Number:1 Commit Time: 1418211204
Extent Number:2 Commit Time: 1418824836
Extent Number:3 Commit Time: 1418896851
Extent Number:4 Commit Time: 1418896851
********************************************************************************
区提交的时间,以秒为单位。
********************************************************************************
TRN CTL:: seq: 0x00e4 chd: 0x000f ctl: 0x0014 inc: 0x00000000 nfb: 0x0000
mgc: 0xb000 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
uba: 0x01405eb7.00e4.33 scn: 0x0000.00299627
******************************************************************************************************************************
重点看这里! (十六进制转十进制)
seq: 0x00e4 被覆盖228次。
chd: 0x000f 事务表的链头,这里是15.
ctl: 0x0014 事务表的链尾,这里是20.
nfb: 0x0000 表示UNDO块在空闲池的空闲块数。
uba: 0x01405eb7.00e4.33 (记住这个。)
分为三部分:
0x01405eb7 代表undo块地址。
00e4 代表被覆盖次数. --即UNDO块被覆盖了228次 (这里和seq是一样的)
33 代表在undo块的第几行记录。 --undo块的51条记录
******************************************************************************************************************************
Version: 0x01
FREE BLOCK POOL::
uba: 0x00000000.00e4.32 ext: 0x4 spc: 0x5fa
uba: 0x00000000.00e4.28 ext: 0x4 spc: 0xf62
uba: 0x00000000.00e4.12 ext: 0x4 spc: 0xe4e
uba: 0x00000000.00d1.01 ext: 0x5 spc: 0x1f9c
uba: 0x00000000.00d0.16 ext: 0x4 spc: 0x1786
***********************************************************************************************************************
undo块的空闲池。
uba: 0x00000000.00e4.32 块地址为0,说明UNDO块不是空闲的,即0x00000000
ext: 0x4 undo块在哪个区。这里是在第四个区。
spc: 0x5fa undo块中有多少空闲空间,单位字节。
***********************************************************************************************************************
TRN TBL::
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x00 9 0x00 0x07f6 0x0006 0x0000.0029e758 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x01 9 0x00 0x07f2 0x0017 0x0000.0029e72e 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x02 9 0x00 0x07f4 0x0020 0x0000.0029e642 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x03 9 0x00 0x07f3 0x0012 0x0000.0029e5f1 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903967
0x04 9 0x00 0x07f3 0x0003 0x0000.0029e5ce 0x00000000 0x0000.000.00000000 0x00000000 0x00000000 1418903948
0x05 9 0x00 0x07f4 0x000e 0x0000.0029e6a1 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x06 9 0x00 0x07f5 0x001d 0x0000.0029e75d 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x07 9 0x00 0x07f5 0x0014 0x0000.0029e9a5 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418904001
0x08 9 0x00 0x07f5 0x0021 0x0000.0029e6bb 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x09 9 0x00 0x07f6 0x000b 0x0000.0029e6d3 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x0a 9 0x00 0x06e7 0x0016 0x0000.0029e66a 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x0b 9 0x00 0x07f3 0x001f 0x0000.0029e6e9 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x0c 9 0x00 0x07f4 0x000a 0x0000.0029e665 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x0d 9 0x00 0x07f4 0x001b 0x0000.00299635 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418898808
0x0e 9 0x00 0x07f2 0x0008 0x0000.0029e6ad 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x0f 9 0x00 0x07f5 0x000d 0x0000.0029962c 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418898808
0x10 9 0x00 0x07f5 0x0007 0x0000.0029e8c5 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903983
0x11 9 0x00 0x07ec 0x0010 0x0000.0029e879 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903982
0x12 9 0x00 0x07e8 0x0018 0x0000.0029e60b 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903971
0x13 10 0x80 0x07f3 0x0004 0x0000.0029e9b8 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 0
0x14 9 0x00 0x07f3 0xffff 0x0000.0029e9ad 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418904001
0x15 9 0x00 0x07f3 0x0001 0x0000.0029e71d 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x16 9 0x00 0x07f1 0x0019 0x0000.0029e674 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x17 9 0x00 0x07f7 0x001c 0x0000.0029e734 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x18 9 0x00 0x07f5 0x0002 0x0000.0029e62e 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x19 9 0x00 0x07ef 0x0005 0x0000.0029e68c 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x1a 9 0x00 0x07f1 0x0015 0x0000.0029e705 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x1b 9 0x00 0x07f2 0x0004 0x0000.0029967f 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418898903
0x1c 9 0x00 0x07ef 0x0000 0x0000.0029e748 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x1d 9 0x00 0x07f3 0x0011 0x0000.0029e798 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903977
0x1e 9 0x00 0x07f5 0x000c 0x0000.0029e663 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x1f 9 0x00 0x07f6 0x001a 0x0000.0029e6ef 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x20 9 0x00 0x07f2 0x001e 0x0000.0029e656 0x01405eb6 0x0000.000.00000000 0x00000001 0x00000000 1418903973
0x21 9 0x00 0x07f3 0x0009 0x0000.0029e6cc 0x01405eb7 0x0000.000.00000000 0x00000001 0x00000000 1418903973
***********************************************************************************************************************
index 表示事务表中槽号,从0x00开始到0x21结束,11g的版本有34个槽。
uel 表示所在undo段序号。对应xid中的usn
wrap# 表示被覆盖次数。
---这三者结合起来即是XID。
state 表示事务状态:9代表事务不活动,10代表事务正在活动。
cflags 表示正在使用穿上事务槽的事务的状态:0x00表示非活动事务、0x80表示活动事务、0x10表示死事务。
scn 表示务事启动、提交、回滚的SCN.
dba 表示uba:第一部分的undo块地址。
nub 表示当前事务所用到的UNDO块的个数。
cmt 表示最接近当前的提交时间戳,0表示事务正在活动。
***********************************************************************************************************************
7.使用dbms_rowid包得出该事物修改的数据块。
SQL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid),empno from emp where empno=7369;
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) EMPNO
------------------------------------ ------------------------------------ ----------
6 323 7369
8.dump出数据块。
SQL> alter system dump datafile 6 block 323;
系统已更改。
SQL> select * from v$diag_info where name=‘Default Trace File‘;
INST_ID NAME VALUE CON_ID
---------- ------------------------- ---------------------------------------------------------------------- ----------
1 Default Trace File F:APPADMINISTRATORdiag dbmsyzhyzh raceyzh_ora_1604.trc 0
9.详细看看数据块头信息。(图data block header:transaction layer,结合图理解)
********************************************************************************
以下是该事物需要到数据块中的ITL一部分。
********************************************************************************
*** 2014-12-18 22:27:39.268
Block header dump: 0x01800143
Object id on Block? Y
seg/obj: 0x16d78 csc: 0x00.2a0b11 itc: 3 flg: E typ: 1 - DATA
brn: 0 bdba: 0x1800140 ver: 0x01 opc: 0
inc: 0 exflg: 0
***********************************************************************************************************************
seg/obj: 0x16d78 --object_id号。十六转十,可以在dba_objects上查到。
csc: 0x00.2a0b11 --cleanSCN。清除时的SCN(覆盖时的SCN)
itc: 3 --该块ITL的数量。Oracle的每个数据块中都有一个或者多个事务槽,每一个对数据块的并发访问
事务都会占用一个事务槽。
flg: E --指ASSM(automatic segment space management自动段空间管理(段空间有两种方法管理))。
如果是O表示用的是free list。
typ: 1 - DATA --类型1表示数据,类型2表示索引
***********************************************************************************************************************
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x0002.00e.000008e9 0x014003e2.0105.01 C--- 0 scn 0x0000.0028cfa3
0x02 0x0005.00a.00000943 0x014000c3.0160.0b C--- 0 scn 0x0000.0028dced
0x03 0x0004.013.000007f3 0x01405eb7.00e4.35 ---- 3 fsc 0x0001.00000000
********************************************************************************
Itl -- ITL事务槽号的流水编号
Xid -- transac[X]tion identified(事务ID),在回滚段事务表中有一条记录和这个事务对应。
Uba --undo block address记录了最近一次的该记录的前镜像(修改前的值,对应数据块的UBA)
Flag --C是提交,U是快速提交,---是未提交
Lck --锁住了几行数据,即是有几个行锁(行锁)
********************************************************************************
10.从第二步,可以知道undo块的位置。(ubablk,ubafil ---v$transaction)
dump出undo块头。(图为undor block结构,结合图理解)
UNDO BLK:
xid: 0x0004.013.000007f3 seq: 0xe4 cnt: 0x35 irb: 0x35 icl: 0x0 flg: 0x0000
********************************************************************************
主要看上面这个字段:
xid: 0x0004.013.000007f3 事务ID,对应数据块中ITL的XID。
seq: 0xe4 块序号 0xe4是228.
cnt: 0x35 块中回滚记录次数
irb: 0x35 index of first to consider in case of a transaction rollback
icl: 0x0
********************************************************************************
Rec Offset Rec Offset Rec Offset Rec Offset Rec Offset
---------------------------------------------------------------------------
0x01 0x1f3c 0x02 0x1ed4 0x03 0x1e6c 0x04 0x1e04 0x05 0x1d8c
0x06 0x1d24 0x07 0x1cbc 0x08 0x1c10 0x09 0x1b64 0x0a 0x1ab8
0x0b 0x1a50 0x0c 0x19e8 0x0d 0x1980 0x0e 0x18d4 0x0f 0x1828
0x10 0x17c0 0x11 0x1758 0x12 0x16f0 0x13 0x1644 0x14 0x15dc
0x15 0x1530 0x16 0x14c8 0x17 0x141c 0x18 0x13a4 0x19 0x131c
0x1a 0x12c4 0x1b 0x1218 0x1c 0x116c 0x1d 0x1104 0x1e 0x1058
0x1f 0x0fac 0x20 0x0ef4 0x21 0x0e94 0x22 0x0e44 0x23 0x0df4
0x24 0x0d14 0x25 0x0cc4 0x26 0x0be4 0x27 0x0b60 0x28 0x0b04
0x29 0x0ab4 0x2a 0x0a54 0x2b 0x09a0 0x2c 0x0938 0x2d 0x08e0
0x2e 0x0880 0x2f 0x0830 0x30 0x074c 0x31 0x06c8 0x32 0x0670
0x33 0x05d8 0x34 0x0584 0x35 0x052c
*-----------------------------
* Rec #0x34 slt: 0x13 objn: 93560(0x00016d78) objd: 93560 tblspc: 4(0x00000004)
***********************************
Rec #0x34 --undo块中的第52行记录
slt: 0x13 --undo块中的槽号。
***********************************
* Layer: 11 (Row) opc: 1 rci 0x33
Undo type: Regular undo Last buffer split: No
Temp Object: No
Tablespace Undo: No
rdba: 0x00000000
*-----------------------------
KDO undo record:
KTB Redo
op: 0x02 ver: 0x01
compat bit: 4 (post-11) padding: 0
op: C uba: 0x01405eb7.00e4.33
KDO Op code: URP row dependencies Disabled
xtype: XAxtype KDO_KDOM2 flags: 0x00000080 bdba: 0x01800143 hdba: 0x01800142
itli: 3 ispac: 0 maxfr: 4858
tabn: 0 slot: 1(0x1) flag: 0x2c lock: 0 ckix: 0
ncol: 8 nnew: 1 size: 0
Vector content:
col 5: [ 2] c2 03
********************************************
col 5: [ 2] c2 03 --表示具体的undo数据
********************************************
oracle_事务与undo块