[20250201]21c library cache mutex的深入探究4.txt --//前面的测试已经大致确定这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字节似乎是某个地址,以前11g没有这部分内容,本文在一些细节上在验证看看。 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. 2.测试: --//先确定某条sql语句的KGL_BUCKET。 SCOTT@book01p> select * from dept where deptno= 20; DEPTNO DNAME LOC ---------- ------------------------------ ------------- 20 RESEARCH DALLAS SCOTT@book01p> @ hash HASH_VALUE SQL_ID CHILD_NUMBER KGL_BUCKET PLAN_HASH_VALUE HASH_HEX SQL_EXEC_START SQL_EXEC_ID ---------- ------------- ------------ ---------- --------------- ---------- ------------------- ----------- 1418564050 62m9tata8v4fk 0 102866 2852011669 548d91d2 2025-02-01 15:31:19 16777216 SYS@book> oradebug setmypid Statement processed. SYS@book> oradebug dump library_cache 4 Statement processed. SYS@book> @t TRACEFILE -------------------------------------------------------------------------------- /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3514.trc $ grep "^Bucket: #=102866" /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3514.trc Bucket: #=102866 Mutex=0x6c493990(1189705940992, 7, 0, 6) --//0x6c493990-0x10 = 0x6c493980 SYS@book> @ opeek 0x6c493980 48 0 [06C493980, 06C4939B0) = 6995F5E0 00000000 6995F5E0 00000000 00000000 00000000 00000018 00000000 000191D2 00000000 659F8EE0 00000000 --//0x000191D2 = 102866,32-35字节是Bucket桶号102866.实际上是HASH_VALUE%2^_kgl_bucket_count * 256 = 1418564050%2^17 = 102866. SYS@book> @ sharepool/shp4z 62m9tata8v4fk -1 HANDLE_TYPE KGLHDADR KGLHDPAR C40 KGLHDLMD KGLHDPMD KGLHDIVC KGLOBHD0 KGLOBHD6 KGLOBHS0 KGLOBHS6 KGLOBT16 N0_6_16 N20 KGLNAHSH KGLOBT03 KGLOBT09 ---------------------- ---------------- ---------------- ---------------------------------------- ---------- ---------- ---------- ---------------- ---------------- ---------- ---------- ---------- --------- ---------- ---------- ------------- ---------- parent handle address 000000006995F5E0 000000006995F5E0 select * from dept where deptno= 20 1 0 0 0000000062226DA8 00 4064 0 0 4064 4064 1418564050 62m9tata8v4fk 65535 --//前面0-7,8-15字节分别是对象sql语句句柄的尾首指针。 3.测试该mutex的gets是否正确。 SYS@book> @ opeek 0x6c493980 48 0 [06C493980, 06C4939B0) = 6995F5E0 00000000 6995F5E0 00000000 00000000 00000000 0000001A 00000000 000191D2 00000000 659F8EE0 00000000 --//gets=0x1A SCOTT@book01p> alter session set session_cached_cursors=0 ; Session altered. SCOTT@book01p> select * from dept where deptno= 20; DEPTNO DNAME LOC ---------- ------------------------------ ------------- 20 RESEARCH DALLAS SCOTT@book01p> select * from dept where deptno= 20; DEPTNO DNAME LOC ---------- ------------------------------ ------------- 20 RESEARCH DALLAS --//每执行1次使用opeek脚本查看1次。 SYS@book> @ opeek 0x6c493980 48 0 [06C493980, 06C4939B0) = 6995F5E0 00000000 6995F5E0 00000000 00000000 00000000 0000001B 00000000 000191D2 00000000 659F8EE0 00000000 SYS@book> @ opeek 0x6c493980 48 0 [06C493980, 06C4939B0) = 6995F5E0 00000000 6995F5E0 00000000 00000000 00000000 0000001C 00000000 000191D2 00000000 659F8EE0 00000000 --//gets数量从0000001B->0000001C. 4.测试该mutex的sleeps。 --//通过修改该值验证看看。 SYS@book> @ spid ============================== SID : 16 SERIAL# : 37354 PROCESS : 3708 SERVER : DEDICATED SPID : 3709 PID : 52 P_SERIAL# : 5 KILL_COMMAND : alter system kill session '16,37354' immediate; PL/SQL procedure successfully completed. $ rlgdb -f -p 3709 .... (gdb) x /16wx 0x6c493980 0x6c493980: 0x6995f5e0 0x00000000 0x6995f5e0 0x00000000 0x6c493990: 0x00000000 0x00000000 0x0000001c 0x00000000 ~~~~~~~~~~ 0x6c4939a0: 0x000191d2 0x00000000 0x659f8ee0 0x00000000 ~~~~~~~~~~ 0x6c4939b0: 0x6c4939b0 0x00000000 0x6c4939b0 0x00000000 --//sleeps位置在地址0x6c49399c,顺便修改0x6c4939a4里面的保存信息。 (gdb) set *(int *)0x6c49399c=0xff (gdb) set *(int *)0x6c4939a4=0xee (gdb) x /16wx 0x6c493980 0x6c493980: 0x6995f5e0 0x00000000 0x6995f5e0 0x00000000 0x6c493990: 0x00000000 0x00000000 0x0000001d 0x000000ff ~~~~~~~~~~~ 0x6c4939a0: 0x000191d2 0x000000ee 0x659f8ee0 0x00000000 ~~~~~~~~~ 0x6c4939b0: 0x6c4939b0 0x00000000 0x6c4939b0 0x00000000 --//注:oracle 21c版本已经不支持oradebug poke修改内存值。 SYS@book> @ opeek 0x6c493980 48 0 [06C493980, 06C4939B0) = 6995F5E0 00000000 6995F5E0 00000000 00000000 00000000 0000001D 000000FF 000191D2 000000EE 659F8EE0 00000000 --//验证修改正确!! ~~~~~~~~ ~~~~~~~~ SYS@book> @ti New tracefile_identifier = /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3514_0001.trc SYS@book> oradebug dump library_cache 4 Statement processed. $ grep "^Bucket: #=102866" /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3514_0001.trc Bucket: #=102866 Mutex=0x6c493990(1189705940992, 30, 255, 6) --//最后1个值都是6.前面1189705940992前面已经修改mutex的值,11g版本dump显示的都是0.在这里显示的dump会话的sid(前4个字节) --//,后4个字节表示mutex持有的数量。 --//1189705940992 = 0x11500000000,补齐前面的0,0x0000011500000000,0x115 = 277,dump转储会话sid=277,大家可以自行验证。 SYS@book> @ opeek 0x6c493980 48 0 [06C493980, 06C4939B0) = 6995F5E0 00000000 6995F5E0 00000000 00000000 00000000 0000001E 000000FF 000191D2 00000000 659F8EE0 00000000 ~~~~~~~~ ~~~~~~~~ --//每次转储gets数量增加1,从0000001D->0000001E。sleeps=255,而转储后最后1个值变成6,而实际在内存里面是0,注:原来是0xee。 5.再看看最后8个字节(位于40-47字节): --//前面猜测是一个地址,探究看看。 SYS@book> @ fchaz 659F8EE0 LOC KSMCHPTR KSMCHIDX KSMCHDUR KSMCHCOM KSMCHSIZ KSMCHCLS KSMCHTYP KSMCHPAR KSMCHPTR_BEGIN KSMCHPTR_END+1 --- ---------------- ---------- ---------- ---------------- ---------- -------- ---------- ---------------- ---------------- ----------------- SGA 00000000659F8ED0 1 1 KGLHBPVEC 88 perm 0 00000000659F8EB0 00000000659F8ED0 00000000659F8F28 --//00000000659F8ED0-00000000659F8EB0 = 0x20 --//KSMCHCOM=KGLHBPVEC ,KSMCHSIZ=88. SYS@book> @ fchaz 00000000659F8EB0 no rows selected --//通过堆描述符查询没有显示占用空间,KSMCHPAR=00000000659F8EB0。是否可以这样理解,建立相应chunk后,堆描述符占用的空间回 --//收了。 --//查看该chunk保存什么信息: SYS@book> @ opeek 00000000659F8ED0 88 1 New tracefile_identifier = /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3514_0003.trc [0659F8ED0, 0659F8F28) = 00000059 00B38F00 17ADF554 00000000 0000000A 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ... --//0x00000059 = 89 = 88+1. --//查看跟踪文件: *** 2025-02-01T16:08:19.549687+08:00 (CDB$ROOT(1)) Processing Oradebug command 'peek 0x00000000659f8ed0 88 1' [0659F8ED0, 0659F8F28) = 00000059 00B38F00 17ADF554 00000000 0000000A ... Dump of memory from 0x0659F8EE4 to 0x0659F8F28 0659F8EE0 00000000 00000000 00000000 [............] 0659F8EF0 00000000 00000000 00000000 00000000 [................] Repeat 2 times 0659F8F20 00000000 00000000 --//如果不算前面16字节,仅仅剩下0000000A 表示怎么呢?主要是很难理解KGLHBPVEC缩略写表示什么?建立这样chunk用意何在。 $ grep "^Bucket: #=" /u01/app/oracle/diag/rdbms/book/book/trace/book_ora_3514_0001.trc | head -4 Bucket: #=5 Mutex=0x6cfa14f0(1189705940992, 42, 0, 6) Bucket: #=39 Mutex=0x6cfa1b50(1189705940992, 40, 0, 6) Bucket: #=42 Mutex=0x6cfa1be0(1189705940992, 8, 0, 6) Bucket: #=47 Mutex=0x6cfa1cd0(1189705940992, 8, 0, 6) --//随便抽查几个检查都是类似,例子Bucket: #=5 Mutex=0x6cfa14f0(1189705940992, 42, 0, 6)。 SYS@book> @ opeek 0x6cfa14f0 32 0 [06CFA14F0, 06CFA1510) = 00000000 00000000 00000038 00000000 00000005 00000000 63838310 00000000 SYS@book> @ fchaz 63838310 LOC KSMCHPTR KSMCHIDX KSMCHDUR KSMCHCOM KSMCHSIZ KSMCHCLS KSMCHTYP KSMCHPAR KSMCHPTR_BEGIN KSMCHPTR_END+1 --- ---------------- ---------- ---------- ---------------- ---------- -------- ---------- ---------------- ---------------- ----------------- SGA 0000000063838300 1 1 KGLHBPVEC 88 perm 0 0000000063804000 0000000063838300 0000000063838358 SYS@book> @ fchaz 0000000063804000 no rows selected SYS@book> select count(*) from x$ksmsp where KSMCHCOM='KGLHBPVEC' and KSMCHSIZ=88 and KSMCHCLS='perm'; COUNT(*) ---------- 23174 --//按照这样推测,如果全部bucket都使用应该总数是2^17 = 131072. $ 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; / --//该脚本没有使用绑定变量,也就是尽可能地建立KSMCHCOM='KGLHBPVEC'类型的chunk。 $ zzdate ; seq 20 | xargs -P 20 -IQ sqlplus -s -l scott/book@book01p @ m9.txt 2e4 Q > /dev/null ; zzdate trunc(sysdate)+16/24+18/1440+19/86400 1738397899.253119747 trunc(sysdate)+16/24+20/1440+13/86400 1738398013.374670218 SYS@book> select count(*) from x$ksmsp where KSMCHCOM='KGLHBPVEC' and KSMCHSIZ=88 and KSMCHCLS='perm'; COUNT(*) ---------- 130873 --//已经非常接近了2^17= 131072. --//修改m9.txt select 为Select. $ zzdate ; seq 20 | xargs -P 20 -IQ sqlplus -s -l scott/book@book01p @ m9.txt 5e4 Q > /dev/null ; zzdate trunc(sysdate)+16/24+43/1440+26/86400 1738399406.216715625 trunc(sysdate)+16/24+45/1440+22/86400 1738399522.855450824 SYS@book> select count(*) from x$ksmsp where KSMCHCOM='KGLHBPVEC' and KSMCHSIZ=88 and KSMCHCLS='perm'; COUNT(*) ---------- 130898 --//嗯,还是不到131072. SYS@book> select count(*) from x$ksmsp where KSMCHCOM='KGLHBPVEC' and KSMCHSIZ=88 ; COUNT(*) ---------- 131072 SYS@book> select count(*),KSMCHSIZ,KSMCHCLS from x$ksmsp where KSMCHCOM='KGLHBPVEC' and KSMCHSIZ=88 group by KSMCHSIZ,KSMCHCLS; COUNT(*) KSMCHSIZ KSMCHCLS ---------- ---------- -------- 174 88 R-perm 130898 88 perm --//其中有174个是KSMCHCLS=R-perm类型,我估计我的测试环境共享内存太小,一部分使用保留池内存。 --//到此基本验证多出来的8字节保存的是地址信息,而且仅仅使用该bucket后才会出现地址不为0的情况。 4.小结: --//关于mutex的结构,测试的结果如下: --// 0- 7 字节是muext的值。 --// 8-11 字节是mutex gets的数量。 --//12-15 字节是mutex sleep的数量。 --//16-19 字节是Bucket桶号。 --//20-23 字节是转储看到的6,而opeek看都是0,表示什么不是很清楚。 --//mutex结构占用24字节。 --//前面的16字节保存的是对象句柄的地址。如果仅仅存在1个对象,两者相等(保存为父游标句柄地址)。如果存在多个对象会形成1 --//个双向链表,如果仅仅存在0个对象,两者等于mutex的地址-0x10。 --//后面的8字节对应的是某个地址,类型KSMCHCOM='KGLHBPVEC' and KSMCHSIZ=88。 --//16+24+8 = 48, 正好等于48字节。
[20250201]21c library cache mutex的深入探究4.txt
来源:这里教程网
时间:2026-03-03 21:33:29
作者:
编辑推荐:
- [20250201]21c library cache mutex的深入探究4.txt03-03
- [20250202]21c library cache mutex的深入探究5.txt03-03
- [20250203]21c library cache mutex的深入探究5(补充).txt03-03
- [20250203]21c library cache mutex的深入探究6(gets的变化).txt03-03
- 当哪吒邂逅铂乐・极满家,开启家居新境界03-03
- [20250204]21c library cache mutex的深入探究7(_mutex_wait_scheme=2).txt03-03
- [20250204]21c library cache mutex的深入探究8(_mutex_wait_time>1)03-03
- [20250205]21c library cache mutex的深入探究9(_mutex_wait_scheme=0).txt03-03
下一篇:
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- 当哪吒邂逅铂乐・极满家,开启家居新境界
当哪吒邂逅铂乐・极满家,开启家居新境界
26-03-03 - hyper xp,hyper xp的实操攻略,hyper-v批量管理工具的使用指南
- hyper 共享,hyper 共享的实操流程,hyper-v批量管理工具的使用指南
- hyper v win10,hyper v win10的实操流程,hyper-v批量管理工具的使用指南
- hyper v vmware,hyper v vmware的实操流程,hyper-v批量管理工具的使用指南
- 数据库io负载瓶颈问题
数据库io负载瓶颈问题
26-03-03 - log file sync导致的Oracle重大生产性能故障
log file sync导致的Oracle重大生产性能故障
26-03-03 - 蛇年第一个Oracle 600错误!15年老司机也没见过
蛇年第一个Oracle 600错误!15年老司机也没见过
26-03-03 - oracle多次密码错误登录,用户锁住或失效
oracle多次密码错误登录,用户锁住或失效
26-03-03 - 第28期 Oracle LOB数据实际存储在哪里
第28期 Oracle LOB数据实际存储在哪里
26-03-03
