Tuning Linux kernel for PostgreSQL

Last updated on 18 September 2021

Let us look at how to tune the Linux kernel before deploying PostgreSQL on production servers.

Check this documentation If you want detailed information concerning the linux kernel. Also there is an Ansible role developed by me to fine-tune the linux kernel before deploying PostgreSQL.

Blixy has runes the Linux kernel for PostgreSQL, and now it runs blazing fast!

shmmax parameter

Shmmax, a kernel parameter refers to the maximum size of a shared memory segment allocated to a process. So assuming we did not adjust the kernel.shmmax parameter for the PostgreSQL service, executing the ipcs command will show the default value of kernel.shmmax assigned to PostgreSQL.

------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x01a42e4c 0 postgres 600 56 6
0x00000000 7 mikey 600 524288 2 dest
0x00000000 21 mikey 600 524288 2 dest
0x00000000 22 mikey 600 49152 2 dest
0x00000000 23 mikey 600 49152 2 dest
0x00000000 26 mikey 600 524288 2 dest

It is advisable to increase the value of shmmax to allocate a sizeable memory segment to PostgreSQL.

Changing the value of kernel.shmmax

We can change the value of the kernel.shmmax parameter via sysctl command or add an entry to the path /etc/sysctl.conf . The sysctl command allows us to change the value of shmmax temporarily. You can add an entry to the sysctl.conf file makes the change permanent.

Using the systctl command to set a new value for kernel.shmmax

sudo sysctl -w kernel.shmmax=16777216

Adding an entry to sysctl.conf file

Use the command sudo vim /etc/sysctl.conf to open the file sysctl.conf and add the following value for kernel.shmmax parameter:

kernel.shmmax=16777216

shmall parameter

This kernel parameter refers to the total size of the shared memory pages. Make sure the value you set for the kernel.shmall parameter is large enough for the PostgreSQL server (and other processes or applications).

You can set the value of kernel.shmall parameter to 2097152 via the sysctl command as shown below or add it to the sysctl.conf file inside the /etc directory to make it permanent.

sudo sysctl -w kernel.shmall=2097152

Swappiness parameter

The vm.swappiness parameter is used to control memory paging. Memory paging (also referred to as swapping) is a memory management plan that allows the operating system to retrieve processes from secondary storage into the main memory in the form of pages.

The value for this parameter ranges from 0 to 100. By default, the swappiness value is set to 60. We should expect the operating system to swap more frequently. Frequent swapping could affect database performance.

Setting the vm.swappiness parameter value to 1 prevents the operating systems from swapping frequently. It will only swap when it’s necessary to avoid a PostgreSQL crash.

Overcommit memory parameter

The vm.overcommit_memory parameter allows the kernel to allocate more memory than the available RAM on the system.

Over-committing memory is possible because the kernel assumes that not every process running on a Linux server would completely consumes the memory assigned to it.

If we have an Ec2 instance available with a RAM or main memory of 5GB, we can allocate 2GB each to A, B, and C Linux processes running on the Ec2 instance server. This simply means we have allocated more memory resources to active processes than the physical memory available.

Assuming process A does not consume all the memory assigned to it since it is not active anymore. So the kernel in this case moves process A to disk and then assigns unused memory of process A to another active process.

However, it is not advisable to enable this kernel parameter if you have a Linux server hosting other processes apart from the postmaster process belonging to PostgreSQL.

Why? Because the kernel will terminate the postmaster process if it finds out that there is not enough memory for PostgreSQL to consume.

Out of Memory: Killed process 12345 (postgres)

You can disable the vm.overcommit_memory parameter by assigning the value 2 to it if you are not sure of the workload of the PostgreSQL server.

Overcommit memory ratio parameter

This parameter prevents the kernel from over-committing memory to active processes on a Linux server beyond the percentage range. By default, the value for the vm.overcommit_ratio is 50. So in this case, the kernel can’t overcommit memory beyond the 50% range to active processes.

A Linux server with a RAM of 2GB expects the kernel to over-commit 3GB (and not more than 3GB of RAM to active/running processes).

Huge pages

Huge Pages is present in Linux kernel 2.6 and above. This parameter allows the kernel to manage memory pages greater than the default value of 4KB. In Linux, every active process is allocated a chunk or block of RAM known technically known as a memory page. So if there is a process like the postmaster process which requires more memory, then more pages or chunks of RAM will be allocated. Every process in Linux has its independent page table.

So assuming we decided not to increase the page size above the default value which is 4K for processes noted for excess memory operations, then the kernel needs to allocate many pages in smaller sizes.

The smaller the page size, the more time it takes for the kernel to look up to a page in the page table. Therefore huge page size reduces the overhead in accessing a page in the page table.

So in a situation where you have active processes on a Linux server known for performing excess memory operations, then you may need to set the Huge page size to 1GB.

Dirty background ratio parameter

vm.dirty_background_ratio sets the minimum memory percentage of the system memory for dirty pages, before the system starts to flush dirty pages to the disk. Flushing is done in the background. The value for this parameter ranges from 0 to 100.

When the percentage memory for dirty pages is reached, all dirty pages in the memory are flushed in the background to the disk without blocking the application making writes also to the disk.

You can set the value for this parameter to 10 or 15 depending on the total size of RAM. If you set it too high, it might introduce bottlenecks into your system. If you set it too low, flushing may not be done often enough, and occasional intensive flushing operations may slow down your system.

Dirty ratio parameter

vm.dirty_ratio is somehow related to the previous parameter vm.dirty_background_ratio . It defines the memory percentage for dirty pages. But unlike the dirty background ratio parameter, it blocks all processes from making writes till it has flushed all dirty pages to the disk. In other words, when dirty pages reach the vm.dirty_background_ratio they start being flushed; if they don’t flush fast enough and they reach vm.dirty_background_ratio they will start flushing aggressively, blocking other processes.

It is advisable to set this parameter to a higher value than the vm.dirty_background_ratio parameter.

Conclusions

Although there are other kernel parameters like file-max , rmem_default , and rmem_max , the above listed kernel parameters are the most important ones to optimise the Linux kernel before deploying PostgreSQL. But if you tune parameters that are not mentioned here, please let us know in the comments.

Reviewing your Linux kernel parameters is part of our PostgreSQL Health Checks.

Michael Aboagye

Did you like this article?

About Michael Aboagye

Michael is PostgreSQL consultant at Vettabase. He is specialised in PostgreSQL performance, security and automation.

Leave a Reply

Your email address will not be published. Required fields are marked *

*