UNIX
and Linux Shared Memory and Oracle
The UNIX and LINUX operating systems allocate memory based on
an interprocess communication model (IPC) to manage memory
segments for Oracle database environments.
To obtain details on shared memory for UNIX and LINUX, make use
of the ipcs command. Details on syntax are illustrated below from
within the UNIX and LINUX man pages:
NAME
ipcs : provide information on ipc facilities
SYNOPSIS
ipcs [ -asmq ] [ -tclup ]
ipcs [ -smq ] -i id
ipcs -h
DESCRIPTION
ipcs provides information on the ipc facilities for which the
calling process has read access
The -i option allows a specific resource ID to be specified.
Only information on this id will be printed.
Resources may be specified as follows:
-m shared memory segments
-q message queues
Determine what Oracle database has a
semaphore set
As we have noted, when an Oracle database
hangs, you may have leftover background processes, held RAM memory
segment and held semaphore sets. When you have multiple instances on
a UNIX server and need to release a semaphore set for an Oracle
database, you must first determine which semaphore set belongs to
your crippled instance.
Unfortunately, you cannot tell with the ipcs
'sa command which semaphore set belongs to each Oracle database.
Here is the Oracle procedure for determining the semaphore set
number for an individual Oracle database so that you can remove the
semaphores with the ipcs command.
root>
svrmgrl
Oracle
Server Manager Release 2.3.2.0.0 - Production
Copyright
(c) Oracle Corporation 1994, 1995. All rights reserved.
Oracle7
Server Release 7.3.2.3.0 - Production Release
With the distributed and replication options
PL/SQL Release 2.3.2.3.0 - Production
SVRMGR>
connect internal
Connected.
SVRMGR> oradebug ipc
-------------- Shared memory --------------
Seg Id Address Size
24064 c1739000 28975104
Total: # of segments = 1, size = 28975104
-------------- Semaphores ----------------
Total number of semaphores = 400
Number of semaphores per set = 400
Number of semaphore sets = 1
Semaphore identifiers:
In Oracle8i and beyond, you can use SQL*Plus to perform the same
function.
root> sqlplus /nologin
SQL*Plus:
Release 3.3.2.0.0 - Production on Mon Sep 10 17:27:04 2001
Copyright
(c) Oracle Corporation 1979, 1994. All rights reserved.
SQL>
connect system/manager as sysdba;
Connected.
Since we cannot get the semaphore set number
for the crippled database, we must determine the semaphore set using
the process of elimination. We issues the above commands for
each live database on the server, and the un-claimed semaphore set
will belong to the crippled instance.
Once identified, you can use the following
procedure for removing the semaphore set.
Removing a semaphore set for Oracle
We start by issuing the ipcs 'sb command to
display details of the semaphore set.
root> ipcs
-sb|grep oracle
s 67 0x00000000 --ra-r-----
oracle dba 400
s 223 0x00000000 --ra-r-----
oracle dba 400
s 334 0x00000000 --ra-r-----
oracle dba 300
Now, we can remove the semaphores from the
locked-up database. In this example, we assume that set 223 is the
one for the crippled database.
root>
ipcrm -s 223
Now we can confirm that the semaphores are
deleted.
root> ipcs
-sb|grep oracle
s
67 0x00000000 --ra-r----- oracle
dba 400
s 334 0x00000000 --ra-r-----
oracle dba 300
=========================================================
Rampant author Laurent Schneider shows how to remove shared
mrmory segments on a server with multiple databases:
STEP 1: First, list the ipc process
$
ipcs
IPC
status from /dev/mem as of Mon Nov 14 11:28:58 CET 2015
T ID
KEY MODE
OWNER GROUP
Message Queues:
q
0 0x4107001c -Rrw-rw---- root
printq
Shared Memory:
m
0 0x7800006f --rw-rw-rw- itmuser1 itmusers
m
1 0x78000070 --rw-rw-rw- itmuser1 itmusers
m 5242882 0x41d2ba80
--rw-r----- oracle dba
m 99614723 0xb0d4d164 --rw-rw----
oracle dba
m 12582917 0xb84cbc28 --rw-rw----
oracle dba
m 79691782 0x1058873f --rw-------
oracle dba
m 638582792 0x78000382 --rw-rw-rw-
root system
m 218103817 0x780003b7 --rw-rw-rw-
root system
Semaphores:
s
1 0x6202c477 --ra-r--r-- root
system
s
6291461 0x0102c2d8 --ra------- root
system
s
6 0xa100004b --ra-ra-ra- root
system
STEP 2: Get a list of the running databases
$ ps
-ef | grep pmon | grep -v grep
oracle 483334
1 1 Aug 16 - 6:46 ora_pmon_db03
oracle 1253476
1 0 Oct 31 - 2:00 ora_pmon_db01
oracle 2298042
1 0 Sep 05 - 11:07 ora_pmon_db02
STEP 3: Then, for each database,
get the ipc information
$ export
ORACLE_SID=db01
$ sqlplus / as sysdba
SQL> oradebug
setmypid
Statement processed.
SQL> oradebug ipc
Information written to trace file.
SQL> oradebug tracefile_name
/u01/app/oracle/admin/db01/udump/db01_ora_2625574.trc
$ awk '/Shared
Memory:/{getline;getline;print}'
/u01/app/oracle/admin/db01/udump/db01_ora_2625574.trc
5242882
0x41d2ba80
$ export ORACLE_SID=db02
$ sqlplus / as sysdba
SQL> oradebug setmypid
Statement processed.
SQL> oradebug ipc
Information written to trace file.
SQL> oradebug tracefile_name
/u01/app/oracle/diag/rdbms/db02a/db02/trace/db02_ora_2441408.trc
$ awk '/Shared
Memory:/{getline;getline;print}'
/u01/app/oracle/diag/rdbms/db02a/db02/trace/db02_ora_2441408.trc
99614723 0xb0d4d164
$ export ORACLE_SID=db03
$ sqlplus / as sysdba
SQL> oradebug setmypid
Statement processed.
SQL> oradebug
ipc
Information written to trace file.
SQL> oradebug
tracefile_name
/u01/app/oracle/diag/rdbms/db03b/db03/trace/db03_ora_2617416.trc
$ awk '/Shared
Memory:/{getline;getline;print}'
/u01/app/oracle/diag/rdbms/db03b/db03/trace/db03_ora_2617416.trc
12582917 0xb84cbc28
We compare this list with the first list, and if you are
absolutely sure to do what you are doing, remove the oracle
segments that are not assigned to any database instance with
ipcrm. If possible try first to figure out where they come from
and do a shutdown abort of the not-correctly-stopped database.
Ok, with ipcrm
$ ipcrm -m
79691782
I removed the segment that apparently
does not relate to any running instance