ITPub博客

首页 > 数据库 > Oracle > [20220406]使用那个shared pool latch的疑问1.txt

[20220406]使用那个shared pool latch的疑问1.txt

原创 Oracle 作者:lfree 时间:2022-04-19 09:46:21 0 删除 编辑

[20220406]使用那个shared pool latch的疑问1.txt

--//放假看了以前写的blog,做一些必要的补充以及说明.
--//前面我的测试已经验证一条sql语句会使用 其sql语句的 hash_value % bucket_size % _kghdsidx_count +1 的 shared pool
--//latch.
--//参考链接 => [20210708]使用那个shared pool latch.txt
--// _kghdsidx_count 参数定义了shared pool latch的数量,同时也定义共享池分成多个子池.
--//链接里面也测试了使用那个shared pool latch,也意味者其使用的chunk也基本上相应子池中分配.
--//参考链接 => [20210803]使用那个shared pool latch(补充).txt,但是确实也遇到了不从相应子池中分配的情况.

--//另外在链接 [20220303]oracle如何定位使用library cache mutex 3.txt ,我提到存在一个表或者数组保存了
--//library cache mutex的地址表.
--//假设知道基地址A后,如果知道bucket值.使用bucket/256 取整就可以定位 该数组的地址 等于 A +  trunc(bucket/256)*8 地址
--//指向的内容B, 再通过bucket%256 * 40 + B , 就知道定位该bucket的library cache mutex的地址。
--//我在当时测试_kghdsidx_count=3的情况,该地址表的记录信息在几个chunk上跳来跳去,文字很难表达.

--//本文仔细探究sql语句以及一些chunk使用那个shared pool latch,其使用的chunk的分配细节,许多是我的猜测.

1.环境:
SYS@127.0.0.1:9014/ywdb> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

SYS@127.0.0.1:9014/ywdb> @ hide _kgl_bucket_count
NAME              DESCRIPTION                                                        DEFAULT_VALUE SESSION_VALUE SYSTEM_VALUE ISSES ISSYS_MOD
----------------- ------------------------------------------------------------------ ------------- ------------- ------------ ----- ---------
_kgl_bucket_count Library cache hash table bucket count (2^_kgl_bucket_count * 256)  TRUE          9             9            FALSE FALSE
--// 2^9*2^8 = 131072

SYS@127.0.0.1:9014/ywdb> @ hide idx_count
NAME            DESCRIPTION        DEFAULT_VALUE SESSION_VALUE SYSTEM_VALUE ISSES ISSYS_MOD
--------------- ------------------ ------------- ------------- ------------ ----- ---------
_kghdsidx_count max kghdsidx count TRUE          7             7            FALSE FALSE
--//生产系统共享内存很大并且CPU_count=32.

SYS@127.0.0.1:9014/ywdb> @ tix
New tracefile_identifier = /u01/app/oracle/diag/rdbms/ywdb/ywdb1/trace/ywdb1_ora_3733_0001.trc

SYS@127.0.0.1:9014/ywdb> oradebug setmypid
Statement processed.

SYS@127.0.0.1:9014/ywdb> oradebug dump heapdump 2;
Statement processed.
--//生产系统,转储有点慢...

--//建立表xx1,保存x$kglob信息.
create table xx1 tablespace users as
select KGLHDPAR,KGLHDADR,KGLOBHD0,KGLOBHD1,KGLOBHD2,KGLOBHD3,KGLOBHD4,KGLOBHD5,KGLOBHD6,kglnahsh,substr(kglnaobj,1,40) c40 from x$kglob;

create index i_xx1_KGLHDADR  on xx1(KGLHDADR) tablespace users;
create index i_xx1_KGLHDPAR  on xx1(KGLHDPAR) tablespace users;

create table xx2 tablespace users as select * from x$ksmsp;

--//生成表xx1,xx2的主要目的是避免后面的查询分析时很慢,另外直接查询x$kglob不现实,可能一些对象已经刷出共享池.
--//保存在一张表相当于建立x$kglob的快照.

--//SQLA   表示child cursor heap6
--//KGLH0  表示parent/child cursor heap0
--//KGLHD  表示parent/child cursor handle
--//KGLDA  表示parent/child cursor heap 描述符
--//KGLH0,SQLA的后面都存在^hash_value(16进制).不知道为什么KGLHD,KGLDA没有对应标识.

# egrep "HEAP DUMP|KGLH0\^|SQLA\^|KGLHD|KGLDA" /u01/app/oracle/diag/rdbms/ywdb/ywdb1/trace/ywdb1_ora_3733_0001.trc >| aa.txt

2.分析:
--//分析KGLHD,建立d1.sh脚本取出包含KGLHD的chunk的开始地址.
$ cat d1.sh
#! /bin/bash
echo "sga heap($1,0) --- sga heap($2,0)"
sed -n "/sga heap($1/,/sga heap($2/p" aa.txt | awk '/KGLHD/{print $2}' | sort | uniq

--//对于11g,sql语句的这些chunk的开始地址+48(0x30) 就是对应句柄的地址,也就是对应XKGLOB.KGLHDADR字段信息.改写脚本如下:
$ cat d1.sh
#! /bin/bash
# echo "sga heap($1,0) --- sga heap($2,0)"
sed -n "/sga heap($1/,/sga heap($2/p" aa.txt | awk '/KGLHD/{print $2}' | sort | uniq | tr 'a-z' 'A-Z' | \
xargs -IQ echo Q + 30  | sed  '1iobase=16;ibase=16' | bc -q

--//通过它查询X$kglob 就可以获得hash值,然后做运算看看情况.
$ cat qq1.txt
Select mod(mod(kglnahsh, 131072),7)+1 N10
from xx1 where
--    KGLHDPAR = hextoraw(lpad(upper('&1'), 16, '0'))
--or  
KGLHDADR = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD0 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD1 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD2 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD3 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD4 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD5 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD6 = hextoraw(lpad(upper('&1'), 16, '0'))
/

$ ./d1.sh 1 2 | xargs -IQ echo @ qq1.txt Q > qq2.txt

--//编辑qq2.txt加入
set head off feedback off term off
spool qq3.txt
@ qq1.txt ....
...
spool off
set head on feedback on term on

$ sort  qq3.txt | uniq -c
      6
  27805                     1
    501                     2
    467                     3
    519                     4
    502                     5
    469                     6
    518                     7

--//可以发现大部分计算结果mod(mod(kglnahsh, 131072),7)+1 =1.不过依然存在少量的chunk分配在sga heap($1,0) --- sga heap($2,0)范围。
--//但是mod(mod(kglnahsh, 131072),7)+1  <> 1 的情况。
--//其它也出现类似的情况。

--//修改qq1.txt脚本如下,执行:

$ cat qq1.txt
column N10 format 9999
Select mod(mod(kglnahsh, 131072),7)+1 N10
,xx1.*
from xx1 where
--    KGLHDPAR = hextoraw(lpad(upper('&1'), 16, '0'))
--or
KGLHDADR = hextoraw(lpad(upper('&1'), 16, '0'))
and mod(mod(kglnahsh, 131072),7)+1 =2
--or  KGLOBHD0 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD1 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD2 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD3 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD4 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD5 = hextoraw(lpad(upper('&1'), 16, '0'))
--or  KGLOBHD6 = hextoraw(lpad(upper('&1'), 16, '0'))
/

--//再次执行qq2.txt 脚本:

$ head -2  qq3.txt ;tail -2 qq3.txt
N10 KGLHDPAR         KGLHDADR         KGLOBHD0         KGLOBHD1 KGLOBHD2 KGLOBHD3 KGLOBHD4 KGLOBHD5 KGLOBHD6   KGLNAHSH C40
--- ---------------- ---------------- ---------------- -------- -------- -------- -------- -------- -------- ---------- --------------------------------
  2 00000005A0441EF0 00000005A0441EF0 00000005A279D548 00       00       00       00       00       00        931942480 4515c2b969e6ffd4fe80d95c235d8877
  2 00000005A06FF080 00000005A06FF080 00000005F79BF608 00       00       00       00       00       00       3751868314 d30d8b02f3c324b3f584889088200a2c
  2 0000000617F09CD0 0000000617F09CD0 00000005BCF801B0 00       00       00       00       00       00       1611424971 9e5040d05f9ac41f20626ba2760602c3
  2 0000000617F9CF28 0000000617F9CF28 00000005BF57C140 00       00       00       00       00       00       2156270772 e32ec116e8098cee5af3814212629a
--//注:行头我自己加上的,便于查看.

--//取C40也就是等于substr(kglnaobj,1,40),取最后8位.
--//235d8877 = 593332343 593332343%131072%7+1 = 1
--//88200a2c = 2283801132 2283801132%131072%7+1  = 1
--//0x760602c3%131072%7+1 = 1
--//0x4212629a%131072%7+1 = 1

--//不过你可以发现如果使用kglnaobj的后8位按照类似的方式计算正好都是1,可以写脚本验证看看。

$ cat qq1.txt
column N10 format 9999
-- Select mod(mod(kglnahsh, 131072),7)+1 N10
-- ,xx1.*
-- from xx1 where
-- --    KGLHDPAR = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or
--  KGLHDADR = hextoraw(lpad(upper('&1'), 16, '0'))
-- and mod(mod(kglnahsh, 131072),7)+1 =2
-- --or  KGLOBHD0 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD1 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD2 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD3 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD4 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD5 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD6 = hextoraw(lpad(upper('&1'), 16, '0'))
-- /

select mod(mod(TO_NUMBER(substr(c40,-8),'xxxxxxxxxxxxxxx'),131072),7)+1 N10 from xx1
where
 KGLHDADR = hextoraw(lpad(upper('&1'), 16, '0'))
and mod(mod(kglnahsh, 131072),7)+1 <> 1
/

--//再次执行qq2.txt。
$ uniq -c qq3.txt
   2976     1

--//全部符合需求.。
--//我看了这些类型都是KGLHDNSD='SQL AREA STATS',KGLOBTYD='CURSOR STATS'的chunk,感觉这些是一些对象的统计信息相关的chunk。
--//我给重新建立xx1表来分析这些问题。

create table xx3 tablespace users as
select KGLHDPAR,KGLHDADR,KGLOBHD0,KGLOBHD1,KGLOBHD2,KGLOBHD3,KGLOBHD4,KGLOBHD5,KGLOBHD6,kglnahsh,kglnaobj,KGLNAHSV,KGLHDNSD,KGLOBTYD from x$kglob;

create index i_xx3_KGLHDPAR  on xx3(KGLHDPAR) tablespace users;
create index i_xx3_KGLHDADR  on xx3(KGLHDADR) tablespace users;

$ cat qq1.txt
column N10 format 9999
-- Select mod(mod(kglnahsh, 131072),7)+1 N10
-- ,xx1.*
-- from xx1 where
-- --    KGLHDPAR = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or
--  KGLHDADR = hextoraw(lpad(upper('&1'), 16, '0'))
-- and mod(mod(kglnahsh, 131072),7)+1 =2
-- --or  KGLOBHD0 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD1 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD2 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD3 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD4 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD5 = hextoraw(lpad(upper('&1'), 16, '0'))
-- --or  KGLOBHD6 = hextoraw(lpad(upper('&1'), 16, '0'))
-- /

-- select mod(mod(TO_NUMBER(substr(c40,-8),'xxxxxxxxxxxxxxx'),131072),7)+1 N10 from xx1
-- where
--  KGLHDADR = hextoraw(lpad(upper('&1'), 16, '0'))
-- and mod(mod(kglnahsh, 131072),7)+1 <>1
-- /

select kglnahsh,substr(kglnaobj,40) c40 ,KGLHDNSD,KGLOBTYD from xx3
where
KGLHDADR = hextoraw(lpad(upper('&1'), 16, '0'))
and mod(mod(kglnahsh, 131072),7)+1 <>1
/

--//再次执行qq2.txt。
$ cut -c30- qq3.txt  | awk '{print $0}' |uniq -c
   1515        SQL AREA STATS        CURSOR STATS

--//501+467+519+502+469+518 = 2976,很明显许多对象已经不再共享池了。但是还是可以看出这些对象的KGLHDNSD='SQL AREA
--//STATS',KGLOBTYD='CURSOR STATS'。

--//我的测试有一些问题,qq1.txt直接带参数,没有使用绑定变量,导致许多对象已经不再共享池,明天改进重复该测试看看。
--//不过可以基本验证我的判断。sql语句类型的KGLHD (表示parent/child cursor handle ),根据hash_value % bucket_size % _kghdsidx_count +1
--//确定使用那个sga heap中的chunk。

--//而KGLHDNSD='SQL AREA STATS',KGLOBTYD='CURSOR STATS'相关的chunk按照kglnaobj & 0xffffffff  % _kghdsidx_count +1来计算的。
--//当然这个是我乱猜的,不知道这个oracle的具体算法。
--//写的有点乱,自己能看懂。
--//总之,晚上回家好好整理,明天重复测试。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-2887683/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7970691