ITPub博客

首页 > 数据库 > Oracle > 对象有多少个数据块缓冲在Data buffer中

对象有多少个数据块缓冲在Data buffer中

原创 Oracle 作者:tanxiaoke88 时间:2009-10-25 22:09:09 0 删除 编辑

对象有多少个数据块缓冲在Data buffer中

为了详细说明具体的情况,先创建一个测试表,并且插入一定的记录进去。

Piner@10gR2>create table test(a int);
Table created.
Piner@10gR2>begin
2 for i in 1..5000 loop
3 insert into test values(i);
4 end loop;
5 end;
6 /
PL/SQL procedure successfully completed.
Piner@10gR2>commit;
Commit complete
如以上,先创建了一个叫test的表,并插入了5000条记录,插入记录后,用showspace存储过程分析一下表的空间使用情况。关于这个存储过程的具体代码,在本书的附录B中可以获得,因为这个存储过程本身很通用,这里就不多介绍这个存储过程本身了。
Piner@10gR2>set serveroutput on
Piner@10gR2>exec show_space('TEST');
Total Blocks............................16
Total Bytes.............................131072
Unused Blocks...........................0
Unused Bytes............................0
Last Used Ext FileId....................4
Last Used Ext BlockId...................17
Last Used Block.........................8
PL/SQL procedure successfully completed.
可以看到的是,这张TEST的表一共使用了16个块,数据文件id为4,我们再分析一下数据所在的Rowid。
Piner@10gR2>select f,b from (
2 select dbms_rowid.rowid_relative_fno(rowid) f,
3  dbms_rowid.rowid_block_number(rowid) b
4 from test) group by f,b;
            F             B
---------- ----------
4 12
4 20
4 13
4 21
4 14
4 16
4 22
4 15
8 rows selected.

可以看到,数据块其实只占用了8个块,但是表合计占用了16个数据块,另外8个块是什么呢,它们是段头,位图块等,是表中的额外开销。至于这些块的详细信息,在本书的表空间与数据分布一章会有详细介绍,现在只需要知道,该表有16个block,数据块占了8个。

注意:以上通过Rowid查询使用了哪些数据块,只适合没有发生行迁移与行链接的情况下,如新创建的表,插入的小记录是适合的。如果发生了行迁移与行链接,因为Rowid本身不发生变化,而数据块的使用却会发生变化。

那么,现在分别查询一下x$bh与v$bh,看看它们中间保存了几条记录。

Piner@10gR2>select file#,dbablk,tch from x$bh where obj=
2 (select data_object_id from dba_objects
3 where owner='PINER' and object_name='TEST')
4 order by dbablk;

FILE# DBABLK TCH
---------- ---------- ----------
4 9 2
4 10 2
4 11 5

4 12 2
4 13 2
4 14 2
4 15 2
4 16 2
4 17 2
4 18 2
4 19 2
4 20 2
4 21 2
4 22 2
4 23 2
4 24 2

16 rows selected.

Piner@10gR2>select file#,block#,status from v$bh where objd=
2 (select data_object_id from dba_objects
3 where owner='PINER' and object_name='TEST')
4 order by block#;

FILE# BLOCK# STATUS
---------- ---------- -------
4 9 xcur
4 10 xcur
4 11 xcur
4 12 xcur
4 13 xcur
4 14 xcur
4 15 xcur
4 16 xcur
4 17 xcur
4 18 xcur
4 19 xcur
4 20 xcur
4 21 xcur
4 22 xcur
4 23 xcur
4 24 xcur

16 rows selected.

可以看到,这两个查询都返回了16条记录,从块9到块24,中间包含了数据块所在的8个块。至于为什么从块9开始,在本书的后面也会有解释,因为本地管理的数据文件头部,有8个保留块。

看x$bh,返回了块的触摸(touch count)信息,表示了一个块的热点程度,现在最热的是数据块11,它并不是数据块,而是段头,通过如下查询也可以证明:

Piner@10gR2>select header_file,header_block from dba_segments
  2  where owner='PINER' and segment_name='TEST';
HEADER_FILE HEADER_BLOCK
----------- ------------
4 11

看v$bh,返回了块的状态信息,这里是xcur,表示排斥状态,被当前instance独占,也就是该块正在被使用。常见的状态还有scur,表示被instance共享;cr,表示一致性读;free表示空闲状态;read,表示正在从磁盘上读取;write,表示正在被写入。至于v$bh的这些状态,也是从x$bh中通过decode函数根据字段state解释过来的,所以能看得更明白一些。

如果这个时候,手工清除一次Data buffer,会发生什么情况呢?

Piner@10gR2>alter system flush buffer_cache;
System altered.
Piner@10gR2>select file#,dbablk,tch from x$bh where obj=
2 (select data_object_id from dba_objects
3 where owner='PINER' and object_name='TEST')
4 order by dbablk;
       FILE#       DBABLK          TCH
---------- ---------- ----------
4 9 0
4 10 0
4 11 0
4 12 0
4 13 0
4 14 0
4 15 0
4 16 0
4 17 0
4 18 0
4 19 0
4 20 0
4 21 0
4 22 0
4 23 0
4 24 0
16 rows selected.
Piner@10gR2>select file#,block#,status from v$bh where objd=
2 (select data_object_id from dba_objects
3 where owner='PINER' and object_name='TEST')
4 order by block#;
       FILE#       BLOCK# STATUS
---------- ---------- -------
4 9 free
4 10 free
4 11 free
4 12 free
4 13 free
4 14 free
4 15 free
4 16 free
4 17 free
4 18 free
4 19 free
4 20 free
4 21 free
4 22 free
4 23 free
4 24 free
16 rows selected.

可以看到,x$bh中的块的tch都恢复到0了,而v$bh中的状态也都变成free了,但是记录数并没有发生变化,也就是说,数据块虽然被刷到磁盘上去了,数据块的记录指针只不过是简单地被清空而已。

源 http://holyane.blog.163.com/blog/static/4192717220099161104576/

[@more@]

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/21340813/viewspace-1028127/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: rowid浅析
请登录后发表评论 登录
全部评论

注册时间:2009-05-12

  • 博文量
    36
  • 访问量
    38333