[20250128]21c library cache mutex的深入探究2.txt

[20250128]21c library cache mutex的深入探究2.txt

--//探究21c library cache mutex address的chunk分布。

0. 测试前准备:
--//测试前最好设置db_cache_size,shared_pool_size大小,避免其大小发生变化。我个人习惯测试环境设置它,这样不会出现大量非
--//绑定变量sql语句导致共享池变大的情况。这样重复测试下次启动library cache mutex的地址不会变化,方便自己的重复测试工作。

SYS@book> alter system set db_cache_size=404M ;
System altered.

SYS@book> alter system set shared_pool_size=344M;
System altered.
--//在使用pdb下发现不能设置太小,不然很容易出现ora-4031错误。

SYS@book> shutdown immediate ;
Database closed.
Database dismounted.
ORACLE instance shut down.

SYS@book> startup
ORACLE instance started.

Total System Global Area  805306280 bytes
Fixed Size                  9691048 bytes
Variable Size             360710144 bytes
Database Buffers          427819008 bytes
Redo Buffers                7086080 bytes
Database mounted.
Database opened.

--//另外注意关闭resmgr cpu quantum,不然激活resmgr cpu quantum,看到的getrusage调用间隙时间不再是2秒,特别在
--//_mutex_wait_scheme=0模式下特别容易激活,我以前的测试没有注意这个细节,而且一旦出现每次测试结果不稳定。

SYS@book> alter system set resource_manager_plan='' scope=both sid='*';
System altered.

SYS@book> alter system set resource_limit=false scope=both;
System altered.

SYS@book> alter system set "_resource_manager_always_off"=true scope=spfile;
System altered.

--//alter system set "_resource_manager_always_on"=false scope=spfile sid='*';
--//21c没有该参数。

1.环境:
SYS@book> @ver2
==============================
PORT_STRING                   : x86_64/Linux 2.4.xx
VERSION                       : 21.0.0.0.0
BANNER                        : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
BANNER_FULL                   : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.3.0.0.0
BANNER_LEGACY                 : Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
CON_ID                        : 0
PL/SQL procedure successfully completed.

SYS@book> show parameter  resource_
PARAMETER_NAME                  TYPE    VALUE
------------------------------- ------- --------------
_resource_manager_always_off    boolean TRUE
resource_limit                  boolean FALSE
resource_manage_goldengate      boolean FALSE
resource_manager_cpu_allocation integer 0
resource_manager_cpu_scope      string  INSTANCE_ONLY
resource_manager_plan           string

2.建立测试环境:
$ cat m9.txt
DECLARE
   l_count PLS_INTEGER;
BEGIN
    FOR i IN 1..&&1
    LOOP
        EXECUTE IMMEDIATE 'select /*+ &&2 */ count(*) from dept where deptno = '||i  INTO l_count ;
    END LOOP;
END;
/
--//注:没有使用绑定变量,主要目的使用更多的library cache mutex,因为没有使用它dump看不见。

$ zzdate ; seq 20 | xargs -P 20 -IQ sqlplus -s -l scott/book@book01p @ m9.txt 2e4 Q > /dev/null ; zzdate
trunc(sysdate)+08/24+31/1440+26/86400 -1738024286.061232225
trunc(sysdate)+08/24+33/1440+44/86400 1738024424.466891808
--//Sum = 138.405659583

--//另外找2个bucket=0的sql语句,以后当做测试使用。
select /*+ 9 */ count(*) from dept where deptno = 93834;
select /*+ 9 */ count(*) from dept where deptno = 93091;
--//执行以上2条语句多次。

--//转储library_cache:
SYS@book> oradebug setmypid
Statement processed.
SYS@book> oradebug dump library_cache 4
Statement processed.

SYS@book> @ spid
==============================
SID                           : 158
SERIAL#                       : 85
PROCESS                       : 3829
SERVER                        : DEDICATED
SPID                          : 3830
PID                           : 61
P_SERIAL#                     : 6
KILL_COMMAND                  : alter system kill session '158,85' immediate;
PL/SQL procedure successfully completed.

SYS@book> @ t
TRACEFILE
--------------------------------------------------------------------------------
/u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3830.trc

3.分析跟踪文件:

$ cdf /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3830.trc
cd /u01/app/oracle/diag/rdbms/book/book/trace

$ grep "^Bucket:" book_ora_3830.trc | head -4
Bucket: #=0 Mutex=0x6cba03f0(678604832768, 61, 0, 6)
Bucket: #=42 Mutex=0x6cba0bd0(678604832768, 44, 0, 6)
Bucket: #=47 Mutex=0x6cba0cc0(678604832768, 49, 0, 6)
Bucket: #=60 Mutex=0x6cba0f30(678604832768, 10, 0, 6)
--//Bucket: #=0,Mutex=0x6cba03f0
$ grep "^Bucket:" book_ora_3830.trc | cut -d"(" -f2 | cut -d"," -f1,4 | uniq -c
   4522 678604832768, 6)
--//补充muext的第1个值在11g下是0,而这里看到是678604832768。对应的实际上执行dump会话的sid。
--//678604832768 = 0x9e00000000,补充前面的0就是0x0000009e00000000,0x0000009e = 158,与前面的spid输出的sid对上。
--//第2值gets的数量,第3个值sleeps的数量,第4个值总是6,不知道表示什么?

$ grep "^Bucket:" book_ora_3830.trc | sed   "s/^Bucket: #=//;s/Mutex=//;s/(.*)//" | head -4
0 0x6cba03f0
42 0x6cba0bd0
47 0x6cba0cc0
60 0x6cba0f30

$ grep "^Bucket:" book_ora_3830.trc | sed   "s/^Bucket: #=//;s/Mutex=//;s/(.*)//" > d1.txt
--//仅仅取出bucketc桶号以及mutex地址。

$ awk 'NR==1{a=$1;b=strtonum($2);c=$2 } NR>1{ print a,c,$1,$2,(strtonum($2)-b)/($1-a);a=$1;b=strtonum($2);c=$2}'  d1.txt | grep "48$" |wc
   4024   20120  150165
--//简单介绍,将下一行复制到前一行,然后2个地址相减,2个bucket桶号相减,再两者做除法。
--//例子 0x6cba0bd0-0x6cba03f0 = 2016, 2016/(42-0) = 48
--//11g下结尾的显示都是40的,现在大部分都是48,21c多出了8个字节.
--//$ awk 'NR==1{a=$1;b=$2 } NR>1{ print a,b,$1,$2,(strtonum($2)-strtonum(b))/($1-a);a=$1;b=$2}'  d1.txt | grep "48$" |wc

--//看看结尾不是48的情况。
$ awk 'NR==1{a=$1;b=strtonum($2);c=$2 } NR>1{ print a,c,$1,$2,(strtonum($2)-b)/($1-a);a=$1;b=strtonum($2);c=$2}'  d1.txt | grep -C 1 -v "48$" | head -12
195 0x6cba2880 212 0x6cba2bb0 48
212 0x6cba2bb0 392 0x6cba4d80 48.0889
~~~~~~~~~~~~~~~~~
392 0x6cba4d80 418 0x6cba5260 48
418 0x6cba5260 508 0x6cba6340 48
508 0x6cba6340 551 0x6cba6b60 48.3721
~~~~~~~~~~~~~~~~~~~~~~~~
551 0x6cba6b60 598 0x6cba7430 48
--
695 0x6cba8660 738 0x6cba8e70 48
738 0x6cba8e70 786 0x6cba9780 48.3333
~~~~~~~~~~~~~~~~~~~~
786 0x6cba9780 787 0x6cba97b0 48
--
991 0x6cbabdf0 1020 0x6cbac360 48

--//实际上只要仔细看下划线的行就基本可以确定在buckcet=256-1,512-1,3*256-1的位置出现跳跃(注:buckect从0开始计数)。

--//不过21c下的测试与11g的测试不同:
--//1.mutex地址的偏移量以前大部分是40,现在是48。
--//2.11g下确定buckcet=256-1,512-1的位置没有出现跳跃,而这次出现,为什么?

--//我仔细看了偏移量,最大也就是64.
$ awk 'NR==1{a=$1;b=strtonum($2);c=$2 } NR>1{ print a,c,$1,$2,(strtonum($2)-b)/($1-a);a=$1;b=strtonum($2);c=$2}'  d1.txt | awk '$NF>=64 {print $0}'
31999 0x6c51e5e0 32000 0x6c51e620 64
--//64-48 = 16

$ awk 'NR==1{a=$1;b=strtonum($2);c=$2 } NR>1{ print a,c,$1,$2,(strtonum($2)-b)/($1-a);a=$1;b=strtonum($2);c=$2}'  d1.txt | awk '$NF<48 {print $0}'
7927 0x6cbfd420 7971 0x6c4046d0 -189983
94671 0x6c7fdc30 94735 0x6c034310 -127588
--//仅仅出现2个大的跳跃,前后相减是负数。
--//7927/256 = 30.96484375
--//94671/256 = 369.80859375

4.继续分析:
$ awk 'NR==1{a=$1;b=strtonum($2);c=$2 } NR>1{ print a,c,$1,$2,(strtonum($2)-b)/($1-a);a=$1;b=strtonum($2);c=$2}'  d1.txt | awk '$NF!=48 {print $0}'|wc
    511    2555   21428
--//不等于48出现511个,说明library cache mutex address按照256作为1个chunk来分配。
--//而且从位置看应该许多chunk在内存的地址是紧挨着的。
--//前面的测试仅仅出现2个大的跳跃,说明分成3个大片。

$ awk 'NR==1{a=$1;b=strtonum($2);c=$2 } NR>1{ print a,c,$1,$2,(strtonum($2)-b)/($1-a);a=$1;b=strtonum($2);c=$2}'  d1.txt | grep -C 1 -v "48$" | head -12
195 0x6cba2880 212 0x6cba2bb0 48
212 0x6cba2bb0 392 0x6cba4d80 48.0889
~~~~~~~~~~~~~~~~~
392 0x6cba4d80 418 0x6cba5260 48
418 0x6cba5260 508 0x6cba6340 48
508 0x6cba6340 551 0x6cba6b60 48.3721
~~~~~~~~~~~~~~~~~~~~~~~~
551 0x6cba6b60 598 0x6cba7430 48
--
695 0x6cba8660 738 0x6cba8e70 48
738 0x6cba8e70 786 0x6cba9780 48.3333
~~~~~~~~~~~~~~~~~~~~
786 0x6cba9780 787 0x6cba97b0 48
--
991 0x6cbabdf0 1020 0x6cbac360 48

--//看看下划线地址的相应chunk的位置:
SYS@book> @ fchaz 0x6cba2bb0
LOC KSMCHPTR           KSMCHIDX   KSMCHDUR KSMCHCOM           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR         KSMCHPTR_BEGIN   KSMCHPTR_END+1
--- ---------------- ---------- ---------- ---------------- ---------- -------- ---------- ---------------- ---------------- -----------------
SGA 000000006CBA03D0          1          1 KGLSG                 12304 perm              0 000000006C804000 000000006CBA03D0 000000006CBA33E0

SYS@book> @ fchaz 0x6cba6340

LOC KSMCHPTR           KSMCHIDX   KSMCHDUR KSMCHCOM           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR         KSMCHPTR_BEGIN   KSMCHPTR_END+1
--- ---------------- ---------- ---------- ---------------- ---------- -------- ---------- ---------------- ---------------- -----------------
SGA 000000006CBA33E0          1          1 KGLSG                 12304 perm              0 000000006C804000 000000006CBA33E0 000000006CBA63F0

SYS@book> @ fchaz 0x6cba8e70

LOC KSMCHPTR           KSMCHIDX   KSMCHDUR KSMCHCOM           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR         KSMCHPTR_BEGIN   KSMCHPTR_END+1
--- ---------------- ---------- ---------- ---------------- ---------- -------- ---------- ---------------- ---------------- -----------------
SGA 000000006CBA63F0          1          1 KGLSG                 12304 perm              0 000000006C804000 000000006CBA63F0 000000006CBA9400
--//查看3个可以发现一些特点:KSMCHCOM=KGLSG ,KSMCHSIZ=12304,KSMCHPAR=000000006C804000,KSMCHCLS=perm。

SYS@book> @ fchaz 000000006C804000
no rows selected
--//奇怪查询不到chunk信息。

SYS@book> select count(*),KSMCHSIZ from x$ksmsp where KSMCHCOM='KGLSG' group by KSMCHSIZ ;
  COUNT(*)   KSMCHSIZ
---------- ----------
       512      12304
         1       4128
         1       9312
         1       4976
         1         40
--//KSMCHSIZ=12304 ,正好512条记录。符合2^_kgl_bucket_count=2^9 = 512.
--//在1个chunk内muetx每个地址偏移48字节。12304-256*48 = 16,正好16字节。这也是前面分析为什么最大偏移量是64.
--//执行如下

SYS@book> select count(*),KSMCHPAR from x$ksmsp where KSMCHCOM='KGLSG'  and KSMCHSIZ=12304 group by KSMCHPAR;
  COUNT(*) KSMCHPAR
---------- ----------------
        31 000000006C804000
       339 000000006C404000
       142 000000006C034000
--//仅仅存在3个KSMCHPAR值。

$ awk 'NR==1{a=$1;b=strtonum($2);c=$2 } NR>1{ print a,c,$1,$2,(strtonum($2)-b)/($1-a);a=$1;b=strtonum($2);c=$2}'  d1.txt | awk '$NF<48 {print $0}'
7927 0x6cbfd420 7971 0x6c4046d0 -189983
94671 0x6c7fdc30 94735 0x6c034310 -127588
--//仅仅出现2个大的跳跃,前后相减是负数。
--//7927/256 = 30.96484375
--//7971/256 = 31.13671875
--//94671/256 = 369.80859375
--//94735/256 = 370.05859375
--//分成3个大片,第1个31。 第2个370-31 = 339,第2个512-370 = 142,正好符合前面的查询。
       
SYS@book> @ fchaz 000000006C404000
no rows selected

SYS@book> @ fchaz 000000006C034000
no rows selected
--//利用KSMCHPAR的信息查询都没有信息返回。

--//看看每个chunk开头部分。
SYS@book> @ opeek 000000006CBA03D0 48 0
[06CBA03D0, 06CBA0400) = 00003011 00B38F00 17ADF8D0 00000000 6770EB80 00000000 63B6A1E0 00000000 00000000 00000000 00000041 00000000

SYS@book> @ opeek 000000006CBA33E0 48 0
[06CBA33E0, 06CBA3410) = 00003011 00B38F00 17ADF8D0 00000000 6CBA33F0 00000000 6CBA33F0 00000000 00000000 00000000 00000017 00000000
                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SYS@book> @ opeek 000000006CBA63F0 48 0
[06CBA63F0, 06CBA6420) = 00003011 00B38F00 17ADF8D0 00000000 6CBA6400 00000000 6CBA6400 00000000 00000000 00000000 00000025 00000000
                                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--//前面16字节都是00003011 00B38F00 17ADF8D0 00000000,我验证基本都是相同信息,可以自行测试。
--//注意下划线的对应信息就是对应对象的句柄地址,如果正好等于mutex地址,表示没有对象使用该muext。
0x000000006CBA33E0+0x10 = 0x6cba33f0
0x000000006CBA63F0+0x10 = 0x6cba6400
--//正好等于对应mutex地址。
--//顺便提一下,每个chunk的开头0x00003011 = 12305,正好等于chunk大小+1.另外写blog验证自己的判断。

5.小结:
--//到此,整个21c的library cache mutex address的chunk分布基本明了。
--//1个chunk 有256个mutex地址,占用12304,每个前面有16字节开头,许多chunk在内存分布上紧挨的。共计512个chunk。
--//在1个chunk内muetx每个偏移48字节.
--//我的测试被分成3个大片:注:我在另外一台生产系统看到分成2个大片。
--//通过fchaz脚本查询对应的KSMCHPAR,没有信息输出。
--//下面测试验证使用相同muext地址的对象句柄如何链接在一起的。
posted @   lfree  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
历史上的今天:
2024-02-19 [20240219]建立完善sql_idx.sh脚本.txt
2019-02-19 [20190219]那个更快(11g).txt
点击右上角即可分享
微信分享提示