During installation, PureMessage automatically adjusts the PostgreSQL database in an attempt to improve performance. If the adjustments are successful, PureMessage displays a confirmation message. If the adjustments fail, it is likely due to the shared memory configuration of your system. PureMessage will revert the changes and create a postgresql.conf.recommended file that contains appropriate system settings. This tuning guide provides recommendations for hardware usage, system allocation and configuration, and settings for shared memory and semaphores.
Important: The PureMessage installer assumes that the Database Server role is installing PostgreSQL on a system with 1GB of RAM. If more than 1GB of RAM is available, you should follow these instructions to improve the performance of PostgreSQL.
System Hardware Considerations
Disks, RAM and CPU
PostgreSQL, like other transactional RDBMS's, is I/O intensive for updates. A fast SCSI disk array is the single greatest performance factor. After the I/O subsystem, RAM is the next most significant factor, followed by CPU speed. Expect to use up to 4 GB of RAM. Note:
Hyperthreading on Intel Xeon systems should be disabled in the BIOS because it adversely affects PostgreSQL performance.
PostgreSQL competes with other system processes for disk access and OS disk cache, which can make the database and the other processes perform poorly under load. For optimal performance in high-volume deployments, the Database server role (PostgreSQL) should be installed on a separate server from other PureMessage roles (for example, the Mail Filter role and Mail Transfer Agent role). This is particularly important in deployments with multiple mail-filtering servers.
Transaction Log (pg_xlog)
PostgreSQL uses Write-Ahead Logging (WAL) for transactions to protect against data loss. For high traffic systems, the performance of this logging can be increased by moving the log file (
pg_xlog) to its own disk.
For example, to move
pg_xlog to its own disk and symbolically link it to the default
$ mkdir /disk2/pg_xlog # Or a disk or directory of your choosing
$ pmx-database stop
$ cd /opt/pmx/postgres/var/data
$ find pg_xlog | cpio -pmd /disk2
$ mv pg_xlog pg_xlog.old #Make backup of original pg_xlog
$ ln -s /disk2/pg_xlog . # You must use the full path
$ pmx-database start
RAID 1+0 / 0+1 vs. RAID 5
RAID 5 with 3 disks, though it is a standard configuration, is the slowest array configuration possible for PostgreSQL. A RAID 5 configuration performs as much as two times slower for
pg_xlog traffic. This also can give you as little as 50% of the query speed as running on a plain SCSI disk. We recommend RAID 1, 1+0 or 0+1 for any set of 2, 4 or 6 disks.
Shared Memory and Semaphores
PostgreSQL requires semaphore ("sem") and shared memory ("shm") resources. System limits on these resources will restrict the number of concurrent database connections, and affect performance. On Solaris systems, the default system resource parameters are set too low and must be increased.
Detailed instructions on configuring kernel parameters for running PostgreSQL, with formulas for deriving reasonable settings, are available in the "Managing Kernel Resources" section of the PostgreSQL documentation. The PureMessage installation script attempts to set this minimally, but if it is unable to do so, or if you want to reconfigure what it has set, then this section has guidelines for appropriate settings and instructions for making these changes manually.
The table below shows the recommended minimum shared memory (SHM) settings, based on the RAM installed on the machine that is running the PureMessage Database server role (PostgreSQL). On a dedicated PureMessage database server, the SHM setting should represent at least one half of the machine's physical RAM .
|Dedicated Linux Server||Dedicated Solaris 10 DB Server |
|RAM in GB||SHM in bytes||RAM in GB||SHM in bytes |
|2 ||1073741824 ||2 ||1073741824 |
|4 ||2147483648 ||4 ||2147483648 |
|8 ||4294967295 ||8 ||4294967295 |
Make the changes that are applicable to your operating system and version, in accordance with the table above. These changes must be made as the root user.
- Edit /etc/sysctl.conf, adding or modifying the following lines. This sets the shared memory segment to the specified amount on boot:
kernel.shmall=[SHM in bytes from the table above]
kernel.shmmax=[SHM in bytes from the table above]
- To set the shared memory size immediately, without rebooting the server, run the following two commands:
$ sysctl -w kernel.shmall=[SHM in bytes from the table above]
$ sysctl -w kernel.shmmax=[SHM in bytes from the table above]
PostgreSQL Configuration on a Dedicated Server
Adjustments to the
effective_cache_size settings of PostgreSQL may be required.
Detailed instructions on configuring PostgreSQL run-time parameters can be found in the "Run-time Configuration" section of the PostgreSQL documentation.
effective_cache_size can be set according to the guidelines below. To change these settings:
- As the PMX user, shutdown PostgreSQL with the following command:
/opt/pmx/postgres/var/data/postgresql.conf for editing, and enter the values as shown in the following table in accordance with the physical RAM on your dedicated PureMessage database server. This is the server running the Database server role (PostgreSQL).
|2 GB System||4 GB System||8 GB System |
|Solaris 10||Linux||Solaris 10||Linux||Solaris 10||Linux |
|100 ||100 ||150 ||150 ||200 ||200 |
|6000 ||16384 ||12000 ||32768 ||24000 ||65536 |
|vacuum_mem ||262144 |
|250,000 ||800,000 ||500,000 ||1,600,000 ||1,000,000 ||3,200,000 |
- Restart PostgreSQL with the following command:
PostgreSQL Configuration in a Single-Server Deployment
Shared memory is not the total memory PostgreSQL can work with; rather it is the block of dedicated memory PostgreSQL uses for active operations, and it should be a minority of the total RAM on the machine. This is because PostgreSQL must dynamically allocate memory per connection (process) for sorts, for in-memory hash tables, and for other activities that don't use shared memory.
On a single-server PureMessage deployment, milters consume a large amount of memory. So the milters should run with a concurrency limit that leaves enough physical memory for PostgreSQL.
- As the "pmx" user, find out how much memory your milters are using by running the following command:
The output of this command will look, in part, something like:
slot#1: pid=34207 vsz=78.9 acc=1/1/1 req=1
- Use the
vsz value on slot 1, which is the memory in MB, to calculate what the milter concurrency limit using the following formula:
(RAM for PostgreSQL x (<server RAM in GB> - 1)) / milter size in MB = optimum milter concurrency limit
So, in this example, this would be:
(1024 x (4 - 1)) / 79 = 39 milters
- Set the milter concurrency limit by running the following command as the "pmx" user:
$ pmx-config concurrency_limit 39
- Restart the milter by running the following command as the "pmx" user: