学习动态视图(五) v$bh + x$bh

动态视图学习计划列表

视图定义

SQL> desc v$bh
 名称                     类型
 --------------------------------------------
 FILE#                       NUMBER
 BLOCK#                  NUMBER
 CLASS#                   NUMBER
 STATUS                   VARCHAR2(7)     free - not currently in use
                                                                  xcur - exclusive current,表示该数据块处于排外模式;
                                                                  scur - shared current,在RAC环境中表示该数据库正在和其他实例共享数据。
                                                                  cr - consistent read,表示该数据块是一个克隆(clone)的数据库,可以执行共享的只读操作;
                                                                   read - being read from disk 
                                                                   mrec - in media recovery mode,表示数据块处于介质恢复模式;
                                                                   irec - in instance recovery mode ,表示数据块处于实例恢复模式;
                                                                   write - 表示数据库正在往磁盘写入数据;
 XNC                                     NUMBER
 FORCED_READS            NUMBER
 FORCED_WRITES           NUMBER
 LOCK_ELEMENT_ADDR       RAW(4)
 LOCK_ELEMENT_NAME       NUMBER
 LOCK_ELEMENT_CLASS      NUMBER
 DIRTY                   VARCHAR2(1)                                                y - block modified
 TEMP                    VARCHAR2(1)                                                y - temporary block
 PING                     VARCHAR2(1)                                                y - block pinged
 STALE                  VARCHAR2(1)                                                y - block is stale
 DIRECT                VARCHAR2(1)                                               y - direct block
 NEW                     CHAR(1)
 OBJD                    NUMBER
 TS#                       NUMBER
 
从 v$fixed_view_definition 的视图定义可以看到,v$bh来自x$bh:

SQL> desc x$bh
 名称                     类型
 --------------------------------------------

 ADDR                     RAW(4)
 INDX                       NUMBER
 INST_ID                 NUMBER
 HLADDR                RAW(4)         关联v$latch_children.addr查找热点块,参见学习动态视图(七) v$latch + v$latch_children
 BLSIZ                      NUMBER
 NXT_HASH            RAW(4)
 PRV_HASH            RAW(4)
 NXT_REPL             RAW(4)
 PRV_REPL             RAW(4)
 FLAG                        NUMBER
 RFLAG                   NUMBER
 SFLAG                   NUMBER
 LRU_FLAG           NUMBER        非脏数据缓冲列表标志
 TS#                        NUMBER
 FILE#                     NUMBER
 DBARFIL                 NUMBER       数据对象Id,关联dba_extents.relative_no
 DBABLK                  NUMBER        数据块号
 CLASS                   NUMBER
 STATE                   NUMBER
 MODE_HELD               NUMBER
 CHANGES                 NUMBER
 CSTATE                  NUMBER
 LE_ADDR                 RAW(4)
 DIRTY_QUEUE             NUMBER
 SET_DS                  RAW(4)
 OBJ                     NUMBER        对象编号
 BA                      RAW(4)
 CR_SCN_BAS              NUMBER
 CR_SCN_WRP              NUMBER
 CR_XID_USN              NUMBER
 CR_XID_SLT              NUMBER
 CR_XID_SQN              NUMBER
 CR_UBA_FIL              NUMBER
 CR_UBA_BLK              NUMBER
 CR_UBA_SEQ              NUMBER
 CR_UBA_REC              NUMBER
 CR_SFL                  NUMBER
 CR_CLS_BAS              NUMBER
 CR_CLS_WRP              NUMBER
 LRBA_SEQ                NUMBER
 LRBA_BNO                NUMBER
 HSCN_BAS                NUMBER
 HSCN_WRP                NUMBER
 HSUB_SCN                NUMBER
 US_NXT                  RAW(4)
 US_PRV                  RAW(4)
 WA_NXT                  RAW(4)
 WA_PRV                  RAW(4)
 TCH                     NUMBER         接触次数
 TIM                     NUMBER         上次修改tch的时间
 obj可以知道当前这个块是那个对象使用的。通过查询dba_objects,关联object_id可以知道具体对象。
 tch越高表明该块被调用次数越多,oracle每3秒会更新一次这个字段,同时也会不定期地“冷却”它。 频繁使用的块将会被缓存,不常使用的块不会被缓存太久,这也就意味着tch值较高的块存活时间较值低的块会更长一点。

理解v$bh,参见 http://blog.chinaunix.net/u2/65666/showart_693387.html

+--------------------------------------------------------------------------------------------------
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:
   

文件:show_spaceprocedure.rar
大小:0KB
下载:下载

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

4, 获得表test在数据块中的分布情况:
  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$bh和v$bh的更新:
  SQL> select file#,dbablk,tch from x$bh where bj=
  2  (select data_object_id from dba_objects
  3  where wner='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 bjd=
  2  (select data_object_id from dba_objects
  3  where wner='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 wner='SYS' and segment_name='TEST';

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

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

6,清空数据缓存:
    SQL> alter system flush buffer_cache;

7,重新检查v$bh和x$bh的内容:
  SQL> select file#,dbablk,tch from x$bh where bj=
  2  (select data_object_id from dba_objects
  3  where wner='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 bjd=
  2  (select data_object_id from dba_objects
  3  where wner='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这些数据块中,这就是说,虽然数据已经被写到了磁盘中,但是数据库记录的指针并没有清空,仅仅是其状态发生了改变。

8,进阶
     明白是oracle数据库管理数据块的部分工作模式后,我们可以利用v$bh文件统计对象在数据缓冲中被cache的块数了,如:
    SQL> select count(*) from v$bh where bjd=
  2  (select data_object_id from dba_objects
  3  where wner='SYS'  and object_name='TEST')
  4  and status != 'free';

  COUNT(*)
----------
        17
    表示表test中有17个数据块还存在于缓存当中。

+--------------------------------------------------------------------------------------------------

使用1:列出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);

使用2:v$bh 和 v$cache 视图,可以查询 buffer cache中缓存的数据块,其中包括脏数据块以及为读一致性构造的cr 块.


alter system flush buffer_cache;

select * from scott.test;

SQL> select OWNER,OBJECT_NAME,OBJECT_ID from dba_objects where wner='SCOTT' and object_type='TABLE' and object_name='TEST';

OWNER                          OBJECT_NAME           OBJECT_ID
------------------------------ -------------------- ----------
SCOTT                          TEST                      53389          


查询 v$bh ,查看读取到 buffer_cache 中的 block

QL> select FILE#,BLOCK#,STATUS,DIRTY from v$bh where bjd=53389 ORDER BY BLOCK#;

     FILE#     BLOCK# STATUS  D
---------- ---------- ------- -
         4         75 xcur    N
         4         76 xcur    N
         4         77 xcur    N
         4         78 xcur    N
         4         79 xcur    N
         4         80 xcur    N

通过 v$cache 查看(创建v$cache: ?\rdbms\admin\catclust.sql)

SQL> select FILE#,BLOCK#,STATUS from v$cache where file#=1 and block# BETWEEN 75 AND 80 order by block ;

     FILE#     BLOCK# STATUS
---------- ---------- -------
         1         75 free
         1         75 free
         1         75 free
         1         76 free
         1         76 free
         1         76 free
         1         77 free
         1         77 free
         1         77 free
         1         78 free
         1         78 free
         1         78 free
         1         79 free
         1         79 free
         1         79 free
         1         80 free
         1         80 free
         1         80 free


SQL> select FILE#,BLOCK#,STATUS from v$cache where owner# = (select user_id from dba_users where username='SCOTT');

     FILE#     BLOCK#     CLASS# STATUS        XNC  NAME       KIND                OWNER#
---------- ---------- ---------- ------ ----------  -------------------------- ----------
         1       1489          4 xcur            0  TEST       TABLE                   52
         1       1490          1 xcur            0  TEST       TABLE                   52


sql> update SCOTT.test set ID=5 WHERE ID BETWEEN 10 AND 20;

可以从 v$bh 的 DIRTY 列,查出变脏的数据块

sqlplus "/ as sysdba"
SQL> select FILE#,BLOCK#,STATUS,DIRTY from v$bh where bjd=53389 ORDER BY BLOCK#;

     FILE#     BLOCK# STATUS  D
---------- ---------- ------- -
         4         75 xcur    N
         4         76 xcur    N
         4         77 xcur    N
         4         78 xcur    N
         4         79 cr      N
         4         79 xcur    N
         4         80 xcur    N
        
多了一行,系统为这个新进程构造了 cr (一致性读) block.

 

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

转载于:http://blog.itpub.net/55472/viewspace-374950/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值