[20260917]oracle共享内存段Key值的计算4.txt
[20260917]oracle共享内存段Key值的计算4.txt
--//前几天遇到斜线引起的问题,突然想了解共享内存段Key值的计算,肯定是某种hash算法,开始使用ora_hash函数盲猜,根本对不上。
--//做一个小小的分析尝试,中间遇到许多问题,比如sqlplus登录连接数据库,导致是那个函数调用shmget,在这里浪费了许多时间,
--//另外写blog分析。
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.
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 56
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
--//当前key=0xafa94c20 = 2947107872.
--//2097152/1024/1024 = 2M.
2.分析:
--//^J在linux下按ctrl+v ctrl+j输入,相当于\n.
$ strace -Ttt -f -e ipc sqlplus -s -l / as sysdba <<<"host sleep 3^Jquit"
strace: Process 4359 attached
[pid 4359] 09:43:04.444115 shmget(0xafa94c20, 0, 000) = 3 <0.000124>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--//带入key值计算0xafa94c20返回shmid=3.说明在之前已经计算获得其hash值.
[pid 4359] 09:43:04.444475 shmctl(3, IPC_STAT, {shm_perm={uid=54321, gid=54321, mode=0600, key=2947107872, cuid=54321, cgid=54321}, shm_segsz=2097152, shm_cpid=2744, shm_lpid=4352, shm_nattch=56, shm_atime=1789609343, shm_dtime=1789609343, shm_ctime=1789606883}) = 0 <0.000092>
[pid 4359] 09:43:04.444764 shmat(3, NULL, 0) = 0x7f9a08c00000 <0.000107>
[pid 4359] 09:43:04.445083 shmdt(0x7f9a08c00000) = 0 <0.000113>
[pid 4359] 09:43:04.445367 shmget(0xafa94c21, 0, 000) = -1 ENOENT (No such file or directory) <0.000085>
[pid 4359] 09:43:04.445670 shmget(0xafa94c22, 0, 000) = -1 ENOENT (No such file or directory) <0.000112>
[pid 4359] 09:43:04.446015 shmget(0xafa94c23, 0, 000) = -1 ENOENT (No such file or directory) <0.000124>
[pid 4359] 09:43:04.446383 shmat(3, 0xa6000000, 0) = 0xa6000000 <0.000102>
[pid 4359] 09:43:04.446656 shmat(1, 0x61000000, 0) = 0x61000000 <0.000104>
[pid 4359] 09:43:04.446943 shmat(2, 0xa5000000, 0) = 0xa5000000 <0.000133>
[pid 4359] 09:43:04.447234 shmat(0, 0x60000000, 0) = 0x60000000 <0.000104>
[pid 4359] 09:43:04.476375 shmget(0xa93a2388, 0, 000) = -1 ENOENT (No such file or directory) <0.000117>
[pid 4359] 09:43:04.476661 shmget(0xa93a2389, 0, 000) = -1 ENOENT (No such file or directory) <0.000152>
[pid 4359] 09:43:04.476996 shmget(0xa93a238a, 0, 000) = -1 ENOENT (No such file or directory) <0.000100>
[pid 4359] 09:43:04.477238 shmget(0xa93a238b, 0, 000) = -1 ENOENT (No such file or directory) <0.000121>
[pid 4359] 09:43:04.495974 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x2} ---
strace: Process 4360 attached
--//以下host sleep 3执行.
[pid 4360] 09:43:07.862971 +++ exited with 0 +++
[pid 4358] 09:43:07.863132 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4360, si_uid=54321, si_status=0, si_utime=0, si_stime=0} ---
[pid 4358] 09:43:07.876305 +++ exited with 0 +++
09:43:07.884981 shmdt(0x61000000) = 0 <0.000223>
09:43:07.885412 shmdt(0xa5000000) = 0 <0.000139>
09:43:07.885733 shmdt(0x60000000) = 0 <0.000202>
09:43:07.886122 shmdt(0xa6000000) = 0 <0.000149>
09:43:07.897475 +++ exited with 0 +++
--//补充说明:不清楚为什么又做了shmget(0xafa94c21, 0, 000),shmget(0xafa94c22, 0, 000),shmget(0xafa94c23, 0, 000)三次尝
--//试失败,hash冲突吗?
--//然后使用shmat attach 共享内存段。后面做了4次
shmget(0xa93a2388, 0, 000) = -1 ENOENT (No such file or directory) <0.000117>
shmget(0xa93a2389, 0, 000) = -1 ENOENT (No such file or directory) <0.000152>
shmget(0xa93a238a, 0, 000) = -1 ENOENT (No such file or directory) <0.000100>
shmget(0xa93a238b, 0, 000) = -1 ENOENT (No such file or directory) <0.000121>
--//看后面跟踪的结果参与计算的是/u01/app/oracle/product/21.0.0/dbhome_1book.pga_#$,从内容看似乎与pga相关。难道pga也可以
--//使用类似共享内存段吗?可惜启动没有建立。
--//建立bpftrace脚本记录调用shmget的调用堆栈。注:开始使用gdb跟踪,一直无法知道执行的调用栈。
$ cat shmget.bt
tracepoint:syscalls:sys_enter_shmget
/ pid == $1 || $1 == 0 /
{
@stacks[ustack, comm] = count();
}
END
{
printf("\n=== Top Stacks (sample count) ===\n");
print(@stacks);
clear(@stacks);
}
--//执行1次登录数据库操作,完成按ctrl+c退出.
# bpftrace shmget.bt 0
Attached 2 probes
^C
=== Top Stacks (sample count) ===
@stacks[
shmget+14
skgmlocate+261
skgmattach_primaryseg+234
skgmattach_nondeferareas+313
skgmattach+36
ksmnfy+11816
kscnfy+1212
opiino+106
opiodr+1256
opidrv+1067
sou2o+165
opimai_real+400
ssthrdmain+412
main+292
__libc_start_call_main+128
, oracle]: 4
@stacks[
shmget+14
skgmlocate+261
skgmattach_primaryseg+234
skgmattach_nondeferareas+313
ksm_attach_sga+300
ksmlsge_phaseone+449
opimai_init+284
opimai_real+356
ssthrdmain+412
main+292
__libc_start_call_main+128
, oracle]: 4
--//一共执行8次,与前面strace跟踪可以对上.可以看出整个调用栈使用的函数.
--//注:实际上少了一个函数sskgmget.应该是skgmlocate调用sskgmget,sskgmget调用shmget.
--//后面+的数字是偏移量,反汇编代码很容易确定.
(gdb) disassemble skgmlocate
Dump of assembler code for function skgmlocate:
0x0000000005790b80 <+0>: xchg %ax,%ax
0x0000000005790b82 <+2>: push %rbp
0x0000000005790b83 <+3>: mov %rsp,%rbp
0x0000000005790b86 <+6>: push %r12
0x0000000005790b88 <+8>: push %r13
0x0000000005790b8a <+10>: push %r14
0x0000000005790b8c <+12>: push %r15
0x0000000005790b8e <+14>: push %rbx
...
0x0000000005790c78 <+248>: mov -0x40(%rbp),%rdx
0x0000000005790c7c <+252>: mov -0x50(%rbp),%r9
0x0000000005790c80 <+256>: call 0x57a67c0 <sskgmget>
0x0000000005790c85 <+261>: mov %eax,%r9d
--//基本可以确定调用sskgmget调用shmget函数。
--//查看调用栈的函数skgmattach_primaryseg,反汇编skgmattach_primaryseg.
(gdb) disassemble skgmattach_primaryseg
Dump of assembler code for function skgmattach_primaryseg:
0x00000000057905e0 <+0>: xchg %ax,%ax
0x00000000057905e2 <+2>: push %rbp
0x00000000057905e3 <+3>: mov %rsp,%rbp
0x00000000057905e6 <+6>: push %r12
0x00000000057905e8 <+8>: push %r13
0x00000000057905ea <+10>: push %r14
0x00000000057905ec <+12>: push %r15
0x00000000057905ee <+14>: push %rbx
0x00000000057905ef <+15>: sub $0x128,%rsp
0x00000000057905f6 <+22>: mov %rdx,%r12
0x00000000057905f9 <+25>: mov %rdi,%rbx
0x00000000057905fc <+28>: mov %r12,%rdi
0x00000000057905ff <+31>: mov %rsi,%r15
0x0000000005790602 <+34>: xor %eax,%eax
0x0000000005790604 <+36>: mov %rcx,-0x38(%rbp)
0x0000000005790608 <+40>: mov 0x100(%r12),%rsi
0x0000000005790610 <+48>: movl $0xffffffff,-0x30(%rbp)
0x0000000005790617 <+55>: mov %rax,-0x48(%rbp)
0x000000000579061b <+59>: movl $0x0,-0x2c(%rbp)
0x0000000005790622 <+66>: mov %rax,-0x40(%rbp)
0x0000000005790626 <+70>: call 0x57909b0 <skgmhash>
...
--//可以大致猜测计算使用skgmhash函数.
3. 继续:
$ cat shm.bt
//uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:sskgmget
//uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:skgmlocate
//uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:skgmattach_primaryseg
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:skgmhash
/ $1 == 0 || pid == $1 /
{
// printf("[%s] %s pid=%d arg0=%016lx arg1=%016lx arg2=%016lx arg3=%016lx\n", strftime("%H:%M:%S", nsecs), func,pid,arg0, arg1,arg2,arg3);
// printf("[%s] %s pid=%d arg0=%s arg1=%s arg2=%s arg3=%s\n", strftime("%H:%M:%S", nsecs), func,pid,buf(arg0,64),buf(arg1,64),buf(arg2,64),buf(arg3,64));
// printf("[%s] %s pid=%d arg2=%s\n", strftime("%H:%M:%S", nsecs), func,pid,buf(arg2,52));
printf("[%s] %s pid=%d ptr0=%016lx hash_text=%s length=%d\n", strftime("%H:%M:%S", nsecs), func,pid,arg0, buf(arg0,arg1),arg1);
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:skgmhash
/ $1 == 0 || pid == $1 /
{
printf("[%s] %s pid=%d return hash_value=%016lx %lu\n", strftime("%H:%M:%S", nsecs), func,pid, retval, retval);
}
--//执行1次登录数据库操作,完成按ctrl+c退出.
# bpftrace shm.bt 0
Attached 2 probes
[10:00:50] skgmhash pid=4605 ptr0=00007ffe767ecb30 hash_text=/u01/app/oracle/product/21.0.0/dbhome_1book length=43
[10:00:50] skgmhash pid=4605 return hash_value=00000000afa94c20 2947107872
[10:00:50] skgmhash pid=4605 ptr0=00007ffe767ead30 hash_text=/u01/app/oracle/product/21.0.0/dbhome_1book.pga_#$ length=50
[10:00:50] skgmhash pid=4605 return hash_value=00000000a93a2388 2839159688
^C
--//验证我的判断,共享内存段key值的计算使用skgmhash函数,返回值也可以对上。至于使用什么hash算法,超出我的能力.
--//如果换成如下环境变量再次登录:
$ export ORACLE_HOME=//u01/app/oracle/product/21.0.0/dbhome_1/
--//注:两头都有斜线/
# bpftrace shm.bt 0
Attached 2 probes
[10:05:40] skgmhash pid=4690 ptr0=00007ffe1c4e1a30 hash_text=//u01/app/oracle/product/21.0.0/dbhome_1book length=44
[10:05:40] skgmhash pid=4690 return hash_value=00000000af89bb44 2945039172
[10:05:40] skgmhash pid=4690 ptr0=00007ffe1c4dfc30 hash_text=//u01/app/oracle/product/21.0.0/dbhome_1book.pga_#$ length=51
[10:05:40] skgmhash pid=4690 return hash_value=000000002ecfdd0c 785374476
[10:05:40] skgmhash pid=4690 ptr0=00007ffe1c4e0330 hash_text=//u01/app/oracle/product/21.0.0/dbhome_1book length=44
[10:05:40] skgmhash pid=4690 return hash_value=00000000af89bb44 2945039172
[10:05:40] skgmhash pid=4690 ptr0=00007ffe1c4d46e0 hash_text=//u01/app/oracle/product/21.0.0/dbhome_1book length=44
[10:05:40] skgmhash pid=4690 return hash_value=00000000af89bb44 2945039172
^C
--//注意看hash_text的值,长度变成44多了一个字符,这样自然连接空实例。
--//拼接的字符串dbhome_1 book之间没有/,以前测试也验证从11.2.0.4版本开始环境变量ORACLE_HOME结尾有没有/,不会受到这个因素的影响.
--//前几天遇到斜线引起的问题,突然想了解共享内存段Key值的计算,肯定是某种hash算法,开始使用ora_hash函数盲猜,根本对不上。
--//做一个小小的分析尝试,中间遇到许多问题,比如sqlplus登录连接数据库,导致是那个函数调用shmget,在这里浪费了许多时间,
--//另外写blog分析。
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.
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 0 oracle 600 10485760 56
0x00000000 1 oracle 600 1140850688 56
0x00000000 2 oracle 600 8388608 56
0xafa94c20 3 oracle 600 2097152 56
--//当前key=0xafa94c20 = 2947107872.
--//2097152/1024/1024 = 2M.
2.分析:
--//^J在linux下按ctrl+v ctrl+j输入,相当于\n.
$ strace -Ttt -f -e ipc sqlplus -s -l / as sysdba <<<"host sleep 3^Jquit"
strace: Process 4359 attached
[pid 4359] 09:43:04.444115 shmget(0xafa94c20, 0, 000) = 3 <0.000124>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--//带入key值计算0xafa94c20返回shmid=3.说明在之前已经计算获得其hash值.
[pid 4359] 09:43:04.444475 shmctl(3, IPC_STAT, {shm_perm={uid=54321, gid=54321, mode=0600, key=2947107872, cuid=54321, cgid=54321}, shm_segsz=2097152, shm_cpid=2744, shm_lpid=4352, shm_nattch=56, shm_atime=1789609343, shm_dtime=1789609343, shm_ctime=1789606883}) = 0 <0.000092>
[pid 4359] 09:43:04.444764 shmat(3, NULL, 0) = 0x7f9a08c00000 <0.000107>
[pid 4359] 09:43:04.445083 shmdt(0x7f9a08c00000) = 0 <0.000113>
[pid 4359] 09:43:04.445367 shmget(0xafa94c21, 0, 000) = -1 ENOENT (No such file or directory) <0.000085>
[pid 4359] 09:43:04.445670 shmget(0xafa94c22, 0, 000) = -1 ENOENT (No such file or directory) <0.000112>
[pid 4359] 09:43:04.446015 shmget(0xafa94c23, 0, 000) = -1 ENOENT (No such file or directory) <0.000124>
[pid 4359] 09:43:04.446383 shmat(3, 0xa6000000, 0) = 0xa6000000 <0.000102>
[pid 4359] 09:43:04.446656 shmat(1, 0x61000000, 0) = 0x61000000 <0.000104>
[pid 4359] 09:43:04.446943 shmat(2, 0xa5000000, 0) = 0xa5000000 <0.000133>
[pid 4359] 09:43:04.447234 shmat(0, 0x60000000, 0) = 0x60000000 <0.000104>
[pid 4359] 09:43:04.476375 shmget(0xa93a2388, 0, 000) = -1 ENOENT (No such file or directory) <0.000117>
[pid 4359] 09:43:04.476661 shmget(0xa93a2389, 0, 000) = -1 ENOENT (No such file or directory) <0.000152>
[pid 4359] 09:43:04.476996 shmget(0xa93a238a, 0, 000) = -1 ENOENT (No such file or directory) <0.000100>
[pid 4359] 09:43:04.477238 shmget(0xa93a238b, 0, 000) = -1 ENOENT (No such file or directory) <0.000121>
[pid 4359] 09:43:04.495974 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x2} ---
strace: Process 4360 attached
--//以下host sleep 3执行.
[pid 4360] 09:43:07.862971 +++ exited with 0 +++
[pid 4358] 09:43:07.863132 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=4360, si_uid=54321, si_status=0, si_utime=0, si_stime=0} ---
[pid 4358] 09:43:07.876305 +++ exited with 0 +++
09:43:07.884981 shmdt(0x61000000) = 0 <0.000223>
09:43:07.885412 shmdt(0xa5000000) = 0 <0.000139>
09:43:07.885733 shmdt(0x60000000) = 0 <0.000202>
09:43:07.886122 shmdt(0xa6000000) = 0 <0.000149>
09:43:07.897475 +++ exited with 0 +++
--//补充说明:不清楚为什么又做了shmget(0xafa94c21, 0, 000),shmget(0xafa94c22, 0, 000),shmget(0xafa94c23, 0, 000)三次尝
--//试失败,hash冲突吗?
--//然后使用shmat attach 共享内存段。后面做了4次
shmget(0xa93a2388, 0, 000) = -1 ENOENT (No such file or directory) <0.000117>
shmget(0xa93a2389, 0, 000) = -1 ENOENT (No such file or directory) <0.000152>
shmget(0xa93a238a, 0, 000) = -1 ENOENT (No such file or directory) <0.000100>
shmget(0xa93a238b, 0, 000) = -1 ENOENT (No such file or directory) <0.000121>
--//看后面跟踪的结果参与计算的是/u01/app/oracle/product/21.0.0/dbhome_1book.pga_#$,从内容看似乎与pga相关。难道pga也可以
--//使用类似共享内存段吗?可惜启动没有建立。
--//建立bpftrace脚本记录调用shmget的调用堆栈。注:开始使用gdb跟踪,一直无法知道执行的调用栈。
$ cat shmget.bt
tracepoint:syscalls:sys_enter_shmget
/ pid == $1 || $1 == 0 /
{
@stacks[ustack, comm] = count();
}
END
{
printf("\n=== Top Stacks (sample count) ===\n");
print(@stacks);
clear(@stacks);
}
--//执行1次登录数据库操作,完成按ctrl+c退出.
# bpftrace shmget.bt 0
Attached 2 probes
^C
=== Top Stacks (sample count) ===
@stacks[
shmget+14
skgmlocate+261
skgmattach_primaryseg+234
skgmattach_nondeferareas+313
skgmattach+36
ksmnfy+11816
kscnfy+1212
opiino+106
opiodr+1256
opidrv+1067
sou2o+165
opimai_real+400
ssthrdmain+412
main+292
__libc_start_call_main+128
, oracle]: 4
@stacks[
shmget+14
skgmlocate+261
skgmattach_primaryseg+234
skgmattach_nondeferareas+313
ksm_attach_sga+300
ksmlsge_phaseone+449
opimai_init+284
opimai_real+356
ssthrdmain+412
main+292
__libc_start_call_main+128
, oracle]: 4
--//一共执行8次,与前面strace跟踪可以对上.可以看出整个调用栈使用的函数.
--//注:实际上少了一个函数sskgmget.应该是skgmlocate调用sskgmget,sskgmget调用shmget.
--//后面+的数字是偏移量,反汇编代码很容易确定.
(gdb) disassemble skgmlocate
Dump of assembler code for function skgmlocate:
0x0000000005790b80 <+0>: xchg %ax,%ax
0x0000000005790b82 <+2>: push %rbp
0x0000000005790b83 <+3>: mov %rsp,%rbp
0x0000000005790b86 <+6>: push %r12
0x0000000005790b88 <+8>: push %r13
0x0000000005790b8a <+10>: push %r14
0x0000000005790b8c <+12>: push %r15
0x0000000005790b8e <+14>: push %rbx
...
0x0000000005790c78 <+248>: mov -0x40(%rbp),%rdx
0x0000000005790c7c <+252>: mov -0x50(%rbp),%r9
0x0000000005790c80 <+256>: call 0x57a67c0 <sskgmget>
0x0000000005790c85 <+261>: mov %eax,%r9d
--//基本可以确定调用sskgmget调用shmget函数。
--//查看调用栈的函数skgmattach_primaryseg,反汇编skgmattach_primaryseg.
(gdb) disassemble skgmattach_primaryseg
Dump of assembler code for function skgmattach_primaryseg:
0x00000000057905e0 <+0>: xchg %ax,%ax
0x00000000057905e2 <+2>: push %rbp
0x00000000057905e3 <+3>: mov %rsp,%rbp
0x00000000057905e6 <+6>: push %r12
0x00000000057905e8 <+8>: push %r13
0x00000000057905ea <+10>: push %r14
0x00000000057905ec <+12>: push %r15
0x00000000057905ee <+14>: push %rbx
0x00000000057905ef <+15>: sub $0x128,%rsp
0x00000000057905f6 <+22>: mov %rdx,%r12
0x00000000057905f9 <+25>: mov %rdi,%rbx
0x00000000057905fc <+28>: mov %r12,%rdi
0x00000000057905ff <+31>: mov %rsi,%r15
0x0000000005790602 <+34>: xor %eax,%eax
0x0000000005790604 <+36>: mov %rcx,-0x38(%rbp)
0x0000000005790608 <+40>: mov 0x100(%r12),%rsi
0x0000000005790610 <+48>: movl $0xffffffff,-0x30(%rbp)
0x0000000005790617 <+55>: mov %rax,-0x48(%rbp)
0x000000000579061b <+59>: movl $0x0,-0x2c(%rbp)
0x0000000005790622 <+66>: mov %rax,-0x40(%rbp)
0x0000000005790626 <+70>: call 0x57909b0 <skgmhash>
...
--//可以大致猜测计算使用skgmhash函数.
3. 继续:
$ cat shm.bt
//uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:sskgmget
//uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:skgmlocate
//uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:skgmattach_primaryseg
uprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:skgmhash
/ $1 == 0 || pid == $1 /
{
// printf("[%s] %s pid=%d arg0=%016lx arg1=%016lx arg2=%016lx arg3=%016lx\n", strftime("%H:%M:%S", nsecs), func,pid,arg0, arg1,arg2,arg3);
// printf("[%s] %s pid=%d arg0=%s arg1=%s arg2=%s arg3=%s\n", strftime("%H:%M:%S", nsecs), func,pid,buf(arg0,64),buf(arg1,64),buf(arg2,64),buf(arg3,64));
// printf("[%s] %s pid=%d arg2=%s\n", strftime("%H:%M:%S", nsecs), func,pid,buf(arg2,52));
printf("[%s] %s pid=%d ptr0=%016lx hash_text=%s length=%d\n", strftime("%H:%M:%S", nsecs), func,pid,arg0, buf(arg0,arg1),arg1);
}
uretprobe:/u01/app/oracle/product/21.0.0/dbhome_1/bin/oracle:skgmhash
/ $1 == 0 || pid == $1 /
{
printf("[%s] %s pid=%d return hash_value=%016lx %lu\n", strftime("%H:%M:%S", nsecs), func,pid, retval, retval);
}
--//执行1次登录数据库操作,完成按ctrl+c退出.
# bpftrace shm.bt 0
Attached 2 probes
[10:00:50] skgmhash pid=4605 ptr0=00007ffe767ecb30 hash_text=/u01/app/oracle/product/21.0.0/dbhome_1book length=43
[10:00:50] skgmhash pid=4605 return hash_value=00000000afa94c20 2947107872
[10:00:50] skgmhash pid=4605 ptr0=00007ffe767ead30 hash_text=/u01/app/oracle/product/21.0.0/dbhome_1book.pga_#$ length=50
[10:00:50] skgmhash pid=4605 return hash_value=00000000a93a2388 2839159688
^C
--//验证我的判断,共享内存段key值的计算使用skgmhash函数,返回值也可以对上。至于使用什么hash算法,超出我的能力.
--//如果换成如下环境变量再次登录:
$ export ORACLE_HOME=//u01/app/oracle/product/21.0.0/dbhome_1/
--//注:两头都有斜线/
# bpftrace shm.bt 0
Attached 2 probes
[10:05:40] skgmhash pid=4690 ptr0=00007ffe1c4e1a30 hash_text=//u01/app/oracle/product/21.0.0/dbhome_1book length=44
[10:05:40] skgmhash pid=4690 return hash_value=00000000af89bb44 2945039172
[10:05:40] skgmhash pid=4690 ptr0=00007ffe1c4dfc30 hash_text=//u01/app/oracle/product/21.0.0/dbhome_1book.pga_#$ length=51
[10:05:40] skgmhash pid=4690 return hash_value=000000002ecfdd0c 785374476
[10:05:40] skgmhash pid=4690 ptr0=00007ffe1c4e0330 hash_text=//u01/app/oracle/product/21.0.0/dbhome_1book length=44
[10:05:40] skgmhash pid=4690 return hash_value=00000000af89bb44 2945039172
[10:05:40] skgmhash pid=4690 ptr0=00007ffe1c4d46e0 hash_text=//u01/app/oracle/product/21.0.0/dbhome_1book length=44
[10:05:40] skgmhash pid=4690 return hash_value=00000000af89bb44 2945039172
^C
--//注意看hash_text的值,长度变成44多了一个字符,这样自然连接空实例。
--//拼接的字符串dbhome_1 book之间没有/,以前测试也验证从11.2.0.4版本开始环境变量ORACLE_HOME结尾有没有/,不会受到这个因素的影响.
浙公网安备 33010602011771号