psql : 치명적 : 너무 많은 클라이언트가 이미 있습니다


16

postgresql 데이터베이스를 사용하는 웹 사이트에 액세스하거나 psql 유틸리티 또는 pgadmin3을 사용할 때 갑자기이 오류가 발생합니다.

내 데이터베이스는 최대 150 개의 연결을 처리하도록 설정되어 있습니다.

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

내 웹 사이트가있는 우분투 서버를 재부팅 한 후 (실제로 연결을 사용하는 유일한 것임) 현재 연결 수가 140입니다.

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

서버를 재부팅 한 후 얼마나 갑자기 연결이 많은지 이해하지 못합니다. 그래서 postgresql 활동을 확인합니다.

# SELECT * FROM pg_stat_activity;

그리고 다음과 같은 정확한 쿼리가있는 100 개가 넘는 열을 봅니다.

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

더 중요한 것은 모두 동일한 클라이언트 주소 (내 웹 서버)를 가지고 있다는 것입니다.

이 웹 서버는 연결 풀이 50 인 루비 온 레일을 사용하고 있습니다. 연결 풀이 50이지만 여객 프로세스 / 프리 포크 아파치 구성은 단일 스레드이므로 각 프로세스는 50 개의 스레드와 50 개의 데이터베이스 연결을 생성 할 수 없습니다. 또한 시스템을 재부팅 한 후 모든 사용자가 내 웹 서버에서 떨어져 나갔습니다. 데이터베이스 서버의 postgresql이 웹 서버 재부팅을 인식하지 못하고 이러한 쿼리를 계속 실행하려고 할 가능성이 있습니다.

Craig의 의견에 답하기 위해 대기 열 아래에 문자 'f'가 표시됩니다. 쿼리가 여전히 실행 중이고 잠금이 아직 해제되지 않은 것 같습니다. 앞에서 언급했듯이, 너무 이상한 점은 갑자기이 실행 상태에서 밀리 초 이내에 서로 동일한 100 개가 넘는 쿼리가 갑자기 나타납니다. 그것이 저에게 미스터리입니다.

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

를보십시오 pg_stat_activity.backend_start. 웹 서버를 재부팅하기 전이나 후에 이러한 연결이 생성 되었습니까? 그들이 모두 새로운 연결이라면 문제가 웹 서버 끝에 있다는 것을 의미합니다.
Nick Barnes

@NickBarnes 이러한 연결은 모두 "current_query"열에서 동일한 쿼리를 가지며 backend_start 시간은 모든 연결에서 실질적으로 동일합니다 (밀리 초 간격). 그것은 너무 이상한 일이며 메모리가 제대로 작동하면 재부팅하기 전에 모두 가능하다고 생각합니다. 그러나 재부팅하면 연결이 끊어 질 것이라고 가정했습니다.
JohnMerlino 2016 년

1
Ok ... top이러한 프로세스가 사용 중인지 확인 하기 위해 서버를 확인해야 할 수도 있습니다 . 그렇다면 쿼리가 끝나면 연결이 사라져야한다고 생각합니다 (또는 대안으로 지금 죽일 수 있습니다). 그들이 유휴 상태이고 연결이 확실히 죽었다면, 무슨 일이 일어나고 있는지 또는 다음 번에 그것을 막는 방법을 모르겠습니다 ...
Nick Barnes

1
waiting깃발을 확인하고 pg_stat_activity자물쇠에 붙어 있는지 확인하십시오 .
Craig Ringer 2018 년

1
붙여 넣은 결과 SELECT * FROM pg_stat_activity;는 믿을 수 없습니다. 열이 충분하지 않습니다. 상태 열은 무엇을 말합니까? 이것이이 질문에서 가장 중요한 분야입니다.
eradman

답변:


5

이것은 클라이언트 프로그래밍 관련 문제인 것 같습니다. "max_connections"매개 변수를 올리면이 문제를 해결할 수 없습니다.

가능한 관련 문제를 발견했습니다 : Ruby 데이터베이스 연결 풀링

모든 서버 측 디버깅을 수행 할 수도 있습니다.

"log_connections"및 "log_disconnections"를 활성화하십시오. 또한 "% m % a % p"와 함께 "log_line_prefix"를 사용하십시오.

PostgreSQL의 서버를 디버깅하기위한 매우 유용한 응용 프로그램은 powa 또는 훨씬 더 와 같은 최고 : pg_activity

실시간 서버 디버깅의 경우 pg_activity를 선호합니다. 특히 차단기를 표시하고 세션을 종료하는 기능이 있습니다.


-4

이것이 문제를 해결하는 가장 좋은 방법입니다.

SSH 퍼티를 사용하여 서버에 로그인하십시오.

sudo /etc/init.d/postgresql 중지

그러면 데이터베이스에서 데드 로그 프로세스가 종료됩니다.

sudo /etc/init.d/postgresql 시작


6
그리고 다음에 프로덕션 서버를 다시 중지 할 때? 귀하의 솔루션은 중단 된 프로세스를 명확하게 제거하지만 해당 프로세스가 존재하는 이유와 지속 가능한 프로세스를 설명하지는 않습니다.
dezso
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.