Managing Kernel Resources

A large PostgreSQL installation can quickly hit various operating system resource limits.

Shared Memory and Semaphores

Shared memory and semaphores are collectively referred to as "System V IPC". When PostgreSQL exceeds one of the various hard limits of the IPC resources, the postmaster refuses to start up and leaves an error message about which problem was encountered and what needs to be done about it.

The most important shared memory parameter is SHMMAX, the maximum size, in bytes, that a shared memory segment can have. If you get an error message from shmget along the lines of Invalid argument, it is possible that this limit has been exceeded. The size of the required shared memory segments varies both with the number of requested buffers (-B option) and the number of allowed connections (-N option), although the former is the dominant item. (You can therefore, as a temporary solution, lower these settings to get rid of the failures.) As a rough approximation you can estimate the required segment size as the number of buffers times the block size (8192 KB by default) plus ample overhead (at least half a megabyte). All error messages will contain the size of the failed allocation request.

Less likely to cause problems is the minimum size for shared memory segments (SHMMIN), which should be at most somewhere around 256 KB for PostgreSQL (it is usually just 1). The maximum number of segments system-wide (SHMMNI) or per-process (SHMSEG) should not cause a problem unless your system has them set to zero.

PostgreSQL uses one semaphore per allowed connection (-N option), in sets of 16. Each such set will also contain a 17th semaphore that contains a "magic number", to avoid collision with semaphore sets used by other applications. The maximum number of semaphores in the system is set by SEMMNS, which consequently must be at least as high as the connection setting plus one extra for each 16 allowed connections (see the formula in the section "System V IPC Parameters"). The parameter SEMMNI determines the limit on the number of semaphore sets that can exist on the system at one time. Hence this parameter must be at least ceil(max_connections / 16). Lowering the number of allowed connections is a temporary workaround for failures, which are usually confusingly worded "No space left on device", from the function semget().

In some cases it might also turn out to be necessary to increase SEMMAP to be at least on the order of SEMMNS. This parameter defines the size of the semaphore resource map, in which each contiguous block of available semaphores needs an entry. When a semaphore set is freed it is either added to an existing entry that is adjacent to the freed block or it is registered under a new map entry. If the map is full, the freed semaphores get lost (until reboot). Fragmentation of the semaphore space could therefore over time lead to less available semaphores than there should be.

The SEMMSL parameter, which determines how many semaphores can be in a set, must be at least 17 for PostgreSQL.

Various other settings related to "semaphore undo", such as SEMMNU and SEMUME, are not of concern for PostgreSQL.

The default shared memory limit for SHMMAX is 32 MB and for SHMALL is 2 MB, but it can be changed in the proc file system (without reboot). For example, to allow 128 MB:
$ echo 134217728 >/proc/sys/kernel/shmall
$ echo 134217728 >/proc/sys/kernel/shmmax
You could put these commands into a script run at boot-time.

Alternatively, you can use sysctl(8), if available, to control these parameters. Look for a file called /etc/sysctl.conf and add lines like the following to it:
kernel.shmall = 134217728
kernel.shmmax = 134217728
This file is usually processed at boot time, but sysctl can also be called explicitly later.

Other parameters are sufficiently sized for any application. If you want to see for yourself look into /usr/src/linux-2.4/include/asm-xxx/shmparam.h and /usr/src/linux-2.4/include/linux/sem.h.

Resource Limits

Linux enforces various kinds of resource limits that might interfere with the operation of your PostgreSQL server. Of importance are especially the limits on the number of processes per user, the number of open files per process, and the amount of memory available to a process. Each of these have a "hard" and a "soft" limit. The soft limit is what actually counts but it can be changed by the user up to the hard limit. The hard limit can only be changed by the root user. The system call setrlimit is responsible for setting these parameters. The shell's built-in command ulimit (Bourne shells) or limit (csh) is used to control the resource limits from the command line.

On Linux, /proc/sys/fs/file-max determines the maximum number of files that the kernel will allocate. It can be changed by writing a different number into the file or by adding an assignment in /etc/sysctl.conf. The maximum limit of files per process is fixed at the time the kernel is compiled.

The PostgreSQL server uses one process per connection so you should provide for at least as many processes as allowed connections, in addition to what you need for the rest of your system. This is usually not a problem but, if you run several servers on one machine, things might get tight.

The factory default limit on open files is often set to "socially friendly" values that allow many users to coexist on a machine without using an inappropriate fraction of the system resources. If you run many servers on a machine, this is perhaps what you want, but on dedicated servers you may want to raise this limit.