视图定义
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:
|
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/