Oracle 学习笔记 图解深入剖析一个事务的操作流程

Posted 新站

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle 学习笔记 图解深入剖析一个事务的操作流程相关的知识,希望对你有一定的参考价值。

Oracle 学习笔记

图解深入剖析一个事务的操作流程

这节课讲一下一个事务的操作流程
内容有点难度

先简单的看一下

一)事务ID

当一个事务开始以后
在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信息
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

我们再来剖析一下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指向最新的回滚块

八)UBA的指向

undo段段头有事务表
段头里面有XID还有UBA

段头事务表中事务的uba指向最新的undo段

比如一个事务产生有三个回滚块

因为我这个事务修改了很多数据
可能产生了很多个回滚块
有最新的回滚块,有其次新的,有最老的回滚块
一个事务的回滚块自动地它们串起来了

我们知道数据块块的头部
都有个xid使数据块指向事务表

一个事务的所有数据块头部的xid都指向事务表中的一行数据

修改的某一个数据块
修改前的数据放到了一个回滚块里面

各个数据块里面的uba都指向各自修改时的回滚块

一个事务对应undo段头的uba指向最后一个最新的那个回滚块

有这两种UBA的原因:

1)事务表中的UBA作用

假设一个事务修改三个数据块块
先修改了第一个块,再修改第二个块,又修改了第三个块

要回滚的时候
要先把第三个块的数据回滚回去,再把第二个块的数据回滚回去

先修改了产生1号块,再修改产生2号块,再修改产生3号块
修改的顺序1、2、3

要回滚的时候
把3号回滚块中的数据先回滚回去,再回滚2号,再回滚1号

修改的时候从1、2到3
回滚的时候逆着回滚

undo段头事务表中这个事务uba指向最新的回滚块

要回滚的时候,根据事务表中的uba找到最新的
先把最新的回滚块回滚了

因为最新的回滚块有个地址指向前一个回滚块,这里指向了第二个
再把第二个回滚块回滚了

第二个回滚块又指向了第一个回滚块
这里再把最早的一个回滚块回滚了
回滚完以后,第一个回滚块不指向任何块了
表示这个事务回滚完了

oracle做rollback的时候
会这样做:

首先在事务表里找到这个要回滚的事务
然后找到uba,再找到最新的回滚块把对应数据块回滚了
然后使用前一个回滚块把它对应的数据块回滚了
然后再使用最早的回滚块把它对应的数据块回滚了
这样就回滚完了,rollback成功了

例中三个回滚块串起来
undo段头事务表中的对应事务记录指向最后的undo block
是有道理的

2)事务槽中UBA作用

数据块中的事务槽中有一个地址指向一个回滚块
有直接指向的意义

数据块数据槽中的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日
文字:韵筝

以上是关于Oracle 学习笔记 图解深入剖析一个事务的操作流程的主要内容,如果未能解决你的问题,请参考以下文章

C语言深度剖析深入理解C语言中的移位操作符(代码+图解)

Oracle学习笔记 读一致性(ORA-01555错误机制分析)及Undo表空间大小设置

Oracle学习笔记 读一致性(ORA-01555错误机制分析)及Undo表空间大小设置

深入剖析 HIVE 的锁和事务机制

深入剖析 HIVE 的锁和事务机制

oracle学习笔记 锁相关视图及相关操作