首页 > 数据库 > Oracle > 转:oracle 中的CR块详解+
转自http://blog.csdn.net/cymm_liu/article/details/7496775
1、概述
Cr块consistent read块也就是用来维护oracle的读一致性的数据块。当查询某些数据的时候,发现数据块的版本比我们要查询的新,例如session1执行了dml操作并没有提交,session2此时查找跟session1相关的dml操作的数据信息,此时查询的数据却是原来的数据信息。
查询的过程会在undo段中查找该数据块的前映像后,然后把前映像和current块合并形成了一个CR block,通过查询cr block就可以满足数据的一致性了。
CR block存在与sga的buffer cache中,在db cache里申请一个数据块,然后对应的回滚段的前映像生成cr block。
cr块的数量是由隐含参数_db_block_max_cr_dba控制的,默认是最高同时存在5个cr块,构造cr块时cr block created计数器都会增加1.
由于cr block和current block的数据块的rdba都是相同的,会放在相同的hash链上,当然某些block的cr block的版本过多,自然会引起hash链上的竞争,导致latch buffer cache chain闩竞争。
当然在利用回滚段的前映像和current block构造cr块时,很有可能回滚段的已经被覆盖,也就会出现常见的ora-01555快照过旧。
一个sql语句如何去查询数据信息了,根据以前的latch基本记载知道获取该数据块的latch然后才能对该数据块进行读取,其实一个sql访问数据信息的数据块,需要像链接一样的结构中去收索这个数据块是否在内存中,此时访问链表也需要一个latch,如果获取失败也就是会产生latch buffer cache chain等待了。
2、一些疑问
问题1:A用户在对block X进行一致性读时构造了cr块,B用户随后也对block X进行一致性读,是直接用A用户构造好的cr块,还是自己再构造一个?
B得到的是A的block X的COPY
我的测试结果很奇怪。
刚开始v$bh里显示是cr块的数量随着一致读的session的增加而增加,但增加到一定数目(我的测试结果是5个)后,一致读的session增加,但cr块不再增加。似乎又开始共享cr块了。(其实原因是这样的:cr数量由隐含参数_db_block_max_cr_dba控制,默认值是5,5个之后开始就覆盖了,否则无限增多,消耗
buffer量太大)
问题2:如果并发一致性读过多,cr块覆盖会不会影响数据读取?也就是说,A1刚构造了cr块,马上就被A2覆盖了,这时A1会怎么读呢?
在宏观领域是并发,在微观领域(buffer级别)都是串行的。
cr构造前还有对
以及还有对
如果一个 cache
问题3:如果可以共享的话,其实过程可以类似于读block到buffer,此时可以有一个类似于buffer busy waits的等待,只能有一个进程构造CR,而其他进程等待CR构造完成。如果CR已经构造完成,利用cache buffer chain的读共享新特性,并发性岂不是更高?
cr
但是当时间到了 t2 这个点,如果 block 里面本身有了新的事务,查询也有了新的 查询 scn ,你怎么能重用原来的
cr
cr block
一个
就假定你的前提: 如果不同时间点的两个查询具有相同的
scn,那实际上第一个查询已经对该block进行了
不同时间点的查询几乎不可能得到相同的查询 scn,所以
cr
关于cr块共享,听起来好像能提高性能,可这只是想当然。
假设process1要对block
X进行一致性读,首先要判断是否X已经有cr块存在,如果存在,还要判断该cr块是否符合当前scn的要求。这样有点得不偿失。
而且,对block的变更一般都会很快就commit了,短时间内并发访问不会太多。Oracle的设计师们肯定做过仔细考虑的。
这让我想起了以前的一个问题:Oracle为什么会将尚未commit的数据写入datafile?一般人可能会想(me
too):先将数据存放到cache中,等commit时再写入datafile。
实际上事务commit的几率远高于rollback的几率(rollback的代价也远高于commit),直接写入datafile绝对能大幅提高性能。这样想来,会明白Oracle的设计师们的思维果真超群啊!。
问题4:是不是可以猜测到oracle并没有实现cr共享,但又存在需要多个cr的情况,而多个cr可能是同版本的,也可能由于数据修改而不是同版本的?
多个
如果不存在
CR ,也不需要从回滚段获取数据,所有事务都是干净的,就直接读了,不需要构造cr。
如果存在CR而查询scn又不一样,那这个问题又分,到底后面这个查询是否需要从回滚段获取数据,
如果不需要从回滚段获得数据,那就不需要构造 CR了。如果需要,如何校验和上一个 CR 实际上是一样的?
看两个查询之间该block是否发生过变化? 很显然这样事情会越来越复杂。所以,我们完全可以理解为,cr是基于scn的查询,不存在什么共享问题。
几个细节:
Cr块不会写入回滚表空间所在的数据文件
cr块是从undo表空间中来的,就会存在一个物理读
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/21774112/viewspace-1115145/ ,如需转载,请注明出处,否则将追究法律责任。