Oracle 块清除

      一. 块清除概念

      我们知道在oracle中数据锁实际上是数据上的属性,存储在数据块首部。每一次用户访问这一个块的时候,如果发现这个块首部有以前用户访问的锁定信息,但以前的用户已经释放了锁。这个时候,应该首先将块首部清空。总而言之,块清除就是清除块首部一些锁定信息。

      二. 块清除发生场景

      1. Commit 的时候

       用户提交数据的时候,commit有一个步骤是这样的:访问一个块的时候,如果块还在SGA中,就要再次访问这些块,如果可以访问,则对这些块进行清理。

      2. update语句会清除块首部的事务信息(锁信息)

      3. 进行大批量更新,删除,插入数据之后进行查询操作。

     三. COMMIT清理块的条件

      在与我们的事务相关的提交列表中,Oracle会记录已修改的块列表。这些列表都有20个块,Oracle会根据需要分配多个这样的列表,直至达到某个临界点。如果我们修改的块加起来超过了块缓冲区缓存大小的10%,Oracle会停止为我们分配新的列表。例如,如果缓冲区缓存设置为可以缓存3,000个块,Oracle会为我们维护最多300个块(3,000的10%)。COMMIT时,Oracle会处理这些包含20个块指针的列表,如果块仍可用,它会执行一个很快的清理。所以,只要我们修改的块数没有超过缓存中总块数的10%,而且块仍在缓存中并且是可用的,Oracle就会在COMMIT时清理这些块。否则,它只会将其忽略(也就是说不清理)。换言之,如果你事先执行了很大批量数据的插入,修改或者删除,commit的时候,不会清理这些修改或者插入数据所在块的块首部信息。下次一个用户查询这些数据的时候,首先会要清理这些块首部。由此,这个select语句会生成redo信息,显得很诡异!而且这些redo信息会反过来弄脏数据块。

     四. 如何避免select生成redo信息

     必须知道,如果块需要清理,第一接触这个数据的查询将带来一些额外的处理。(甚至会弄脏数据)如果认识到这一点,你就应该在UPDATE之 后自己主动地“接触”数据。你刚刚加载或修改了大量的数据;现在至少需要分析这些数据。可能要自行运行一些报告来验证数据已经加载。这些报告会完成块清 除,这样下一个查询就不必再做这个工作了。更好的做法是:由于你刚刚批量加载了数据,现在需要以某种方式刷新统计。通过运行DBMS_STATS实用程序来收集统计,就能很好地清理所有块,这是因为它只是使用SQL来查询信息,会在查询当中很自然地完成块清除

猜你喜欢

转载自liwenshui322.iteye.com/blog/1568175
今日推荐