oracle redo与undo_笔记6:块清除
块清除
块清除(block cleanout),即删除所修改数据库块上与“锁定”有关的信息。
数据锁实际上是数据的属性,存储在块首部。这就带来一个副作用,下一次访问这个块时,可能必须清理这个块,换句话说,要将这些事务信息删除。这个动作会生成redo,并导致块变脏(原本并不脏,因为数据本身没有修改),这说明一个简单的SELECT也可能生成redo,而且可能导致完成下一个检查点时将大量的块写至磁盘。如果系统中主要是小型或中型事务(OLTP),或者数据仓库会执行直接路径加载或使用DBMS_STATS在加载操作后分析表,会发现块通常已经得到“清理”。提交(COMMIT)时处理的步骤之一是:如果块还在SGA中,就要再次访问这些块,如果可以访问(没有别人在修改这些块),则对这些块完成清理。这个活动称为提交清除(commit cleanout),即清除已修改块上的事务信息。最理想的是,COMMIT可以完成块清除,这样后面的SELECT就不必再清理了。
只有块的UPDATE才会真正清除残余的事务信息,由于UPDATE已经在生成redo,所以注意不到这个清除工作。在与我们的事务相关的提交列表中,Oracle会记录已修改的块列表。这些列表都有20个块,Oracle会根据需要分配多个这样的列表,直至达到某个临界点。如果我们修改的块加起来超过了块缓冲区缓存大小的10%,Oracle会停止为我们分配新的列表。例如,如果缓冲区缓存设置为可以缓存3000个块,Oracle会为我们维护最多300个块。COMMIT作用时,Oracle会处理这些包含20个块指针的列表,如果块仍可用,它会执行一个很快的清理。所以,只要我们修改的块数没有超过缓存中总块数的10%,而且块仍在缓存中并且是可用的,Oracle就会在提交时清理这些块。否则,它只会将其忽略。
如果把缓冲区缓存设置为能保存至少100000个块,再次运行前面的例子。会发现,无论哪一个SELECT,生成的redo都很少,甚至没有——我们不必在其中任何一个SELECT语句期间清理脏块。这是因为,我们修改的10000多(索引同样也被修改了)个块完全可以在缓冲区缓存的10%中放下,而且我们是独家用户。别人不会动数据,不会有人导致我们的数据刷新输出到磁盘,也没有人在访问这些块。在实际系统中,有些情况下,至少某些块不会进行块清除,这是正常的。
如果执行了一个大的INSERT、UPDATE或DELETE,这种块清除行为的影响最大,它会影响数据库中的许多块(缓存中10%以上的块都会完成块清除)。在此之后,第一个“接触”块的查询会生成少量的redo,并把块弄脏,如果DBWR已经将块刷新输出或者实例已经关闭,可能就会因为这个查询而导致重写这些块,并完全清理缓冲区缓存。对此你基本上做不了什么。这是正常的,也在意料之中。
如果Oracle不对块完成这种延迟清除,那么COMMIT的处理就会与事务本身一样长。提交必须重新访问每一个块,可能还要从磁盘将块再次读入(它们可能已经刷新输出)。
如果你不知道块清除,不明白块清除如何工作,在你看来这可能就是一种好像毫无来由的神秘事物。例如,假设你更新(UPDATE)了大量数据,然后提交(COMMIT)。现在对这些数据运行一个查询来验证结果。看上去查询生成了大量写I/O和redo。倘若不知道存在块清除,这似乎是不可能的。然后你请别人一起来观察这个行为,但这是不可再生的,因为在第二次查询时块又是“干净”的了。这样一来,你就会把它当成是数据库的奥秘之一,该奥秘只出现在你孤立无援的时候。
在一个OLTP系统中,可能从来不会看到这种情况发生,因为OLTP系统的特点是事务都很短小,只会影响为数不多的一些块。根据设计,所有或者大多数事务都短而精。只是修改几个块,而且这些块都会得到清理。在一个数据仓库中,如果加载之后要对数据执行大量UPDATE,就要把块清除作为设计中要考虑的一个因素。有些操作会有“干净”的块上创建数据。例如,CREATE TABLE AS SELECT、直接路径加载的数据以及直接路径插入的数据都会创建“干净”的块。UPDATE、正常的INSERT或DELETE创建的块则可能需要在第一次读时完成块清除。如果你有如下的处理,就会受到块清除的影响。
.将大量新数据批量加载到数据仓库中
.在刚刚加载的所有数据上运行UPDATE(产生需要清理的块)
.让们查询这些数据
必须知道,如果块需要清理,第一个接触这个数据的查询将带来一些额外的处理。如果认识到这一点,你就应该在UPDATE之后自己主动地“接触”数据。你刚刚加载或修改了大量的数据,现在需要分析这些数据。可能要运行一些报告来验证数据已经加载。这些报告会完成块清除,这样下一个查询就不必再做这个工作了。更好的做法是:由于你刚刚批量加载了数据,现在需要以某种方式刷新统计。通过运行DBMS_STATS实用程序来收集统计,就能很好地清理所有块,这是因为它只是使用SQL来查询信息,会在查询当中很自然地完成块清除。
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5266.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
