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.
Thanks for this great article! Information on kernel settings is often elusive.
I did find a useful Metalink note that summarizes the settings for numerous configurations:
169706.1
Also, in a Metalink forum it was mentioned (and confirmed by someone in Support) that the SMVMX setting is obsolete in Solaris 10. It appears to be a system-wide maximum for semaphores, so it’s probably not a ceiling that a lot of systems run into anyway.
The 10g preinstall script checks for these settings, and there is a script available at Metalink for doing preinstall checks on older versions of the RDBMS (referenced in the note cited above).
Regards,
Chris Gait
Chris, thanks for the info on SEMVMX! I did notice that it is not mentioned in the later Oracle documentation so I am not surprised to find out it is obsolete.
The Metalink note mentioned by Chris is a great reference for semaphore settings. It covers Database 8.0.5 through 10.2.
Thanks for sharing Chris!
it is superb excellent
Thank you….
I am running officepower on a sun box v240. When people are opening attachments or documents it comes up with SEM_UNDO process limit exceeded and says could not create semaphore.
Can you advise?
Mashie,
I’ve never come up on a sem_undo problem. A quick google search turned up some information but most of it looks dated.
I’d suggest talking to your software vendor and/or Sun about this one. It’s probably a tunable parameter but that doesn’t necessarily mean you should go in and change it.
Good luck.
Very helpful and readable explanation when troubleshooting problem with cluster failover that produced following error:
ORA-27300: OS system dependent operation:semget failed with status: 28
ORA-27301: OS failure message: No space left on device
ORA-27302: failure occurred at: sskgpcreate
Thanks
Thanks for sharing the info
This was a great mini tutorial/lesson!
Thank you for this interesting artical and for your support
Thank u