In the last post in this two post series we’ve briefly looked at configuring huge pages on Linux for PostgreSQL. It became clear, that calculating the number of huge pages purely based on the setting of shared_buffers will not work. PostgreSQL requires more shared memory, but what exactly is it? Well, this is the goal of this post and I’ll introduce a new feature of PostgreSQL 15 which helps in identifying those bits without digging into the operating systems details about memory management.
Let’s quickly review the current situation. We have shared_buffers set to 128MB:
postgres=# show shared_buffers; shared_buffers ---------------- 128MB (1 row)
Using the official way of calculating the huge pages we see that PostgreSQL currently requires this amount of shared memory (huge pages in PostgreSQL need to be disabled for this):
postgres@debian11pg:/home/postgres/ [pgdev] head -1 $PGDATA/postmaster.pid 826 postgres@debian11pg:/home/postgres/ [pgdev] pmap 826 | awk '/rw-s/ && /zero/ {print $2}' 145360K
As we already have seen in the last post this is more than the 128MB configured for shared_buffers. What else could change the requirement for shared memory. What about wal_buffers? In the default configuration (-1) this consumes 128/32 MB:
postgres=# show wal_buffers; wal_buffers ------------- 4MB (1 row)
What happens if we change it?
postgres@debian11pg:/home/postgres/ [pgdev] psql -c "alter system set wal_buffers='16MB'" ALTER SYSTEM postgres@debian11pg:/home/postgres/ [pgdev] pg_ctl restart postgres@debian11pg:/home/postgres/ [pgdev] head -1 $PGDATA/postmaster.pid 858 postgres@debian11pg:/home/postgres/ [pgdev] pmap 858 | awk '/rw-s/ && /zero/ {print $2}' 157664K
This increases shared memory usage from 145360K to 157664K. So, yes, wal_buffers definitely impact the usage of shared memory. What about extensions, could they have an impact as well?
postgres@debian11pg:/home/postgres/ [pgdev] psql -c "alter system set shared_preload_libraries=pg_stat_statements" ALTER SYSTEM postgres@debian11pg:/home/postgres/ [pgdev] pg_ctl restart postgres@debian11pg:/home/postgres/ [pgdev] head -1 $PGDATA/postmaster.pid 882 postgres@debian11pg:/home/postgres/ [pgdev] pmap 882 | awk '/rw-s/ && /zero/ {print $2}' 159176K
We’ve again increased shared memory usage from 157664K to 159176K. Extensions also might consume shared memory. What about max_connections?
postgres@debian11pg:/home/postgres/ [pgdev] psql -c "show max_connections" max_connections ----------------- 100 (1 row) postgres@debian11pg:/home/postgres/ [pgdev] psql -c "alter system set max_connections=1000" ALTER SYSTEM postgres@debian11pg:/home/postgres/ [pgdev] pg_ctl restart postgres@debian11pg:/home/postgres/ [pgdev] head -1 $PGDATA/postmaster.pid 900 postgres@debian11pg:/home/postgres/ [pgdev] pmap 900 | awk '/rw-s/ && /zero/ {print $2}' 201288K
Next increase, this time from 159176K to 201288K. Without going any further: There was no way to see the real shared memory consumption from inside PostgreSQL and this is why this discussion started. The result is this:
postgres=# show shared_buffers; shared_buffers ---------------- 128MB (1 row) postgres=# show shared_memory_size; shared_memory_size -------------------- 197MB (1 row)
… which is pretty close to 201288K. Really nice.