Uno de los problemas relativamente comunes que aparecen en un servidor Linux que esté corriendo PostgreSQL es la aparición del “OOM-killer”, el cual puede detectarse porque en el log del kernel aparece un mensaje como el siguiente:
kernel: Out of Memory: Killed process 1337 (postmaster)OOM significa, obviamente, “out of memory” (sin memoria), y el “OOM-killer” es una tarea del kernel que se hace cargo de una difícil situación que tiene que ver con el “overcommit de memoria”.
Overcommit (literalmente podría traducirlo como “exceso de compromiso”, pero no estoy seguro si esa frase tiene sentido en español) significa que el kernel permite más asignaciones de memoria que las que realmente tiene espacio para satisfacer. Por ej. si se tienen 2GB de RAM y 1 GB de swap, un kernel que no haga overcommit va a retornar ENOMEM ("no hay suficiente memoria") cuando haya 3 GB ya utilizados en total, y una aplicación pida más memoria. En cambio, un kernel que haga overcommit, va a retornar que sí se puede usar el espacio solicitado extra, y la aplicación puede continuar funcionando.
El problema ocurrirá cuando las aplicaciones que pidieron espacio lleguen a utilizarlo. Hay muchos casos en que esto no ocurre, por variados motivos, y es tan común que la configuración por omisión del kernel de Linux trae overcommit activado, sin mayores problemas.
Ahora, si llega a suceder que todas las solicitudes (o una mayoría de ellas) se utilicen, puede ser fatal. El problema es que cuando el kernel queda sin memoria libre y necesita satisfacer una promesa anterior de que ya se otorgó memoria a algún proceso, se ve entre la espada y la pared. La única solución que tiene para salir del paso es matar algún proceso que esté usando mucha memoria, con la esperanza de que al hacer eso se libere suficiente memoria para que el resto del sistema pueda continuar funcionando normalmente.
En un sistema sin overcommit, PostgreSQL tiene un sistema bastante bueno para protegerse de las situaciones en que se queda sin memoria: simplemente, aborta la transacción en curso y el sistema sigue funcionando normalmente. El usuario puede volver a intentar la transacción que causó el problema, y si la estrechez de memoria era transitoria, es posible que funcione.
Sin embargo, si un kernel con overcommit activo le dice a Postgres que tiene memoria disponible, y Postgres continúa procesando la transacción, pero más tarde el kernel se da cuenta que en realidad no la tenía, lo que hará el kernel será matar el proceso “postmaster”, y el servicio Postgres será terminado forzosamente, con lo cual habrá un reinicio de la base de datos: todos los proceso activos serán terminados, las conexiones serán cerradas, y el servidor tendrá que volver a levantarse. Es decir, una situación desagradable.
Por consiguiente, en un servidor PostgreSQL es importante desactivar el overcommit de memoria en el kernel. La documentación de PostgreSQL dice cómo hacerlo:
http://www.postgresql.org/docs/current/static/kernel-resources.html#AEN24162La parte importante es poner una línea
vm.overcommit_memory=2 en
sysctl.conf y releer la configuración con la orden
sysctl -p.