In UNIX semaphore and shared memory settings control several aspects of how applications can use memory. Many people just drop these settings into place without truly understanding what they do but this can bite you in the long run.

In this article I hope to shed some light on what these settings really do. Though settings vary by platform and database version their purpose remains constant. As always, mileage may vary. Consult the documentation for your system/db version before changing any settings.

My examples come from a Solaris system running several Oracle 9i databases. Semaphore and shared memory settings need to be set by root and will likely require a restart of the system to take affect.

Typically in UNIX each process obtains memory for its purposes. That memory is protected from access by other processes. Shared memory allows an application to allocate a chunk of memory which can be viewed by other processes. Oracle uses shared memory to create the System Global Area (SGA) which all Oracle processes must be able to access.

Semaphores act as flags for shared memory. Semaphores are either set on or off. When an Oracle process accesses the SGA (in shared memory) it will check for a semaphore for that portion of memory. If it finds a semaphore set on for that portion of memory that process will sleep and check again later. If there is no semaphore set on for that portion of memory it will set one on and proceed with its operation. When it is done it will switch that semaphore back to off.

If that all makes sense let’s look at some of these settings and some example values. These appear in the format you would see in a Solaris /etc/system file. An asterisk (*) is treated as a comment in this file.

Shared Memory Parameters

Ideally Oracle would like to find one contiguous chunk of shared memory to put the entire SGA into. When this is not possible it will attempt to find several contiguous segments of shared memory. Failing that it will resort to several non-contiguous segments of shared memory. If none of these are available your Oracle database will fail to start.

set shmsys:shminfo_shmmax=4294967295
*shmmax sets the largest memory segment which can be
*allocated

As the comment implies, this is the largest single segment of shared memory which can be allocated in the system. This setting is set in bytes. Setting this to a large value (half of the physical memory of the system or more) makes it possible that Oracle will be able to allocate the SGA in one contiguous memory segment. This example is from a machine with 8GB of physical memory so the largest shared segment is set to 4GB. Note that this is a maximum, so Oracle will still only occupy as much memory as the SGA requires.

set shmsys:shminfo_shmmin=1
*shmmin sets the smallest memory segment which can be
*allocated

This sets the minimum size a shared memory segment is allowed to be. Of course it is unlikely (read impossible) to have a 1 byte SGA, but having this set to 1 guarantees maximum flexibility.

set shmsys:shminfo_shmmni=500
*shmmni defines the maximum number of shared memory
*segments in the entire system

The number of shared memory segments available is controlled by SHMMNI. Ideally we may only use one per Oracle instance, but realistically it is nice to have plenty around.

set shmsys:shminfo_shmseg=50
*shmseg defines the maximum number of shared memory
*segments which can be used by one process

SHMSEG limits the number of simultaneous shared memory segments which can be accessed by an individual process. Again, this would ideally be low, but it doesn’t seem to hurt to have plenty of overhead on this setting.

Semaphore Parameters

Oracle requires one semaphore for each process of each database on a system. By this logic the number of semaphores available need only be equal to the PROCESSES parameter in the init.ora file (or spfile). For systems with multiple databases the number would be the sum of the PROCESSES parameter for all databases.

That’s nice in theory, but there are a couple additional considerations. For some reason durring database startup Oracle will request enough semaphores for twice the processes specified. I guess the theory is to make sure there are plenty of semaphores to go around.

It is also nice to consider expansion when planning semaphores. If you need to increase the PRCOESSES parameter for one of your databases, or want to add a database to an existing server, you would have to restart to update the semaphore parameters. For this reason it seems fortuitous to have relatively (but not astronomically) high values for the semaphore settings.

set semsys:seminfo_semmni=300
*semmni sets the number of semaphore sets available

This controls the number of semaphore sets available. In an ideal world we would only need one set per database, but more realistically it is nice to have a bunch extra around.

set semsys:seminfo_semmsl=500
*semmsl sets the number of semaphores per set

This parameter will determine how many semaphores exist in each semaphore set. Since semaphores are always allocated in sets it is most convenient if this is greater than or equal to the PROCESSES parameter for your largest database.

set semsys:seminfo_semmns=30000
*semmns sets the total number of semaphores available

SEMMNS limits the number of semaphores which can be generated in the system. I recommend setting this fairly high to avoid limiting the number of semaphores available. The actual number of semaphores available will actually be the lower of either SEMMNS or SEMMSL*SEMMNI.

set semsys:seminfo_semvmx=65534
*semvmx is the semaphore maximum value

I have to admit to not knowing exactly what SEMVMX controls (other than what is in the comment above). After some extensive googleing I cannot turn up a satisfactory answer for this. If you know, please leave a comment to this post.

NOTE: See comment from Christopher Gait regarding SEMVMX. He mentions that this parameter is obsolete in Solaris 10. I don’t believe this is even in the Oracle install guide for Database 9i and up, but has been left in this article for legacy purposes.

set semsys:seminfo_semopm=250
*semopm determines the maximum number of operations
*per semop call

This controls the number of operations which can occur during a single semaphore call. A value of 250 should allow a sufficient number of operations while keeping the number of calls low.

NOTE: These are examples given for educational purposes. As mentioned earlier in this article, always consult your documentation before changing system parameters.

oracle, database, dba, database administration, system administration, solaris, database tuning