暂无图片
暂无图片
4
暂无图片
暂无图片
暂无图片

oracle数据库中undo机制(一)

原创 _ 2025-01-24
425

一、提交与回滚的机制对比

1.提交机制

Oracle提供了多种机制(如管道、外部程序或utl_file)来从PL/SQL块中推送消息,以便及时发现提交与查询数据之间的差异。
提交时,Oracle不需要重新标记所有已更改的块,以避免与更改本身相同的时间消耗。
Oracle设计为使提交尽可能快,而允许回滚机制更慢。

2.回滚机制

如果决定回滚而不是提交,Oracle需要一个机制来按相反顺序链接所有更改的撤销记录,以便撤销更改。
由于实际回滚更改是(或应该是)相对于提交的罕见事件,Oracle优化了提交过程,而回滚过程可以更慢。

二、Undo段头块

1. Undo段头块概述
Undo段头块是存储在Undo表空间中的一个特殊块,它包含了Undo段的控制信息和事务表。
存储Undo信息:Undo段头块用于存储Undo段的控制信息,这些信息对于数据库事务的回滚和一致性至关重要。
事务控制:每个Undo段头块中都包含一个事务控制部分,它保存了关于该段事务表状态的汇总信息。
2. Undo段头块的组成部分
事务表:事务表是一个简短的列表,保存在每个Undo段头块中,包含最近事务的参考详细信息。
事务控制:事务控制部分包含有关Undo段事务表状态的汇总信息。
3. Undo段头块中的关键信息
  • 3.1 数据块地址(DBA)
    DBA是Redo Change Vector中最重要的细节之一,它标识了将要写入的块的块头信息,例如块0x0080009a,这可能是数据文件2(Undo表空间所在的文件)的块154。
  • 3.2 事务ID
    事务ID是最近修改了该块的事务的标识,格式为Undo段.Undo槽.Undo序列号。
SQL> select trunc(ID1/65535) usn,mod(id1,65535) slot,id2 wrap# from v$lock where type='TX';
       USN       SLOT      WRAP#
---------- ---------- ----------
        10         31        880
SQL> select XIDUSN,XIDSLOT,XIDSQN,STATUS from v$transaction where status='ACTIVE';
    XIDUSN    XIDSLOT     XIDSQN STATUS
---------- ---------- ---------- --------------------------------
        10         21        880 ACTIVE

三、事务表

事务表是记录在Undo段中的重要组件,用于追踪和管理事务信息。事务表中的条目数量有限,因此只能记录一定数量的近期事务。必须重复使用条目,这涉及到wrap#列的使用。
wrap#列:每次重用事务表中的条目时,该条目的wrap#值会递增。
事务控制:是Undo段头块中的一个部分,包含有关该段事务表状态的汇总信息。包含用于指示下一个和最后一个使用的事务表槽的信息。

1.事务表条目的重用和信息保存

在重用事务表条目前,Oracle需要保存该条目中的信息。每个事务表条目的提交SCN(系统变更号)和事务的第一个Undo记录的地址被写入事务控制中。之前的事务控制信息被写入新事务的第一个Undo记录中,形成可用于回滚事务表的Undo记录链表。

2. Oracle错误ORA-01555

如果Oracle在跟随Undo段的指针列表时遇到一个具有错误seq(化身)号的Undo块,将引发Oracle错误ORA-01555,“snapshot too old”,因为所需的块已被重用。

3. 事务表信息的访问

无需进行块转储,即可通过xktuxe结构访问事务表信息。xktuxe是一个特殊的结构,查询该结构会导致Oracle访问数据库中每个Undo段的每个Undo段头块。该结构的内容格式化不同,且cmt列(事务提交时间)不可用。

4. x$ktuxe
  • indx:标识事务表中的行,通常被称为事务表槽号。不是物理存储在块中的值,而是通过位置推导得出。
  • ktuxesta:事务状态。
  • ktuxecfl:相关的控制标志。
  • ktuxesqn:事务序列号。
  • wrap#:
  • ktuxescnw(scnW):某种 SCN 相关的值。
  • ktuxescnb(scnB):另一种 SCN 相关的值。
  • ktuxerdbf(dba_file):数据文件号。
  • ktuxerdbb(dba_block):数据块号。
  • ktuxesiz(nub):相关数量。
SQL> select addr,kaddr,sid,type,trunc(id1/65535),mod(id1,65535),lmode,ctime from v$lock where type ='TX';
ADDR             KADDR                   SID TYPE TRUNC(ID1/65535) MOD(ID1,65535)      LMODE      CTIME
---------------- ---------------- ---------- ---- ---------------- -------------- ---------- ----------
000000006C945A18 000000006C945A50        415 TX                  9             32          6        132

SQL> select indx,ktuxeusn,ktuxesta,ktuxecfl,ktuxesqn wrap#,ktuxescnw scnW,ktuxescnb scnB,ktuxerdbf dba_file,ktuxerdbb dba_block,ktuxesiz nub from x$ktuxe where  KTUXESTA='ACTIVE';
      INDX   KTUXEUSN KTUXESTA                         KTUXECFL                            WRAP#       SCNW       SCNB   DBA_FILE  DBA_BLOCK        NUB
---------- ---------- -------------------------------- ------------------------------ ---------- ---------- ---------- ---------- ---------- ----------
       393          9 ACTIVE                           NONE                                 1023          0    2460321          4       2889          1

SQL> select XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,STATUS,START_TIME,FLAG,SPACE from v$transaction where XIDUSN=9;
    XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK STATUS                           START_TIME                                     FLAG SPACE
---------- ---------- ---------- ---------- ---------- -------------------------------- ---------------------------------------- ---------- ------
         9         23       1023          4       2889 ACTIVE                           01/24/25 23:26:48                              3587 NO 

四、事务的开始和结束定义

1.事务开始
  • 会话启动事务时,会选择一个undo段(undo segment),并从事务表中选取一个条目。
  • 增加wrap#值,将事务状态更改为“active”(值为10)。
  • 修改其他一些列。
  • 由于这是对数据库块的更改,将生成一个带有OP代码5.2的redo变更向量(redo change vector),最终进入redo日志文件。
  • 这表明会话具有一个活动的事务,并将其写入数据库。
2. 事务结束
  • 通常是commit
  • 将事务状态更改为“free”(值为9)
  • 修改其他一些列。
  • 由于这是对数据库块的更改,将生成一个带有OP代码5.4的redo变更向量(redo change vector),最终进入redo日志文件。
  • 调用lgwr写日志

五、数据块

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc
0x01   0xffff.000.00000000  0x00000000.0000.00  C---    0  scn  0x0000000000261876
0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
0x03   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000
bdba: 0x0041c421
data_block_dump,data header at 0xa2a54074
===============
tsiz: 0x1f88
hsiz: 0x26
pbl: 0xa2a54074
     76543210
flag=--------
ntab=1
nrow=10
frre=-1
fsbo=0x26
fseo=0x1b73
avsp=0x1b4d
tosp=0x1b4d
0xe:pti[0]  nrow=10 offs=0
0x12:pri[0] offs=0x1f16
0x14:pri[1] offs=0x1ea2
0x16:pri[2] offs=0x1e31
0x18:pri[3] offs=0x1dd3
0x1a:pri[4] offs=0x1d5f
0x1c:pri[5] offs=0x1d01
0x1e:pri[6] offs=0x1ca3
0x20:pri[7] offs=0x1c2f
0x22:pri[8] offs=0x1bd1
0x24:pri[9] offs=0x1b73
block_row_dump:
tab 0, row 0, @0x1f16
tl: 114 fb: --H-FL-- lb: 0x0  cc: 22
col  0: [ 3]  53 59 53
col  1: [ 3]  54 53 24
col  2: *NULL*
col  3: [ 2]  c1 11
col  4: [ 2]  c1 07
col  5: [ 5]  54 41 42 4c 45
col  6: [ 7]  78 77 04 11 01 39 0c
col  7: [ 7]  78 77 04 11 02 2f 3a
col  8: [19]  32 30 31 39 2d 30 34 2d 31 37 3a 30 30 3a 35 36 3a 31 31
col  9: [ 5]  56 41 4c 49 44
col 10: [ 1]  4e
col 11: [ 1]  4e
col 12: [ 1]  4e
col 13: [ 2]  c1 02
col 14: *NULL*
col 15: [13]  4d 45 54 41 44 41 54 41 20 4c 49 4e 4b
col 16: *NULL*
col 17: [ 1]  59                                                                                                                                                                                                                        
col 18: [ 1]  4e
col 19: [14]  55 53 49 4e 47 5f 4e 4c 53 5f 43 4f 4d 50
col 20: [ 1]  4e
col 21: [ 1]  4e
tab 0, row 1, @0x1ea2
  1. Itl
    • 表示数组索引,用于列表中。
    • 数字不是物理存储在块中,而是由执行转储的代码生成。
    • 用于行的锁字节(lb:)中,显示哪个事务锁定了该行。
  2. Xid
    • 表示事务ID。
  3. Uba
    • 表示撤销记录地址。
  4. Flag
    • 包含多种标志位,用于描述事务的状态和特性。
    • 例如:"-B–"可能与递归事务中的索引块拆分有关。
    • 该标志意味着UBA指向一个记录,该记录保存了ITL条目的先前内容,但这一点尚未得到确认。
  5. Lck
    • 表示锁状态。
  6. Scn/Fsc
    • 表示系统变更号(SCN)或文件系统更改号(FSC)。
    • SCN用于记录事务的提交点。
    • FSC用于记录事务的回滚点。
      六、数据块转储分析
  7. 数据块头部信息
    • tsiz: 0x1fa0 表示数据块的总大小。–8096
    • hsiz: 0x18 表示头部大小。
    • pbl: 0xa2a54074 表示数据块的物理位置。
    • flag: 表示数据块的标志位。
    • ntab: 1 表示表的数量。
    • nrow: 10 表示行的数量。
    • frre: -1 表示自由空间的行号。
    • fsbo: 0x26 表示自由空间的偏移量。
    • fseo: 0x1b73 表示下一个行条目的偏移量。
    • avsp: 0x1b4d 表示可用空间的偏移量。
    • tosp: 0x1b4d 表示顶部空间的偏移量。
  8. 行条目信息
    • pti[0] 表示第一个行条目。
    • nrow=10 表示行的数量。
    • offs=0 表示行条目的偏移量。
    • pri[0] 表示第一个行。
    • offs=0x1f16 表示行的偏移量。
    • pri[1] 表示第二个行。
    • offs=0x1ea2 表示行的偏移量。
    • pri[2] 表示第三个行。
    • offs=0x1e31 表示行的偏移量。
  9. 行数据转储
    • 显示了三个行的数据。
    • 每个行包含两个列。
    • 列的值分别为[ 3] 53 59 53。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论