x$bh的ADDR是啥东西?

在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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值