📜 ⬆️ ⬇️

Huge pages in postgreSQL

Since PostgreSQL version 9.4, there is support for large pages. This is very good news, I met with large pages when I was working with virtualization. Briefly what is it about. In Linux, working with memory is based on referring to pages that are 4kB in size (in fact, depending on the platform, you can check it with getconf PAGE_SIZE ), so when the memory size exceeds several dozen or even hundreds of gigabytes, it becomes more difficult to manage the overhead of addressing memory and maintaining page tables increases. To make life easier, large pages were invented, the size of which can be 2MB or even 1GB. Due to the use of large pages, you can get a tangible increase in the speed of work and an increase in responsiveness in applications that actively work with memory. As I have already noted, for the first time I ran into large pages when working with virtualization, in particular with KVM. Tests conducted at one time showed that the performance gain of virtual machines ranged from 7 to 10% (this whole case was measured by synthetic tests of various services like redis / memcache / postgres / etc inside virtual machines). Now it has appeared in PostgreSQL.

image


So back to the topic of the article, to the support of large pages in PostgreSQL. To be honest, I have been waiting for this for a long time. In general, it was possible to start PostgreSQL with support for large pages earlier, using libhugetlbfs . However, there is now built-in support. So, below is a description of the process of how to configure and run PostgreSQL with support for large pages.

First you need to make sure that the kernel supports large pages. We check the kernel config for the presence of the CONFIG_HUGETLBFS and CONFIG_HUGETLB_PAGE options.
# grep HUGETLB /boot/config-$(uname -r) CONFIG_CGROUP_HUGETLB=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y 

')
In the absence of these options, nothing will work and the kernel should be rebuilt (relevant for Gentoo for example).
Obviously, we will need PostgreSQL version 9.4. I leave package installation and cluster initialization behind the scenes, because depending on the distribution method will be different. Go directly to the postgresql.conf configuration file. For the support of large pages, the huge_page parameter is responsible which can take three values, off - not to use large pages, on - to use large pages, try - to try to use large pages and in case of inaccessibility roll back to the use of regular pages. The try value is used by default and is a safe option. In the case of on, the service will not start if the large pages are not defined in the system (or not enough). In the case of startup, you can get the following error:

FATAL: couldn’t map anonymous shared memory: Cannot allocate memory
Hint: This error usually means that there is a memory card that can be used for the shared memory segment. To reduce the request size (currently 148324352 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

So, we rule postgresql.conf (my postgresql.conf is located in the place standard for RHEL-based distributions):

 # vi /var/lib/pgsql/9.4/data/postgresql.conf huge_page = try 


Now we include support for large pages in the system, by default they are not involved. The calculation of the pages is approximate and here you should rely on how much memory you are ready to allocate for the needs of the DBMS. I note that the value is measured in 2Mb pages, if you want to allocate 16GB, it will be 8000 pages.

Official documentation suggests relying on the VmPeak value from the status file which is located in the / proc / PID / directory that corresponds to the postmaster process number. VmPeak as the name suggests is the peak value of virtual memory usage. This option allows you to determine the minimum bar from which to repel, but in my opinion, this method of determination is also random.

 # head -1 /var/lib/pgsql/9.4/data/postmaster.pid 3076 # grep ^VmPeak /proc/3076/status VmPeak: 4742563 kB # echo $((4742563 / 2048 + 1)) 2316 # echo 'vm.nr_hugepages = 2316' >> /etc/sysctl.d/30-postgresql.conf # sysctl -p --system 


Moving on to launch PostgreSQL. Depending on the initialization system, the launch method may differ, I have a trendy-youth systemd.

 # systemctl start postgresql-9.4.service 


Recycling large pages can be viewed here.

 # grep ^HugePages /proc/meminfo HugePages_Total: 2316 HugePages_Free: 2301 HugePages_Rsvd: 128 HugePages_Surp: 0 


That's all, you can go to the benchmarks with your specific workloads. Thanks for attention!

Source: https://habr.com/ru/post/228793/


All Articles