psql: FATAL: lo siento, demasiados clientes ya


16

De repente recibo este error cuando intento acceder al sitio web que usa la base de datos postgresql, o incluso cuando uso la utilidad psql o pgadmin3.

Mi base de datos está configurada para manejar 150 conexiones máximas:

# SHOW max_connections;
 max_connections 
-----------------
 150
(1 row)

Después de reiniciar el servidor ubuntu en el que se encuentra mi sitio web (que en realidad es lo único que usa conexiones), veo que la cantidad actual de conexiones es 140:

# select count(*) from pg_stat_activity;
 count 
-------
   140
(1 row)

No entiendo cómo de repente tantas conexiones después de reiniciar mi servidor. Así que verifico la actividad postgresql:

# SELECT * FROM pg_stat_activity;

Y veo más de 100 columnas con la misma consulta exacta que se ve así:

SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1

Aún más importante es que todos tienen la misma dirección de cliente (mi servidor web).

Este servidor web está utilizando Ruby on Rails con un grupo de conexiones de 50. Aunque hay un grupo de conexiones de 50, la configuración de Apache de proceso / prefork de Passenger es de un solo subproceso y, por lo tanto, cada proceso no puede generar 50 hilos y 50 conexiones de base de datos. Además, esto ocurrió después de un reinicio del sistema que eliminó a todos los usuarios de mi servidor web. Lo más probable es que postgresql en el servidor de la base de datos no tenga conocimiento del reinicio del servidor web y todavía esté intentando ejecutar estas consultas.

Para responder los comentarios de Craig, debajo de la columna de espera muestra la letra 'f'. Parece que la consulta aún se está ejecutando y el bloqueo aún no se ha liberado. Como dije anteriormente, lo que es tan extraño es que de repente más de 100 consultas idénticas entre sí dentro de milisegundos de distancia aparecieron repentinamente en este estado de ejecución. Ese es el misterio para mí:

mydb=# SELECT * FROM pg_stat_activity;

 datid  | datname  | procpid | usesysid | usename |                                                                           current_query                                                                           | waiting |          xact_start           |          query_start          |         backend_start         |  client_addr   | client_port
--------+----------+---------+----------+---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------+-------------------------------+-------------------------------+-------------------------------+----------------+-------------
 464875 | mydb     |    4992 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:48.437081-04 | 2014-06-28 22:46:48.437081-04 | 2014-06-28 22:46:44.089764-04 | 192.111.11.111 |       37166
 464875 | mydb     |    4993 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:48.497764-04 | 2014-06-28 22:46:48.497764-04 | 2014-06-28 22:46:44.277856-04 | 192.111.11.111 |       37167
 464875 | mydb     |    4994 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:48.504425-04 | 2014-06-28 22:46:48.504425-04 | 2014-06-28 22:46:44.485269-04 | 192.111.11.111 |       37168
 464875 | mydb     |    4996 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:48.482695-04 | 2014-06-28 22:46:48.482695-04 | 2014-06-28 22:46:44.688203-04 | 192.111.11.111 |       37169
 464875 | mydb     |    4998 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:48.432836-04 | 2014-06-28 22:46:48.432836-04 | 2014-06-28 22:46:44.703883-04 | 192.111.11.111 |       37170

-- many more

 464875 | mydb     |    5052 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.584386-04 | 2014-06-28 22:46:59.584386-04 | 2014-06-28 22:46:51.85682-04  | 192.111.11.111 |       37360
 464875 | mydb     |    5053 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.506483-04 | 2014-06-28 22:46:59.506483-04 | 2014-06-28 22:46:52.083316-04 | 192.111.11.111 |       37367
 464875 | mydb     |    8958 |    16387 | myuser | <IDLE>                                                                                                                                                            | f       |                               | 2014-06-29 00:05:06.735249-04 | 2014-06-27 16:34:39.307312-04 | 192.111.11.111 |       52759
 464875 | mydb     |    5054 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.52573-04  | 2014-06-28 22:46:59.52573-04  | 2014-06-28 22:46:52.285867-04 | 192.111.11.111 |       37371
 464875 | mydb     |    5055 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.530804-04 | 2014-06-28 22:46:59.530804-04 | 2014-06-28 22:46:52.303562-04 | 192.111.11.111 |       37372
 464875 | mydb     |    5056 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.572198-04 | 2014-06-28 22:46:59.572198-04 | 2014-06-28 22:46:52.31447-04  | 192.111.11.111 |       37373
 464875 | mydb     |    5057 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.872037-04 | 2014-06-28 22:46:59.872037-04 | 2014-06-28 22:46:52.323721-04 | 192.111.11.111 |       37374
 464875 | mydb     |    5058 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.961803-04 | 2014-06-28 22:46:59.961803-04 | 2014-06-28 22:46:52.334238-04 | 192.111.11.111 |       37375
 464875 | mydb     |    5059 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.53713-04  | 2014-06-28 22:46:59.53713-04  | 2014-06-28 22:46:52.347227-04 | 192.111.11.111 |       37376
 464875 | mydb     |    5060 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:47:00.208948-04 | 2014-06-28 22:47:00.208948-04 | 2014-06-28 22:46:52.360008-04 | 192.111.11.111 |       37377
 464875 | mydb     |    5061 |    16387 | myuser | SELECT  "reports".* FROM "reports"  WHERE (("reports"."time" < '2014-06-28 13:30:42.000000' AND "reports"."unit_id" = 3192)) ORDER BY "reports"."id" DESC LIMIT 1 | f       | 2014-06-28 22:46:59.938983-04 | 2014-06-28 22:46:59.938983-04 | 2014-06-28 22:46:52.369496-04 | 192.111.11.111 |       37378

Echa un vistazo a pg_stat_activity.backend_start. ¿Se crearon estas conexiones antes o después del reinicio del servidor web? Si todas son conexiones nuevas, me imagino que eso significa que el problema está en el extremo del servidor web.
Nick Barnes

@NickBarnes, todas estas conexiones tienen la misma consulta en la columna "current_query" y el tiempo backend_start es prácticamente el mismo para todas ellas (con una separación de milisegundos). Eso es lo que es tan extraño y creo que si la memoria me sirve, todos estaban antes del reinicio. Pero supuse que el reinicio rompería la conexión.
JohnMerlino

1
Ok ... Es posible que deba verificar topel servidor para ver si estos procesos están ocupados. Si lo son, creo que las conexiones deberían desaparecer una vez que finalicen las consultas (o, alternativamente, puede matarlas ahora). Si están inactivos y las conexiones están definitivamente muertas, entonces no estoy seguro de lo que está sucediendo o cómo prevenirlo la próxima vez ...
Nick Barnes

1
Verifique la waitingbandera pg_stat_activity, vea si están atrapados en una cerradura.
Craig Ringer

1
La salida que pegó SELECT * FROM pg_stat_activity;no es creíble: no hay suficientes columnas. ¿Qué dice la columna de estado? Ese es el campo más importante para esta pregunta.
eradman

Respuestas:


5

Esto parece ser un problema específico de programación del cliente. No podrá solucionar esto, por ejemplo, elevando el parámetro "max_ connections".

He encontrado un posible problema relacionado: agrupación de conexiones de base de datos Ruby

Aunque también podría hacer un poco más de depuración del lado del servidor:

Habilite "log_connections" y "log_disconnections". Utilice también "log_line_prefix" con "% m% a% p".

Las aplicaciones muy útiles para depurar servidores PostgreSQL son powa o mucho más superiores como: pg_activity

Para la depuración del servidor en tiempo real, prefiero pg_activity , especialmente con su función para mostrar bloqueadores y matar sesiones.


-4

Esta es la mejor manera de resolver el problema ... funciona

Inicie sesión en el servidor con masilla SSH,

sudo /etc/init.d/postgresql stop

esto mata los procesos de registro muertos en la base de datos entonces,

sudo /etc/init.d/postgresql start


55
¿Y luego la próxima vez que detengas de nuevo un servidor de producción? Su solución elimina claramente los procesos atascados, pero no explica por qué están allí, ni es sostenible.
dezso
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.