这节课讲一下一个事务的操作流程
内容有点难度
先简单的看一下
当一个事务开始以后
在oracle数据库里面针对这个事务
oracle会给它分配一个事务ID就是编号这个东西
简单的做一个操作
实验需要一个t2表,若没有可以自己建一个
SQL> create table t2(id number,name varchar2(20));
Table created.
可以查看有没有这个表
没有这个表的时候的结果
SQL> desc t2;
ERROR:
ORA-04043: object t2 does not exist
有这个表时的结果
SQL> desc t2;
Name Null? Type
----------------------------------------- -------- ----------------------------
ID NUMBER
NAME VARCHAR2(20)
看表中有没有数据
SQL> select * from t2;
no rows selected
这时没有数据,插入一行数据
insert into t2 values(1,’xkj’);
这个命令一执行就开始一个事务
执行以前先查一下,
目前数据库没有任何的操作,应该没有任何的事务
SQL> select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction;
no rows selected
目前结果是空的
然后去执行一下
SQL> insert into t2 values(1,'xkj');
1 row created.
这时应该开始一个事务了
再查一下系统中的事务
SQL> select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction;
XID XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL
---------------- ---------- ---------- ---------- ---------- ----------
02001C009E010000 2 28 414 580 2
这是一个事务开始以后的结果
这个时候
oracle分配了一个XID(transaction identifier)既:事务编号
这是事务唯一的一个编号,像身份证一样
一个事务开始以后,oracle会给它分配一个事务ID
再看一下有一个叫事务表的概念
undo表空间有undo段,undo段有第一个数据块
oracle的undo表空间的undo段的第一个数据块里面放着一个事务表
这个事务表鉴于这个块的大小最多可以放47个事务
在undo表空间里面的一个undo段
第一个块叫undo段的段头块
在这个段头块里面有一个事务表
这个事务表最多有47行
每一行放一个事务
一个事务开始以后
首先来讲oracle给它分配了一个XID事务编号
这个时候这个事务会做的第一件事
就是在undo表空间里面找一个undo段
在undo段的段头块里面有事务表,事务表有47行
找其中一行把自己的事务信息写上,至少把XID写上
就是找一个空行将自己的信息写上
就是说
一个undo段最多可以同时有47个活动事务
意味着47个活动事务共用这一个段
第一、oracle尽量的一个事务使用一个回滚段
第二、如果说事务太多回滚段太少,这时会出现多个事务使用一个回滚段的情况
第三、oracle尽量的均匀的将活动的事务分布在各个回滚段上
事务表在undo段的第一个数据块,每一个回滚段最多可以同时有47个活动事务
可以把回滚段段头块给大家看一下
select * from v$rollname;
这个语句看有多少个回滚段
执行一下
SQL> select * from v$rollname;
USN NAME
---------- ------------------------------
0 SYSTEM
1 _SYSSMU1$
2 _SYSSMU2$
3 _SYSSMU3$
4 _SYSSMU4$
5 _SYSSMU5$
6 _SYSSMU6$
7 _SYSSMU7$
8 _SYSSMU8$
9 _SYSSMU9$
10 _SYSSMU10$
11 rows selected.
当前有这么多的回滚段,根据undo表空间负载情况系统会根据情况自动增加undo段数目
将一个回滚段的名字复制一下,如:_SYSSMU1$
复制进命令
select header_block,header_file from dba_segments where segment_name=’_SYSSMU1$’;
这个语句可以看到这个回滚段的段头块的地址
SQL> select header_block,header_file from dba_segments where segment_name='_SYSSMU1$';
HEADER_BLOCK HEADER_FILE
------------ -----------
9 2
地址是2号文件的第9个块
接着可以把段头块给dump出来
语句
alter system dump undo header ‘_SYSSMU1$’;
可以将_SYSSMU1$段的段头块dump出来
dump出来以后就可以去vi去看
dump一下试试
SQL> alter system dump undo header '_SYSSMU1$';
System altered.
dump成功了
我们去看一下它dump哪个文件去了
查看当前会话的进程编号语句
select spid from v$process where addr in (select paddr from v$session where
sid=(select sid from v$mystat where rownum=1));
执行结果
SQL> select spid from v$process where addr in (select paddr from v$session where
sid=(select sid from v$mystat where rownum=1)); 2
SPID
------------
21978
得到当前会话所对应的server process的进程ID号
刚才dump出来的数据
dump出的段头的信息就写到一个文件里面去
这个文件的命名就以serverprocess的编号命名
我们去找一下,记住21978
先退出当前会话
SQL> exit
Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
进入目录
[oracle@redhat4 ~]$ cd $ORACLE_BASE
[oracle@redhat4 oracle]$ cd admin
[oracle@redhat4 admin]$ ls
jiagulun
[oracle@redhat4 admin]$ cd jiagulun/
[oracle@redhat4 jiagulun]$ ls
adump bdump cdump dpdump pfile udump
这里有一个udump目录
[oracle@redhat4 jiagulun]$ cd udump/
最终路径
[oracle@redhat4 udump]$ pwd
/u01/app/oracle/admin/jiagulun/udump
[oracle@redhat4 udump]$ ls *21978*
jiagulun_ora_21978.trc
看到路径下有一个jiagulun_ora_21978.trc文件
这个文件里面就是我们dump出来的这个回滚段段头的信息
vi一下这个文件
[oracle@redhat4 udump]$ vi jiagulun_ora_21978.trc
文件内容:
/u01/app/oracle/admin/jiagulun/udump/jiagulun_ora_21978.trc
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1
System name: Linux
Node name: redhat4
Release: 2.6.9-78.ELsmp
Version: #1 SMP Wed Jul 9 15:39:47 EDT 2008
Machine: i686
Instance name: jiagulun
Redo thread mounted by this instance: 1
Oracle process number: 28
Unix process pid: 21978, image: oracle@redhat4 (TNS V1-V3)
*** 2017-08-03 10:16:01.750
*** SERVICE NAME:(SYS$USERS) 2017-08-03 10:16:01.750
*** SESSION ID:(145.3581) 2017-08-03 10:16:01.750
********************************************************************************
Undo Segment: _SYSSMU1$ (1)
********************************************************************************
Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 spare2: 0 #extents: 4 #blocks: 271
last map 0x00000000 #maps: 0 offset: 4080
Highwater:: 0x008003c9 ext#: 2 blk#: 64 ext size: 128
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 2
Unlocked
Map Header:: next 0x00000000 #extents: 4 obj#: 0 flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x0080000a length: 7
0x00800011 length: 8
0x00800389 length: 128
0x00800589 length: 128
Retention Table
-----------------------------------------------------------
Extent Number:0 Commit Time: 1501725693
Extent Number:1 Commit Time: 1501725693
Extent Number:2 Commit Time: 1501725693
Extent Number:3 Commit Time: 1501725693
TRN CTL:: seq: 0x0100 chd: 0x0012 ctl: 0x0018 inc: 0x00000000 nfb: 0x0001
mgc: 0x8201 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)
uba: 0x008003c9.0100.04 scn: 0x0000.000c07e1
Version: 0x01
FREE BLOCK POOL::
uba: 0x008003c9.0100.04 ext: 0x2 spc: 0x1d72
uba: 0x00000000.00fd.05 ext: 0x2 spc: 0xe94
uba: 0x00000000.00fa.02 ext: 0x2 spc: 0x1e86
uba: 0x00000000.0000.00 ext: 0x0 spc: 0x0
uba: 0x00000000.0000.00 ext: 0x0 spc: 0x0
TRN TBL::
index state cflags wrap# uel scn dba parent-xid nub stmt_num cmt
------------------------------------------------------------------------------------------------
0x00 9 0x00 0x013d 0x0007 0x0000.000c138c 0x008003c3 0x0000.000.00000000 0x00000001 0x00000000 1501725703
0x01 9 0x00 0x013d 0x0006 0x0000.000c13aa 0x008003c3 0x0000.000.00000000 0x00000001 0x00000000 1501725704
0x02 9 0x00 0x013d 0x0005 0x0000.000c146b 0x008003c3 0x0000.000.00000000 0x00000001 0x00000000 1501725963
0x03 9 0x00 0x013d 0x0011 0x0000.000c150f 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726182
0x04 9 0x00 0x013d 0x0009 0x0000.000c1409 0x008003c3 0x0000.000.00000000 0x00000001 0x00000000 1501725879
0x05 9 0x00 0x013d 0x000d 0x0000.000c1487 0x008003c3 0x0000.000.00000000 0x00000001 0x00000000 1501726008
0x06 9 0x00 0x013d 0x0004 0x0000.000c13cb 0x008003c3 0x0000.000.00000000 0x00000001 0x00000000 1501725768
0x07 9 0x00 0x013d 0x0001 0x0000.000c139a 0x008003c3 0x0000.000.00000000 0x00000001 0x00000000 1501725703
0x08 9 0x00 0x013d 0x000a 0x0000.000c1578 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x09 9 0x00 0x013d 0x0002 0x0000.000c1450 0x008003c3 0x0000.000.00000000 0x00000001 0x00000000 1501725963
0x0a 9 0x00 0x013c 0x001c 0x0000.000c1588 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x0b 9 0x00 0x013d 0x0017 0x0000.000c15b2 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x0c 9 0x00 0x013d 0x0018 0x0000.000c169e 0x008003c9 0x0000.000.00000000 0x00000001 0x00000000 1501726418
0x0d 9 0x00 0x013d 0x002f 0x0000.000c14a9 0x00000000 0x0000.000.00000000 0x00000000 0x00000000 1501726044
0x0e 9 0x00 0x013d 0x0014 0x0000.000c15f2 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x0f 9 0x00 0x013d 0x0003 0x0000.000c14e5 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726128
0x10 9 0x00 0x013d 0x0008 0x0000.000c155b 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x11 9 0x00 0x013d 0x0010 0x0000.000c1542 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726278
0x12 9 0x00 0x013c 0x001f 0x0000.000c080e 0x008005dc 0x0000.000.00000000 0x00000002 0x00000000 1501725104
0x13 9 0x00 0x013d 0x001e 0x0000.000c1622 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x14 9 0x00 0x013d 0x0013 0x0000.000c160f 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x15 9 0x00 0x013c 0x0028 0x0000.000c08c0 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725247
0x16 9 0x00 0x013d 0x0022 0x0000.000c1647 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726288
0x17 9 0x00 0x013d 0x000e 0x0000.000c15de 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x18 9 0x00 0x013d 0xffff 0x0000.000c16e1 0x008003c9 0x0000.000.00000000 0x00000001 0x00000000 1501726548
0x19 9 0x00 0x013c 0x0023 0x0000.000c08df 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725247
0x1a 9 0x00 0x013c 0x0020 0x0000.000c085a 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725148
0x1b 9 0x00 0x013c 0x001d 0x0000.000c091a 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725313
0x1c 9 0x00 0x013d 0x000b 0x0000.000c15a1 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x1d 9 0x00 0x013b 0x0026 0x0000.000c0930 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725313
0x1e 9 0x00 0x013d 0x0016 0x0000.000c162e 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726279
0x1f 9 0x00 0x013c 0x001a 0x0000.000c0835 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725148
0x20 9 0x00 0x013c 0x0021 0x0000.000c0874 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725183
0x21 9 0x00 0x013c 0x0015 0x0000.000c08b0 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725247
0x22 9 0x00 0x013d 0x000c 0x0000.000c167c 0x008003c8 0x0000.000.00000000 0x00000005 0x00000000 1501726374
0x23 9 0x00 0x013c 0x001b 0x0000.000c0905 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725282
0x24 9 0x00 0x013c 0x002d 0x0000.000c09a8 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725492
0x25 9 0x00 0x013c 0x0000 0x0000.000c0b99 0x008003c2 0x0000.000.00000000 0x00000075 0x00000000 1501725693
0x26 9 0x00 0x013c 0x0024 0x0000.000c0975 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725408
0x27 9 0x00 0x013c 0x002e 0x0000.000c0a04 0x008005dd 0x0000.000.00000000 0x00000001 0x00000000 1501725638
0x28 9 0x00 0x013c 0x0019 0x0000.000c08d3 0x008005dc 0x0000.000.00000000 0x00000001 0x00000000 1501725247
0x29 9 0x00 0x013c 0x002b 0x0000.000c0a50 0x008005dd 0x0000.000.00000000 0x00000001 0x00000000 1501725679
0x2a 9 0x00 0x013c 0x0029 0x0000.000c0a26 0x008005dd 0x0000.000.00000000 0x00000001 0x00000000 1501725638
0x2b 9 0x00 0x013c 0x002c 0x0000.000c0a68 0x008005dd 0x0000.000.00000000 0x00000001 0x00000000 1501725679
0x2c 9 0x00 0x013c 0x0025 0x0000.000c0a76 0x008005dd 0x0000.000.00000000 0x00000001 0x00000000 1501725679
0x2d 9 0x00 0x013c 0x0027 0x0000.000c09e6 0x008005dd 0x0000.000.00000000 0x00000001 0x00000000 1501725573
0x2e 9 0x00 0x013c 0x002a 0x0000.000c0a13 0x008005dd 0x0000.000.00000000 0x00000001 0x00000000 1501725638
0x2f 9 0x00 0x013c 0x000f 0x0000.000c14d6 0x008003c4 0x0000.000.00000000 0x00000001 0x00000000 1501726119
这就是信息
关于这个段头可以去读里面相关的信息
如:
********************************************************************************
Undo Segment: _SYSSMU1$ (1)
********************************************************************************
部分说明是哪个回滚段
里面有一些区的信息
如:
Extent Control Header
-----------------------------------------------------------------
Extent Map
-----------------------------------------------------------------
Retention Table
-----------------------------------------------------------
最后面的部分
TRN TBL::后面
是事务表
刚才给大家讲了一个操作
如何把块给dump出来,然后再去看
除了dump出来dump段头块以外
我们单独的去dump出来某个数据块也可以
如:
alter system dump datafile 5 block 4308;//转储数据块
把某个文件的某个块dump出来
关于
alter system dump undo header ‘_SYSSMU1$’;//转储回滚段头
转储回滚段段头块,转储出来以后如何去细细的解读
会作为以后的一个高级课程,去讲段头块里面的一些细节
我们回顾一下刚才讲的内容
Undo段的组成:段头、回滚块
事务ID
select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction;
事务表
undo段的第一个数据块,每一个回滚段最多可以47个事务
回滚段的段头块
select * from v$rollname;
select header_block,header_file from dba_segments where segment_name=’_SYSSMU1$’;
alter system dump undo header ‘_SYSSMU1$’;//转储回滚段头
alter system dump datafile 5 block 4308;//转储回滚段数据块
实例中有三个地方有undo信息
Undo Segment Header 回滚段段头
Data block header 数据块头
Undo block 回滚块
已下面的语句为例:
Begin transaction
T1:update table set column=' value' where id=1;
T2:update table set column=' value' where id=2;
T3:update table set column=' value' where id=3;
Commit;
开始一个事务
然后这个事务做了三个操作
不管怎么说开始一个事务了
Undo Segment Header是undo段的段头块
开始一个事务首先找到一个回滚段
找到回滚段以后就在回滚段的段头块的事务表里面将我的事务信息写上
然后一个事务开始了
一个事务开始做的第一个事情
在undo段的段头块的事务表里面找一个空槽控制槽位
把事务信息写上
事务的基础还有一个:事务槽
一个事务可能修改一个数据块,在数据块块的头部有事务槽
一个事务可以修改多个数据块
一个数据块有多个事务槽,可以有1到255个
修改一个数据块,首先这个事务要
在这个数据块的头部的事务槽的位置找一个事务槽一个空槽将我的事务信息写上
一个事务开始以后
首先在回滚段的段头块的事务表里面写上一行事务信息
第二个在那个要修改的数据块的块的头部的事务槽里面也要写上事务信息
目前为止我们发现一个事情
一个事务开始以后至少要在两个位置,不是说两个具体地方是在两个位置
一个位置是回滚段的段头块的事务表里面写上事务信息
第二个位置在要修改的数据块里面还要写上事务信息
事务信息为什么要在两个地方
和oracle事务的一种提交方式有关
事务表是在undo回滚段的段头块里面
事务槽在具体的数据块里面,比如要修改的某个数据块
事务槽也可以dump出来vi去看
需要把数据块dump出来看其中的事务槽
事务表、事务槽讲了,还有个UBA(undo block address)
是undo数据块的地址
第一个是在回滚段的段头块里面事务表
第二个事务槽是我们要修改的那个数据块,块的头部有事务槽
第三个叫回滚块 我要修改这个数据块的时候
我会做一件事情,把要修改前的数据存起来,存到回滚块里面去
回滚块是实实在在的存回滚数据的
事务表和事务槽都是存事务信息的
所以说回滚块会有很多
讲了回滚块、事务表、事务槽三个概念
一个事务开始的时候首先oracle做一件事情
在undo表空间里面找一个相对空闲的undo段
然后在undo表空间里面一个相对空闲的undo段的段头块的事务表里面
找其中的一个槽位
找到里面一个槽位以后,将自己的事务信息写上,写到这个槽位上
同时在Undo Segment Header做完后
其实oralce还会给这个事务分配一个undo块
因为一个事务开始以后
只是在undo回滚段段头的事务表里面分配一个槽位,不够
还要给他分配一个undo块,这个undo块实实在在的写数据
同时将undo块的地址写到事务表里面去
第一步找回滚段,段头,段头里面找到事务表
事务表里面将xid写上
同时还要在回滚段里面分配一个空块
这个空块要给oracle写回滚数据
事务表的槽位里面除了写xid以外还要写UBA地址
就是所分配的一个回滚块地址
第二步要实实在在的修改数据了
要修改某个数据块
首先在要修改的数据块的头部事务槽里面又找到一个槽位
把XID(事务id)写上
这个事务id既是一个编号也是一个地址
会写到我要修改的数据块的事务槽里面去
接着修改里面的数据
比如修改了三行数据
修改数据以后,我就需要把修改前的数据保存到undo块里面去
针对这个事务的undo块已分配了
就把修改前的数据写到undo块里面去
同时数据块事务槽里面也有uba地址,它指向回滚块
描述到目前为止就有点脉络了
我们再来剖析一下Xid(transaction identifier 或 Transaction ID)
事务的Xid既是事务编号也是个地址
它代表着这个事务用哪个回滚段
首先它在段的头部,还有使用哪个回滚段,使用哪个段头块
xid里面写的信息
第一个、
使用了哪个回滚段的段头块
第二个、
段头块事务表里面有47行,使用的哪一行
第三个、
所用槽位是第几次被使用
回过来看看事务表
一个事务表有47行
第一个因素xid是使用哪个回滚段的段头块
找到这个块了有一个回滚段段的编号
第二个事务表里有47行
找到事务表里的哪一行
这两个都确定以后
可以确认是一行了
但不能唯一的确认是这一行
这个事务表里的47行可能被覆盖了多次
是第几次覆盖,比如第十次覆盖
块号行号加上是第10次覆盖
可以唯一的标志某一行
举例讲
对我们来讲事务是唯一的
事务编号也是唯一的
假设没有第3部分会出现
第一个事务A事务
用了2号段头的第13行
用完了以后提交了,提交了以后就可以被覆盖了
过了很长时间
有可能B事务也是用了2号段的第13行
如果xid中使用回滚段的段号和事务表中的行号这两个信息
如果唯一的标识事务id的话
就会出现两个事务事务id一样
加上一个覆盖的次数
比如A事务是第一次覆盖,而B事务是第13次覆盖或第14次覆盖
这三个信息和起来
就可以唯一的组成事务的id,即XID
所以说xid由三块组成
块号 行号 和 覆盖次数
包括第几次被repeat被循环使用
通过xid事务id可以找到事务表
回顾一下
第一步、
一个事务开始oracle做的第一件事情
在undo表空间里找一个相对空闲的undo段
找到undo段的段头块里的事务表
在事务表里面找到其中一行,把事务信息写上
除了在事务表里面找到一个槽位
还要在这个回滚段里面找到一个undo块
让它事务表中的槽位指向这个块
第二步、
我要修改具体的数据块
要修改数据块的时候
首先在数据块的头部的事务槽里面找一行
然后要修改数据块的事务槽里面把xid写上
这个事务编号就指向undo段头部的事务表中的那个记录
因为xid是地址,通过地址可以找到事务表
第三步、
然后对数据块进行修改
如:
修改了1行2行3行4行5行
修改了5行
然后它把这5行信息写到回滚块里面去
同时数据块的事务槽有地址指向这个回滚块
这个事务我修改了一个块,还可以修改第二个块
一个事务可以修改多个块
同样的这个事务修改的数据块头部有事务槽
把数据块头部事务槽指向undo段头部的事务表中的那个事务记录
然后在第二个数据块中修改
修改的时候这个回滚块满了
再分配一个回滚块
然后把数据块的修改信息写进去
第二个数据块头部的事务槽又指向新的回滚块
这两个回滚块有先后关系
有最早的回滚信息和最新的回滚信息
新的回滚块指向早的回滚块把这两个回滚块链起来
就是新的回滚块有个链接指向老的回滚块
也就是找到最新的回滚信息可以依次向前推
这时事务表里面的uba就指向这个事务最新的回滚块
当然可以再继续加修改、修改……
每个数据块指向自己对应修改时最新的回滚块
最新修改的数据块中事务uba指向最新的回滚块
undo段段头有事务表
段头里面有XID还有UBA
段头事务表中事务的uba指向最新的undo段
比如一个事务产生有三个回滚块
因为我这个事务修改了很多数据
可能产生了很多个回滚块
有最新的回滚块,有其次新的,有最老的回滚块
一个事务的回滚块自动地它们串起来了
我们知道数据块块的头部
都有个xid使数据块指向事务表
一个事务的所有数据块头部的xid都指向事务表中的一行数据
修改的某一个数据块
修改前的数据放到了一个回滚块里面
各个数据块里面的uba都指向各自修改时的回滚块
一个事务对应undo段头的uba指向最后一个最新的那个回滚块
有这两种UBA的原因:
假设一个事务修改三个数据块块
先修改了第一个块,再修改第二个块,又修改了第三个块
要回滚的时候
要先把第三个块的数据回滚回去,再把第二个块的数据回滚回去
先修改了产生1号块,再修改产生2号块,再修改产生3号块
修改的顺序1、2、3
要回滚的时候
把3号回滚块中的数据先回滚回去,再回滚2号,再回滚1号
修改的时候从1、2到3
回滚的时候逆着回滚
undo段头事务表中这个事务uba指向最新的回滚块
要回滚的时候,根据事务表中的uba找到最新的
先把最新的回滚块回滚了
因为最新的回滚块有个地址指向前一个回滚块,这里指向了第二个
再把第二个回滚块回滚了
第二个回滚块又指向了第一个回滚块
这里再把最早的一个回滚块回滚了
回滚完以后,第一个回滚块不指向任何块了
表示这个事务回滚完了
oracle做rollback的时候
会这样做:
首先在事务表里找到这个要回滚的事务
然后找到uba,再找到最新的回滚块把对应数据块回滚了
然后使用前一个回滚块把它对应的数据块回滚了
然后再使用最早的回滚块把它对应的数据块回滚了
这样就回滚完了,rollback成功了
例中三个回滚块串起来
undo段头事务表中的对应事务记录指向最后的undo block
是有道理的
数据块中的事务槽中有一个地址指向一个回滚块
有直接指向的意义
数据块数据槽中的uba直接指向回滚块
是数据块实实在在的指向它自己的回滚数据
一个数据块要找回滚数据的话
第一种办法、
可以直接找过来,从数据块的事务槽uba信息直接找到回滚块
第二个办法、
从数据块找到undo段头事务表中对应的事务信息,再过来找到undo块也可以
因为从数据块找到事务表再找到undo块一个链也可以找到
数据块单独有地址指向回滚数据,这个链短
在要进行cr读、读一致性的时候有好处
读数据块的时候发现这个块有未提交事务,就需要构造cr块
就找一个空块把数据块和undo块信息两个合起来,拼成一个新块,然后读这个块
如果这个数据块直接写上对应undo块地址的话
直接读数据块和对应的回滚块两个块就可以了,就可以拼一个cr块
不需要再读段头了
在数据块里面直接写上uba地址指向自己的回滚数据
将来对cr读非常有帮助,也有意义
undo segment header 和 data block header 和 Undo block
的事务信息之间有很多的链,有很多的地址
它们的意义:
1、rollback
在回滚段的段头块里面有事务有事务信息和uba地址
事务表uba地址指向该事务最后一个undo块
最后一个undo块又串着前一个undo块又向前串着上一个undo块
意义主要是为rollback回滚做准备
2、cr读
数据块的事务槽有uba直接指向undo块回滚数据
是为了一致性读cr做准备
3、快速提交
数据块xid还要指向undo段头的事务表
此意义下节课讲,先简单的描述一下就是
如果一个事务快速提交时未清理这个事务对应数据块事务槽中的相关信息,
再有其它操作需要修改这个数据块中前面这个事务已修改的数据时,在事务槽不能确定这个事务的提交状态
就需要通过这个事务槽找到这个事务在事务表中对应的行,来最终确定前面这个事务的提交状态
所以需要这种指向链
上面讲了一个事务改变过程
我们再来描述一下这个事务的修改过程
第一步、
一个事务开始
首先在undo表空间里面相对空闲的undo段的段头块的事务表里面找一行信息,将自己的xid写上
同时在undo段里面分配一个空块,回滚块
同时将回滚块的地址写到事务表里的事务槽里面去
在undo里面操作完成
第二步、
要修改具体的数据块
修改任何一个数据块都是要在数据块块的头部获取到一个事务槽
然后将xid写上就是将事务id写上
获取到事务槽就开始修改数据块
修改数据块的时候
还将修改前的数据写到回滚块里面去
因为这个事务已经被分配一个回滚块了,就直接写到回滚块里面去
同时将这个数据块所对应的回滚块的地址也写到事务槽里面去
回滚数据写完了,接下来修改实实在在的行
第一个数据块修改完了
再修改第二个数据块
同样的操作,再修改第三个数据块
同时如果这个时候一个回滚块不够以后
要分配第二个第三个回滚块
回滚块和回滚块之间要串起来
最老的回滚块串其次新的再串最新的
同时如果你加了回滚块了
会把最新的回滚块信息写到事务表里面去
这是整个事务的操作流程
同时我们也知道了
这三个回滚块串起来
以及事务表的uba指向最新的回滚块有意义是为了回滚
在每个数据块里面
直接写uba指向自己的undo数据也是有意义的是为了构造cr块
一个事务信息在两个地方都有
事务块里面也有,事务表里面也有
数据块里面的事务槽指向undo段头的事务表
这个和oracle的一种提交方式有关,下节课讲
在这个过程中
一个事务开始以后
oracle修改了四个地方
第一个
回滚段的段头块的事务表被修改了
第二个
回滚块被修改了
第三个
数据块的事务槽被修改了
第四个
数据块里面实实在在的数据行被修改了
有4个地方被修改了
这四个地方的数据都在数据块里面
数据块的任何地方的改变都会产生redo
在刚才整个过程里面
这四个地方被修改都产生redo
redo不仅仅记录的是数据行的改变
事务槽的改变undo块的改变事务表的改变一样都会产生redo
这就是一个事务的一个操作流程
也讲了怎么转储回滚段头、转储回滚段数据块,怎么去看
2017年8月25日
文字:韵筝