2011-12-10

Really? A SHMMAX of 36MB

I was running some tests on OpenGroupware Coils on my new HP workstation - and PostgresSQL seemed to be huffing-and-puffing like an overweight guy trying to run up stairs.  Huh.  What is the first thing a PostgreSQL administraor always checks? The shared_buffers parameter [in /var/lib/pgsql/data/postgresql.conf]; the default package typically sets this value to some absurdly small value resulting in dreadful performance.  This default value is the principal reason the absurd notion that "MySQL is faster than PostgreSQL" got traction.  Sure enough - the default value is 24MB! Yikes.  So I changed that setting to a more reasonable 512MB.
shared_buffers = 512MB
Then I tried to restart PostgreSQL, and it flopped.
$ service postgresql start
redirecting to systemctl
Job failed. See system logs and 'systemctl status' for details.
Looking in /var/log/messages I see:
Dec  9 19:27:23 workstation postgresql[7288]: Starting PostgreSQL2011-12-09 19:27:23 EST   FATAL:  could not create shared memory segment: Invalid argument
Dec  9 19:27:23 workstation postgresql[7288]: 2011-12-09 19:27:23 EST   DETAIL:  Failed system call was shmget(key=5432001, size=76685312, 03600).
Huh.  I remember an error message like that from the RedHat 6.x & 7.x days when the kernel's default settings regarding System V IPC resources where really low.  Back then you possibly had to go look at defines in header files for these values. Fortunately we now have sysctl.  And what does sysctl tell us?
$ sysctl kernel.shmmax
kernel.shmmax = 33554432
What?!?!  That value is in bytes - so the limit is ~32MB?!  This is on a 64-bit installation with 8GB of RAM. That makes no sense at all.  Time to change that to something reasonable:
$ sysctl -w kernel.shmmax=1000000000
And now "service postgresql start" succeeds.  The ipcs command which reports System V IPC resources allocated in the system shows that the PostgreSQL engine has allocated the expected buffer pool:
$ ipcs
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x0052e2c1 1212416    postgres   600        572383232  4   
Once you change a sysctl setting in a helpful way the change has to be added to the /etc/sysctl.d/ so that it gets re-applied when the machine reboots;  otherwise our PostgreSQL instance is going to fail to start next time.  Create a file in that directory with a name such as postgresql.conf containing a single line of -
kernel.shmmax = 1000000000
The files in /etc/sysctl.d/ are processed after distribution and package defaults are applied.  It is also possible to edit /etc/sysctl.conf; however manual changes to that file may get overwritten by system management tools.  So use the /etc/sysctl.d/ strategy to override distribution defaults.
Now, back to work.

0 comments:

Post a Comment