通过自己学习总结的这些undo知识能够让大家都能深刻了解oracle的undo相关原理。

一、undo撤销表空间的作用

撤销表空间通常称为undo表空间:undo表空间的段也称为撤销段或undo段、回滚段;撤销段中存放的数据就是撤销信息,这些撤销信息也称为撤销数据或undo数据。撤销段是最直接管理撤销新的逻辑层。

1.1、读写一致性

在不同的进程或用户模式下检索数据时,oracle只能给用户提供被提交的数据,这样可以确保数据的一致性。某个连接登录到数据库对某个表某个行进行update操作时未提交,其他连接查询该行数据只能查询到该行被改变之前的数据。具体实现的过程是undo段中记录该行数据的镜像,第二个连接上来,在buffer中找一个块,从Undo回滚段中找出前面的镜像,加上该行所在块其他未修改的行,合成一个块一起构造成cr块,我们叫它构造cr块,保证一致性读。

1.2、可以回滚事务

当执行修改操作如insert、delete、update操作时,旧的数据被存放到undo段中,新的数据(脏数据)在没被dbwr写到数据文件时是存放在数据文件的块所对应的buffer块中。如果影虎不想完成之前的操作就可以回滚,rollback进行回滚。

1.3、事务恢复

事务恢复是实例恢复的一部分,他是oracle服务器自动完成的,如果数据库在运行过程中出现实例失败如断电等,那么当重启oracle服务时,后天进程smon进程会自动执行实例恢复,在恢复的过程中,跑日志前滚并回滚未提交的事务。

1.4、闪回操作

11g新增了强大的闪回功能,其中很多闪回技术都是基于undo段实现的,比如闪回表,闪回事务查询,闪回版本查询。

二、undo段的初始化参数

2.1、undo_tablespace

该参数用于指定实例所要使用的undo表空间,使用自动undo管理时,通过配置该参数指定实例所使用的undo表空间。如果auto模式没有指定第一参数的话,oracle会自动选择第一个可用的undo表空间来存放undo数据,如果没有可用的undo表空间的话,oracle会使用system表空间存放undo数据,并在alter日志中告警。

2.2、undo_management

该参数用于指定undo表空间的管理模式,如auto自动管理模式,manual则为手动管理模式。

2.3、undo_retention

该参数用于控制undo数据最大保留事假,默认是900秒即为15分钟。从9i开始配置该参数指定保留时间,这个参数我是这么理解的,事务A的回滚段(已提交,该回滚段为inactive),当数据库的事务不是特比多或者基本没有其他事务,A事务undo数据可以被保存很长时间,当数据库的事务正常,可能15分钟的时候被覆盖,也可能20分钟被覆盖,但是当数据库事务繁忙,undo表空间没有空余的free expired的空间的话,A事务对应的回滚段数据可能第5分钟就被覆盖了。如果需要固定必须15分钟后才被覆盖的话,可以设置参数,

alter tablespace undotbs1 retention guarantee,则此时无法使用Inactive的undo段,如果没有free,则自动扩展,如不能扩展则优先使用expired,但是此时设置了retention guarantee,无法使用inactive,此时数据库容易产生ora-30035。我们可以通过下面语句查询回滚段信息:

select segment_name,tablespace_name,status from dba_undo_extents;

free --没有分配给任何段

active---区中有事务没有提交

inactive--区中有事务已提交,但是没有超过undo_retention时间

expired---事务提交了,也超过undo_retention时间

三、事务跟undo的关联

1、事务表

oracle在undo表空间的段中的第一个块存在一个事务表,事务表最多有47行,每一行可以放一个事务。当一个事务开始的时候,oracle给它分配一个xid事务编号,这个时候这个事务会做的第一件事就是在undo表空间找一个段,在段头块中找一行,把自己的事务信息写上,至少写上xid。oracle一个事务尽量使用一个回滚段,如果事务太多回滚段太少,这时会出现多个事务使用一个回滚段,oracle尽量均匀的将活动的事务分布在各个回滚段。总结:事务表在undo段中的一个数据块中,每一个回滚段最多同时可以有47个活动的事务。

select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction;

2、回滚段的段头块

数据库有多少回滚段

select * from v$rollname;

可以用以上的sql查看,当前有查询结果出来的这么多段头块,根据undo的负载情况系统会自动增加undo的段头块数量。查询段头块地址:

select header_block,header_file from dba_segments where segment_name='_SYSSMU1_3086899707$';
HEADER_BLOCK HEADER_FILE
------------ -----------
         128           3
上面的结果就是3号文件的第128个块,3号文件就是undo的表空间文件。我们可以把这个段头块给dump出来,并进行查看
alter system dump undo header '_SYSSMU1$';
上面执行成功后,我们查询下我们当前连接的进程号:
SQL> select spid from v$process where addr in (select paddr from v$session where sid=(select sid from v$mystat where rownum=1));
SPID
------------------------
5632
然后去oracle软件的安装目录去查找*_ora*5632.trc,在Windows下可以编辑查看,Undo Segment:  _SYSSMU1_3086899707$ (1)就是这个段头块的信息,TRN TBL::就是事务表的信息。( alter system dump datafile 5 block 4308;//转储数据块)
 
3、undo的位置信息
实例在三个地方有undo的信息:undo segment header回滚段段头块,data block header数据块块头,undo block回滚块上。
一个事务开始,先找一个回滚段,在回滚段段头块的事务表中找一个空的事务槽位,写上事务信息如xid。事务的基础还有一个就是事务槽,一个事务可以修改一个数据块,数据块上有事务槽,一个数据块有多个事务槽,1-255,修改一个数据块,首先这个事务要在数据块头部的事务槽找一个空的槽位写上事务信息。
根据前面这两点,我们知道了,一个事务开始以后,首先在undo表空间找到一个回滚段,在回滚段的段头块的事务表写上一行事务信息,在要修改的数据块头部的事务槽上写上事务信息。关于事务信息为什么要在上面说的两个地方写上和oracle事务的一种提交方式有关。
undo数据块的地址:oracle要修改数据块的话,要将数据块修改前的数据存到回滚块里去,回滚块是实实在在存数据的,而事务表跟数据块的事务槽都是存事务信息的,所以回滚块会有很多。
 
4、事务表、事务槽、回滚块的关系

一个事务开始的时候,首先oracle做一件事情,在undo表空间上找一个相对空闲的undo段的段头块的事务表上找一个空的槽位,在上面写上事务信息。同时给这个事务分配一个undo块,同时将undo块的地址写到事务表里,即UBA地址。以上第一步是找回滚段段头里的事务表,在事务表里写上XID,同时分配一个undo块,并在刚才的事务槽上写上UBA地址。第二步要实实在在的修改数据了,要修改数据块,首先在要修改的数据块的头部事务槽里找到一个空的槽位,把XID写上,接着修改数据块,比如修改了三行数据,修改数据以后就需要把修改前的数据保存到undo块里面去,针对这个事务的Undo块已经分配了,就把修改前的数据写到undo块里去,同时数据块的事务槽里也写上UBA地址,他指向回滚块。
 
5、xid事务id
xid (transaction identifier 或transaction id)
事务的xid即是事务编号,也是一个地址,它代表着这个事务用哪个回滚段,
xid的信息内容包括:使用了哪个回滚段段头,段头块的事务表有47行该事务使用的是哪一行,所在的槽位是第多少次被使用(第多少次被覆盖),所以说xid有三块内容组成,块号、行号和覆盖次数,这就是确定了这个事务的唯一性。
 
6、事务流程中的事务信息
回顾一下,第一步:一个事务开始oracle做的第一件是,在undo表空间里找到一个相对空闲的undo段,找到回滚段段头块里的事务表,在事务表里找到其中一行,把事务信息写上,除了在事务表找到一个槽位,还要在回滚段里找到一个undo块,让事务表中的槽位指向这个块。
第二步,这时要修改具体的数据块,首先在数据块的头部的事务槽里找一行,然后在事务槽写上xid,这个事务编号就相当于指向了undo头部事务表中的那个记录,因为xid是地址,通过地址就能找到事务表。
第三步:然后对数据块进行修改,修改了几行,就把这几行原理的数据写到回滚块里面。同时数据块的事务槽有地址指向这个回滚块。这个事务修改了一个块,还可以修改第二个块,可以修改多个块。第一个块修改完了,修改第二个数据块,也是上面步骤,如果这个时候undo块满了,再分配一个回滚块,然后把数据块的修改前的信息写进去,第二个数据块的事务槽又指向新的回滚块,两个回滚块有先后关系,有最早的回滚信息和最新的回滚信息,新的回滚块指向早的回滚块,把两个块链起来,就是新的回滚块有个链指向老的回滚块。也就是找到最新的回滚信息可以依次向前退,这时事务表的uba就指向这个事务最新的回滚块。这样的操作可以继续修改新的块,分配新的undo回滚块。每个数据块指向自己对应修改时最新的回滚块,最新的修改的数据块中的Uba指向最新的回滚块,事务表的uba指向最新的回滚块。
 
7、uba的指向及作用
undo段段头块有事务表,事务表的事务槽上有xid和uba,回滚段事务表中事务槽的Uba指向最新的undo块,比如一个事务产生有三个回滚块,有最新的回滚块,有其次新的,有最老的回滚块,一个事务的回滚块自动地串起来。数据块的块头部都有个xid使数据块指向事务表,一个事务的所有数据块头部的xid都指向回滚段段头事务表的一行数据。修改的某一个数据块,修改前的数据存放到一个回滚块里,各个数据块里面的uba都指向各自修改时的回滚块,一个事务对应undo段段头块事务表里的Uba指向该事务最新的那个回滚块。
 
7.1、事务表中Uba的作用
假设一个事务修改了三个数据块,先修改了第一个块,再修改第二个块,又修改了第三个块。要回滚的时候,要先把第三个块的数据回滚,再回滚2再回滚1号的。修改的时候是123,回滚的时候是321反着来。undo段头事务表中这个事务Uba指向最新的回滚块,要回滚的时候,根据事务表中的Uba找到最新的,先把最新的回滚块回滚,因为最新的回滚块有个地址指向该条事务的前一个回滚块,这个指向了第二个再把第二个回滚块回滚了,第二个回滚块又指向了第一个回滚块,这里再把最早的一个回滚块回滚了,回滚完了,第一个回滚块不指向任务块了,表示这个事务回滚完了。
oracle做rollback的时候会这样做:
首先在事务表里找到这个要回滚的事务,然后找到uba,根据uba找到最新的回滚块,把对应的数据回滚了,在这个回滚块中记录了该条事务的上一个回滚块,找到上一个回滚块,然后使用这个回滚块回滚对应的数据块,然后在使用最早的回滚块把它对应的数据块回滚了,这样就回滚完了,rollback完成。
 
7.2、数据块事务槽中uba的作用
数据块中的事务槽中有一个地址指向一个回滚块,有直接指向的意义,数据块事务槽中的uba直接指向回滚块,是数据块实实在在的指向它自己的回滚数据。一个数据块要找回回滚数据的话,第一种方法可以直接拿过来,从数据库的事务槽uba信息直接找到回滚块。第二种方法从数据块事务槽找到undo段头事务表中对应的事务信息,再找到undo块。-----数据块单独有地址指向回滚数据,这个链短,在要进行cr读、读一致性的时候有好处,读数据块的时候,发现这个块有未提交的事务,就需要构造cr块,就在buffer cache中找一个空块,把数据块和undo块信息合起来,拼成一个新块,然后读这个块。所以数据块直接写上对应的undo的uba地址,直接读数据块和对应回滚块两个块就拼成一个CR块,不需要读段头事务表了。
 
8、事务信息的链的意义
undo segment header和data block header 和undo block的事务信息之间有很多链,有很多的地址,他们的意义是:
1、rollback
在回滚段的段头块里面有事务有事务信息和uba地址,事务表uba地址指向事务最后一个undo块,最后一个undo块又串着前一个undo块,又向前串着上一个undo块,主要是为了rollback回滚做准备。
2、构造cr块读
数据块的事务槽有uba直接指向undo块回滚数据,为了一致性读ce做准备。
3、快速提交
数据块xid还要指向undo段头的事务表,如果一个事务快速提交时未清理这个事务对应数据块事务槽中的相关信息,再有其他操作需要修改这个数据块中前面这个事务已经修改的数据行时,在事务槽不能确定这个事务的提交状态,就需要通过这个事务找到这个事务表中对应的行,来最终确定前面这个事务的提交状态,所以需要这种指向链。也就是数据块事务槽xid信息。
 
9、关于本节的总结,务必掌握
下面描述下事务的修改过程
1、第一步
一个事物开始,首先在undo表空间里面找相对空闲的undo段的段头块的事务表里的一行,将自己的xid写上,同时在undo段里面分配一个空块作为回滚块,同时将回滚块的地址写到事务表的事务槽里。
2、第二步
要修改具体的数据了
修改任何一个数据库都是要在数据块块的头部获取一个事务槽,然后写上xid,获取到事务槽就开始修改数据块,修改数据块的时候,还将修改前的数据写到回滚块里,因为这个事务已经分配一个回滚块了,就直接写到回滚块里面去,同时将这个数据块所对应的回滚块的地址也写到数据块的事务槽里,回滚数据写完了,接下来修改实实在在的行,第一个数据块修改完了,再修改第二个数据块,同样的操作继续修改数据块,同时如果这个时候一个回滚块不够,要分配第二第三个回滚块,同是一个事务的回滚块之间要串起来,由新到旧的指向,同时如果加了回滚块,会把最新的回滚块信息uba地址写到该事务的事务表里。
以上是整个事务的操作流程,这三个回滚块串起来以及事务表的uba指向最新的回滚块,这样为了更方便的回滚。在每个数据块里面,直接写uba指向自己的undo数据块,为了更方便的构造cr块及一致性读。同时,一个事务信息在两个位置都有,数据块的事务槽里有,undo段头块的事务表里有,数据块的事务槽指向事务表,这个和Oracle的一种提交方式有关!
一个事务开始以后,Oracle修改了四个地方:
回滚段的段头块的事务表被修改;
回滚块被修改;
数据块的事务槽被修改;
数据块的数据行被修改。
这四个地方的数据都在数据块里面,数据块的任务地方的改变都会产生redo,redo不仅仅记录的是数据行的改变,事务槽的改变、undo块的改变、事务表的改变一样都会产生redo,这就是一个事务的操作流程。
 
 

oracle学习之undo的基本知识及事务与undo、数据块的关联的更多相关文章

  1. ORACLE体系结构一 (逻辑结构)-表空间、段、区和数据块

    一.Oracle的逻辑结构 Oracle的逻辑结构是一种层次结构.主要由:表空间.段.区和数据块等概念组成.逻辑结构是面向用户的,用户使用Oracle开发应用程序使用的就是逻辑结构.数据库存储层次结构 ...

  2. Oracle 学习系列之二(会话与事务级临时表和dual表 )

    一. 会话临时表 --创建会话临时表create global temporary table tmp_user_session(user_id int, user_name varchar2(20) ...

  3. oracle学习----逻辑读

    1.物理读 当数据块第一次读取到,就会缓存到buffer cache 中,而第二次读取和修改该数据块时就在内存buffer cache 清空数据缓冲区 SQL> alter session se ...

  4. MySQL学习总结:提问式回顾 undo log 相关知识

    原文链接:MySQL学习总结:提问式回顾 undo log 相关知识 1.redo 日志支持恢复重做,那么如果是回滚事务中的操作呢,也会有什么日志支持么? 也回滚已有操作,那么就是想撤销,对应的有撤销 ...

  5. Oracle学习线路

    出自huyangg的博客,地址是:oracle学习路线图 1.sql.pl/sql(网上有很多的视频,可以做一个简单的入手,然后看几本书,多做实验)    作为oracle的基本功,需要大家对sql和 ...

  6. [转]oracle学习入门系列之五内存结构、数据库结构、进程

    原文地址:http://www.2cto.com/database/201505/399285.html 1 Oracle数据库结构 关于这个话题,网上一搜绝对一大把,更别提书籍上出现的了,还有很多大 ...

  7. Oracle 学习总结 - 物理结构

    参考了很多文章,学习自网络 数据库 = 实例(数据库启动时初始的进程和内存结构,进程会作用到对应的内存区域-数据写入器到写入内存缓冲区,日志写入器到日志缓冲区等) + 数据库(物理文件-控制文件,数据 ...

  8. Oracle学习-Power Designer、visio 2003、Oracle sql developer、OEM、expdp

    Oracle的体系太庞大了.对于刚開始学习的人来说,难免有些无从下手的感觉. 经过一学期的学习对Oracle学习有了一些深入的了解,由于之前学习过Oracle的一些主要的知识.所以学习起来上手比較快一 ...

  9. Oracle学习总结(8)—— 面向程序员的数据库访问性能优化法则

    特别说明: 1.  本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识: 2.  本文许多示例及概念是基于Oracle数据库描述,对于其它关系型数据库也 ...

  10. Oracle手边常用70则脚本知识汇总

    Oracle手边常用70则脚本知识汇总 作者:白宁超 时间:2016年3月4日13:58:36 摘要: 日常使用oracle数据库过程中,常用脚本命令莫不是用户和密码.表空间.多表联合.执行语句等常规 ...

随机推荐

  1. vue中所有的封装方式总结

    如何确定我需要封装呢? 1.复用,如果觉得以后还会用到 2.你觉得方便,别的地方可能也需要用 3.如果不封装,页面代码臃肿的时候 1.封装API 使用场景:业务中最常见最普通的封装 详细在这篇:htt ...

  2. django我学习的第一个web框架

    第一个APP----------联通后台管理系统 第二个APP----------baby商场

  3. 在使用vite报global的错

    解决:

  4. 回顾——Dom节点类型

    DOM 节点 在 HTML DOM 中,所有事物都是节点.DOM 是被视为节点树的 HTML. 根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点: 整个文档是一个文档节点 ...

  5. 【C学习笔记】day5-3 编写代码模拟三次密码输入的场景

    3.编写代码模拟三次密码输入的场景. 最多能输入三次密码,密码正确,提示"登录成功",密码错误, 可以重新输入,最多输入三次.三次均错,则提示退出程序. #define _CRT_ ...

  6. 如何将多个TXT合并成一个TXT,文件名称提取

    方法1:1.将所有需要合并的TXT整理到一个文件夹中,切记,TXT合并最好每个TXT内容头或尾留一行间距,因为合并是直接合并,不会保留间距. 2.使用Windows命令cmd,切换到文件所在文件夹 3 ...

  7. HttpClient Post 提交表单数据

    运行环境 .net 4.6.1 //为防止因HTTPS证书认证失败造成API调用失败,需要先忽略证书信任问题 var sslHandler = new HttpClientHandler() { }; ...

  8. 老毛桃WinPE以ISO镜像模式安装CentOS7

    准备: 一台新台式机(2TB磁盘),将用于安装centos 7,注意安装前请使用工具将磁盘分区先删除. 一个u盘,用户制作老毛桃winpe启动盘. 从www.laomaotao.org下载最新9.3增 ...

  9. vue中input触发方法中调用ajax,导致input失去焦点问题

    发现在vue中监控input绑定的值,调用方法时,如果方法中有调用后端接口(使用Ajax),会导致input输入框失去焦点,这样导致的问题就是每输入一个字符,就要重新聚焦一次,可通过以下方式在方法中重 ...

  10. Pycharm 2022.2激活码到2023年7月,亲测有效

    33MEHOB8W0-eyJsaWNlbnNlSWQiOiIzM01FSE9COFcwIiwibGljZW5zZWVOYW1lIjoiUG9saXRla25payBNZXJsaW1hdSBNZWxha ...