psql:致命:對不起,已經有太多客戶了
在嘗試訪問使用 postgresql 數據庫的網站時,甚至在使用 psql 實用程序或 pgadmin3 時,我突然收到此錯誤。
我的數據庫設置為最多處理 150 個連接:
# SHOW max_connections; max_connections ----------------- 150 (1 row)
重新啟動我的網站所在的 ubuntu 伺服器後(這實際上是唯一使用連接的東西),我看到目前的連接數是 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
更重要的是它們都具有相同的客戶端地址(我的 Web 伺服器)。
此 Web 伺服器使用 ruby on rails 連接池為 50。即使連接池為 50,Passenger 程序/prefork apache 配置是單執行緒的,因此每個程序無法產生 50 個執行緒和 50 個數據庫連接。更重要的是,這發生在系統重新啟動後,將所有使用者都從我的 Web 伺服器中刪除。可能是數據庫伺服器上的 postgresql 不知道 Web 伺服器重新啟動,並且仍在嘗試執行這些查詢。
為了回答克雷格的評論,在等待欄下顯示字母“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
這似乎是客戶端程式的特定問題。您將無法通過例如提高“max_connections”參數來解決此問題。
我發現了一個可能的相關問題: Ruby database connection pooling
儘管您還可以進行更多伺服器端調試:
啟用“log_connections”和“log_disconnections”。還將“log_line_prefix”與“%m %a %p”一起使用。
用於調試 PostgreSQL 伺服器的非常有用的應用程序是powa或更多頂級應用程序,例如:pg_activity
對於實時伺服器調試,我更喜歡pg_activity - 特別是它具有顯示阻止程序和終止會話的功能。
可能主要是由於開發環境。
如果將 knex.js 用於 pql + next.js,請檢查此問題