giết -9 một quá trình postgres


25

Một truy vấn CHỌN postgres đã hết kiểm soát trên máy chủ DB của chúng tôi và bắt đầu ăn hết hàng tấn bộ nhớ và trao đổi cho đến khi máy chủ hết bộ nhớ. Tôi tìm thấy quá trình cụ thể thông qua ps aux | grep postgresvà chạy kill -9 pid. Điều này đã giết quá trình và bộ nhớ giải phóng như mong đợi. Phần còn lại của hệ thống và truy vấn postgres dường như không bị ảnh hưởng. Máy chủ này đang chạy postgres 9.1.3 trên SLES 9 SP4.

Tuy nhiên, một trong những nhà phát triển của chúng tôi đã nhai tôi vì đã giết quá trình postgres kill -9, nói rằng nó sẽ phá hủy toàn bộ dịch vụ postgres. Trong thực tế, nó đã không. Tôi đã làm điều này trước một vài lần và không thấy bất kỳ tác dụng phụ tiêu cực nào.

Như đã nói, và sau khi đọc thêm, có vẻ như kill pidkhông có cờ là cách ưa thích để giết quá trình postgres chạy trốn, nhưng đối với những người dùng khác trong cộng đồng postgres, có vẻ như postgres đã "trở nên tốt hơn" trong những năm qua kill -9trên một quy trình truy vấn cá nhân / chủ đề không còn là bản án tử hình.

Ai đó có thể khai sáng cho tôi cách thích hợp để tiêu diệt quá trình postgres bỏ trốn cũng như mức độ tai hại (hoặc lành tính) sử dụng kill -9với Postgres ngày nay không? Cảm ơn vì sự sáng suốt.

Câu trả lời:


31

Câu trả lời của voretaq7 bao gồm các điểm chính, bao gồm cách chính xác để chấm dứt phụ trợ nhưng tôi muốn thêm một chút giải thích.

kill -9(tức là SIGKILL) không bao giờ, bao giờ, sẽ là mặc định lựa chọn đầu tiên của bạn . Nó sẽ là giải pháp cuối cùng của bạn khi quá trình không đáp ứng với các yêu cầu tắt máy thông thường của nó và SIGTERM( kill -15) không có hiệu lực. Điều đó đúng với PG và khá nhiều thứ khác.

kill -9 làm cho quá trình bị giết không có cơ hội để làm bất kỳ việc dọn dẹp nào cả.

Khi nói đến PostgreSQL, PG thấy một sự hỗ trợ bị chấm dứt bởi kill -9sự cố được hỗ trợ . Nó biết phần phụ trợ có thể đã bị hỏng bộ nhớ chia sẻ - vì bạn có thể đã làm gián đoạn nó nửa chừng bằng cách viết một trang thành shm hoặc sửa đổi một trang, chẳng hạn - vì vậy nó chấm dứt và khởi động lại tất cả các phần phụ trợ khác khi thông báo rằng phần phụ trợ đột nhiên biến mất và thoát với mã lỗi khác không.

Bạn sẽ thấy điều này được báo cáo trong nhật ký.

Nếu nó dường như không gây hại, thì bởi vì PG đang khởi động lại mọi thứ sau sự cố và ứng dụng của bạn đang phục hồi sạch sẽ từ các kết nối bị mất. Điều đó không làm cho nó một ý tưởng tốt. Nếu không có gì khác, các sự cố phụ trợ được kiểm tra ít hơn so với các bộ phận hoạt động bình thường của PG và phức tạp / đa dạng hơn nhiều, vì vậy khả năng xảy ra lỗi trong xử lý và phục hồi sự cố phụ trợ cao hơn.

BTW, nếu bạn kill -9là người quản lý bưu điện, sau đó loại bỏ postmaster.pidvà bắt đầu lại mà không đảm bảo mọi postgresphụ trợ đều biến mất, những điều rất xấu có thể xảy ra . Điều này có thể dễ dàng xảy ra nếu bạn vô tình giết chết người quản lý bưu điện thay vì phụ trợ, thấy cơ sở dữ liệu bị hỏng, cố gắng khởi động lại, xóa tệp .pid "cũ" khi khởi động lại thất bại và cố gắng khởi động lại. Đó là một trong những lý do bạn nên tránh vẫy tay chào kill -9và không nên xóa postmaster.pid.

Một cuộc biểu tình:

Để xem chính xác những gì xảy ra khi bạn kill -9phụ trợ, hãy thử các bước đơn giản sau. Mở hai thiết bị đầu cuối, mở psql trong mỗi thiết bị và trong mỗi lần chạy SELECT pg_backend_pid();. Trong một thiết bị đầu cuối khác, kill -9một trong các PID. Bây giờ chạy SELECT pg_backend_pid();trong cả hai phiên psql một lần nữa. Chú ý làm thế nào cả hai mất kết nối của họ?

Phần 1, mà chúng tôi đã giết:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6357
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6463
(1 row)

Phần 2, đó là thiệt hại tài sản thế chấp:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6283
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
WARNING:  terminating connection because of crash of another server process
DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6464
(1 row)

Xem làm thế nào cả hai phiên bị phá vỡ? Đó là lý do tại sao bạn không kill -9phụ trợ.


1
Tất cả các câu trả lời rất tốt ở đây, và tôi rất khiêm tốn. Tôi có thể đánh dấu tất cả chúng là được chấp nhận, nhưng @Craig Ringer có một số điểm bổ sung ở đây và thực sự khiến nó trở nên tuyệt vời. Cảm ơn một lần nữa SF đã làm sạch tôi những thói quen xấu của tôi!
Banjer

2
@Craig: Thật là một phản ứng tuyệt vời; và để bao gồm một cuộc biểu tình, tôi ước tôi có thể bỏ phiếu 100 lần này. Tôi là nhà phát triển phần mềm làm việc với PG hàng ngày và kể từ ngày 6.x và phản hồi của bạn được chú ý! Tốt đẹp!
Kilo

2
Câu trả lời tốt đẹp. Một phụ lục: nếu bạn có một quá trình phụ trợ hoàn toàn sẽ không chết - không phải với pg_terminate_backend, không phải với khởi động lại ngăn xếp máy chủ, không phải bất cứ điều gì, bạn có thể giết nó theo cách bạn muốn, nhưng hãy chắc chắn rằng bạn có một bản sao lưu cơ sở dữ liệu của bạn. Bạn có thể làm điều đó theo một số cách: bạn có thể sử dụng pg_basebackuphoặc tương tự (hoặc chỉ rsyncpg_start\stop_backup) để sao lưu thư mục dữ liệu của mình (kiểm tra các bản sao lưu trước khi tiếp tục!) Hoặc bạn có thể sử dụng pg_dump[all]để cứu hộ dữ liệu của mình. Chỉ sau đó bạn nên xem xét kill -9, hoặc khởi động lại, hoặc bất cứ điều gì.
Zac B

1
@ZacB Yep, và nếu bạn giết nó, hãy đảm bảo tất cả các phụ trợ đều chết. Mạnh mẽ nhất, không bao giờ xóa postmaster.pid. Không bao giờ.
Craig Ringer

29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
KHÔNG! XẤU! BƯỚC NGAY TỪ TRỞ LẠI!

Nghiêm túc - Đừng giết các phần cuối của Postgres như thế - Điều TERRIBLE có thể xảy ra (ngay cả với tất cả các cải tiến ổn định đã được thực hiện kể từ 7.x ngày) có thể làm hỏng toàn bộ DB của bạn và nhà phát triển của bạn hoàn toàn có quyền nhai bạn ra ngoài để làm điều này.

Trên thực tế, có một cách may mắn và được chấp thuận để thực hiện việc này từ bên trong Postgres - Ngay cả trong hướng dẫn của Postgres mặc dù bài đăng SO đó làm tốt hơn việc giải thích nó ...

SELECT pg_cancel_backend(pid)
Gửi SIGINTtín hiệu hủy ( ) đến phụ trợ đã chỉ định, hủy bỏ truy vấn hiện đang chạy.

select pg_terminate_backend(pid)
Gửi SIGTERMtín hiệu kết thúc ( ) đến phụ trợ đã chỉ định, hủy bỏ truy vấn và hủy bỏ phụ trợ (bỏ kết nối của nó).

ID cuối cùng có thể được lấy từ pg_stat_activitybảng (hoặc ps)


4
Trong trường hợp bất kỳ ai thắc mắc về những điều khủng khiếp, cho rằng điều đó kill -9không giống với việc đột nhiên tắt nguồn hệ thống khi có liên quan đến quá trình bị giết: PG rất chịu đựng các sự cố phụ trợ (như a kill -9) và không bao giờ nên tham nhũng dữ liệu. Có sẽ được tham nhũng nếu bạn giết bưu điện , loại bỏ postmaster.pid, và khởi động lại mà không có cũng giết chết tất cả các phụ trợ đầu tiên. Điều đó sẽ phá hủy cơ sở dữ liệu của bạn, nhưng mất nhiều hơn chỉ là kill -9một phụ trợ. kill -9không cho bưu điện thời gian để tiêu diệt các phụ trợ, đó là lý do tại sao nó nguy hiểm.
Craig Ringer

2
... giống như một trường hợp tư vấn khẩn cấp tôi đã làm tuần trước. Cơ sở dữ liệu của họ bị hỏng nghiêm trọng, mất hai ngày làm việc vì các bản sao lưu của họ không thành công (và họ không tự động kiểm tra khôi phục), đã ngừng hoạt động trong 48 giờ. Đừng xóa postmaster.pid.
Craig Ringer

8

Giết một tiến trình máy khách PostgreSQL sẽ ổn. Giết một tiến trình daemon PostgreSQL có thể khiến bạn bị mắng.

Vì các trình nền SQL cũng có các điều khiển quy trình nội bộ, nên cách ưu tiên là thử sử dụng kênh đó trước.

Xem Dừng (dài) chạy truy vấn SQL trong PostgreSQL ... từ StackOverflow.


4
kill -9dù sao cũng không nên là lựa chọn mặc định của bạn, đó là phương sách cuối cùng. Gửi một SIGTERMvới kill -TERMhoặc đồng bằng killvà nếu người nhận không trả lời sau một thời gian, chỉ khi đó bạn nên xem xét kill -KILL( kill -9).
Craig Ringer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.