通过案例学调优之--动态视图(v$bh和x$bh)
来源:互联网 发布:淘宝管控记录一般多久 编辑:程序博客网 时间:2024/06/04 13:21
v$bh与x$bh
v$bh:非常详细地记录了数据块在数据缓冲区内的使用情况,一条记录对应一个block的详细记录。
v$bh来自于基表x$bh与x$le
查看v$bh结构:
13
:
07
:
20
SYS@ test1 >desc v$bh
Name Null? Type
----------------------------------------------------------------- -------- --------------------------------------------
FILE# NUMBER
BLOCK# NUMBER
CLASS# NUMBER
STATUS VARCHAR2(
10
)
XNC NUMBER
FORCED_READS NUMBER
FORCED_WRITES NUMBER
LOCK_ELEMENT_ADDR RAW(
4
)
LOCK_ELEMENT_NAME NUMBER
LOCK_ELEMENT_CLASS NUMBER
DIRTY VARCHAR2(
1
)
TEMP VARCHAR2(
1
)
PING VARCHAR2(
1
)
STALE VARCHAR2(
1
)
DIRECT VARCHAR2(
1
)
NEW CHAR(
1
)
OBJD NUMBER
TS# NUMBER
LOBID NUMBER
CACHEHINT NUMBER
STATUS
free - not currently in use
xcur - exclusive current,表示该数据块处于排外模式,正在被当前Instance占用;
scur - shared current,在RAC环境中表示该数据库正在和其他实例共享数据。
cr - consistent read,一致性读。
read - being read from disk
mrec - in media recovery mode,表示数据块处于介质恢复模式;
irec - in instance recovery mode ,表示数据块处于实例恢复模式;
write -表示数据库正在往磁盘写入数据;
13:07:19 SYS@ test1 >select * from v$fixed_view_definition t where t.view_name='GV$BH'
VIEW_NAME VIEW_DEFINITION
------------------------------ --------------------------------------------------
GV$BH select bh.inst_id, file#, dbablk,
class
, decode(st
ate,
0
,
'free'
,
1
,
'xcur'
,
2
,
'scur'
,
3
,
'cr'
,
4
,
'read'
,
5
,
'mrec'
,
6
,
'irec'
,
7
,
'write'
,
8
,
'pi'
,
9
,
'memory'
,
10
,'m
write
',11,'
donated
', 12,'
protected
', 13,'
securefi
le
', 14,'
siop
',15,'
recckpt
', 16, '
flashfree',
17
,
'flashcur'
,
18
,
'flashna'
),
0
,
0
,
0
, bh.le_addr,
le_id1, le_id2, decode(bitand(flag,
1
),
0
,
'N'
,
'Y'
), decode(bitand(flag,
16
),
0
,
'N'
,
'Y'
), decode(bi
tand(flag,
1536
),
0
,
'N'
,
'Y'
), decode(bitand(flag,
16384
),
0
,
'N'
,
'Y'
), decode(bitand(flag,
65536
),
0
,
'N'
,
'Y'
),
'N'
, obj, ts#, lobid, bitand(OBJ_FLA
G,
240
)/
16
from
x$bh bh, x$le le
where
bh.le_addr
= le.le_addr (+)
13:08:20 SYS@ test1 >desc x$bh
Name Null? Type
----------------------------------------------------------------- -------- --------------------------------------------
ADDR RAW(
4
)
INDX NUMBER
INST_ID NUMBER
HLADDR RAW(
4
)
BLSIZ NUMBER
NXT_HASH RAW(
4
)
PRV_HASH RAW(
4
)
NXT_REPL RAW(
4
)
PRV_REPL RAW(
4
)
FLAG NUMBER
FLAG2 NUMBER
LOBID NUMBER
RFLAG NUMBER
SFLAG NUMBER
LRU_FLAG NUMBER
TS# NUMBER
FILE# NUMBER
DBARFIL NUMBER
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
)
OQ_NXT RAW(
4
)
OQ_PRV RAW(
4
)
AQ_NXT RAW(
4
)
AQ_PRV RAW(
4
)
OBJ_FLAG NUMBER
TCH NUMBER
TIM NUMBER
CR_RFCNT NUMBER
SHR_RFCNT NUMBER
x$bh中“touch count”信息对应到x$bh的tch字段,而段的data_object_id信息对应到x$bh的obj,或者是v$bh的objd。
案例分析:
(1)对象有多少个数据块缓存到Data buffer中
13
:
29
:
01
SCOTT@ test1 >truncate table t1;
13
:
29
:
09
SCOTT@ test1 >begin
13
:
29
:
12
2
for
i
in
1.
.5000
loop
13
:
29
:
25
3
insert
into
t1 values (i);
13
:
29
:
35
4
end loop;
13
:
29
:
38
5
end;
13
:
29
:
39
6
/
PL/SQL procedure successfully completed.
Elapsed:
00
:
00
:
00.67
13
:
29
:
41
SCOTT@ test1 >commit;
创建一存储过程:show space读取数据块信息
13
:
29
:
43
SCOTT@ test1 >create
or
replace
procedure show_space
13
:
34
:
44
2
13
:
34
:
44
3
( p_segname
in
varchar2,
13
:
34
:
44
4
13
:
34
:
44
5
p_owner
in
varchar2 default user,
13
:
34
:
44
6
13
:
34
:
44
7
p_type
in
varchar2 default
'TABLE'
,
13
:
34
:
44
8
13
:
34
:
44
9
p_partition
in
varchar2 default NULL )
13
:
34
:
44
10
13
:
34
:
44
11
as
13
:
34
:
44
12
13
:
34
:
44
13
l_total_blocks number;
13
:
34
:
44
14
13
:
34
:
44
15
l_total_bytes number;
13
:
34
:
44
16
13
:
34
:
44
17
l_unused_blocks number;
13
:
34
:
44
18
13
:
34
:
44
19
l_unused_bytes number;
13
:
34
:
44
20
13
:
34
:
44
21
l_LastUsedExtFileId number;
13
:
34
:
44
22
13
:
34
:
44
23
l_LastUsedExtBlockId number;
13
:
34
:
44
24
13
:
34
:
44
25
l_last_used_block number;
13
:
34
:
44
26
13
:
34
:
44
27
procedure p( p_label
in
varchar2, p_num
in
number )
13
:
34
:
44
28
13
:
34
:
44
29
is
13
:
34
:
44
30
13
:
34
:
44
31
begin
13
:
34
:
44
32
13
:
34
:
44
33
dbms_output.put_line( rpad(p_label,
40
,
'.'
) ||
13
:
34
:
44
34
13
:
34
:
45
35
p_num );
13
:
34
:
45
36
13
:
34
:
45
37
end;
13
:
34
:
45
38
13
:
34
:
45
39
begin
13
:
34
:
45
40
13
:
34
:
45
41
13
:
34
:
45
42
13
:
34
:
45
43
dbms_space.unused_space
13
:
34
:
45
44
13
:
34
:
45
45
( segment_owner => p_owner,
13
:
34
:
45
46
13
:
34
:
45
47
segment_name => p_segname,
13
:
34
:
45
48
13
:
34
:
45
49
segment_type => p_type,
13
:
34
:
45
50
13
:
34
:
45
51
partition_name => p_partition,
13
:
34
:
45
52
13
:
34
:
45
53
total_blocks => l_total_blocks,
13
:
34
:
45
54
13
:
34
:
45
55
total_bytes => l_total_bytes,
13
:
34
:
45
56
13
:
34
:
45
57
unused_blocks => l_unused_blocks,
13
:
34
:
45
58
13
:
34
:
45
59
unused_bytes => l_unused_bytes,
13
:
34
:
45
60
13
:
34
:
45
61
last_used_extent_file_id => l_LastUsedExtFileId,
13
:
34
:
45
62
13
:
34
:
45
63
last_used_extent_block_id => l_LastUsedExtBlockId,
13
:
34
:
45
64
13
:
34
:
45
65
last_used_block => l_last_used_block );
13
:
34
:
45
66
13
:
34
:
45
67
13
:
34
:
45
68
13
:
34
:
45
69
p(
'Total Blocks'
, l_total_blocks );
13
:
34
:
45
70
13
:
34
:
45
71
p(
'Total Bytes'
, l_total_bytes );
13
:
34
:
45
72
13
:
34
:
45
73
p(
'Unused Blocks'
, l_unused_blocks );
13
:
34
:
45
74
13
:
34
:
45
75
p(
'Unused Bytes'
, l_unused_bytes );
13
:
34
:
45
76
13
:
34
:
45
77
p(
'Last Used Ext FileId'
, l_LastUsedExtFileId );
13
:
34
:
45
78
13
:
34
:
45
79
p(
'Last Used Ext BlockId'
, l_LastUsedExtBlockId );
13
:
34
:
45
80
13
:
34
:
45
81
p(
'Last Used Block'
, l_last_used_block );
13
:
34
:
45
82
13
:
34
:
45
83
end;
13
:
34
:
47
84
/
13:34:49 SCOTT@ test1 >set serverout on
13
:
35
:
01
SCOTT@ test1 >exec show_space(p_segname=>
'T1'
);
Total Blocks...........................
.16
Total Bytes............................
.131072
Unused Blocks..........................
.0
Unused Bytes...........................
.0
Last Used Ext FileId...................
.4
Last Used Ext BlockId..................
.136
Last Used Block........................
.8
PL/SQL procedure successfully completed.
数据文件id为4,t1表总共使用了16个块
分析数据块的rowid:
13
:
35
:
40
SCOTT@ test1 >select f,b
from
(
13
:
41
:
15
2
select dbms_rowid.rowid_relative_fno(rowid) f,
13
:
41
:
44
3
dbms_rowid.rowid_block_number(rowid) b
13
:
42
:
04
4
from
t1) group by f,b;
F B
---------- ----------
4
143
11
691
4
142
11
693
11
694
4
141
11
692
11
695
8
rows selected.
Users 表空间有两个datafile,id为4,11
13
:
42
:
52
SYS@ test1 >select file#,name
from
v$datafile;
FILE# NAME
---------- --------------------------------------------------
1
/u01/app/oracle/oradata/test1/system01.dbf
2
/u01/app/oracle/oradata/test1/sysaux01.dbf
3
/u01/app/oracle/oradata/test1/undotbs01.dbf
4
/u01/app/oracle/oradata/test1/users01.dbf
10
/u01/app/oracle/oradata/test1/index01.dbf
11
/dsk1/oradata/test1/users02.dbf
6
rows selected.
T1表总共为16个块,数据占用了8个块
13:47:43 SYS@ test1 >select file#,dbablk,tch from x$bh where obj=
2 (select data_object_id from dba_objects
3 where owner='SCOTT' AND object_name='T1')
4* order by dbablk
FILE# DBABLK TCH
---------- ---------- ----------
4
136
2
4
137
2
4
138
2
4
139
2
4
140
2
4
141
2
4
142
2
4
143
2
11
688
1
11
689
1
11
690
4
11
690
1
11
691
2
11
692
2
11
693
2
11
694
2
11
695
2
17
rows selected.
13:48:59 SYS@ test1 >select file#,block#,status from v$bh where objd=
13:49:18 2 (select data_object_id from dba_objects
13:49:33 3 where owner='SCOTT' and object_name='T1')
13:49:51 4 order by block#;
FILE# BLOCK# STATUS
---------- ---------- ----------
4
136
xcur
4
137
xcur
4
138
xcur
4
139
xcur
4
140
xcur
4
141
xcur
4
142
xcur
4
143
xcur
11
688
xcur
11
689
xcur
11
690
xcur
11
690
cr
11
691
xcur
11
692
xcur
11
693
xcur
11
694
xcur
11
695
xcur
17
rows selected.
查看x$bh,返回了block的touch count信息,表示了块的热点程度,现在最热的块是690,此块应该是段头块。
13
:
56
:
05
SYS@ test1 >select header_file,header_block
from
dba_segments
13
:
56
:
25
2
where
owner=
'SCOTT'
and
segment_name=
'T1'
;
HEADER_FILE HEADER_BLOCK
----------- ------------
11
690
手工清空buffer_cache:
14
:
03
:
30
SYS@ test1 >alter system flush buffer_cache;
System altered.
14
:
06
:
02
SYS@ test1 >select file#,dbablk,tch
from
x$bh
where
obj=(select data_object_id
from
dba_objects
where
owner=
'SCOTT'
AND object_name=
'T1'
) order by dbablk;
no rows selected
14
:
06
:
16
SYS@ test1 >select file#,block#,status
from
v$bh
where
objd=(select data_object_id
from
dba_objects
where
owner=
'SCOTT'
and
object_name=
'T1'
) order by block#;
no rows selected
统计一个object的非free状态的v$bh的记录数,基本就反映了一个对象再data buffer中被cache的块数。
14:10:29 SYS@ test1 >select count(*) from v$bh where objd=
14:10:45 2 (select data_object_id from dba_objects
14:10:59 3 where owner='SCOTT' and object_name='T1')
14:11:23 4 and status !='free';
COUNT(*)
----------
0
对t1表进行事务操作:
14
:
12
:
05
SCOTT@ test1 >
insert
into
t1 values (
5001
);
1
row created.
Elapsed:
00
:
00
:
00.00
14
:
13
:
38
SCOTT@ test1 >commit;
Commit complete.
14
:
13
:
12
SYS@ test1 >select count(*)
from
v$bh
where
objd=
2
(select data_object_id
from
dba_objects
3
where
owner=
'SCOTT'
and
object_name=
'T1'
)
4
*
and
status !=
'free'
COUNT(*)
----------
4
14:13:43 SYS@ test1 >select file#,block#,status from v$bh where objd=(select data_object_id from dba_objects where owner='SCOTT' and object_name='T1') order by block#;
FILE# BLOCK# STATUS
---------- ---------- ----------
4
143
xcur
11
688
xcur
11
689
xcur
11
690
xcur
(2)热点块问题
x$bh的touch count,这个数字将作为LRU算法的一个重要参考信息,如果一个块被多次访问,每次访问都会导致该块的记录加一。
1)查看t1的object_id
14
:
26
:
37
SYS@ test1 >select data_object_id from dba_objects
14
:
26
:
56
2
where owner=
'SCOTT'
and object_name=
'T1'
;
DATA_OBJECT_ID
--------------
16399
2)查看block 143的tch
14
:
29
:
05
SYS@ test1 >select tch from x$bh
14
:
29
:
20
2
where obj=
16399
and dbablk=
143
and file#=
4
and tch>
0
;
TCH
----------
1
3)访问block 143
采用了dbms_rowid.rowid_create函数来创建rowid,表示新创建的rowid类型为扩展rowid,类型为1;data_object_id为16399;数据文件id为4;块的id为143;行数为一行(0)。
14
:
30
:
47
SYS@ test1 >select count(*) from scott.t1
14
:
31
:
02
2
where rowid=dbms_rowid.rowid_create(
1
,
16399
,
4
,
143
,
0
);
COUNT(*)
----------
1
多次访问后,block 143的tch在增加
14
:
32
:
19
SYS@ test1 >select tch
from
x$bh
where
obj=
16399
and
dbablk=
143
and
file#=
4
and
tch>
0
;
TCH
----------
2
14
:
32
:
35
SYS@ test1 >select count(*)
from
scott.t1
where
rowid=dbms_rowid.rowid_create(
1
,
16399
,
4
,
143
,
0
);
COUNT(*)
----------
1
14
:
33
:
23
SYS@ test1 >select tch
from
x$bh
where
obj=
16399
and
dbablk=
143
and
file#=
4
and
tch>
0
;
TCH
----------
3
block 143的初始tch=1,经过连续两次查询后,tch=3.根据这一变化,可以基本判断x$bh表中的tch大的块,一般都是热点块。
查询top 10热点块所在的对象:
14
:
43
:
43
SYS@ test1 >select
/*+ rule */
owner,object_name from dba_objects
2
where data_object_id in
3
(select obj from
4
(select obj from x$bh order by tch desc )
5
* where rownum <
11
)
OWNER OBJECT_NAME
------------------------------ ------------------------------
SYS I_OBJ#
SYS I_OBJ2
SYS I_ICOL1
SYS I_CDEF2
SYS I_OBJ#_INTCOL#
SYS I_HH_OBJ#_INTCOL#
SYS I_TAB_STATS$_OBJ#
SYS I_IND_STATS$_OBJ#
8
rows selected.
- 通过案例学调优之--动态视图(v$bh和x$bh)
- 通过案例学调优之--动态视图(v$bh和x$bh)
- Oracle内部视图:X$BH
- Oracle内部视图:X$BH
- X$BH及V$BH中各字段意义
- X$BH及V$BH中各字段意义
- 关于 v$waitstat 和 x$bh.class 的关系
- 关于 v$waitstat 和 x$bh.class 的关系
- 关于 v$waitstat 和 x$bh.class 的关系
- x$bh
- Buffer Cache ---- BH&X$BH
- 42.Oracle杂记——Oracle常用动态视图v$bh
- v$BH解释
- x$bh详解
- x$bh详解
- oracle x$bh 说明
- 怎样将V$LATCH_CHILDREN、X$BH、DBA_EXTENTS三张表关联起来
- rac sga cache_buffer_size "V$BH"
- C语言——解数独程序[源码]
- 深入了解android平台的jni---注册native函数
- AJAX工作原理及其优缺点
- Python’s getattr function
- 无法打开物理文件xxx.mdf操作系统错误 5:“5(拒绝访问。)” (Microsoft SQL Server,错误: 5120)的解决方法
- 通过案例学调优之--动态视图(v$bh和x$bh)
- 从开发者到管理者,过来人的自述!
- Hadoop相关面试题(二)
- 联合体存储空间
- POJ 2769 Reduced ID Numbers
- 关于Ubuntu入门讲解,目前见过最好的一份
- HDU1019 最小公倍数
- 我28岁了,还能成为一名程序员吗?迷茫和沮丧中
- 【BZOJ】【P3505】【CQOI2014】【数三角形】【题解】【组合数】