oracle如何保证数据一致性和避免脏读

oracle通过undo保证一致性读和不发生脏读

1.不发生脏读
2.一致性读
3. 事务槽(ITL)小解

1.不发生脏读

例如:用户A对表更新了,没有提交,用户B对进行查询,没有提交的更新不能出现在用户的查询结果中

举例并通个dump数据块说明避免脏读的原理

创建测试表,并插入两条记录,会话A执行更新但不提交

  1. SQL>select*from test;
  2. ID NAME
  3. --------------------
  4. 1 A
  5. 2 B
  6. SQL> update test set name='C'where id=2;
  7. 1 row updated.

会话B查询,数据没变

  1. SQL>select*from test;
  2. ID NAME
  3. --------------------
  4. 1 A
  5. 2 B

通过下面sql语句查询数据所在的数据文件和块号,并进行dump

  1. SQL>select id, rowid, dbms_rowid.rowid_relative_fno(rowid) fn,dbms_rowid.rowid_block_number(rowid) bk from test order by id;
  2. ID ROWID FN BK
  3. ------------------------------------------------
  4. 1AAAzkeAAIAAAACDAAA8131
  5. 2AAAzkeAAIAAAACDAAB8131
  6. SQL> alter system dump datafile 8 block 139;
  7. System altered.

未提交的数据块dump结果

  1. ItlXidUbaFlagLckScn/Fsc
  2. 0x010x0002.001.000a90a20x00c00093.9f1d.16 C---0 scn 0x0000.395178de
  3. 0x020x0007.010.000a93c50x00c00f4b.9f5d.34----1 fsc 0x0000.00000000
  4. ---上面事务槽中Flag----0x00c00f4b undo地址中读取
  5. bdba:0x0200008b
  6. data_block_dump,data header at 0x7fb742fc8a64
  7. ===============
  8. tsiz:0x1f98
  9. hsiz:0x16
  10. pbl:0x7fb742fc8a64
  11. 76543210
  12. flag=--------
  13. ntab=1
  14. nrow=2
  15. frre=-1
  16. fsbo=0x16
  17. fseo=0x1f88
  18. avsp=0x1f70
  19. tosp=0x1f70
  20. 0xe:pti[0] nrow=2 offs=0
  21. 0x12:pri[0] offs=0x1f90
  22. 0x14:pri[1] offs=0x1f88
  23. block_row_dump:---下面是表中数据行的dump
  24. tab 0, row 0,@0x1f90
  25. tl:8 fb:--H-FL-- lb:0x0 cc:2
  26. col 0:[2] c1 02
  27. col 1:[1]41--第一行 A
  28. tab 0, row 1,@0x1f88
  29. tl:8 fb:--H-FL-- lb:0x2 cc:2---lb0x2说明未提交
  30. col 0:[2] c1 03
  31. col 1:[1]43---第二行 C
  32. end_of_block_dump

说明:通过上面的dump文件发现,数据已经被修改成C(43),但是Oracle发现这条数据有lb: 0x2 对应的是ITL,从ltl为0x02的记录看到flag为—-,表示有事务标记,数据被加锁,需要从undo段的uba(undo block address)中读取

undo段中对应的块信息为:0x00c00f4b,这里是十六进制,下面先转换成10进制

  1. SQL>select to_number('00c00f4b','XXXXXXXXXXXXXXX')from dual;
  2. TO_NUMBER('00C00F4B','XXXXXXXXXXXXXXX')
  3. ---------------------------------------
  4. 12586827
  5. 得到值为12586827

对undo块进行dump

  1. 在通过下面的语句得到数据块信息:
  2. SQL>select dbms_utility.data_block_address_file(12586827), dbms_utility.data_block_address_block(12586827)from dual;
  3. DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(12586827) DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(12586827)
  4. ---------------------------------------------------------------------------------------------
  5. 33915
  6. SQL>select file#,name from v$datafile where file#=3;
  7. FILE# NAME
  8. ------------------------------------------------------------
  9. 3/u01/app/oracle/oradata/FGLDB/undotbs01.dbf
  10. SQL> alter system dump datafile 3 block 3915;
  11. System altered.

dump内容如下:

  1. *-----------------------------
  2. *Rec#0x34 slt: 0x10 objn: 211231(0x0003391f) objd: 211231 tblspc: 4(0x00000004) --objd 为object id
  3. *Layer:11(Row) opc:1 rci 0x00
  4. Undo type:Regular undo Begin trans Last buffer split:No
  5. TempObject:No
  6. TablespaceUndo:No
  7. rdba:0x00000000Ext idx:0
  8. flg2:0
  9. *-----------------------------
  10. uba:0x00c00f4b.9f5d.25 ctl max scn:0x0000.39516d48 prv tx scn:0x0000.39516db3
  11. txn start scn: scn:0x0000.395178de logon user:83
  12. prev brb:12586818 prev bcl:0
  13. KDO undo record:
  14. KTB Redo
  15. op:0x03 ver:0x01
  16. compat bit:4(post-11) padding:1
  17. op: Z
  18. ArrayUpdate of 1 rows:
  19. tabn:0 slot:1(0x1) flag:0x2clock:0 ckix:12
  20. ncol:2 nnew:1 size:0
  21. KDO Op code:21 row dependencies Disabled
  22. xtype:XAxtype KDO_KDOM2 flags:0x00000080 bdba:0x0200008b hdba:0x0200008a
  23. itli:2 ispac:0 maxfr:4858
  24. vect =3
  25. col 1:[1]42--- undo中数据为B

从undo块中发现值为B(42),故其他用户看到的是B,看不到C,避免了脏读

附:提交后的数据块dump结果

  1. ItlXidUbaFlagLckScn/Fsc
  2. 0x010x0002.001.000a90a20x00c00093.9f1d.16 C---0 scn 0x0000.395178de
  3. 0x020x0007.010.000a93c50x00c00f4b.9f5d.34 C---0 scn 0x0000.39517d7a
  4. ---FlagC---
  5. bdba:0x0200008b
  6. data_block_dump,data header at 0x7fa3c77efa64
  7. ===============
  8. tsiz:0x1f98
  9. hsiz:0x16
  10. pbl:0x7fa3c77efa64
  11. 76543210
  12. flag=--------
  13. ntab=1
  14. nrow=2
  15. frre=-1
  16. fsbo=0x16
  17. fseo=0x1f88
  18. avsp=0x1f70
  19. tosp=0x1f70
  20. 0xe:pti[0] nrow=2 offs=0
  21. 0x12:pri[0] offs=0x1f90
  22. 0x14:pri[1] offs=0x1f88
  23. block_row_dump:
  24. tab 0, row 0,@0x1f90
  25. tl:8 fb:--H-FL-- lb:0x0 cc:2
  26. col 0:[2] c1 02
  27. col 1:[1]41
  28. tab 0, row 1,@0x1f88
  29. tl:8 fb:--H-FL-- lb:0x0 cc:2--- lb0x0
  30. col 0:[2] c1 03
  31. col 1:[1]43
  32. end_of_block_dump


总结:数据库通过判断数据块头部的ITL槽的信息来确定是否有未提交的事务,如果事务槽Flag为—-,则通过事务槽中的undo块地址查询到原来的数据,进而达到数据隔离的效果,避免脏读。

2.一致性读

例如:假设某一个用户A在6点对某一个表发出了一个查询数据量很大的数据,需要15分钟才能把结果完全查询出来,在这期间,6点10分用户B对数据进行了更新并提交了,用户A查询的结果仍然是6点时候的表的数据,用户B更新的数据不出现在用户A的查询结果中,这就是一致性读。

  1. 用户A在执行开始的时候会记录当时的SCN号,如图中10021
  2. 在每次从数据块中读数据的时候会比较记录的SCN号和数据块事务槽中的SCN号(下一个事务的SCN号一定比当前的大)
    a.如果数据块中的SCN比当前分配的SCN号小,则认为该数据没有被修改,直接读取;
    b.如果数据块中的SCN号比当前分配的SCN大,则根据块中保存的地址去undo中读取当时分配SCN时间点的数据(根据undo数据块在内存中重新构造出该数据块,称为consistent read (CR)块)

    一个查询如果耗费很长时间,而查询的结果在查询的阶段被更改了,而且对应着undo段的数据已经被清理了,就会发生Oracle中著名的ORA-01555: snapshot too old(快照太久)错误。

    如果一条数据在查询期间被更新过多次并且提交,后放入undo段的块会记录相对的块上次放在undo段中的块地址,从而一路寻找到查询开始时间点在undo段中的数据块。

3. 事务槽(ITL)小解


ITL(Interested Transaction List)是Oracle数据块内部的一个组成部分,位于数据块头(block header),itl由xid,uba,flag,lck和scn/fsc组成,用来记录该块所有发生的事务,一个itl可以看作是一条事务记录。当然,如果这个事务已经提交,那么这个itl的位置就可以被反复使用了,因为itl类似记录,所以,有的时候也叫itl槽位。如果一个事务一直没有提交,那么,这个事务将一直占用一个itl槽位,itl里面记录了事务信息,回滚段的入口,事务类型等等。如果这个事务已经提交,那么,itl槽位中还保存的有这个事务提交时候的SCN号。

 

Xid:事务id,在回滚段事务表中有一条记录和这个事务对应
Uba:回滚段地址,该事务对应的回滚段地址

  • 第一段地址:回滚数据块的地址,包括回滚段文件号和数据块号
  • 第二段地址:回滚序列号
  • 第三段地址:回滚记录号
    –查看UBA
    SELECT UBAFIL undo_file_id,UBABLK undo_blk_num,UBASQN undo_segment_num,UBAREC undo_recode_num FROM v$transaction;

Flag:事务标志位。这个标志位就记录了这个事务的操作,各个标志的含义分别是:

  • —– = 事务是活动的,或者在块清除前提交事务
  • C— = 事务已经提交并且清除了行锁定。
  • -B– = this undo record contains the undo for this ITL entry
  • –U- = 事务已经提交(SCN已经是最大值),但是锁定还没有清除(快速清除)。
  • —T = 当块清除的SCN被记录时,该事务仍然是活动的,块上如果有已经提交的事务,

那么在clean ount的时候,块会被进行清除,但是这个块里面的事务不会被清除。

Lck:影响的记录数

Scn/Fsc:快速提交(Fast Commit Fsc)的SCN或者Commit SCN。

每条记录中的行级锁对应于Itl列表中的序号,即哪个事务在该记录上产生的锁。


关注公众号:数据库技术分享,不定期分享技术干货

转载于:https://www.cnblogs.com/haoxiaoyu/p/314e2d07c0ab6c86a6378d79fd0facdf.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Google Guava BloomFilter

当Guava项目发布版本11.0时,新添加的功能之一是BloomFilter类。 BloomFilter是唯一的数据结构,用于指示元素是否包含在集合中。 使BloomFilter有趣的是,它将指示元素是否绝对不包含或可能包含在集合中。 永远不会出现假阴性的特性使BloomFil…

php 编程祝新年快乐_用于测试自动化的7种编程语言

导读:本文重点介绍测试自动化中排名前七位的编程语言。当人们想要开始做自动化测试,此时却需要开发自动化测试脚本,也就是要学习一门编程语言。那么,我们怎样迈出这一步?也有你已经精通一种编程语言,也可以…

Vue.js开发环境搭建的介绍

包含了最基础的Vue.js的框架,包含了打包工具和测试工具,开发调试的最基本的服务器,不需要关注细节,只需关注Vuejs对项目的实现 npm在国内的网络使用较慢,所以推荐下载安装淘宝的镜像 1: 2:安装c…

html文件转换html格式,pdf文件怎么转换成html格式

PDF文件怎么转换成html格式呢?html格式其实就是网页格式,PDF文件和网页文件一般情况下是两种完全不搭边的格式,但是不可否定的是办公室的多样化总有人会有这样的需求,只要有需求就会有其相应的解决方案。我们可以利用PDF转Word一样…

Eclipse中的Github Gists

我想描述有关在Eclipse中集成GitHub Gists的简单步骤。 有几个来源促使我这样做: Eclipse的GitHub Mylyn连接器 EGit / GitHub /用户指南 http://eclipse.github.com 我一直在使用Eclipse Java EE发行版,其中已经安装了Mylyn插件: 1.通…

CSS3景深-perspective

3D视图正方体&#xff1a; 1 <!DOCTYPE html>2 <html lang"en">3 <head>4 <meta charset"UTF-8">5 <title>CSS3景深-perspective</title>6 </head>7 <style>8 #div1{9 position: rel…

【BZOJ4262】Sum 单调栈+线段树

【BZOJ4262】Sum Description Input 第一行一个数 t&#xff0c;表示询问组数。第一行一个数 t&#xff0c;表示询问组数。接下来 t 行&#xff0c;每行四个数 l_1, r_1, l_2, r_2。Output 一共 t 行&#xff0c;每行一个数 Sum。Sample Input 4 1 3 5 7 2 4 6 8 1 1 9 9 9 9 1…

父类一实现serializable_我的java基础学习易错点和易忘点总结(一)

一.继承A:子类只能继承父类所有非私有的成员(成员方法和成员变量)B:子类不能继承父类的构造方法&#xff0c;但是可以通过super关键字去访问父类构造方法。二.继承中构造方法的关系A:子类中所有的构造方法默认都会访问父类中空参数的构造方法B:为什么呢?因为子类会继承父类中的…

深入克隆

在继续克隆概念之前&#xff0c;让我们用对象创建概念刷新基础知识。 使用new运算符创建对象时&#xff0c;对象将在堆中获取内存分配。 堆中的对象创建 在Java中&#xff0c;理想情况下仅通过引用变量修改对象&#xff0c;即仅复制对象的内存地址&#xff0c;因此原始对象中…

索引和未索引执行计划的比较_详解Oracle复合索引+实例说明

复合索引复合索引顾名思义&#xff0c;区别于单列索引&#xff0c;是由两个或多个列一起构成的索引。其在B树上的数据结构是什么样&#xff1f;如下图&#xff0c;是一个包含两列的复合索引。如果你观察仔细&#xff0c;还会发现它的叶子节点是ASC递增排序的。现根据第一个值排…

Datables使用总结

本文共四部分&#xff1a;官网 | 基本使用|遇到的问题|属性表 一&#xff1a;官方网站&#xff1a;[http://www.datatables.net/] 二&#xff1a;基本使用&#xff1a;[http://www.guoxk.com/node/jquery-datatables] 1、DataTables的默认配置 $(document).ready(function() { …

用方面清理代码

在我以前的文章中&#xff0c;我描述了字母转换&#xff0c;并且提到了我们使用AspectJ解决了该任务&#xff0c;但是我没有提及AspectJ的工作原理以及一般性的方面。 因此&#xff0c;在接下来的几行中&#xff0c;我将解释&#xff1a; 什么是面向方面的编程&#xff0c;为什…

原型 - 实现自己的jQuery

每个第一次使用jq的开发者都感到惊叹,jq的$太神奇了,究竟是怎么做到的使用$控制dom 赞叹前人之余,探究其本源才是前端开发者应该做的事,社区常常说,不要重复造轮子, 可是啊,连轮子都造不出来,又怎么去了解在什么环境下用什么轮子,怎么样才可以造成更加优秀的轮子, 不同阶段对…

server.transfer 无法跳转页面_H5 腾讯地图无法导航

uni-app 打包H5腾讯地图无法导航前言&#xff1a;最近几天用uni-app开发安卓和iOS应用&#xff0c;打包成APP安装包后&#xff0c;APP内做地图导航没有问题&#xff0c;APP内使用的是高德地图&#xff1b;但是打包成为H5页面后&#xff0c;运行在微信内置浏览器或者运行在第三方…

打破PermGen神话

在我的最新文章中&#xff0c;我解释了可能导致java.lang.OutOfMemoryError&#xff1a;PermGen空间崩溃的原因 。 现在该讨论该问题的可能解决方案了。 或者&#xff0c;更确切地说&#xff0c;是关于互联网对可能解决方案的建议。 不幸的是&#xff0c;我只能说&#xff0c;我…

android 弹出弹框2秒消失_基于HTML5 Canvas 实现弹出框

前言用户鼠标移入时&#xff0c;有弹出框出现&#xff0c;这样的需求很常见。这在处理 HTML 元素实现时简单&#xff0c;但是如果是对 HTML5 Canvas 构成的图形进行处理&#xff0c;这种方法不再适用&#xff0c;因为 Canvas 使用的是另外一套机制&#xff0c;无论在 Canvas 上…

【CSS】小妙招,各种问题总结方法处理

1.实现div文字溢出自动省略号截取 overflow:hidden; /*超过部分不显示*/       text-overflow:ellipsis; /*超过部分用点点表示*/       white-space:nowrap;/*不换行*/ 2.规定行数的截取效果 text-overflow: ellipsis; /*有些示例里需要定义该属性&#xff0c…

Java2Days 2012:Java EE

Java2Days会议是东欧的主要活动&#xff0c;目的是介绍Java开发的最新趋势。 今年&#xff0c;该活动于10月25日至26日在保加利亚的索非亚举行。 我在那里&#xff0c;并有机会与一些SAP的同事一起品尝了一些最新的Java&#xff0c;云和移动内容&#xff0c;这些内容已直接发送…

c++ 优先队列_C/C++数据结构:队列结构最全解析!带你零基础入门队列结构

前言上一章节针对于C语言栈结构做了解析&#xff0c;不清楚的可以回顾一下。本章节主要针对于C语言的基础数据结构队列做以解析。数据结构之队列队列是一种特殊的 线性表 &#xff0c;特殊之处在于它只允许在表的前端&#xff08;front&#xff09;进行删除操作&#xff0c;而在…

周期均方根和有效值的区别_黑猪肉和白猪肉有啥区别?

为啥散养黑猪肉的价格要比白猪贵很多?这其中的原因不看不知道!市面上的散养黑猪肉通常要比白猪肉贵很多&#xff0c;但是仍有不少人喜欢买黑猪肉回家吃&#xff0c;散养黑猪肉和白猪肉不仅仅是口感上有所差距&#xff0c;其价值差距体现在很多方面&#xff0c;接下来小编就和大…