Bagi mereka yang tertarik, inilah solusi yang saya buat, terinspirasi dari komentar Craig Ringer:
(...) gunakan tugas cron untuk melihat kapan koneksi terakhir aktif (lihat pg_stat_activity) dan gunakan pg_terminate_backend untuk mematikan koneksi lama.(...)
Solusi yang dipilih turun seperti ini:
- Pertama, kita upgrade ke Postgresql 9.2.
- Kemudian, kami menjadwalkan utas untuk dijalankan setiap detik.
- Saat utas berjalan, utas akan mencari koneksi lama yang tidak aktif.
- Sambungan dianggap tidak aktif jika statusnya apakah
idle
,idle in transaction
,idle in transaction (aborted)
ataudisabled
. - Sambungan dianggap lama jika statusnya tetap sama selama lebih dari 5 menit.
- Sambungan dianggap tidak aktif jika statusnya apakah
- Ada utas tambahan yang melakukan hal yang sama seperti di atas. Namun, utas tersebut terhubung ke database dengan pengguna yang berbeda.
- Kami membiarkan setidaknya satu koneksi terbuka untuk aplikasi apa pun yang terhubung ke database kami. (
rank()
fungsi)
Ini adalah kueri SQL yang dijalankan oleh utas:
WITH inactive_connections AS (
SELECT
pid,
rank() over (partition by client_addr order by backend_start ASC) as rank
FROM
pg_stat_activity
WHERE
-- Exclude the thread owned connection (ie no auto-kill)
pid <> pg_backend_pid( )
AND
-- Exclude known applications connections
application_name !~ '(?:psql)|(?:pgAdmin.+)'
AND
-- Include connections to the same database the thread is connected to
datname = current_database()
AND
-- Include connections using the same thread username connection
usename = current_user
AND
-- Include inactive connections only
state in ('idle', 'idle in transaction', 'idle in transaction (aborted)', 'disabled')
AND
-- Include old connections (found with the state_change field)
current_timestamp - state_change > interval '5 minutes'
)
SELECT
pg_terminate_backend(pid)
FROM
inactive_connections
WHERE
rank > 1 -- Leave one connection for each application connected to the database