[20261007]oracle Semaphore Arrays Key值的冲突.txt
--//前面的测试已经验证了oracle Semaphore Arrays Key值使用sskgphpjw函数,通过跟踪它已经知道对应oracle Semaphore Arrays
--//Key值.如果存在冲突呢?测试看看oracle如何处理这些问题。
1.使用bpftrace监测结果如下:
# bpftrace sskgphpjw.bt 0
Attached 9 probes
sskgpwidtokeys Begin
sskgpbitspersem Begin
[14:57:00] sskgpbitspersem pid=3295 return hash_value=0x0000000e 14
sskgpbitspersem End
[14:57:00] sskgphpjw pid=3295 ptr=0x00007ffec4d01460 len=43 str=book/u01/app/oracle/product/21.0.0/dbhome_1
[14:57:00] sskgphpjw pid=3295 return hash_value=0x5507207c 1426530428
[14:57:00] sskgphpjw pid=3295 ptr=0x00007ffec4d01460 len=43 str=cppl0v120bqq0psbdmf0qspevdu032/1/10ecipnf`2
[14:57:00] sskgphpjw pid=3295 return hash_value=0x7e0edb60 2114902880
[14:57:00] sskgphpjw pid=3295 ptr=0x00007ffec4d01460 len=43 str=dqqm1w231crr1qtceng1rtqfwev14302021fdjqoga3
[14:57:00] sskgphpjw pid=3295 return hash_value=0x99eaaedc 2582294236
[14:57:00] sskgphpjw pid=3295 ptr=0x00007ffec4d01460 len=43 str=errn2x342dss2rudfoh2surgxfw25413132gekrphb4
[14:57:00] sskgphpjw pid=3295 return hash_value=0x32fcf5bc 855438780
sskgph2 Begin
[14:57:00] sskgph2 pid=3295 ptr=0x00007ffec4d01cb8 len=43 str=book/u01/app/oracle/product/21.0.0/dbhome_1
[14:57:00] sskgph2 pid=3295 return hash_value=0x9937c3fd 2570568701
sskgph2 End
sskgpwidtokeys End
2.建立测试脚本:
$ cat sem_test.c
#include <stdio.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <stdlib.h>
int main ()
{
int segment_id1,segment_id2,segment_id3,segment_id4;
int sem_id1, sem_id2, sem_id3, sem_id4;
printf("$ ipcs -m\n");
system("ipcs -m");
printf ("0.sem test Begin.\n");
getchar();
char* shared_memory;
struct shmid_ds shmbuffer;
int segment_size;
const int shared_segment_size = 2097152;
/* Allocate a Semaphore Arrays. */
sem_id1 = semget(0x5507207c, 10, IPC_CREAT|IPC_EXCL|0600) ;
sem_id2 = semget(0x7e0edb60, 10, IPC_CREAT|IPC_EXCL|0600) ;
sem_id3 = semget(0x99eaaedc, 10, IPC_CREAT|IPC_EXCL|0600) ;
sem_id4 = semget(0x32fcf5bc, 10, IPC_CREAT|IPC_EXCL|0600) ;
printf("$ ipsc -m -s\n");
system("ipcs -m -s");
printf ("1.semget done -- Allocate the Semaphore Arrays.\n\n");
getchar();
/* Detach a Semaphore Arrays. */
semctl (sem_id1, 0,IPC_RMID, NULL);
semctl (sem_id2, 0,IPC_RMID, NULL);
semctl (sem_id3, 0,IPC_RMID, NULL);
semctl (sem_id4, 0,IPC_RMID, NULL);
printf("$ ipsc -m -s\n");
system("ipcs -m -s");
printf ("2.semctl ipc_rmid done -- Detach the Semaphore Arrays.\n\n");
getchar();
printf("$ ipcs -m -s\n");
system("ipcs -m -s");
printf ("3.sem test End.\n");
return 0;
}
--//脚本写的非常简单粗暴,没有检测相应Semaphore Arrays是否存在.
$ gcc sem_test.c -o sem_test
3.测试:
$ ./sem_test
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0.sem test Begin.
$ ipsc -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
------ Semaphore Arrays --------
key semid owner perms nsems
0x5507207c 0 oracle 600 10
0x7e0edb60 1 oracle 600 10
0x99eaaedc 2 oracle 600 10
0x32fcf5bc 3 oracle 600 10
1.semget done -- Allocate the Semaphore Arrays.
--//开始启动数据库:
SYS@book> startup nomount
ORA-00600: internal error code, arguments: [kgerecoserr - no error], [], [], [], [], [], [], [], [], [], [], []
--//4个Semaphore Arrays已经占用,数据库启动失败,报ORA-00600: internal error code, arguments: [kgerecoserr - no error].
$ ./lookup.awk kgerecoserr
kgerecoserr : kernel generic error record operating system error
$ nm $(which oracle) | egrep "kgerecoserr"
0000000013181fd0 T kgerecoserr
--//尝试使用strace跟踪看看:
$ sudo -E strace -f -e semget,semctl -Ttt -y /u01/app/oracle/product/21.0.0/dbhome_1/bin/sqlplus -s -l sys/bookbook as sysdba <<<"startup nomount"
strace: Process 2887 attached
strace: Process 2888 attached
strace: Process 2889 attached
[pid 2888] 14:09:08.533418 +++ exited with 0 +++
[pid 2887] 14:09:08.533677 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=2888, si_uid=54321, si_status=0, si_utime=0, si_stime=0} ---
[pid 2889] 14:09:08.559731 +++ exited with 0 +++
strace: Process 2890 attached
strace: Process 2891 attached
[pid 2890] 14:09:08.562084 +++ exited with 0 +++
[pid 2887] 14:09:08.562361 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=2890, si_uid=54321, si_status=0, si_utime=0, si_stime=0} ---
[pid 2891] 14:09:08.580637 +++ exited with 0 +++
strace: Process 2892 attached
strace: Process 2893 attached
[pid 2892] 14:09:08.582702 +++ exited with 0 +++
[pid 2887] 14:09:08.582975 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=2892, si_uid=54321, si_status=0, si_utime=0, si_stime=0} ---
[pid 2893] 14:09:08.602020 +++ exited with 0 +++
[pid 2887] 14:09:08.757072 --- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0x57bcc33} ---
[pid 2887] 14:09:08.760784 semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|0600) = 16 <0.000182>
[pid 2887] 14:09:08.761200 semctl(16, 0, SETVAL, 0x7fffffffffff) = -1 ERANGE (Numerical result out of range) <0.000174>
[pid 2887] 14:09:08.761843 semctl(16, 0, SETVAL, 0x7fff7fffffff) = -1 ERANGE (Numerical result out of range) <0.000146>
[pid 2887] 14:09:08.762228 semctl(16, 0, SETVAL, 0x7fff3fffffff) = -1 ERANGE (Numerical result out of range) <0.000160>
[pid 2887] 14:09:08.762628 semctl(16, 0, SETVAL, 0x7fff1fffffff) = -1 ERANGE (Numerical result out of range) <0.000207>
[pid 2887] 14:09:08.763088 semctl(16, 0, SETVAL, 0x7fff0fffffff) = -1 ERANGE (Numerical result out of range) <0.000143>
[pid 2887] 14:09:08.763566 semctl(16, 0, SETVAL, 0x7fff07ffffff) = -1 ERANGE (Numerical result out of range) <0.000199>
[pid 2887] 14:09:08.764080 semctl(16, 0, SETVAL, 0x7fff03ffffff) = -1 ERANGE (Numerical result out of range) <0.000147>
[pid 2887] 14:09:08.764460 semctl(16, 0, SETVAL, 0x7fff01ffffff) = -1 ERANGE (Numerical result out of range) <0.000149>
[pid 2887] 14:09:08.764944 semctl(16, 0, SETVAL, 0x7fff00ffffff) = -1 ERANGE (Numerical result out of range) <0.000147>
[pid 2887] 14:09:08.765358 semctl(16, 0, SETVAL, 0x7fff007fffff) = -1 ERANGE (Numerical result out of range) <0.000146>
[pid 2887] 14:09:08.765825 semctl(16, 0, SETVAL, 0x7fff003fffff) = -1 ERANGE (Numerical result out of range) <0.000141>
[pid 2887] 14:09:08.766185 semctl(16, 0, SETVAL, 0x7fff001fffff) = -1 ERANGE (Numerical result out of range) <0.000141>
[pid 2887] 14:09:08.766570 semctl(16, 0, SETVAL, 0x7fff000fffff) = -1 ERANGE (Numerical result out of range) <0.000196>
[pid 2887] 14:09:08.767054 semctl(16, 0, SETVAL, 0x7fff0007ffff) = -1 ERANGE (Numerical result out of range) <0.000172>
[pid 2887] 14:09:08.767504 semctl(16, 0, SETVAL, 0x7fff0003ffff) = -1 ERANGE (Numerical result out of range) <0.000142>
[pid 2887] 14:09:08.767939 semctl(16, 0, SETVAL, 0x7fff0001ffff) = -1 ERANGE (Numerical result out of range) <0.000150>
[pid 2887] 14:09:08.768359 semctl(16, 0, SETVAL, 0x7fff0000ffff) = -1 ERANGE (Numerical result out of range) <0.000148>
[pid 2887] 14:09:08.768777 semctl(16, 0, SETVAL, 0x7fff00007fff) = 0 <0.000146>
[pid 2887] 14:09:08.769188 semctl(16, 0, IPC_RMID, NULL) = 0 <0.000155>
[pid 2887] 14:09:08.769703 semctl(0, 0, IPC_INFO, {semmap=1024000000, semmni=128, semmns=32000, semmnu=1024000000, semmsl=250, semopm=250, semume=500, semusz=20, semvmx=32767, semaem=32767}) = 3 <0.000166>
[pid 2887] 14:09:08.770177 semget(IPC_PRIVATE, 250, IPC_CREAT|IPC_EXCL|0666) = 17 <0.000152>
[pid 2887] 14:09:08.770579 semctl(17, 0, IPC_RMID, NULL) = 0 <0.000146>
[pid 2887] 14:09:08.771038 semctl(0, 0, IPC_INFO, {semmap=1024000000, semmni=128, semmns=32000, semmnu=1024000000, semmsl=250, semopm=250, semume=500, semusz=20, semvmx=32767, semaem=32767}) = 3 <0.000162>
[pid 2887] 14:09:08.771525 semget(IPC_PRIVATE, 250, IPC_CREAT|0660) = 18 <0.000204>
[pid 2887] 14:09:08.772100 semctl(18, 0, IPC_RMID, NULL) = 0 <0.000146>
[pid 2887] 14:09:08.772553 semget(0x5507207c, 0, 000) = 0 <0.000198>
[pid 2887] 14:09:08.773020 semctl(0, 0, GETVAL, NULL) = 0 <0.000158>
[pid 2887] 14:09:08.773434 semctl(0, 3, GETVAL, NULL) = 0 <0.000143>
[pid 2887] 14:09:08.773872 semctl(0, 2, GETVAL, NULL) = 0 <0.000146>
[pid 2887] 14:09:08.774267 semctl(0, 1, GETVAL, NULL) = 0 <0.000145>
[pid 2887] 14:09:08.774647 semget(0x7e0edb60, 0, 000) = 1 <0.000154>
[pid 2887] 14:09:08.775054 semctl(1, 0, GETVAL, NULL) = 0 <0.000145>
[pid 2887] 14:09:08.775503 semctl(1, 3, GETVAL, NULL) = 0 <0.000144>
[pid 2887] 14:09:08.775937 semctl(1, 2, GETVAL, NULL) = 0 <0.000094>
[pid 2887] 14:09:08.776143 semctl(1, 1, GETVAL, NULL) = 0 <0.000063>
[pid 2887] 14:09:08.776426 semget(0x99eaaedc, 0, 000) = 2 <0.000090>
[pid 2887] 14:09:08.776631 semctl(2, 0, GETVAL, NULL) = 0 <0.000062>
[pid 2887] 14:09:08.776886 semctl(2, 3, GETVAL, NULL) = 0 <0.000109>
[pid 2887] 14:09:08.777189 semctl(2, 2, GETVAL, NULL) = 0 <0.000097>
[pid 2887] 14:09:08.777410 semctl(2, 1, GETVAL, NULL) = 0 <0.000145>
[pid 2887] 14:09:08.777691 semget(0x32fcf5bc, 0, 000) = 3 <0.000107>
[pid 2887] 14:09:08.777915 semctl(3, 0, GETVAL, NULL) = 0 <0.000076>
[pid 2887] 14:09:08.778154 semctl(3, 3, GETVAL, NULL) = 0 <0.000088>
[pid 2887] 14:09:08.778351 semctl(3, 2, GETVAL, NULL) = 0 <0.000085>
[pid 2887] 14:09:08.778625 semctl(3, 1, GETVAL, NULL) = 0 <0.000069>
--//相关Semaphore Arrays key已经存在。
[pid 2887] 14:09:08.779381 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x2} ---
...
[pid 2887] 14:09:10.553014 --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=NULL} ---
[pid 2887] 14:09:13.063368 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x5ffffff4} ---
ORA-00600: internal error code, arguments: [kgerecoserr - no error], [], [], [], [], [], [], [], [], [], [], []
[pid 2886] 14:09:24.316572 +++ exited with 0 +++
14:09:24.327026 +++ exited with 0 +++
--//继续sem_test的执行:
$ ./sem_test
......
$ ipsc -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
------ Semaphore Arrays --------
key semid owner perms nsems
2.semctl ipc_rmid done -- Detach the Semaphore Arrays.
$ ipcs -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
------ Semaphore Arrays --------
key semid owner perms nsems
3.sem test End.
4.继续测试:
--//修改sem_test.c,注意如下2行:
//sem_id4 = semget(0x32fcf5bc, 10, IPC_CREAT|IPC_EXCL|0600) ;
//semctl (sem_id4, 0,IPC_RMID, NULL);
$ gcc sem_test.c -o sem_test
$ ./sem_test
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0.sem test Begin.
$ ipsc -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
------ Semaphore Arrays --------
key semid owner perms nsems
0x5507207c 33 oracle 600 10
0x7e0edb60 34 oracle 600 10
0x99eaaedc 35 oracle 600 10
1.semget done -- Allocate the Semaphore Arrays.
--//建立3个Semaphore Arrays key.
--//开始启动数据库:
$ rlsql
SQL*Plus: Release 21.0.0.0.0 - Production on Wed Oct 7 14:16:32 2026
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle. All rights reserved.
Connected to an idle instance.
SYS@book> startup nomount
ORACLE instance started.
Total System Global Area 1157625848 bytes
Fixed Size 9684984 bytes
Variable Size 704643072 bytes
Database Buffers 436207616 bytes
Redo Buffers 7090176 bytes
--//继续sem_test的执行:
$ ./sem_test
......
$ ipsc -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 28 oracle 600 10485760 34
0x00000000 29 oracle 600 1140850688 34
0x00000000 30 oracle 600 8388608 34
0xafa94c20 31 oracle 600 2097152 34
------ Semaphore Arrays --------
key semid owner perms nsems
0x32fcf5bc 39 oracle 600 250
2.semctl ipc_rmid done -- Detach the Semaphore Arrays.
$ ipcs -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 28 oracle 600 10485760 34
0x00000000 29 oracle 600 1140850688 34
0x00000000 30 oracle 600 8388608 34
0xafa94c20 31 oracle 600 2097152 34
------ Semaphore Arrays --------
key semid owner perms nsems
0x32fcf5bc 39 oracle 600 250
3.sem test End.
5.突然明白oracle为什么计算Semaphore Arrays key使用字符串的asc码+1的方式再计算:
--//前面Shared Memory Segments的key仅仅有1个共享内存段有key值,其他为0.而Semaphore Arrays的key不能,必须每个有值.
--//修改参数:
# sysctl -w "kernel.sem = 100 32000 250 12"
kernel.sem = 100 32000 250 12
--//关闭数据库重启实例:
$ ipcs -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 32 oracle 600 10485760 34
0x00000000 33 oracle 600 1140850688 34
0x00000000 34 oracle 600 8388608 34
0xafa94c20 35 oracle 600 2097152 34
------ Semaphore Arrays --------
key semid owner perms nsems
0x5507207c 43 oracle 600 100
0x5507207d 44 oracle 600 100
0x5507207e 45 oracle 600 100
--//建立3个Semaphore Arrays,key顺序+1.
6.继续测试:
--//修改sem_test.c文件:
--//注解semget,semctl所有行,增加如下:
sem_id1 = semget(0x5507207d, 10, IPC_CREAT|IPC_EXCL|0600) ;
semctl (sem_id1, 0,IPC_RMID, NULL);
--//关闭数据库后执行sem_test
$ ./sem_test
$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0.sem test Begin.
$ ipsc -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
------ Semaphore Arrays --------
key semid owner perms nsems
0x5507207d 59 oracle 600 10
1.semget done -- Allocate the Semaphore Arrays.
--//开始启动数据库:
SYS@book> startup nomount
ORACLE instance started.
Total System Global Area 1157625848 bytes
Fixed Size 9684984 bytes
Variable Size 704643072 bytes
Database Buffers 436207616 bytes
Redo Buffers 7090176 bytes
--//继续sem_test的执行:
$ ./sem_test
......
$ ipsc -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 44 oracle 600 10485760 34
0x00000000 45 oracle 600 1140850688 34
0x00000000 46 oracle 600 8388608 34
0xafa94c20 47 oracle 600 2097152 34
------ Semaphore Arrays --------
key semid owner perms nsems
0x5507207e 32768 oracle 600 100
0x5507207f 32769 oracle 600 100
0x5507207c 63 oracle 600 100
--//注意看没有Semaphore Arrays=0x5507207d值.
--//还可以semid的变化,semid=63,突然跳到32768.估计到semid=64时,直接调到32768.
2.semctl ipc_rmid done -- Detach the Semaphore Arrays.
$ ipcs -m -s
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 44 oracle 600 10485760 34
0x00000000 45 oracle 600 1140850688 34
0x00000000 46 oracle 600 8388608 34
0xafa94c20 47 oracle 600 2097152 34
------ Semaphore Arrays --------
key semid owner perms nsems
0x5507207e 32768 oracle 600 100
0x5507207f 32769 oracle 600 100
0x5507207c 63 oracle 600 100
3.sem test End.
4.小结:
--//这类冲突的错误发生概率很低的,除非数据库异常崩溃,相关信息没有清除。
--//顺便再提一下Semaphore Arrays key的计算可以直接调用skgmhash函数。参与运算的字符串ORACLE_SID+ORACLE_HOME,例子:
(gdb) p /x (long int) skgmhash("book/u01/app/oracle/product/21.0.0/dbhome_1",43)
$2 = 0x5507207c
--//生成字符串的脚本可以参考链接:
--//[20261002]验证sskgphpjw函数参与运算的字符串是否存在规律.txt
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3184557/ ,如需转载,请注明出处,否则将追究法律责任。