Oracle数据库一致性读的原理.doc

  1. 1、本文档共7页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
Oracle 数据库一致性读的原理 在Oracle数据库中,undo主要有三大作用: 提供一致性读(Consistent Read)、回滚事务(Rollback Transaction)以及实例恢复(Instance Recovery)。所以,理解了这个三个方面的机制也就理解了undo的工作原理。 对一致性读的理解: 一致性读的现象 例如,表T上一行的name字段值原来为A。现在在会话1下,将之改为B(未提交),接着,还在会话1下,select该行的name字段的值,结果为B。而接下来,在会话2下,select该行的name字段的值,结果为A(这就是一致性读)。 接着,在会话1下,输入commit,再在会话2下,select该行的name字段的值,结果为B(在执行select操作之前任何会话里的提交事务所做的修改,都可以查询出来)。 ? 一致性读的原理 ? 一、当用户A查询期间,用户B删除了表的最后一条记录,以此为例子来进行说明一致性读 一致性读是相对于脏读(Dirty Read)而言的。假设某个表T中有10000条记录,获取所有记录需要15分钟时间,即当前时间为9点整,某用户A发出一条查询语句:select * from T,该语句在9点15分时执行完毕。当用户A(会话1)执行该SQL语句到9点10分的时候,另外一个用户B(会话2)发出了一条delete命令,将T表中的最后一条记录删 除并提交了。那么到9点15分时,A用户将返回多少条记录? 如果返回9999条记录,则说明发生了脏读;如果仍然返回10000条记录, 则说明发生了一致性读。很明显,在 9点钟那个时间点发出查询语句时,表T中确实有10000条记录,只不过由于I/O的相对较慢,所以才会花15分钟完成所有记录的检索。对于Oracle 数据库来说,没有办法实现脏读,必须提供一致性读,并且该一致性读是在没有阻塞用户的DML的前提下实现的。 那么undo数据是如何实现一致性读的呢? 还是针对上面的例子。用户A在9点发出查询语句(select操作)时,服务器进程会将9 点那个时间点上的SCN号记录下来,假设该SCN号为SCN9.00。那么9点整的时刻的SCN9.00一定大于等于记录在所有数据块头部的ITL槽中的 SCN号[即事务槽的scn/fsc字段](如果有多个ITL槽,则为其中最大的那个SCN号)。 注:?ITL(Interested Transaction List)是Oracle数据块内部的一个组成部分,用来记录该块所有发生的事务,一个itl可以看作是一个记录,在一个时间,可以记录一个事务(包括提交或者未提交事务)。当然,如果这个事务已经提交,那么这个itl的位置就可以被反复使用了,因为itl类似记录,所以,有的时候也叫itl槽位。 当用户A执行select操作时,用户A对应的服务器进程会在扫描表T的数据块时,把扫描到的数据块头部的ITL槽(们)的SCN号[即事务槽的scn/fsc字段]与开始执行select操作时的SCN,即SCN9:00进行比较。不过在与当前扫描到的那一个事务槽进行比较之前,服务器进程会先判断该事务槽的flag字段是否为提交状态。 若是未提交状态(顺便说下,该未提交的事务(最后一次)对数据行所做修改的时间无论早于或是晚于开始执行select操作的SCN,对一致性读是不影响的。因为select操作始终以提交的事务的提交SCN[即事务槽的scn/fsc字段]来与开始执行select操作时的SCN进行比较的,不会以事务(最后一次)对数据行所做修改的时间SCN来与之比较的),则(因为块延迟清除机制,这里的未提交不表示真的未提交,还得找事务表上的提交标记)还得根据事务槽上的XID字段找到段头块上的事务表里的对应行,看该行的cmt是否为提交,为提交,就是真的提交,为未提交,就是真的未提交。如果事务表里的对应行上cmt字段为未提交,则还得判断该未提交事务所在的事务槽的XID字段是否属于会话里记录过的事务XID【注释:会话(内存)上应该记录了会话期间修改了哪些表(记录“修改哪些表”这个信息,在回滚时,就可以知道回滚所在的会话修改了哪些表,不用去扫描数据库上的所有表,看表所在的数据块们的事务槽上有否属于自己的事务,从而确定该表是自己修改过的),还有在会话里输入rollback命令前的所有未提交事务的XID(即事务槽上的XID字段)信息(未提交事务的XID是一致性读和回滚都会用到的)。】,若是,就跳过该事务(因为该事务属于本会话的),若不是,则就通过该事务槽(即当前扫描到的那一个事务槽)上的uba字段找到该事务(槽)对应的undo块(确切地说,应该是该事务对应产生的undo chain尾部的那个undo记录)。这里要强调的一点是,在undo记录上,不仅记录了改变

文档评论(0)

dashewan + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档