Đối với những người quan tâm, đây là giải pháp tôi đã đưa ra, lấy cảm hứng từ Craig Ringer 's bình luận:
(...) sử dụng một công việc định kỳ để xem xét khi kết nối lần cuối tích cực (xem pg_stat_activity) và sử dụng pg_terminate_backend để giết những cái cũ (...)
Các giải pháp được lựa chọn đi xuống như thế này:.
- Đầu tiên, chúng tôi nâng cấp lên Postgresql 9.2.
- Sau đó, chúng tôi lên lịch một chuỗi để chạy mỗi giây.
- Khi chuỗi chạy, nó tìm kiếm bất kỳ kết nối không hoạt động cũ nào.
- Một kết nối được coi không hoạt động nếu trạng thái của nó là một trong hai
idle
, idle in transaction
, idle in transaction (aborted)
hoặc disabled
.
- Kết nối được coi là cũ nếu trạng thái cuối cùng của nó đã thay đổi trong hơn 5 phút.
- Có các chuỗi bổ sung tương tự như trên. Tuy nhiên, những luồng đó kết nối với cơ sở dữ liệu với người dùng khác.
- Chúng tôi để lại ít nhất một kết nối mở cho bất kỳ ứng dụng nào được kết nối với cơ sở dữ liệu của chúng tôi. (
rank()
chức năng)
Đây là truy vấn SQL chạy bởi thread:
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
Bạn có thể sử dụng một công việc định kỳ để xem xét khi kết nối lần cuối hoạt động (xem 'pg_stat_activity') và sử dụng' pg_terminate_backend' để giết người cũ. Dễ dàng thể hiện trong một truy vấn đơn giản. Tôi không chắc liệu 'pg_terminate_backend' có sẵn trong phiên bản 8.3 hay không. –