ITPub博客

首页 > 数据库 > Oracle > [20260503]11g下ipcs -m shmid值.txt

[20260503]11g下ipcs -m shmid值.txt

原创 Oracle 作者:lfree 时间:2026-05-06 20:55:16 0 删除 编辑

[20260503]11g下ipcs -m shmid值.txt

--//上午在探究 21c下测试pre_page_sga=false时遇到的疑问,发现ipcs -m显示中nattch列显示的信息与11g遇到的情况不同,问题没有
--//探究出来,无意中发现shmid的规律。在11g下验证看看。

--//21c 下得到的规律如下:
--//1. 第1共享内存段的shmid值等于2^17*N,N=0开始.
--//2. 以后共享内存段的shmid值呈等差数列,相差32769.

--//在11g下验证看看。

1.环境:
# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

SYS@book> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

2.测试:
--//重新打开服务器.
--//第1次启动数据库。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 32768      oracle     640        12582912   22
0x00000000 65537      oracle     640        792723456  22
0x56c108b0 98306      oracle     640        2097152    22

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00008000 32768
0x00010001 65537 32769
0x00018002 98306 32769
--//说明:第1列shmid的16进制,第2列shmod的10进制值,第3列是shmid上下的差值。

--//第2次启动数据库。注仅仅启动到nomount,不影响测试结果。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 163840     oracle     640        12582912   17
0x00000000 196609     oracle     640        792723456  17
0x56c108b0 229378     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00028000 163840
0x00030001 196609 32769
0x00038002 229378 32769

--//第3次启动数据库。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 294912     oracle     640        12582912   17
0x00000000 327681     oracle     640        792723456  17
0x56c108b0 360450     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00048000 294912
0x00050001 327681 32769
0x00058002 360450 32769

--//第4次启动数据库。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 425984     oracle     640        12582912   17
0x00000000 458753     oracle     640        792723456  17
0x56c108b0 491522     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00068000 425984
0x00070001 458753 32769
0x00078002 491522 32769

--//第4次启动数据库。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 557056     oracle     640        12582912   17
0x00000000 589825     oracle     640        792723456  17
0x56c108b0 622594     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00088000 557056
0x00090001 589825 32769
0x00098002 622594 32769

--//第5次启动数据库。
# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 557056     oracle     640        12582912   17
0x00000000 589825     oracle     640        792723456  17
0x56c108b0 622594     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00088000 557056
0x00090001 589825 32769
0x00098002 622594 32769

3.阶段性分析:
--//共享内存段的shmid值呈等差数列,相差32769.
--//如果看16进制值的最后3位,可以看出属于第几个共享内存段,这也是选择相差32769=0x8001的原因,也就是16进制的后3位。
--//每次重启的第1个共享内存段shmid值的与21c的规律不同,继续探究11g的情况:
# echo 32768 163840 294912 425984 557056| tr " " "\n"| xargs -IQ factor Q
32768 : 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
163840: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5
294912: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3
425984: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 13
557056: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 17

# factor 32768 | grep -o " 2"|wc
     15      15      45
--//前面15个2.
--//相乘的因子是1,5,9,13,17,等差数列4.
--//很容易猜测出来shmid的计算公式: 2^15*((N-1)*4+1) , N=1开始计算。

--//验证第6次启动数据库的情况:
--//2^15*(5*4+1) = 688128

# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 688128     oracle     640        12582912   17
0x00000000 720897     oracle     640        792723456  17
0x56c108b0 753666     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x000a8000 688128
0x000b0001 720897 32769
0x000b8002 753666 32769
--//688128 测试与预测的结果完成一致。
--//当我回看21c下测试时,发现计算与11g公式不同,对比发现21c测试时4个共享内存段,而11g测试时3个共享内存段.
--//修改内核参数kernel.shmmax = 792723456/2 = 396361728, 修改200M看看.

4.设置kernel.shmmax = 200*2*1024*1024 = 419430400
--//修改 /etc/sysctl.d/98-oracle.conf文件 kernel.shmmax=419430400.
--//执行:
--//sysctp -p /etc/sysctl.d/98-oracle.conf
--//直接贴出测试结果,注意要重启机器再测试,每次生成的shmid不同。

--//第1次启动数据库。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 32768      oracle     640        12582912   17
0x00000000 65537      oracle     640        419430400  17
0x00000000 98306      oracle     640        373293056  17
0x56c108b0 131075     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00008000 32768
0x00010001 65537 32769
0x00018002 98306 32769
0x00020003 131075 32769

--//第2次启动数据库。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 196608     oracle     640        12582912   17
0x00000000 229377     oracle     640        419430400  17
0x00000000 262146     oracle     640        373293056  17
0x56c108b0 294915     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00030000 196608
0x00038001 229377 32769
0x00040002 262146 32769
0x00048003 294915 32769

--//第3次启动数据库。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 360448     oracle     640        12582912   17
0x00000000 393217     oracle     640        419430400  17
0x00000000 425986     oracle     640        373293056  17
0x56c108b0 458755     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00058000 360448
0x00060001 393217 32769
0x00068002 425986 32769
0x00070003 458755 32769

--//第4次启动数据库。
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 524288     oracle     640        12582912   17
0x00000000 557057     oracle     640        419430400  17
0x00000000 589826     oracle     640        373293056  17
0x56c108b0 622595     oracle     640        2097152    17

# ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
0x00080000 524288
0x00088001 557057 32769
0x00090002 589826 32769
0x00098003 622595 32769

--//分析:
$ echo 32768 196608 360448  524288 | tr " " "\n"| xargs -IQ factor Q
32768 : 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
196608: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3
360448: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 11
524288: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

# factor 32768 | grep -o " 2"|wc
     15      15      45
--//前面15个2.
--//相乘的因子是1,6,11,16.
--//很容易猜测出来当共享内存段=4时的shmid的计算公式: 2^15*((N-1)*5+1) , N=1开始计算。
--//概况总结,可以猜测11g的shmid计算公式如下:
2^15*((N-1)*(S+1)+1)
--//注: N=0开始计算,S=共享内存段数量.

--//验证第5次启动数据库的情况:
--//2^15*((5-1)*(4+1)+1)  = 688128

--//第5次启动数据库。
# ipcs -m ;  ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 688128     oracle     640        12582912   17
0x00000000 720897     oracle     640        419430400  17
0x00000000 753666     oracle     640        373293056  17
0x56c108b0 786435     oracle     640        2097152    17

0x000a8000 688128
0x000b0001 720897 32769
0x000b8002 753666 32769
0x000c0003 786435 32769
--//688128 测试与预测的结果完成一致。
--//688128: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 7

--//第6次启动数据库。
--// 2^15*((6-1)*(4+1)+1)  = 851968
# ipcs -m ;  ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 851968     oracle     640        12582912   17
0x00000000 884737     oracle     640        419430400  17
0x00000000 917506     oracle     640        373293056  17
0x56c108b0 950275     oracle     640        2097152    17

0x000d0000 851968
0x000d8001 884737 32769
0x000e0002 917506 32769
0x000e8003 950275 32769
--//851968 测试与预测的结果完成一致。
--//851968: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 13

5.继续:
--//修改内核参数kernel.shmmax = 792723456/3  = 264241152,264241152/2/1024/1024 = 126
--//128*2*1024*1024 = 268435456
--//修改 /etc/sysctl.d/98-oracle.conf文件 kernel.shmmax=268435456,这样分成5个共享内存段.
# sysctl -p  /etc/sysctl.d/98-oracle.conf
fs.file-max = 6815744
kernel.sem = 250 32000 100 128
kernel.shmmni = 4096
kernel.shmall = 1073741824
kernel.shmmax = 268435456
~~~~~~~~~~~~~~~~~~~~~~~~~~~
kernel.panic_on_oops = 1
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.default.rp_filter = 2
fs.aio-max-nr = 1048576
net.ipv4.ip_local_port_range = 9000 65500
vm.nr_hugepages = 385
vm.nr_overcommit_hugepages = 50

--//第7次启动数据库,注意接着上面的测试进行,注意S=5:
--// 2^15*((N-1)*(S+1)+1)  = 2^15*((7-1)*(5+1)+1) = 1212416

# ipcs -m ;  ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 1015808    oracle     640        12582912   17
0x00000000 1048577    oracle     640        268435456  17
0x00000000 1081346    oracle     640        268435456  17
0x00000000 1114115    oracle     640        255852544  17
0x56c108b0 1146884    oracle     640        2097152    17

0x000f8000 1015808
0x00100001 1048577 32769
0x00108002 1081346 32769
0x00110003 1114115 32769
0x00118004 1146884 32769
--//1015808,计算结果不对.

# factor 1015808
1015808: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 31
--//相乘因子是31,换一句话讲还是按照S=4来计算.

--//第8次启动数据库,注意接着上面的测试进行,注意S=5:
# ipcs -m ;  ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 1212416    oracle     640        12582912   17
0x00000000 1245185    oracle     640        268435456  17
0x00000000 1277954    oracle     640        268435456  17
0x00000000 1310723    oracle     640        255852544  17
0x56c108b0 1343492    oracle     640        2097152    17

0x00128000 1212416
0x00130001 1245185 32769
0x00138002 1277954 32769
0x00140003 1310723 32769
0x00148004 1343492 32769
--//注意这次与第7次启动数据库的计算shmid结果一致.
# factor 1212416
1212416: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 37

--//我的理解,按照前面的推理 shmid值 = 2^15 * ((N-1)*(S+1)+1),开始第1次按照1相乘,不管需要多少共享内存段.
--//启动第1次以后才知道需要多少共享内存段,以后按照是2^15*(S+1)增加(S=4不变的情况下).
--//第7次启动数据库,还是按照S=4来计算.启动完成才知道S=5,这样再原来基础上加S+1=6.这样31+6=37.
--//我的测试不过正好巧合了等于2^15*37.

--//疑问:oracle如何知道前次使用多少共享内存段,难道服务器保存此信息.

--//如果我的推理正确,下次启动数据库,shmid =  2^15*(37+5+1 ) = 1409024.
--//第9次启动数据库,注意接着上面的测试进行,注意S=5:

# ipcs -m ;  ipcs -m | awk '/[0=9]/{print $2}'| awk 'NR==1{printf "0x%08x %d\n",$1,$1;a=$1} NR>1{printf "0x%08x %d %d\n", $1,$1,$1-a;a=$1}'
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000000 1409024    oracle     640        12582912   17
0x00000000 1441793    oracle     640        268435456  17
0x00000000 1474562    oracle     640        268435456  17
0x00000000 1507331    oracle     640        255852544  17
0x56c108b0 1540100    oracle     640        2097152    17

0x00158000 1409024
0x00160001 1441793 32769
0x00168002 1474562 32769
0x00170003 1507331 32769
0x00178004 1540100 32769
--//1409024,完全正确.
--//1409024: 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 43

--//第1共享内存段的shmid值计算公式:
2^15 * (B+S+1)

--//B:前次相乘因子 开始0, S=前次启动需要共享内存段数量. 开始0.
--//这样就很好S=4后变成S=5的测试情况.
1 6 11 16 21 26 --//S=4 +5
31 --//S=5 +5
37 --//S=5 +6
43 --//S=5 +6

6.总结:
--//11g下得到的规律如下:
--//1.第1共享内存段的shmid值等于2^15 * ((N-1)*(S+1)+1)  N=1 开始计算,S=共享内存段数量. 前提S不变的情况下(单实例).
--//  比较正确的公式是 2^15 * (B+S+1)          B:前次相乘因子 开始0, S=前次启动需要共享内存段数量. 开始0.
--//2.以后共享内存段的shmid值呈等差数列,相差32769.
--//3.如果看16进制值的最后3位,可以看出属于第几个共享内存段,这也是选择相差32769=0x8001的原因,也就是16进制的后3位。

--//预测这些结果完全没有意思,权当作学习oracle的一个小小乐趣。
--//另外我没有测试多实例的情况,应该按照2^15 * (B+S+1)公式计算.
--//注意收尾还原kernel.shmmax 值.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3117209/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7969349