postgresql - Procesos postgres inactivos que ocupan mucha memoria.
memory centos (1)
¿A qué tipo de información se aferran estos procesos? Yo esperaría que los procesos postgres inactivos de larga ejecución tuvieran un uso de memoria similar a los nuevos e inactivos.
En realidad, hay algunas cosas que Postgres almacenará en la memoria local una vez que las haya cargado:
- relcache (descriptores de relación)
- catcache (entradas de catálogo del sistema)
- árboles compilados para funciones plpgsql
Para la mayoría de los casos de uso, todos estos se suman a una cantidad insignificante. La clave aquí fue el uso intensivo de esquemas y el efecto en el relcache. Esta base de datos contiene ~ 500 esquemas, cada uno con las mismas ~ 90 tablas. Para Postgres, aunque los esquemas son todos iguales, esto funciona en 45,000 tablas (500 * 90).
Cada solicitud almacenó en la memoria caché algunos de los descriptores de relación de las tablas (la mayoría de las veces en un esquema diferente al de la solicitud anterior), llenando gradualmente el relcache. Desafortunadamente, Postgres no ofrece una manera de limitar el tamaño de estos cachés , ya que la sobrecarga probablemente sería contraproducente para la mayoría de los casos de uso.
Soluciones posibles:
- Reconectarse después de un cierto número de solicitudes
- Agregar mas memoria
- Agrupación de conexiones para poner un límite en el número de conexiones postgres utilizando pgpool-II o PgBouncer
Gracias a Tom Lane y Merlin Moncure por su ayuda en las listas de correo de Postgres .
Estoy tratando de averiguar por qué ~ 30 procesos postgres inactivos ocupan tanta memoria específica del proceso después del uso normal. Estoy usando Postgres 9.3.1 y CentOS versión 6.3 (final). Al usar top
, puedo ver que muchas de las conexiones de postgres utilizan hasta 300mb (promedio ~ 200mb) de memoria no compartida (RES - SHR):
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3534 postgres 20 0 2330m 1.4g 1.1g S 0.0 20.4 1:06.99 postgres: deploy mtalcott 10.222.154.172(53495) idle
9143 postgres 20 0 2221m 1.1g 983m S 0.0 16.9 0:14.75 postgres: deploy mtalcott 10.222.154.167(35811) idle
6026 postgres 20 0 2341m 1.1g 864m S 0.0 16.4 0:46.56 postgres: deploy mtalcott 10.222.154.167(37110) idle
18538 postgres 20 0 2327m 1.1g 865m S 0.0 16.1 2:06.59 postgres: deploy mtalcott 10.222.154.172(47796) idle
1575 postgres 20 0 2358m 1.1g 858m S 0.0 15.9 1:41.76 postgres: deploy mtalcott 10.222.154.172(52560) idle
Hay alrededor de 29 conexiones inactivas totales. Estas conexiones inactivas siguen creciendo en la memoria hasta que la máquina comienza a usar el intercambio, y luego el rendimiento se detiene. Como se esperaba, restablecer la conexión borra la memoria específica del proceso. La misma cantidad de conexiones en la misma máquina solo usa el 20% de la memoria (con intercambio de 0) cuando me reconecto periódicamente. ¿A qué tipo de información se aferran estos procesos? Yo esperaría que los procesos postgres inactivos de larga ejecución tuvieran un uso de memoria similar a los nuevos e inactivos.
Cabe destacar: estoy utilizando pesadamente esquemas. En cada solicitud a mi aplicación, estoy configurando y restableciendo search_path.