Có vẻ như bạn bị rò rỉ kết nối trong ứng dụng của bạn vì ứng dụng đó không đóng được các kết nối được gộp chung . Bạn không gặp sự cố chỉ với <idle> in transaction
nhưng tổng thể có quá nhiều kết nối.
Loại bỏ kết nối không phải là câu trả lời thích hợp cho điều đó, nhưng đó là một giải pháp tạm thời ổn.
Thay vì khởi động lại PostgreSQL để khởi động tất cả các kết nối khác từ cơ sở dữ liệu PostgreSQL, hãy xem:Làm cách nào để tách tất cả người dùng khác khỏi cơ sở dữ liệu postgres? và Làm thế nào để loại bỏ một cơ sở dữ liệu PostgreSQL nếu có các kết nối đang hoạt động với nó? . Phần sau hiển thị một truy vấn tốt hơn.
Để đặt thời gian chờ, như @Doon đã đề xuất, hãy xem Cách tự động đóng các kết nối không hoạt động trong PostgreSQL ?, khuyên bạn nên sử dụng PgBouncer để ủy quyền cho PostgreSQL và quản lý các kết nối không hoạt động. Đây là một ý tưởng rất hay nếu bạn có một ứng dụng bị lỗi làm rò rỉ kết nối; Tôi rất mạnh mẽ khuyên bạn nên định cấu hình PgBouncer.
Một lưu trữ TCP sẽ không thực hiện công việc ở đây, bởi vì ứng dụng vẫn được kết nối và tồn tại, điều đó không nên xảy ra.
Trong PostgreSQL 9.2 trở lên, bạn có thể sử dụng state_change
mới cột dấu thời gian và state
trường pg_stat_activity
để triển khai một máy gặt kết nối nhàn rỗi. Có một công việc cron chạy một cái gì đó như thế này:
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;
Trong các phiên bản cũ hơn, bạn cần triển khai các lược đồ phức tạp để theo dõi thời điểm kết nối không hoạt động. Đừng bận tâm; chỉ cần sử dụng pgbouncer.