psql: FATAL: maaf, sudah terlalu banyak klien


16

Saya tiba-tiba mendapatkan kesalahan ini ketika mencoba mengakses situs web yang menggunakan database postgresql, atau bahkan ketika menggunakan utilitas psql atau pgadmin3.

Basis data saya diatur untuk menangani 150 koneksi maksimum:

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

Setelah me-reboot server ubuntu di mana situs web saya aktif (yang sebenarnya satu-satunya yang menggunakan koneksi), saya melihat jumlah koneksi saat ini adalah 140:

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

Saya tidak mengerti betapa tiba-tiba begitu banyak koneksi setelah me-reboot server saya. Jadi saya memeriksa aktivitas postgresql:

# SELECT * FROM pg_stat_activity;

Dan saya melihat lebih dari 100 kolom dengan kueri yang persis sama dengan yang terlihat seperti ini:

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

Yang lebih penting adalah mereka semua memiliki alamat klien yang sama (server web saya).

Server web ini menggunakan ruby ​​on rails dengan kumpulan koneksi 50. Meskipun ada kumpulan koneksi 50, konfigurasi proses Penumpang / prefork apache adalah single-threaded dan oleh karena itu setiap proses tidak dapat menelurkan 50 thread dan 50 koneksi basis data. Terlebih lagi ini terjadi setelah sistem reboot yang merobohkan semua pengguna dari server web saya. Kemungkinannya adalah postgresql pada server database tidak mengetahui server web reboot dan masih mencoba untuk mengeksekusi query ini.

Untuk menjawab komentar Craig, di bawah kolom tunggu muncul tulisan 'f'. Tampaknya kueri masih menjalankan dan kunci belum dirilis. Seperti yang saya katakan sebelumnya, yang sangat aneh adalah bahwa tiba-tiba lebih dari 100 pertanyaan identik satu sama lain dalam milidetik terpisah tiba-tiba muncul dalam keadaan eksekusi ini. Itulah misteri bagiku:

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

Lihatlah pg_stat_activity.backend_start. Apakah koneksi ini dibuat sebelum atau setelah server web reboot? Jika mereka semua koneksi baru, saya bayangkan itu berarti masalahnya ada di server web.
Nick Barnes

@NickBarnes koneksi ini semua memiliki kueri yang sama di bawah kolom "current_query" dan waktu backend_start praktis sama untuk mereka semua (terpisah milidetik). Itulah yang sangat aneh dan saya percaya jika ingatan saya benar, mereka semua sebelum reboot. Tetapi saya berasumsi bahwa reboot akan memutus koneksi.
JohnMerlino

1
Oke ... Anda mungkin perlu memeriksa topserver untuk melihat apakah proses ini sibuk. Jika ya, maka saya pikir koneksi harus menghilang setelah pertanyaan selesai (atau sebagai alternatif, Anda bisa membunuh mereka sekarang). Jika mereka menganggur, dan koneksinya benar-benar mati, maka saya tidak yakin apa yang terjadi, atau bagaimana cara mencegahnya lain kali ...
Nick Barnes

1
Periksa waitingflag in pg_stat_activity, lihat apakah mereka terjebak di kunci.
Craig Ringer

1
Output yang Anda tempel SELECT * FROM pg_stat_activity;tidak dapat dipercaya - tidak ada cukup kolom. Apa yang dikatakan kolom negara bagian? Itulah bidang yang paling penting untuk pertanyaan ini.
eradman

Jawaban:


5

Ini tampaknya merupakan masalah khusus pemrograman klien. Anda tidak akan dapat memperbaikinya dengan misalnya meningkatkan parameter "max_connections".

Saya telah menemukan masalah terkait yang mungkin: pooling koneksi database Ruby

Allthough Anda juga bisa melakukan lebih banyak debug sisi server:

Aktifkan "log_connections" dan "log_disconnections". Juga gunakan "log_line_prefix" dengan "% m% a% p".

Aplikasi yang sangat berguna untuk men -debug server PostgreSQL adalah powa atau lebih top seperti: pg_activity

Untuk debugging server realtime, saya lebih suka pg_activity - terutama dengan fitur untuk menampilkan blocker dan untuk membunuh sesi.


-4

Ini adalah cara terbaik untuk menyelesaikan masalah ... itu berhasil

Masuk ke server menggunakan SSH dempul,

sudo /etc/init.d/postgresql berhenti

ini membunuh proses log mati dalam database kemudian,

sudo /etc/init.d/postgresql mulai


5
Dan lain kali Anda berhenti lagi server produksi? Solusi Anda dengan jelas menghilangkan proses yang macet, tetapi tidak menjelaskan mengapa mereka ada di sana, juga tidak berkelanjutan.
dezso
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.