2012-11-05 38 views
50
1 S postgres 5038 876 0 80 0 - 11962 sk_wai 09:57 ?  00:00:00 postgres: postgres my_app ::1(45035) idle                     
1 S postgres 9796 876 0 80 0 - 11964 sk_wai 11:01 ?  00:00:00 postgres: postgres my_app ::1(43084) idle    

Tôi thấy rất nhiều người trong số họ. Chúng tôi đang cố gắng khắc phục sự cố rò rỉ kết nối của mình. Nhưng trong khi đó, chúng tôi muốn thiết lập một thời gian chờ cho các kết nối nhàn rỗi, có thể tối đa đến 5 phút.Có thời gian chờ cho các kết nối PostgreSQL không hoạt động không?

+0

thế nào bạn kết nối với DB? socketTimeout có thể là những gì bạn đang tìm kiếm. – Doon

+0

Chúng tôi có ứng dụng web Pylons kế thừa này và chúng tôi đã sử dụng SQLAlchemy nhưng dường như chúng tôi đã không sử dụng đúng cách. Tôi không nhớ. Chúng tôi đang cố gắng sửa lỗi. 'socketTimeout' từ tài liệu có vẻ như điều này hoàn toàn đóng kết nối với DB. Tôi đang cố gắng đóng mỗi nhàn rỗi, và bộ đếm bắt đầu ngay sau khi kết nối được thiết lập. – user1012451

+4

xem http://stackoverflow.com/questions/12391174/is-it-possible-to-configure-postgresql-to-automatically-close-idle-connections – Doon

Trả lời

69

Có vẻ như bạn có lỗ kết nối kết nối trong đơn đăng ký của mình vì nó không đóng được kết nối được gộp chung. Bạn không gặp sự cố chỉ với các phiên <idle> in transaction, nhưng với quá nhiều kết nối tổng thể.

Kết nối giết người không phải là câu trả lời đúng cho điều đó, nhưng đó là giải pháp tạm thời OK-ish.

Thay vì khởi động lại PostgreSQL để khởi động tất cả các kết nối khác khỏi cơ sở dữ liệu PostgreSQL, hãy xem: How do I detach all other users from a postgres database?How to drop a PostgreSQL database if there are active connections to it?. Sau đó cho thấy một truy vấn tốt hơn.

Để đặt thời gian chờ, như @Doon đề xuất, hãy xem How to close idle connections in PostgreSQL automatically?, lời khuyên bạn nên sử dụng PgBouncer cho proxy cho PostgreSQL và quản lý các kết nối không sử dụng. Đây là một ý tưởng rất tốt nếu bạn có một ứng dụng lỗi mà rò rỉ kết nối anyway; Tôi rất mạnh mẽ khuyên bạn nên định cấu hình PgBouncer.

A TCP keepalive sẽ không thực hiện công việc ở đây, bởi vì ứng dụng vẫn còn kết nối và còn sống, nó không nên.

Trong PostgreSQL 9.2 trở lên, bạn có thể sử dụng cột dấu thời gian state_change mới và trường statuspg_stat_activity để triển khai trình kết nối rảnh 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ũ, bạn cần triển khai các đề án phức tạp theo dõi khi kết nối không hoạt động. Đừng bận tâm; chỉ cần sử dụng pgbouncer.

+0

Tốt, nhưng nó sẽ giết các chương trình phụ trợ khác của PgAdmin. Sử dụng điều kiện bổ sung application_name = '' –

+0

Tôi có thể chạy pg_terminate_backend nếu tôi đang sử dụng pgbouncer không? –

+0

@HenleyChiu Tôi không hiểu tại sao không, mặc dù tôi chưa kiểm tra cụ thể. –

15

Trong PostgreSQL 9.1, các kết nối không hoạt động với truy vấn sau. Nó đã giúp tôi tránh khỏi tình huống mà bảo đảm trong việc khởi động lại cơ sở dữ liệu. Điều này xảy ra chủ yếu với các kết nối JDBC được mở và không đóng đúng cách.

SELECT 
    pg_terminate_backend(procpid) 
FROM 
    pg_stat_activity 
WHERE 
    current_query = '<IDLE>' 
AND 
    now() - query_start > '00:10:00'; 
+0

pg_terminate_backend đến từ 8.4 –

+0

Đã cứu mạng tôi !! –

20

Trong PostgreSQL 9.6, có một tùy chọn mới idle_in_transaction_session_timeout nên hoàn thành những gì bạn mô tả. Bạn có thể đặt nó bằng cách sử dụng lệnh SET, ví dụ:

SET SESSION idle_in_transaction_session_timeout = '5min'; 
+0

Nó hút phải hỏi một cái gì đó rất đơn giản nhưng tôi là thương hiệu mới cho cơ sở dữ liệu nói chung - Bạn có thể vui lòng đưa ra một ví dụ rất cơ bản về cách sử dụng chức năng này? –

+2

Không sao, cập nhật câu trả lời. – shosti

+0

Bất cứ điều gì như thế này trong các phiên bản trước của PostgreSQL ?? – sdsc81

0

nếu bạn đang sử dụng 9.6+ postgresql, sau đó trong postgresql.conf của bạn, bạn có thể thiết lập

idle_in_transaction_session_timeout = 30000(msec)

Các vấn đề liên quan