块清除
当Oracle更改数据块时,会对这个数据块进行跟踪。在提交的时候,将会重新访问这个块并将更改标记为已经提交。但是只标示那些还没有从db_block_buffers中清除的块。而且,如果更改了太多的块,那么也只有前面少数的块(db_block_buffers的10%)被重新访问。
当提交的时候,如果这些块还在缓存中,那么Oracle将会进行fast commit,清除块头部的事务信息。对于那些已经从db_block_buffers中清除,被写入磁盘的数据块,Oracle将会忽略这些块。当下次的DML或者查询语句再访问这些块的时候,由这些语句负责清除,这就是所谓的delayed block cleanout。所以,即使是查询语句也可能产生重做日志。
通过如下的方法来验证:
a. 创建表,保证一块只能存储一行,在8K大小数据块中,创建每行大小为6K的数据库;
b. 插入499行纪录,使用499个数据块,其大小已经超过30(也即300的10%);
c. 提交;
d. 对于在db_block_buffers的数据块(同时保证小于db_block_buffers 10%),Oracle执行fast commit,对于其他的数据块Oracle将忽略;
e. 执行全表扫描的查询语句。这条语句将会重新访问步骤d中没有被清除的块,对这些块头的事务信息进行清除,这个步骤将会产生重做日志。
f. 检查通过步骤e查询所产生的重做日志。
g. 执行新的查询,由于步骤e已经清除块头的事务信息,这个时候查询将不会需要清除块,也不会产生重做日志。
SQL> create table t --保证一块只能存储一行
2 ( x char(2000) default 'x',
3 y char(2000) default 'y',
4 z char(2000) default 'z' )
5 /
Table created.
SQL>
SQL> insert into t --插入499行纪录,使用499个数据块
2 select 'x','y','z'
3 from all_objects where rownum <500
SQL> commit;-- 提交,插入过程中部分快会执行fast commit,部分块被忽略
Commit complete.
SQL>
SQL> column value new_value old_value
SQL>
SQL> select * from redo_size;
VALUE
----------
3332424
SQL>
SQL> select *
2 from t
3 where x = y;
no rows selected
SQL> select value-&old_value REDO_GENERATED from redo_size;
old 1: select value-&old_value REDO_GENERATED from redo_size
new 1: select value- 3332424 REDO_GENERATED from redo_size
REDO_GENERATED
--------------
10740 --查询过程产生了重做日志,证明进行了块清除操作
SQL> commit;
Commit complete.
SQL>
SQL> select value from redo_size;
VALUE
----------
3343164
SQL>
SQL> select *
2 from t
3 where x = y;
no rows selected
SQL>
SQL> select value-&old_value REDO_GENERATED from redo_size;
old 1: select value-&old_value REDO_GENERATED from redo_size
new 1: select value- 3343164 REDO_GENERATED from redo_size
REDO_GENERATED
--------------
0--查询过程没有产生重做日志,前面的查询已经清除块,第二次查询不再有清除动作
上面的第一个查询产生了重做日志,有可能促使这些块被DBWR重写。Oracle必须采用delayed clear out的策略,否则在提交的时候必须重新访问更新块,还可能从磁盘中读取快,这将会是相当耗时的工作。
有些事务创建“干净的”数据块,例如:CREATE TABLE AS SELECT。
在某些情况下,进行大量的数据更新之后,也可以主动访问数据块,让最终用户访问的时候速度会更快。例如通过ANALYZE命令,可以清除块。
参考:
Block cleanout - fast or delayed.
订阅:
博文评论 (Atom)
没有评论:
发表评论