Understanding Shared Memory and Semaphores

by Nidhi Jain

Shared memory and semaphores are two important resources for an Oracle instance on Unix. An instance cannot start if it is unable to allocate what it needs.

DEFINATIONS

Shared memory is exactly that - a memory region that can shared between different processes. Oracle uses shared memory for implementing the SGA, which needs to be visible to all database sessions.

Semaphores can be thought of as flags (hence their name, semaphores). They are either on or off. A process can turn on the flag or turn it off. If the flag is already on, processes who try to turn on the flag will sleep until the flag is off. Upon awakening, the process will reattempt to turn the flag on, possibly suceeding or possibly sleeping again. Such behaviour allows semaphores to be used in implementing a post-wait driver - a system where processes can wait for events (i.e. wait on turning on a semphore) and post events (i.e. turning of a semaphore). This mechanism is used by Oracle to maintain concurrency control over the SGA, since it is writeable by all processes attached.

ALLOCATION IN SIMPLE TERMS

Shared memory required by the Oracle Instance : On instance startup, the first things that the instance does is: -Read the "init.ora" -Start the background processes -Allocate the shared memory and semphores required The size of the SGA will be calculated from various "init.ora" parameters. This will be the amount of shared memory required. The SGA is broken into 4 sections - the fixed portion, which is constant in size, the variable portion, which varies in size depending on "init.ora" parameters, the redo block buffer, which has its size controlled by log_buffers, and the db block buffer, which has its size controlled by db_block_buffers. The size of the SGA is the sum of the sizes of the 4 portions. There is unfortunately no simple ormula for determining the size of the variable portion.

Generally, the shared pool dominates all other parts of the variable portion, so as a rule of thumb, one can estimate the size as the value of shared_pool_size.

The number of semphores required is much simpler to determine.
Oracle will need exactly as many semaphores as the value of the processes "init.ora" parameter.

SHARED MEMORY ALLOCATION

1. One-segment

2. Contigous multi-segment

3. Non-contigous multi-segment

When attempting to allocate and attach shared memory for the SGA, it will attempt each one, in the above order, until one succeeds or raises an ORA error. On other, non-fatal, errors, Oracle simply cleans up and tries again using the next memory model. The entire SGA must fit into shared memory, so the total amount of shared memory allocated under any model will be equal of the size of the SGA(SGASIZE).

1. One-segment:- The one-segment model is the simplest and first model tried. In this model, the SGA resides in only one shared memory segment. Oracle attempts to allocate and attach one shared memory segement of size equal to total size of the SGA. However, if the SGASIZE is larger than the configured SHMMAX, this will obviously fail. In this case, the SGA will need to be placed in multiple shared memory segments, and Oracle proceeds to the next memory model for the SGA.

With multiple segments there are two possibilities. The segments can be attached contiguously, so that it appears to be one large shared memory segment, or non-contiguously, with gaps between the segments.

2. Contigous multi-segment - In the contiguous segment model, Oracle simply divides the SGA into SGASIZE/SHMMAX (rounded down) segments of size SHMMAX plus another segment of size SGASIZE modulo SHMMAX

3. Non- contigous multi-segment : Once the number of segments and their sizes is determined, Oracle then allocates and attaches the segments one at a time; first the fixed and variable portion segment(s), then the redo block buffer segment(s), then the db block buffer segment(s). They will be attached non-contiguously,
At this point, we have either attached the entire SGA or returned an ORA error. The total size of segments attached is exactly SGASIZE; no space is wasted. Once Oracle has the shared memory attached, Oracle proceeds to allocating the semaphores it requires.

Recommended values of kernel parameters for Shared memory in
Oracle 8i

SHMMAX= max value of shared memory segment = .5 * size of
physical memory

SHMMIN= min size of shared memory segment=1

SHMMNI= max number of shared memory identifiers on system = 100

SHMSEG= max number of shared memory segments per process = 10

max Sga that can be created by the one segment model is SHMMAX*SHMSEG

You can display the current kernel parameters by doing a "sysdef -i"

SEMAPHORE ALLOCATION

Oracle just needs to allocate a number of semaphores equal to the processes parameter in "init.ora".

SEMMSL= # of semaphores in a semaphore set

SEMMNI= the maximum # of semaphores sets in the system

SEMMNS= the number of semaphores in the system.

SEMOPM= max number of operations per semop call = 100

SEMVMX = semaphore max value = 32767

When an Oracle instance is started, all required semaphores will be allocated. Semaphores are allocated in sets.

Since each oracle process* requires a semaphore, the number that is allocated is equal to the value of the init.ora parameter PROCESSES. The total # of semaphores required is the sum of all your instance's PROCESSES.

You can allocate all of your semaphores in one or more semaphore sets. If SEMMSL=PROCESSES, then only one semaphore set is required.

The maximum # of semaphores that can be allocated will be the lesser of (SEMMSL*SEMMNI) or SEMMNS.

If SEMMSL is not equal to PROCESSES, be sure that the total # of semaphores required (sum of PROCESSES) does not exceed the maximum (SEMMSL*SEMMNI, SEMMNS).

For example, if SEMMSL=25 and SEMMNI=10, total # of semaphores required (sum of PROCESSES) must not exceed 250 (10 semaphore sets * 25 semaphores/set).

Note: some Operating Systems have a maximum # of semaphore sets in the system.

If you have more than one instance and the values of PROCESSES are different, you may want to make SEMMSL equal to the lowest PROCESSES so that you don't allocate semaphores that will not be used. Otherwise, this could prevent you from being able to allocate all of your requirements.

For example:
Instance PROD has PROCESSES=100
Instance DEV has PROCESSES=50

If SEMMSL = 50, 3 semaphore sets will be allocated, 2 for PROD and 1 for DEV.

If SEMMSL = 100, 2 semaphore sets will be allocated, 1 for PROD
and 1 for DEV.In this case, 100 semaphores will be allocated for DEV when it will only use 50. These unused 50 semaphores cannot be allocated for any other databases.

To see what semaphores have been allocated, use the Unix command 'ipcs -b'.

For example:

Semaphores: 
T      ID     KEY      	MODE        OWNER    GROUP NSEMS 
s       0        0 		--ra-r-----  osupport      dba    25 
s       1        0 		--ra-r-----  osupport      dba    25 
s      18        0 		--ra-r-----  osupport      dba    25 
s      19        0 		--ra-r-----  osupport      dba    25 
s       4        0 		--ra-r-----  osupport      dba    25 
s       5        0 		--ra-r-----  osupport      dba    25

NSEMS=the number of semaphores in each semaphores set.

Perform these steps for each instance that is up and running:

$ svrmgrl
SVRMGR>connect internal
SVRMGR>oradebug ipc

This will show the shared memory segment and semaphore that each instance has attached/in use.

Example output from oradebug ipc command:

  -------------- Shared memory --------------
  Seg Id     Address   Size
  10250      c1eaf000  4591616
  Total: # of segments = 1, size = 4591616
  -------------- Semaphores ----------------
  Total number of semaphores = 50
  Number of semaphores per set = 50
  Number of semaphore sets = 1
  Semaphore identifiers:
  188434

The Seg Id shows 10250 for the shared memory which is attacehed to the RUNNING instance. DO NOT REMOVE THAT ONE.

The Semaphore identifiers shows 188434 for the semaphore which is attacehed to the RUNNING instance. DO NOT REMOVE THAT ONE.

Once you have noted ALL of the identifiers for ALL of the instances which are up and running, compare these id numbers to those in the "ipcs -b" listing.

The entry that does not have a running instance to match is the orphaned entry. THAT ONE SHOULD BE REMOVED.

The command used to remove these entries is: ipcrm

NOTE: The option differs for shared memory and semaphores.

ipcrm -m       <== Use for the Shared Memory entry

ipcrm -s       <== Use for the Semaphore entry

About the author: Nidhi Jain is a Senior DBA at Totality.com. He is a certified Oracle and DB2 database administrator.

Comments

Its the best I've seen so far, gives you a clear picture about how Oracle works with semaphores, especially when it comes to deciding semaphores per set.

Great article. Gives excellent information about how oracle works on unix.

Hi,
I have a question.

Question 1

If my machine has 4gig RAM and I set 4Gig to shared
memory then does this mean I will have no memory
left for NON oracle processe ?

question 2
If all of shared memory is used up does Oracle use
SWAP ?

Thank you in advance for your reply.

Arun.

Arun,

To answer your question,

1. Yes, their will be no real memory available to non-oracle processes.

2. If all shared memory is used, Oracle will use swap.

Nidhi

Hi,
Nice article.
However,I wanted to discuss one of your recommendations . You mentioned "If you have more than one instance and the values of PROCESSES
are different, you may want to make SEMMSL equal to the lowest PROCESSES so that you don't allocate semaphores that will not be
used. "

On some platforms,having multiple semaphore sets per instance or dynamic allocation of additional semaphore sets could constitute a small performance issue and hence in those platforms it is recommended to have the maximum number of semaphores per semaphore set(SEMMSL) to be actually equal to or 10 + GREATEST of the 'PROCESSES' init.ora parameter and not the smallest 'processes' parameter as your article recommends.

I understand you dont want to waste semaphores by over allocating them to a particular instance,but in those cases , the overall maximum number of semaphores system side( SEMMNS) should be increased accordingly.

For eg,
Metalink Doc ID: Note:187260.1 discussing about Kernel parameters for Solaris mentions this
"
SEMMSL - Set to 10 plus the largest PROCESSES parameter of any Oracle database on the system."

-Thiru Vadivelu

The best artical to explain shared memory in Oracle. Great job!

It's compilation from Oracle Metalink 15566.1
It is sad that author did not mention it in his "work"

Hi,

I have machine with 4gb of and i set shared memory to 10gb.

Q.1 will it create any issue.
Q.2 if i set sga size to 3gb, if thise case how much shared memory allocated by oracel.

Q.3 can i set sga larger than physical memory size.

Regards
Sachin

It was very useful ...
Good work