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

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

--//下面测试使用相同muext地址的对象句柄如何链接在一起的。

1.环境:
SCOTT@book01p> @ 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> startup
ORACLE instance started.
Total System Global Area  805306280 bytes
Fixed Size                  9691048 bytes
Variable Size             364904448 bytes
Database Buffers          423624704 bytes
Redo Buffers                7086080 bytes
Database mounted.
Database opened.

2.测试前准备:
--//找2个bucket=0的sql语句。
select /*+ 9 */ count(*) from dept where deptno = 93834;
select /*+ 9 */ count(*) from dept where deptno = 93091;
--//执行如下语句多次。
select /*+ 9 */ count(*) from dept where deptno = 93834;

SCOTT@book01p> @ hash
HASH_VALUE SQL_ID        CHILD_NUMBER KGL_BUCKET PLAN_HASH_VALUE HASH_HEX   SQL_EXEC_START      SQL_EXEC_ID
---------- ------------- ------------ ---------- --------------- ---------- ------------------- -----------
3403546624 as3g00v5dw000            0          0      2236899148  cade0000  2025-01-31 17:16:24    16777219

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

$ grep "^Bucket:" /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_10770.trc | head -4
Bucket: #=0 Mutex=0x6cfa1400(1125281431552, 9, 0, 6)
Bucket: #=5 Mutex=0x6cfa14f0(1125281431552, 4, 0, 6)
Bucket: #=17 Mutex=0x6cfa1730(1125281431552, 8, 0, 6)
Bucket: #=39 Mutex=0x6cfa1b50(1125281431552, 4, 0, 6)
--//Bucket: #=0,Mutex=0x6cfa1400.
--//注:这次的地址与前次不同(上次Bucket: #=0 Mutex=0x6cba03f0),估计上次测试导致共享池大小发生变化,我再次修改参数
--//shared_pool_size,db_cache_size参数,做了小幅调整shared_pool_size增加4M,后面的测试不再发生变化。
--//总之,限制db_cache_size,shared_pool_size后,相关内存不再出现增加缩小的变化,保证重启测试mutex地址不再变化。

3.看看Bucket: #=0 Mutex=0x6cfa1400:

SYS@book> @ fchaz 0x6cfa1400
LOC KSMCHPTR           KSMCHIDX   KSMCHDUR KSMCHCOM           KSMCHSIZ KSMCHCLS   KSMCHTYP KSMCHPAR         KSMCHPTR_BEGIN   KSMCHPTR_END+1
--- ---------------- ---------- ---------- ---------------- ---------- -------- ---------- ---------------- ---------------- -----------------
SGA 000000006CFA13E0          1          1 KGLSG                 12304 perm              0 000000006CC04000 000000006CFA13E0 000000006CFA43F0
--//6cfa1400-6CFA13E0 = 0x20,偏离开头32字节。
--//256*48+16 = 12304。16字节作为chunk开头。
--//0x6cfa1400-0x10 = 0x6cfa13f0

SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 60DD2740 00000000 60DD2740 00000000 00000000 00000000 00000009 00000000 00000000 00000000 60C847D0 00000000
--//转储的00000009就是muext gets的数量。

SYS@book> @ sharepool/shp4z as3g00v5dw000
HANDLE_TYPE            KGLHDADR         KGLHDPAR         C40                                        KGLHDLMD   KGLHDPMD   KGLHDIVC KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
---------------------- ---------------- ---------------- ---------------------------------------- ---------- ---------- ---------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
parent handle address  0000000060DD2740 0000000060DD2740 select /*+ 9 */ count(*) from dept where          1          0          0 0000000060DD2580 00                     4064          0          0      4064       4064 3403546624 as3g00v5dw000      65535
--//parent handle address=0000000060DD2740,与前面2个8字节记录信息一致(注意intel CPU 字节顺序问题)。
--//可以发现在这48字节里面前面2个8字节记录对象的句柄地址
--//60C847D0 00000000 就是多出来的8个字节,似乎是地址先暂时放一下。

--//关于mutex的结构,以前的测试的结果如下:
--// 0- 7 字节是muext的值。
--// 8-11 字节是mutex gets的数量。
--//12-15 字节是mutex sleep的数量。
--//16-21 字节是Bucket桶号。
--//22-24 字节是转储看到的6.

SYS@book> @ opeek 0000000060DD2740 48 0
[060DD2740, 060DD2770) = 6CFA13F0 00000000 6CFA13F0 00000000 60DD1600 00000000 60DD28B0 00000000 00010000 10012841 00000001 00000001
                         ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
--//sql_id=as3g00v5dw000父游标句柄的开头记录的就是mutxt地址0x6cfa1400-0x10。

SCOTT@book01p> alter session set session_cached_cursors=0 ;
Session altered.

SCOTT@book01p> select /*+ 9 */ count(*) from dept where deptno = 93834;
COUNT(*)
----------
0

SCOTT@book01p> select /*+ 9 */ count(*) from dept where deptno = 93834;
COUNT(*)
----------
0

--//执行以上语句后查看1次:
SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 60DD2740 00000000 60DD2740 00000000 00000000 00000000 0000000E 00000000 00000000 00000000 60C847D0 00000000

SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 60DD2740 00000000 60DD2740 00000000 00000000 00000000 0000000F 00000000 00000000 00000000 60C847D0 00000000
--//0000000E->0000000F.

SCOTT@book01p> alter session set session_cached_cursors=50 ;
Session altered.

SCOTT@book01p> select /*+ 9 */ count(*) from dept where deptno = 93834;
  COUNT(*)
----------
         0

SCOTT@book01p> select /*+ 9 */ count(*) from dept where deptno = 93834;
  COUNT(*)
----------
         0

SCOTT@book01p> select /*+ 9 */ count(*) from dept where deptno = 93834;
  COUNT(*)
----------
         0

--//执行以上语句后查看1次:
SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 60DD2740 00000000 60DD2740 00000000 00000000 00000000 00000010 00000000 00000000 00000000 60C847D0 00000000

SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 60DD2740 00000000 60DD2740 00000000 00000000 00000000 00000011 00000000 00000000 00000000 60C847D0 00000000

SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 60DD2740 00000000 60DD2740 00000000 00000000 00000000 00000011 00000000 00000000 00000000 60C847D0 00000000
--//00000010 -> 00000011,再次执行已经不再变化,说明已经缓存该游标。

4.继续:
SCOTT@book01p> select /*+ 9 */ count(*) from dept where deptno = 93091;
  COUNT(*)
----------
         0

SCOTT@book01p> @ hash
HASH_VALUE SQL_ID        CHILD_NUMBER KGL_BUCKET PLAN_HASH_VALUE HASH_HEX   SQL_EXEC_START      SQL_EXEC_ID
---------- ------------- ------------ ---------- --------------- ---------- ------------------- -----------
1206124544 8pzxckt3y8000            0          0      2236899148  47e40000  2025-01-28 10:18:46    16777223
--//执行以上语句多次,这样保证bucket=0上仅仅存在2个对象句柄。

SYS@book> @ sharepool/shp4z 8pzxckt3y8000 -1
HANDLE_TYPE            KGLHDADR         KGLHDPAR         C40                                        KGLHDLMD   KGLHDPMD   KGLHDIVC KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
---------------------- ---------------- ---------------- ---------------------------------------- ---------- ---------- ---------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
parent handle address  0000000062D4A5A8 0000000062D4A5A8 select /*+ 9 */ count(*) from dept where          1          0          0 0000000061B58570 00                     4064          0          0      4064       4064 1206124544 8pzxckt3y8000      65535

SYS@book> @ sharepool/shp4z as3g00v5dw000 -1
HANDLE_TYPE            KGLHDADR         KGLHDPAR         C40                                        KGLHDLMD   KGLHDPMD   KGLHDIVC KGLOBHD0         KGLOBHD6           KGLOBHS0   KGLOBHS6   KGLOBT16   N0_6_16        N20   KGLNAHSH KGLOBT03        KGLOBT09
---------------------- ---------------- ---------------- ---------------------------------------- ---------- ---------- ---------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ----------
parent handle address  0000000060DD2740 0000000060DD2740 select /*+ 9 */ count(*) from dept where          1          0          0 0000000060DD2580 00                     4064          0          0      4064       4064 3403546624 as3g00v5dw000      65535

SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 62D4A5A8 00000000 60DD2740 00000000 00000000 00000000 00000017 00000000 00000000 00000000 60C847D0 00000000
--//对比前面可以发现前面变成的62D4A5A8 00000000,对应就是第2条sql语句的父游标句柄。
--//0x60DD2740 就是sql_id=as3g00v5dw000的parent handle address,对应第1条执行语句。
--//0x62D4A5A8 就是sql_id=8pzxckt3y8000的parent handle address,对应第2条执行语句。
--//也就是后者是首地址,前者为尾地址。
--//顺便贴上前面执行第2条语句前的情况:
SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 60DD2740 00000000 60DD2740 00000000 00000000 00000000 00000011 00000000 00000000 00000000 60C847D0 00000000

SYS@book> @ opeek 0000000060DD2740 48 0
[060DD2740, 060DD2770) = 6CFA13F0 00000000 62D4A5A8 00000000 60DD1600 00000000 60DD28B0 00000000 00010000 10012841 00000001 00000001
                         ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
--//前者记录的是mutex地址 0x6cfa1400-0x10,后者就是第2条sql语句的父游标句柄0000000062D4A5A8.

SYS@book> @ opeek 0000000062D4A5A8 48 0
[062D4A5A8, 062D4A5D8) = 60DD2740 00000000 6CFA13F0 00000000 62FB5EC8 00000000 62D4A718 00000000 00010000 10012841 00000001 00000001
                         ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
--//后者记录的是mutex地址 0x6cfa1400-0x10,前者就是第1条sql语句的父游标句柄0000000060DD2740

SYS@book> @ opeek 0x6cfa13f0 48 0
[06CFA13F0, 06CFA1420) = 62D4A5A8 00000000 60DD2740 00000000 00000000 00000000 00000017 00000000 00000000 00000000 60C847D0 00000000
                         ~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~

--//oracle通过这样的方式将上面2条相同bucket的sql语句链接起来的双向链表。

4.小结:
--//48字节内容大致如下:

--//0-7,8-15字节分别是对象句柄的尾首指针,如果仅仅存在1个对象,两者相等。如果存在多个对象会形成1个双向链表。
--//如果仅仅存在0个对象,两者等于mutex的地址-0x10。

--//16-23字节是muext的值。
--//24-27字节是mutex gets的数量。
--//28-31字节是mutex sleeps的数量。
--//32-35字节是Bucket桶号,这里是0。
--//36-39字节是转储看到的6,这是我猜的的,如果你修改其他值,dump看到还是6。
--//40-47字节似乎是某个地址,具体细节看另外一篇blog。

--//如果单独看mutex的结构,测试的结果如下:
--// 0- 7 字节是muext的值。
--// 8-11 字节是mutex gets的数量。
--//12-15 字节是mutex sleep的数量。
--//16-19 字节是Bucket桶号。
--//20-23 字节是转储看到的6,而opeek看都是0,表示什么不是很清楚。
--//mutex结构占用24字节。

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
点击右上角即可分享
微信分享提示