过着简单,真实的生活,喜欢收藏变形金刚(TFE,G1,SL系列),研究金融股市,KOF98,篮球,学习研究Oracle技术,我并不是一个全职的Oracle DBA,但是对于Oracle技术的热爱和研究,是一个不争的事实,愿意结交广大Oracle技术爱好者!MSN:oracle_kof_tf@hotmail.com

Testing for v$bh and x$bh

上一篇 / 下一篇  2008-02-14 15:57:37 / 个人分类:Oracle数据库技术-SQL

做了一个块相关的实验,记录如下:

C:\>set ORACLE_SID=irmdb

C:\>sqlplus /nolog

SQL*Plus: Release 10.2.0.3.0 - Production on 星期四 2月 14 14:26:52 2008

Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.

SQL> conn / as sysdba;
已连接。
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
PL/SQL Release 10.2.0.3.0 - Production
CORE    10.2.0.3.0      Production
TNS for 32-bit Windows: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production

SQL> create table test (a int);

表已创建。

SQL> begin
  2  for i in 1..5000
  3  loop
  4     insert into test values(i);
  5  end loop;
  6  end;
  7  /

PL/SQL 过程已成功完成。

SQL> commit;

提交完成。

SQL> show user;
USER 为 "SYS"
SQL> set serveroutput on
SQL> exec show_space('TEST');
Total Blocks ...........................              16
Total Bytes  ...........................         131,072
Total MBytes ...........................               0
Unused Blocks...........................               3
Unused Bytes ...........................          24,576
Last Used Ext FileId....................               1
Last Used Ext BlockId...................          64,257
Last Used Block.........................               5

PL/SQL 过程已成功完成。


SQL> select file_id,block_number from
  2  (select dbms_rowid.rowid_relative_fno(rowid) file_id,
  3          dbms_rowid.rowid_block_number(rowid) block_number
  4   from test)
  5  group by file_id,block_number;

   FILE_ID BLOCK_NUMBER
---------- ------------
         1        64254
         1        64251
         1        64255
         1        64250
         1        64252
         1        64256
         1        64253
         1        64257

已选择8行。

我们可以看到实际上这个表只占用了8个blocks,那么通过show_space我们看到的却是16,其实剩下的那8个块就是段头,位图块等等,是一种额外的开销。因此我们可以得到一个结论就是,表中有16个block,而data block只有8个。

SQL> select file#,dbablk,tch from x$bh where bj=
  2  (select data_object_id from dba_objects where wner='SYS' and object_name='TEST')
  3  order by dbablk;

     FILE#     DBABLK        TCH
---------- ---------- ----------
         1      64249          7
         1      64250          6
         1      64251          5
         1      64252          6
         1      64253          6
         1      64254          6
         1      64255          6
         1      64256          5
         1      64257          7
         1      64258          7
         1      64259          7
         1      64260          7
         1      64261          7

已选择13行。( 这里的块为什么是13而不是16?那位朋友能给一下答案呢?)

SQL> select file#,block#,status from v$bh where bjd=
  2  (select data_object_id from dba_objects where wner='SYS' and object_name='TEST')
  3  order by block#;

     FILE#     BLOCK# STATUS
---------- ---------- -------
         1      64249 xcur
         1      64250 xcur
         1      64251 xcur
         1      64252 xcur
         1      64253 xcur
         1      64254 xcur
         1      64255 xcur
         1      64256 xcur
         1      64257 xcur
         1      64258 xcur
         1      64259 xcur
         1      64260 xcur
         1      64261 xcur

已选择13行。

这里从v$bh中我们可以进一步来查看block的状态,其实这个值是通过x$bh的state字段通过decode函数得来的:
简单描述一下:
xcur 表示这个块是排斥状态正在被当前的instance独占。
scur 表示这个块正在被当前的instance共享
cr 表示一致读
free 表示块处在空闲状态
read 表示正在从磁盘上读取块
write 表示块正在被写出

我们再来验证一下段头信息:
SQL> desc dba_segments;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ---------------------------
 OWNER                                              VARCHAR2(30)
 SEGMENT_NAME                                       VARCHAR2(81)
 PARTITION_NAME                                     VARCHAR2(30)
 SEGMENT_TYPE                                       VARCHAR2(18)
 TABLESPACE_NAME                                    VARCHAR2(30)
 HEADER_FILE                                        NUMBER
 HEADER_BLOCK                                       NUMBER
 BYTES                                              NUMBER
 BLOCKS                                             NUMBER
 EXTENTS                                            NUMBER
 INITIAL_EXTENT                                     NUMBER
 NEXT_EXTENT                                        NUMBER
 MIN_EXTENTS                                        NUMBER
 MAX_EXTENTS                                        NUMBER
 PCT_INCREASE                                       NUMBER
 FREELISTS                                          NUMBER
 FREELIST_GROUPS                                    NUMBER
 RELATIVE_FNO                                       NUMBER
 BUFFER_POOL                                        VARCHAR2(7)

SQL> select header_file,header_block from dba_segments
  2  where wner='SYS' and segment_name='TEST';

HEADER_FILE HEADER_BLOCK
----------- ------------
          1        64249

进一步实验,首先flush一下buffer cache:

SQL> alter system flush buffer_cache;

系统已更改。

SQL> select file#,dbablk,tch from x$bh where bj=
  2  (select data_object_id from dba_objects where wner='SYS' and object_name='TEST')
  3  order by dbablk;

     FILE#     DBABLK        TCH
---------- ---------- ----------
         1      64249          0
         1      64250          0
         1      64251          0
         1      64252          0
         1      64253          0
         1      64254          0
         1      64255          0
         1      64256          0
         1      64257          0
         1      64258          0
         1      64259          0
         1      64260          0
         1      64261          0

已选择13行。

SQL> select file#,block#,status from v$bh where bjd=
  2  (select data_object_id from dba_objects where wner='SYS' and object_name='TEST')
  3  order by block#;

     FILE#     BLOCK# STATUS
---------- ---------- -------
         1      64249 free
         1      64250 free
         1      64251 free
         1      64252 free
         1      64253 free
         1      64254 free
         1      64255 free
         1      64256 free
         1      64257 free
         1      64258 free
         1      64259 free
         1      64260 free
         1      64261 free

已选择13行。

这里可以看到所有test段相关的block的tch都已经归0了,而且v$bh中的status也都变成了free,说明了当前的块是空闲的。需要主要的是block虽然被flush到disk上去,但是block的记录还存在。 

为了再进一步证明这一点:
SQL> select count(*) from test;

  COUNT(*)
----------
      5000

SQL> select file#,block#,status from v$bh where bjd=
  2  (select data_object_id from dba_objects where wner='SYS' and object_name='TEST')
  3  order by block#;

     FILE#     BLOCK# STATUS
---------- ---------- -------
         1      64249 free
         1      64249 xcur
         1      64250 free
         1      64250 xcur
         1      64251 free
         1      64251 xcur
         1      64252 xcur
         1      64252 free
         1      64253 xcur
         1      64253 free
         1      64254 xcur
         1      64254 free
         1      64255 free
         1      64255 xcur
         1      64256 free
         1      64256 xcur
         1      64257 free
         1      64257 xcur
         1      64258 free
         1      64258 xcur
         1      64259 free
         1      64259 xcur
         1      64260 xcur
         1      64260 free
         1      64261 free
         1      64261 xcur

已选择26行。

注意到x$bh字典表中的tch字段表示的就是block的touch count,一般来说这个值越高那么这个块就越热,我们称这样的块就叫做热点块。

一般我们通过x$bh就可以找出系统的热点块以及相关的信息:
需要注意的是user/all/dba_objects中的data_object_id关联x$bh中的obj或者是v$bh中的objd是关键:

下面的script可以列出top 10的热点块对象
select /*+rule*/ owner,object_name from dba_objects
where data_object_id in
(select obj from (select obj from x$bh order by tch desc) where rownum < 11);


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar