通过案例学调优之--动态视图(v$bh和x$bh)

来源:互联网 发布:淘宝管控记录一般多久 编辑:程序博客网 时间:2024/06/04 13:21

v$bh与x$bh

v$bh:非常详细地记录了数据块在数据缓冲区内的使用情况,一条记录对应一个block的详细记录。

v$bh来自于基表x$bh与x$le

查看v$bh结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
13:07:20SYS@ 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'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)/16from x$bh bh, x$le le where bh.le_addr
                              = le.le_addr (+)

13:08:20 SYS@ test1 >desc x$bh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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中

1
2
3
4
5
6
7
8
9
10
13:29:01SCOTT@ test1 >truncate table t1;
13:29:09SCOTT@ test1 >begin
13:29:12  2  for i in 1..5000loop
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:41SCOTT@ test1 >commit;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
创建一存储过程:show space读取数据块信息
13:29:43SCOTT@ test1 >create orreplace procedure show_space
13:34:44  2
13:34:44  3    ( p_segname invarchar2,
13:34:44  4
13:34:44  5    p_owner   invarchar2 default user,
13:34:44  6
13:34:44  7    p_type    invarchar2 default 'TABLE',
13:34:44  8
13:34:44  9    p_partition invarchar2 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_labelin varchar2, p_numin 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

1
2
3
4
5
6
7
8
9
13:35:01SCOTT@ 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
13:35:40SCOTT@ 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

1
2
3
4
5
6
7
8
9
10
13:42:52SYS@ test1 >select file#,name fromv$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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
     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#;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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,此块应该是段头块。

1
2
3
4
5
13:56:05SYS@ test1 >select header_file,header_block fromdba_segments
13:56:25  2   where owner='SCOTT' andsegment_name='T1';
HEADER_FILE HEADER_BLOCK
----------- ------------
         11         690

手工清空buffer_cache:

1
2
3
4
5
6
7
8
14:03:30SYS@ test1 >alter system flush buffer_cache;
System altered.
14:06:02SYS@ test1 >select file#,dbablk,tch fromx$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:16SYS@ test1 >select file#,block#,status fromv$bh where objd=(select data_object_id from dba_objects where owner='SCOTT' andobject_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表进行事务操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
14:12:05SCOTT@ test1 >insertinto t1 values (5001);
1 row created.
Elapsed: 00:00:00.00
14:13:38SCOTT@ test1 >commit;
Commit complete.
14:13:12SYS@ test1 >select count(*) fromv$bh where objd=
  2 (select data_object_id fromdba_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#;

1
2
3
4
5
6
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

1
2
3
4
5
14:26:37SYS@ 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

1
2
3
4
5
14:29:05SYS@ test1 >select tch from x$bh
14:29:20  2   where obj=16399and 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)。

1
2
3
4
5
14:30:47SYS@ 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在增加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
14:32:19SYS@ test1 >select tch fromx$bh where obj=16399 anddbablk=143 and file#=4and tch>0;
       TCH
----------
         2
        
14:32:35SYS@ test1 >select count(*) fromscott.t1 where rowid=dbms_rowid.rowid_create(1,16399,4,143,0);
  COUNT(*)
----------
         1
14:33:23SYS@ test1 >select tch fromx$bh where obj=16399 anddbablk=143 and file#=4and tch>0;
       TCH
----------
         3

block 143的初始tch=1,经过连续两次查询后,tch=3.根据这一变化,可以基本判断x$bh表中的tch大的块,一般都是热点块。


查询top 10热点块所在的对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
14:43:43SYS@ 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.
0 0
原创粉丝点击