[20260917]oracle共享内存段Key值的冲突.txt

[20260917]oracle共享内存段Key值的冲突.txt

--//接着上午的测试,如果启动数据库前共享内存段的key已经存在呢?先尝试写代码建立1个共享内存段key=0xafa94c20。
--//首先自己不熟悉这类编程,代码来自别人的例子:

$ cat shmtest.c
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <stdlib.h>

int main ()
{
  int segment_id;
  char* shared_memory;
  struct shmid_ds shmbuffer;
  int segment_size;
  const int shared_segment_size = 2097152;

  /* Allocate a shared memory segment.  */
  //segment_id = shmget (IPC_PRIVATE, shared_segment_size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
  segment_id = shmget (0xafa94c20, shared_segment_size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
  printf ("1.shmget done -- Allocate a shared memory segment.\n");
  system("ipcs -m");
  getchar();

  /* Attach the shared memory segment.  */
  shared_memory = (char*) shmat (segment_id, 0, 0);
  printf ("shared memory attached at address %p\n", shared_memory);
  printf ("2.shmat done --  Attach the shared memory segment.\n");
  system("ipcs -m");
  getchar();

  /* Determine the segment's size. */
  shmctl (segment_id, IPC_STAT, &shmbuffer);
  segment_size = shmbuffer.shm_segsz;
  printf ("segment size: %d -- Determine the segment's size.\n", segment_size);
  printf ("3.shmctl done\n");
  system("ipcs -m");
  getchar();

  /* Write a string to the shared memory segment.  */
  //sprintf (shared_memory, "Hello, world.");
  //getchar();
  /* Detach the shared memory segment.  */
  //shmdt (shared_memory);
  //printf ("4.shmdt done -- Detach the shared memory segment.\n");
  //system("ipcs -m");
  //getchar();

  /* Deallocate the shared memory segment.  */
  shmctl (segment_id, IPC_RMID, 0);
  printf ("5.shmctl ipc_rmid done -- Deallocate the shared memory segment.\n");
  system("ipcs -m");
  getchar();

  return 0;
}

--//编译通过。
$ gcc shmtest.c -o shmtest

2.测试前关闭数据库.

$ ./shmtest
1.shmget done -- Allocate a shared memory segment.

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 20         oracle     600        2097152    0
--//建立1个共享内存段.key=0xafa94c20.

$ rlsql
SQL*Plus: Release 21.0.0.0.0 - Production on Thu Sep 17 16:56:27 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

$ ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 20         oracle     600        2097152    0
0x00000000 21         oracle     600        10485760   34
0x00000000 22         oracle     600        1140850688 34
0x00000000 23         oracle     600        8388608    34
0xafa94c21 24         oracle     600        2097152    34
--//数据库建立的共享内存段的key=0xafa94c21,说明冲突时选择+1,继续尝试,估计尝试4次.

$ strace -Ttt -f -e ipc sqlplus -s -l / as sysdba <<<"host sleep 1^Jquit"
strace: Process 6154 attached
[pid  6154] 16:57:55.575898 shmget(0xafa94c20, 0, 000) = 20 <0.000191>
[pid  6154] 16:57:55.576728 shmctl(20, IPC_STAT, {shm_perm={uid=54321, gid=54321, mode=0600, key=2947107872, cuid=54321, cgid=54321}, shm_segsz=2097152, shm_cpid=6005, shm_lpid=6137, shm_nattch=0, shm_atime=1789635396, shm_dtime=1789635396, shm_ctime=1789635348}) = 0 <0.000064>
[pid  6154] 16:57:55.577414 shmat(20, NULL, 0) = 0x7f4b41200000 <0.000129>
[pid  6154] 16:57:55.578089 shmdt(0x7f4b41200000) = 0 <0.000119>
[pid  6154] 16:57:55.578708 shmget(0xafa94c21, 0, 000) = 24 <0.000070>
[pid  6154] 16:57:55.579273 shmctl(24, IPC_STAT, {shm_perm={uid=54321, gid=54321, mode=0600, key=2947107873, cuid=54321, cgid=54321}, shm_segsz=2097152, shm_cpid=6013, shm_lpid=6137, shm_nattch=34, shm_atime=1789635396, shm_dtime=1789635396, shm_ctime=1789635392}) = 0 <0.000067>
[pid  6154] 16:57:55.579945 shmat(24, NULL, 0) = 0x7f4b41200000 <0.000109>
[pid  6154] 16:57:55.580600 shmdt(0x7f4b41200000) = 0 <0.000135>
[pid  6154] 16:57:55.581210 shmget(0xafa94c22, 0, 000) = -1 ENOENT (No such file or directory) <0.000053>
[pid  6154] 16:57:55.581830 shmget(0xafa94c23, 0, 000) = -1 ENOENT (No such file or directory) <0.000142>
[pid  6154] 16:57:55.582460 shmat(24, 0xa6000000, 0) = 0xa6000000 <0.000105>
[pid  6154] 16:57:55.583123 shmat(22, 0x61000000, 0) = 0x61000000 <0.000141>
[pid  6154] 16:57:55.583706 shmat(23, 0xa5000000, 0) = 0xa5000000 <0.000113>
[pid  6154] 16:57:55.584410 shmat(21, 0x60000000, 0) = 0x60000000 <0.000073>
[pid  6154] 16:57:55.616177 shmget(0xa93a2388, 0, 000) = -1 ENOENT (No such file or directory) <0.000050>
[pid  6154] 16:57:55.616808 shmget(0xa93a2389, 0, 000) = -1 ENOENT (No such file or directory) <0.000056>
[pid  6154] 16:57:55.617270 shmget(0xa93a238a, 0, 000) = -1 ENOENT (No such file or directory) <0.000046>
[pid  6154] 16:57:55.617765 shmget(0xa93a238b, 0, 000) = -1 ENOENT (No such file or directory) <0.000054>
[pid  6154] 16:57:55.640502 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x2} ---
strace: Process 6155 attached
[pid  6155] 16:57:57.106159 +++ exited with 0 +++
[pid  6153] 16:57:57.106952 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=6155, si_uid=54321, si_status=0, si_utime=0, si_stime=0} ---

[pid  6153] 16:57:57.125489 +++ exited with 0 +++
16:57:57.141683 shmdt(0x61000000)       = 0 <0.000303>
16:57:57.143350 shmdt(0xa5000000)       = 0 <0.000163>
16:57:57.144430 shmdt(0x60000000)       = 0 <0.000343>
16:57:57.145675 shmdt(0xa6000000)       = 0 <0.000145>
16:57:57.161608 +++ exited with 0 +++
--//也就是尝试4次,有点不理解oracle的操作,既然尝试成功,读取里面的信息正确,为什么还继续后面的shmget的尝试呢?

3.继续:
--//关闭数据库.修改shmtest.c脚本,加入key=0xafa94c20,0xafa94c21,0xafa94c22,0xafa94c23.
--//不要在生产系统做这类测试!!

$ ./shmtest
1.shmget done -- Allocate a shared memory segment.

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0
0xafa94c23 28         oracle     600        2097152    0

 $ rlsql
SQL*Plus: Release 21.0.0.0.0 - Production on Thu Sep 17 17:02:58 2026
Version 21.3.0.0.0
Copyright (c) 1982, 2021, Oracle.  All rights reserved.
Connected to an idle instance.
SYS@book> startup nomount
ORA-00600: internal error code, arguments: [SKGMHASH], [1], [18446744072361692192], [0], [0], [], [], [], [], [], [], []
--//18446744072361692192 = 0xffffffffafa94c20

$ ./shmtest
1.shmget done -- Allocate a shared memory segment.

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0
0xafa94c23 28         oracle     600        2097152    0


shared memory attached at address 0x7f81c7600000
2.shmat done --  Attach the shared memory segment.

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0
0xafa94c23 28         oracle     600        2097152    1
0x00000000 29         oracle     600        10485760   1
0x00000000 30         oracle     600        1140850688 1
0x00000000 31         oracle     600        8388608    1


segment size: 2097152 -- Determine the segment's size.
3.shmctl done

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0
0xafa94c23 28         oracle     600        2097152    1
0x00000000 29         oracle     600        10485760   1
0x00000000 30         oracle     600        1140850688 1
0x00000000 31         oracle     600        8388608    1

5.shmctl ipc_rmid done -- Deallocate the shared memory segment.
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0
0x00000000 28         oracle     600        2097152    1          dest
0x00000000 29         oracle     600        10485760   1
0x00000000 30         oracle     600        1140850688 1
0x00000000 31         oracle     600        8388608    1
--//shmtest.c代码没写好,仅仅删除key=0xafa94c23.有点不理解的是代码执行
--//shmctl (segment_id, IPC_RMID, 0);完成后,ipcs -m依旧能查询到,也许采用shmdt才对。

$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0
0x00000000 29         oracle     600        10485760   1
0x00000000 30         oracle     600        1140850688 1
0x00000000 31         oracle     600        8388608    1
--//shmtest执行完成,shmid=28就不存在了。
--//这种情况其他oracle共享内存段已经建立,也就是内存没有释放.

$ seq 29 31 | xargs -IQ ipcrm shm Q
resource(s) deleted
resource(s) deleted
resource(s) deleted
--//执行前退出sqlplus的连接,不然ipcs -m依旧查询的到。

$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0

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

$ ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0
0x00000000 32         oracle     600        10485760   34
0x00000000 33         oracle     600        1140850688 34
0x00000000 34         oracle     600        8388608    34
0xafa94c23 35         oracle     600        2097152    34
--//数据库共享内存段key=0xafa94c23。

4.收尾:

SYS@book> shutdown immediate
ORA-01507: database not mounted
ORACLE instance shut down.

$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0xafa94c20 25         oracle     600        2097152    0
0xafa94c21 26         oracle     600        2097152    0
0xafa94c22 27         oracle     600        2097152    0

$ seq 25 27 | xargs -IQ ipcrm shm Q
resource(s) deleted
resource(s) deleted
resource(s) deleted



posted @ 2026-09-21 21:24  lfree  阅读(8)  评论(0)    收藏  举报