在pub上有人问x$BH的ADDR这一列是什么意思?
于是经过很长时间的实验,我自己得出的结论是:
这一列是查询x$BH的这个session的PGA session heap中的一个地址。
它既不是buffer header的地址,也不是cache buffer chain latch 的地址,也不是产生这个buffer的session的PGA session heap 地址。
我的回帖如下,欢迎指正,因为是由实验得出的结论,无法成为定理。
很好的一个问题。我本来也不知道ADDR是什么东西,只是知道网上有篇文章说这个x$bh的addr指:
RAW(4) Hex address of the Buffer Header
我也深信不疑。因为很少用到这个列。我相信大家用到的最多的是HLADDR,这个列是cbc child latch address。
但楼上的catchwo兄弟一阵见血地证明了这个addr并不是buffer header的address。那么,网上的那篇文档错了?
于是开始做实验:
我建了一个table,叫BUFFER_TEST,它的object_id 是49926。
这时,我们在buffer header里找到了这个object,其中一个是segment header block,一个是data block。
(class=4代表是segment header block,class=1代表是data block)
SQL> select ADDR,INDX,HLADDR,FLAG,TS#,FILE#,DBABLK,CLASS,BA from x$bh where BJ=49926;
ADDR INDX HLADDR FLAG TS# FILE# DBABLK CLASS BA
---------------- ---------- ---------------- ---------- ---------- ---------- ---------- ---------- ----------------
FFFFFFFF79FC1DC8 3676 00000003A7A190B0 35659776 0 1 35946 1 000000038F67C000
FFFFFFFF79FC1DC8 6017 00000003A71C1178 35659776 0 1 35945 4 000000038F59C000
然后转储buffer cache:
SQL> ALTER SESSION SET EVENTS 'immediate trace name buffers level 1';
Session altered.
这时在trace文件里,我找到了这两个block的buffer header,根据object number:
BH (38f7e9af8) file#: 1 rdba: 0x00408c69 (1/35945) class: 4 ba: 38f59c000
set: 11 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 33
dbwrid: 2 obj: 49926 objn: 49926 tsn: 0 afn: 1
hash: [3a75168d0,3a75168d0] lru: [38f7e9c88,38f7e9a68]
obj-flags: object_ckpt_list
ckptq: [3a7618580,38f7e9f68] fileq: [3a76185a0,38f7e9f78] objq: [3a430c2a8,3a430c2a8]
st: XCURRENT md: NULL tch: 2
flags: buffer_dirty gotten_in_current_mode redo_since_read
LRBA: [0xd.108.0] HSCN: [0x0.c7f2f3b] HSUB: [1]
BH (38f7f11f8) file#: 1 rdba: 0x00408c6a (1/35946) class: 1 ba: 38f67c000
set: 12 blksize: 8192 bsi: 0 set-flg: 2 pwbcnt: 37
dbwrid: 3 obj: 49926 objn: 49926 tsn: 0 afn: 1
hash: [3a7193ca8,3a7193ca8] lru: [38f7f1388,3a75fb3d8]
obj-flags: object_ckpt_list
ckptq: [3a761b7a0,3927dfcd8] fileq: [3a761b7c0,3927dfce8] objq: [3a32b7250,3a32b7250]
st: XCURRENT md: NULL tch: 1
flags: buffer_dirty gotten_in_current_mode redo_since_read
LRBA: [0xd.117.0] HSCN: [0x0.c7f2f3b] HSUB: [1]
于是我们看到,我实在找不到这个ADDR的值代表什么意思。但我确定它代表的是一个内存地址。
于是问题就变成,这个内存地址是什么地址?反正,他肯定不是SGA中的。
重启数据库,用sid=2176的session采用dedicate方式连入数据库,操作系统进程号是4691。
SQL> select sid from v$mystat where rownum<2;
SID
----------
2176
SQL> select * from BUFFER_TEST;
ID
----------
2
这时,我用另一个session(操作系统pid=4629)连入查询v$bh
SQL> select ADDR,INDX,HLADDR,FLAG,TS#,FILE#,DBABLK,CLASS,BA,state from x$bh where BJ=49926;
ADDR INDX HLADDR FLAG TS# FILE# DBABLK CLASS BA STATE
---------------- ---------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------
FFFFFFFF79FC1DC8 3605 00000003A7A190B0 524288 0 1 35946 1 000000038F784000 1
FFFFFFFF79FC1DC8 5912 00000003A71C1178 0 0 1 35945 4 000000038F6AC000 1
FFFFFFFF79FC1CA0 5913 00000003A71C1178 0 0 1 35945 4 000000038F5AC000 3
不知道这个地址到底在哪里,于是我只有把所有的oracle process做pmap。
ps -ef | grep hao | grep -v grep | awk -F' ' '{print $2}' | xargs pmap > temp.txt
然后在里面找这个地址,最后我发现这个地址在我的一个用户进程里:
4629: oraclehaozhu (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
0000000100000000 98304K r-x-- /xxx/10203/bin/oracle
0000000106000000 3824K r-x-- /xxx/10203/bin/oracle
00000001064BA000 816K rwx-- /xxx/10203/bin/oracle
0000000106586000 2016K rwx-- [ heap ]
0000000380000000 720896K rwxs- [ dism shmid=0x6000064 ]
FFFFFFFF79FC0000 64K rw--- [ anon ]
这个操作系统process 4629并不是我们做select * from BUFFER_TEST;的那个用户进程,
而是我们做查询x$bh的进程。
于是我对这个查询x$bh的进程进行pga dump:
SQL> oradebug setospid 4629
Oracle pid: 19, Unix process pid: 4629, image: oracle@xxx(TNS V1-V3)
SQL> oradebug dump heapdump 1
Statement processed.
终于,在trace文件里,显示为session heap!
不放心,退出查询x$bh的session,重新连接重新查询,
SQL> select ADDR,INDX,HLADDR,FLAG,TS#,FILE#,DBABLK,CLASS,BA,state from x$bh where BJ=49926;
ADDR INDX HLADDR FLAG TS# FILE# DBABLK CLASS BA STATE
---------------- ---------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------------- ----------
FFFFFFFF7D7A9FA8 3630 00000003A7A190B0 35659777 0 1 35946 1 000000038F766000 1
FFFFFFFF7D7A9E80 3631 00000003A7A190B0 36175872 0 1 35946 1 000000038FD6C000 3
FFFFFFFF7D7A9FA8 5955 00000003A71C1178 0 0 1 35945 4 000000038FC88000 1
FFFFFFFF7D7A9E80 5956 00000003A71C1178 0 0 1 35945 4 000000038FF6E000 3
重新dump这个session的pga,发现这时的ADDR变成了这个session的PGA session heap。
综上,从实验结果来看,x$BH的ADDR这一列并不是所谓的buffer header的address,也不是cbc child latch的address,也不是产生这个buffer的用户session的地址,
而是做这个x$bh查询的用户session 的PGA heap session!当你重复更换session查询某一个object的x$bh时,你会发现这个addr不停变化,而其他列不变。
至于为什么会有这种诡异的列,恐怕答案只有oracle开发者知道了。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15415488/viewspace-606891/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/15415488/viewspace-606891/