Sepertinya Anda mengalami kebocoran koneksi dalam aplikasi Anda karena gagal menutup koneksi yang dikumpulkan . Anda tidak hanya mengalami masalah dengan <idle> in transaction
sesi, tetapi dengan terlalu banyak koneksi secara keseluruhan.
Membunuh koneksi bukanlah jawaban yang tepat untuk itu, tetapi ini adalah solusi sementara yang OK-ish.
Daripada memulai kembali PostgreSQL untuk mem-boot semua koneksi lain dari database PostgreSQL, lihat: Bagaimana cara melepaskan semua pengguna lain dari database postgres? dan Bagaimana cara menjatuhkan database PostgreSQL jika ada koneksi aktif ke sana? . Yang terakhir menunjukkan kueri yang lebih baik.
Untuk mengatur waktu tunggu, seperti yang disarankan @Doon, lihat Bagaimana cara menutup koneksi yang tidak aktif di PostgreSQL secara otomatis? , yang menyarankan Anda untuk menggunakan PgBouncer sebagai proxy untuk PostgreSQL dan mengelola koneksi yang tidak aktif. Ini adalah ide yang sangat bagus jika Anda memiliki aplikasi buggy yang tetap saja membocorkan koneksi; Saya sangat menyarankan mengonfigurasi PgBouncer.
Sebuah keepalive TCP tidak akan melakukan pekerjaan di sini, karena aplikasi masih terhubung dan hidup, itu hanya tidak seharusnya.
Di PostgreSQL 9.2 dan yang lebih baru, Anda dapat menggunakan state_change
kolom stempel waktu baru dan state
bidang pg_stat_activity
untuk mengimplementasikan mesin penuai koneksi idle. Minta cron job menjalankan sesuatu seperti ini:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'regress'
AND pid <> pg_backend_pid()
AND state = 'idle'
AND state_change < current_timestamp - INTERVAL '5' MINUTE;
Dalam versi yang lebih lama Anda perlu mengimplementasikan skema rumit yang melacak kapan koneksi menganggur. Jangan ganggu; gunakan saja pgbouncer.