1创建一个测试表,test,并且插入10000行数据;
    SQL>  create table test (id int);

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

2
创建一个存储过程SHOW_SPACE

create or replace procedure show_space

       ( p_segname in varchar2,

  p_owner   in varchar2 default user,

  p_type    in varchar2 default 'TABLE',

  p_partition in varchar2 default NULL )

as

    l_total_blocks              number;

    l_total_bytes               number;

    l_unused_blocks             number;

    l_unused_bytes              number;

    l_LastUsedExtFileId         number;

    l_LastUsedExtBlockId        number;

    l_last_used_block           number;

    procedure p( p_label in varchar2, p_num in number )

    is

    begin

        dbms_output.put_line( rpad(p_label,40,'.') ||p_num );

    end;

begin

    dbms_space.unused_space

    ( segment_owner     => p_owner,

      segment_name      => p_segname,

      segment_type      => p_type,

      partition_name    => p_partition,

      total_blocks      => l_total_blocks,

      total_bytes       => l_total_bytes,

      unused_blocks     => l_unused_blocks,

      unused_bytes      => l_unused_bytes,

      last_used_extent_file_id => l_LastUsedExtFileId,

      last_used_extent_block_id => l_LastUsedExtBlockId,

      last_used_block => l_last_used_block );

    p( 'Total Blocks', l_total_blocks );

    p( 'Total Bytes', l_total_bytes );

    p( 'Unused Blocks', l_unused_blocks );

    p( 'Unused Bytes', l_unused_bytes );

    p( 'Last Used Ext FileId', l_LastUsedExtFileId );

    p( 'Last Used Ext BlockId', l_LastUsedExtBlockId );

    p( 'Last Used Block', l_last_used_block );

end;

/

3检查表test的空间使用情况:
    SQL> exec show_space('TEST');
    Total Blocks............................24
    Total Bytes.............................196608
    Unused Blocks...........................3
    Unused Bytes............................24576
    Last Used Ext FileId....................1
    Last Used Ext BlockId...................62177
    Last Used Block.........................5

由上可知,该表test共占用了24个数据块,196608字节,文件ID为1. 其实这里也可以直接查询 dba_segments看到这些信息.

SQL> 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 order by b;

F          B
---------- ----------
         1      62162
         1      62163
         1      62164
         1      62165
         1      62166
         1      62167
         1      62168
         1      62169
         1      62170
         1      62171
         1      62172
         1      62173
         1      62174
         1      62175
         1      62176
         1      62177

16 rows selected.
    由此可见,表test中的数据共占用了16个数据块,但是前面第三步中,发现该表占用了24个数据块。这是正常的,因为oracle本身会使用8个数据块来记录段头、位图块等额外的信息。我们现在只需要了解到,表test共占用了24个数据块,其中16个是数据,8个是表信息。

5,检查x$bhv$bh的更新:
  SQL> select file#,dbablk,tch from x$bh where obj=
  2  (select data_object_id from dba_objects
  3  where owner='SYS'  and object_name='TEST')
  4  order by dbablk;

FILE#     DBABLK        TCH
---------- ---------- ----------
         1      62161          6
         1      62162          3
         1      62163          3
         1      62164          3
         1      62165          3
         1      62166          3
         1      62167          3
         1      62168          3
         1      62169          3
         1      62170          3
         1      62171          3
         1      62172          3
         1      62173          3
         1      62174          3
         1      62175          3
         1      62176          3
         1      62177          3
         1      62178          3
         1      62179          3
         1      62180          3
         1      62181          3

21 rows selected.

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

FILE#     BLOCK# STATUS
---------- ---------- -------
         1      62161 xcur
         1      62162 xcur
         1      62163 xcur
         1      62164 xcur
         1      62165 xcur
         1      62166 xcur
         1      62167 xcur
         1      62168 xcur
         1      62169 xcur
         1      62170 xcur
         1      62171 xcur
         1      62172 xcur
         1      62173 xcur
         1      62174 xcur
         1      62175 xcur
         1      62176 xcur
         1      62177 xcur
         1      62178 xcur
         1      62179 xcur
         1      62180 xcur
         1      62181 xcur

21 rows selected.

这里可以看到,在v$bh和x$bh中得到的数据块,是从62161~62181的21条记录,但是在第四步中,我们知道数据是占用了62162~62177的16个数据库,这里,62161数据块里面存放的是段头信息,可以通过如下命令进行验证:
  SQL> select header_file,header_block from dba_segments
  2  where owner='SYS' and segment_name='TEST';

HEADER_FILE HEADER_BLOCK
    ----------- ------------
          1        62161

在v$bh视图中,我们可以看到这21个数据块都是xcur状态,表示这些数据块都是排斥状态,正在被使用,该字段还有其他的类型,请参见数据块的状态类型

oracle缓冲块(data block)状态类型

oracle的缓冲块的管理机制一直没有正式的发布过,因此许多有经验的oracle工程师都是通过经验或者一下oracle文档中的注释来推断oracle的缓冲块的管理机制的。

事实上,oralce使用v$bh视图来记录与数据缓冲(data buffer)相关的信息,它详细记录了数据缓冲中每一个数据块(data block)的状态信息。

在v$bh视图中的status字段,记录了数据块的状态,在非OPS、非RAC这样的集群环境中,数据块的状态会是下列几种之一:xcur,cr,read,free,用户可以通过如下命令得到数据库的状态信息:
    SQL> select unique status from v$bh;

    其状态的意义分别是:
    xcur:(exclusive current)的意思,表示该数据块处于排外模式;
    cr:表示该数据块是一个克隆(clone)的数据库,可以执行共享的只读操作;
    free:表示这是一个限制的数据块,oracle现在没有使用它;
    read:表示该数据块正在从磁盘读取数据;
    write:表示数据库正在往磁盘写入数据;

在数据库恢复过程中,该字段还有另外两个描述:mrec和irec:
    mrec:(media recovery)表示数据块处于介质恢复模式;
    irec:(instance recovery)表示数据块处于实例恢复模式;

在RAC环境中,数据块还有另外一种模式:
    scur (shared current),表示该数据库正在和其他实例共享数据。


6,清空数据缓存:
    SQL> alter system flush buffer_cache;
(在Oracle9i里,Oracle提供了一个内部事件,用以强制刷新Buffer Cache,其语法为:

alter session set events 'immediate trace name flush_cache level 1';

或者:

alter session set events = 'immediate trace name flush_cache';

类似的也可以使用alter system系统级设置:

alter system set events = 'immediate trace name flush_cache';

在Oracle10g中,Oracle提供一个新的特性,可以通过如下命令刷新Buffer Cache:

alter system flush buffer_cache;


7,重新检查v$bhx$bh的内容:
  SQL> select file#,dbablk,tch from x$bh where  obj=
  2  (select data_object_id from dba_objects
  3  where owner='SYS'  and object_name='TEST')
  4  order by dbablk;

FILE#     DBABLK        TCH
---------- ---------- ----------
         1      62161          0
         1      62162          0
         1      62163          0
         1      62164          0
         1      62165          0
         1      62166          0
         1      62167          0
         1      62168          0
         1      62169          0
         1      62170          0
         1      62171          0
         1      62172          0
         1      62173          0
         1      62174          0
         1      62175          0
         1      62176          0
         1      62177          0
         1      62178          0
         1      62179          0
         1      62180          0
         1      62181          0

21 rows selected.

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

FILE#     BLOCK# STATUS
---------- ---------- -------
         1      62161 free
         1      62162 free
         1      62163 free
         1      62164 free
         1      62165 free
         1      62166 free
         1      62167 free
         1      62168 free
         1      62169 free
         1      62170 free
         1      62171 free
         1      62172 free
         1      62173 free
         1      62174 free
         1      62175 free
         1      62176 free
         1      62177 free
         1      62178 free
         1      62179 free
         1      62180 free
         1      62181 free

21 rows selected.

这时候我们可以看到,x$bh中的tch字段,已经由原来的3变成了0,同时v$bh视图的数据块状态也变成了free,但是记录的数据块并没有发生变化,还是在62161~62181这些数据块中,这就是说,虽然数据已经被写到了磁盘中,但是数据库记录的指针并没有清空,仅仅是其状态发生了改变。

我们读取到了x$bh中的tch字段,该字段表示的该字段被读取/写入的次数,这个值在oracle的LRU算法中,是一个重要的参数,如果这个字段被访问,则该值就会增加:
tch(touch count) 是通过touch标记的方式在追踪热块.

1,第一次查看TCH的值:
    1.1 获得表ID:
    SQL> select data_object_id from dba_objects
    2     where wner='SYS' and object_name='TEST';

DATA_OBJECT_ID
    --------------
             60629
    
    1.2 获得表所占用的数据库ID:
    SQL> select unique dbablk from x$bh where bj=60629;
    
    1.3 获得该表中,62191数据库的tch值:
    SQL> select tch from x$bh where bj=60629 and dbablk=62191;

TCH
    ----------
             2

2,再次读入表test;
    SQL> select count(*) from test;

COUNT(*)
    ----------
         20000

3,重复1.3操作,再次检测tch值:
    SQL> select tch from x$bh where bj=60629 and dbablk=62191;

TCH
    ----------
             3

用户可以继续试验,TCH会继续增长。由此可见,用户可以通过x$bh,获得系统中访问量比较大的字段以及其所在数据库,进一步优化存储的安排,提高系统性能。

下面的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);

关于热块的文章:

http://www.cnblogs.com/princessd8251/articles/3876834.html

oracle视图V$BH && X$BH的使用列子的更多相关文章

  1. Oracle视图分类及各种操作讲解(超级好文)

    目录:一.视图的定义: 二.视图的作用: 三.创建视图: 1.权限 2.语法 3.1  创建简单视图   3.2  创建连接视图  3.2.1 连接视图定义  3.2.2 创建连接视图  3.2.3 ...

  2. Oracle -----视图

    视图简介: 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改.视图基于的表称为基表.视图是存储在数据字典里的一条select语句. 通过创建视图可以提取数 ...

  3. Oracle视图详解

    转载自:http://blog.itpub.net/29785807/viewspace-1270120/ 一. 视图的定义 视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本 ...

  4. oracle视图总结

    视图简介: 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改.视图基于的表称为基表.视图是存储在数据字典里的一条select语句. 通过创建视图可以提取数 ...

  5. oracle视图总结(转)

    视图简介: 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改.视图基于的表称为基表.视图是存储在数据字典里的一条select语句. 通过创建视图可以提取数 ...

  6. ORACLE 视图的 with check option

    ORACLE 视图的 with check option 我们来看下面的例子: create or replace view testview as select empno,ename from e ...

  7. ORACLE视图添加备注

    ORACLE视图添加备注 版权声明:本文为博主原创文章,未经博主允许不得转载. create or replace view oes_material_series_ref as select t.p ...

  8. Oracle 视图 (待更新, 缓存)

    参考: 视图.索引.存储过程优缺点: http://www.cnblogs.com/SanMaoSpace/p/3147059.html oracle视图总结(转):http://tianwei013 ...

  9. Oracle视图(和Mysq一样l)

    本章内容: Oracle视图介绍与创建.Oracle视图的查询与修改.Oracle的复杂视图 1. Oracle视图介绍与创建 (1)了解常见的数据库对象都有哪些 (2)了解什么是视图以及为什么要使用 ...

  10. (转)oracle视图详解

    Oracle视图详解   一. 视图的定义 视图(view),也称虚表, 不占用物理空间,这个也是相对概念,因为视图本身的定义语句还是要存储在数据字典里的.视图只有逻辑定义.每次使用的时候,只是重新执 ...

随机推荐

  1. Js操作Select大全

    判断select选项中 是否存在Value="paraValue"的Item 向select选项中 加入一个Item 从select选项中 删除一个Item 删除select中选中 ...

  2. hdu Oil Deposits

    因为这道题中给的数据比较小,所以可以直接用枚举的方式进行dfs搜索,每出现一个‘@’,就进行一次dfs的搜索,将所有相邻的‘@’全部变成‘*’. #include"iostream" ...

  3. Html - Bootstrap Panel面板

    http://v3.bootcss.com/components/#panels Bootstrap Panel面板 <div class="panel panel-default&q ...

  4. [GE]手动截取当前活动窗口,并且按规则命名(1/2)

    Function Take-ScreenShot { <# .SYNOPSIS Used to take a screenshot of the desktop or the active wi ...

  5. 禁用符合一定条件的AD对象 (含Filter参数的写法)

    Get-ADComputer -Filter "(sAMAccountType -eq 805306369)" -SearchBase "OU=Computers,OU= ...

  6. PAT (Advanced Level) Practise 1003 Emergency(SPFA+DFS)

    1003. Emergency (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue As an emerg ...

  7. mysql下面的INSTALL-BINARY的内容,所有的mysql的配置内容都在这

    2.2 Installing MySQL on Unix/Linux Using Generic Binaries Oracle provides a set of binary distributi ...

  8. 有两个地方,用到了javabean对象和属性字符串值之间的转换

    1.有两个地方,用到了javabean对象和属性字符串值之间的转换 2.一个是接入层spring mvc,将json字符串参数转换为javaBean.通过@RequestBody javaBean方式 ...

  9. 【翻译】Kinect v1和Kinect v2的彻底比较

      本连载主要是比较Kinect for Windows的现行版(v1)和次世代型的开发者预览版(v2),以C++开发者为背景介绍进化的硬件和软件.本文主要是对传感的配置和运行条件进行彻底的比较.   ...

  10. Visual Studio解决方案及项目的配置

    配置解决方案的属性 1.配置解决方案平台,该配置实际上修改的是解决方案目录下的sln(solution)文件. 配置项目的属性 1.配置项目平台及项目的目标平台:项目-右键-属性-生成(竖着第二个选项 ...