Oracle事务原理探究1--oracle核心技术读书笔记五

1. 冲突解决

假如有一个系统只有你和我两个用户,并且我们都在持续对系统中一小部分数据做修改和查询操作。

如果你正在数据库中做一批修改操作,而我正在做查询,我一定不能看到你所做的修改,直到你告诉我可以看到你所做的所有更改才行(你提交了事务)。因此在oracle内部,必须有一个高效的办法来识别哪些数据我可以看到,哪些数据我不可以看到。

从相反的角度来看,在你提交事务的时候,你需要一种高效的机制让其他所有人能够看到事务已经提交(也就是要告诉别人你所有修改过的数据都是可见的了)。更极端一点的情况是,你可能需要决定回滚事务,这样的话,你也需要一种高效的机制能够关联上所有的undo记录,按生成的顺序排序,从而可以按相反的顺序回滚这些更改。

2. 事务与undo

创建数据库的时候,必须创建一个undo表空间。同时,oracle会在undo表空间中自动创建多个undo段,随着数据库负载的变化自动新增,扩大和收缩。

事务管理起始于undo段,并以此为中心。undo段的第一个块(段头块)包含如下结构:扩展映射,扩展控制头(跟其他类型的段头块一样),事务表,事务控制区(特殊的结构)。事务表的大概结构如下:

TRN    TBL:

index   state   cflags     wrap#       uel                  scn                           dba                  nub                 cmt

0X00       9       0X00    0X2013    0X001b  0X0000.016f1fc1   0X0180083e     0X00000001     1302762364

0X01       9       0X00    0X2014    0X001a  0X0000.016f1f54   0X0180083e     0X00000001     1302762364

0X02     10       0X80    0X2013    0X001d  0X0000.016f20fc   0X0180083e     0X00000001      0

0X03       9       0X00    0X200c    0X001c   0X0000.016f20d8  0X0180083e     0X00000001      1302762364

0X04       9       0X00    0X200f     0X001f    0X0000.016f1c75  0X0180083f       0X00000001     1302762364

.........

index 表示事务表中槽号,只是一个序列而已,从0x00开始到0x21结束,11g的版本有34个槽。

state 表示事务状态:9代表事务不活动,10代表事务正在活动,从这里我们看出16进制第0x02号槽上的事务正在活动。

cflags 表示正在使用事务槽的事务的状态:0x00表示非活动事务、0x80表示活动事务、0x10表示死事务、0x90表示被回滚的死事务

wrap# 表示事务表上的事务槽被重用的次数,它是XID的一部分。0x2013表示此时事务槽被重用了8211次。

uel   表示当前活动事务所在事务槽的下一个事务槽的指针(即如果又发生一个新的事务,此时就会用到UEL指向的事务槽上的index)。

scn   表示务事启动、提交、回滚的SCN.

dba   表示uba:第一部分的undo块地址,这个DBA是(rollback)回滚的起始点,也就是说是记录事务修改的最后一条记录所在UNDO块的地址。这使oracle在崩溃恢复时,能够找到事务生成的最后一条undo记录,以便知道从何处开始处理回滚。

nub   表示当前事务所用到的UNDO块的个数。事务回滚时,可以看到该值会逐步减少。

cmt   表示最接近当前的提交时间戳,是从1970年1月1号零晨开始的(以秒为单位记录)。0表示事务正在活动。

2.1 事务的开始和结束

当会话开始一个事务的时候,会先取到一个undo段,从undo段的事务表中取得一条记录,然后增加该记录的wrap#的值,将state改为active(10),同时修改事务表其他一些列(比如cmt置0)。由于这也是对于数据库块的修改,所以会生成一条最终写入重做日志文件的重做改变向量(操作码为5.2),并写入数据库。这样会话就有了一个活动的事务了。

同样,当事务完成时(通常是用户commit),会将state设回为free(9),并更新其他一些列,比如将当期的SCN写入scn列。同样,对数据库块的这一修改也要生成一个重做改变向量(操作码5.4),最终记录到重做日志中。这一刻相当特别的重要,因为这个时刻你的会话正在向日志写进程(lgwr)发布命令将日志缓冲区的当前内容写入磁盘,并等待日志写进程确认写入完成,以保护所提交的更改。(这个发送命令要求lgwr进程输出重做日志到磁盘其实很简单,一旦发现进入日志缓冲区的重做日志操作码是5.4,也就是是提交事务记录,立刻将所有缓冲区的日志刷新输出磁盘,完成后并告知把这条提交记录放入日志缓冲区的会话。)

每一个事务会分配一个事务id,事务id由undo段编号,事务表中的条目索引号以及事务条目中最新的wrap#值构成。因此,当你看到像0X0009.002.00002013这样的事务id时,就会知道:这个事务在undo段9里,用的是第2条事务表记录,wrap#值为0X2013。如果你想看这是哪个undo段,以及相应的段头位置,可以使用segment_id列作为查询条件查询dba_rollback_segs视图。

2.2 事务表

在上面我们已经介绍了事务表的结构了,现在回顾一下,事务表主要的目的无非下面几个:

1. 显示事务是已提交还是仍旧活动

2. 已提交事务的SCN

3. 事务生成的最近一条undo记录的位置信息,便于回滚

4. 事务生成的undo量

如果一个事务必须回滚,或者一个会话被强制杀掉,使得smon(系统监视进程)必须要回滚它的事务,或者如果实例崩溃,在实例恢复期间,smon必须回滚所有崩溃时的活动事务。那么此时可以轻松找到所有活动事务(状态等于10),并且找到每一个事务正在使用的最后的undo块(dba列)。然后可以根据每一个事务对应的undo块链表往回查找,应用每一条undo记录,因为每一条undo记录指向了本事务中前一条undo记录。

2.3 undo块简要介绍

undo块和普通数据块有许多相似之处:块头部分记录了若干控制信息和元数据,行目录列出了堆积存放在块中的每一项的位置,若干undo记录在块中自底向上堆放在一起,块空闲空间位于块中间。但表行和undo记录最大的区别在于,undo记录不会被修改,因此一旦undo记录被写入块中,会永远保留在相同的位置。(表行被修改之后,如果原来位置放不下,会拷贝到另一个新位置,这样块中会留下杂乱的指针和临时的空洞)。

一个不太为人知的事实是,单个undo块也可以包含多个事务的undo记录。一个事务会以独占的方式请求undo块的所有权,pin住,然后使用该块直到块满(此时事务请求新undo块并更新它的事务表槽以指向新块)或事务提交。如果事务提交后,undo块中仍有空闲空间,该块会被加入到undo段头中空闲块池的候选链表中。如果发生这种情况,该undo块会被其他事务使用其剩余的空间。

时间: 2024-10-17 06:41:59

Oracle事务原理探究1--oracle核心技术读书笔记五的相关文章

Oracle事务原理探究2--读书笔记五

续上篇... 3.  数据块访问与undo 任何时候当会话查看一个数据块的时候,都需要保证看到的是适当的数据版本.从外部观点来看,这意味着会话不应该看到任何未提交的数据,或许还不应该看到查询开始后修改并提交的数据(取决于事务的隔离级别),这称为数据的读一致性版本. 下面我们来谈谈oracle怎么实现读一致性版本的: 3.1 设置场景 我们会创建一张表,里面插入3条数据,然后开几个会话对其进行操作 3.1.1 连接oracle,以任何一个用户登录即可,初始化一些格式 execute dbms_ra

《大型网站技术架构 -核心原理与安全分析》读书笔记

大型网站架构演化的价值观 网站的价值在于它能为用户提供什么价值,在于网站能做什么,而不在于它是怎么做的,所以在网站还很小的时候去追求网站的架构是舍本逐末,得不偿失的.小型网站最需要做的就是为用户提供好的服务来创造价值,得到用户的认可,活下去,野蛮生长. 网站架构设计误区 一味追求大公司的解决方案 大公司的经验和成功模式固然重要,值得学习借鉴,但如果因此而变得盲从,就失去了坚持自我的勇气,在架构演化的道路上迟早会迷路. 为了技术而技术 网站技术是为业务而存在的,除此毫无意义.在技术选型和架构设计中

oracle如何保证事务的ACID原则--oracle核心技术读书笔记二

在事务中有四个通用的原则是所有数据库都必须遵守的,简称ACID原则,下面简单概述一下oracle是怎样实现这四个原则的. 一. 原子性(Atomicity):一个事务要么全部执行,要么全部都不执行 在oracle中,当我们做一次变更的时候,系统会自动创建一条undo记录来描述怎样撤销这次变更.也就是说,当执行到一个事务的中间时,如果有其他用户想访问我们更改过的数据,他必须使用undo记录来查看变更前的旧数据,即只有当我们提交这个事务后,所做的更改才能被他人看到.这样就可以确保,其他用户要么能看到

《算法导论》读书笔记(五)

摘要: 本章介绍了二叉查找树的概念及操作.主要内容包括二叉查找树的性质,如何在二叉查找树中查找最大值.最小值和给定的值,如何找出某一个元素的前驱和后继,如何在二叉查找树中进行插入和删除操作.在二叉查找树上执行这些基本操作的时间与树的高度成正比,一棵随机构造的二叉查找树的期望高度为O(lgn),从而基本动态集合的操作平均时间为θ(lgn). 1.二叉查找树 二叉查找树是按照二叉树结构来组织的,因此可以用二叉链表结构表示.二叉查找树中的关键字的存储方式满足的特征是:设x为二叉查找树中的一个结点.如果

Oracle基本数据改变原理浅析(redo与undo)--oracle核心技术读书笔记一

在oracle中我们做一些更新操作,oracle底层是怎么流转的呢,就是这篇文章要讲解的. 一. 原理 假设我们在一个已经更新了很多条分散记录的OLTP系统中,更新了一行数据.那么这个更新的真实步骤如下: 1. 创建一个重做改变向量,描述如何往undo块插入一条undo记录(也就是描述undo块的改变) 2. 创建一个重做改变向量,描述数据块的改变(也就是数据的改变) 3. 合并这两个重做改变向量为一条日志记录,并写到重做日志缓冲区(便于今后重做) 4. 向undo块插入undo记录(便于今后回

Oracle redo 复杂度--oracle核心技术读书笔记三

一. 概述 我们知道,在oracle中,每修改一条数据都会生成一条重做数据(也就是redo,里面记录了修改后的内容).目的就是为了将修改的数据备份,方便今后重做.现在有一个问题.oracle中只要修改数据,都会生成redo,这些redo会存放在一个叫做重做日志缓冲区里面.如果同时多个回话在修改数据,都要往重做日志缓冲区写入内容,就存在为同一片内存区域竞争的问题.存在竞争,就存在开销,这篇文章大概介绍一下,oracle如何尽量降低这种开销. 二.  问题概述 oracle中不断地修改数据,源源不断

oracle undo 复杂度--oracle核心技术读书笔记四

一. 概述 undo 保存的是旧数据.比方.你改动了一条记录将A列abc改动为def.那么undo里面保存的就是abc.目的有两个:1. 假设你的事务没有提交.可是已经将A列改动,那么别人读取这条数据的时候,不应该可以看到你改动后的内容def,应该还仅仅能看到abc,这个时候就须要去读取undo,才干取到abc. 2. 假设你的事务后来失败,须要将A列由改动过的值def回退到之前的值abc.abc也要从undo里面去取. 这篇文章.简要介绍一下读一致性(也就是别人无法读取到你改动的未提交的内容)

从Select语句看Oracle查询原理(了解Oracle的查询机制)

第一步:客户端把语句发给服务器端执行 当我们在客户端执行select语句时,客户端会把这条SQL语句发送给服务器端,让服务器端的进程来处理这语句.也就是说,Oracle客户端是不会做任何的操作,他的主要任务就是把客户端产生的一些SQL语句发送给服务器端.虽然在客户端也有一个数据库进程,但是,这个进程的作用跟服务器上的进程作用是不相同的.服务器上的数据库进程才会对SQL语句进行相关的处理.不过,有个问题需要说明,就是客户端的进程跟服务器的进程是一一对应的.也就是说,在客户端连接上服务器后,在客户端

Oracle SQL培训教程:从实践中学习Oracle SQL及Web快速应用开发-读书笔记

字符集的不同使日期型的显示有问题解决 alter session set NLS_DATE_LANGUAGE='AMERICAN'; 解锁scott账户 alter user scott identified by tiger account unlock; DISTINCT去掉重复的行 基本查询语句的格式 SELECT *|{[DISTINCT] 列表,...} FROM 表名: 其中 列表: 列名|表达式 [别名] SELECT * FROM tab;SELECT * FROM emp;SE