Назад | Перейти на главную страницу

kill -9 процесс postgres

Запрос postgres SELECT вышел из-под контроля на нашем сервере БД и начал поглощать тонны памяти и подкачки, пока на сервере не закончилась память. Я нашел конкретный процесс через ps aux | grep postgres и побежал kill -9 pid. Это остановило процесс, и память освободилась, как и ожидалось. Остальные системные и postgres запросы не пострадали. Этот сервер работает под управлением postgres 9.1.3 на SLES 9 SP4.

Однако один из наших разработчиков разжег меня за то, что я убил процесс postgres с помощью kill -9, сказав, что это приведет к отключению всей службы postgres. На самом деле это не так. Я делал это несколько раз и не видел никаких отрицательных побочных эффектов.

С учетом сказанного и после дальнейшего чтения, похоже, kill pid без флагов - это предпочтительный способ убить беглый процесс postgres, но для других пользователей в сообществе postgres это также звучит так, как будто postgres «улучшился» с годами, так что kill -9 по отдельному процессу / потоку запроса больше не является смертным приговором.

Может ли кто-нибудь просветить меня о том, как правильно убить беглый процесс postgres, а также о том, насколько катастрофическим (или безвредным) использование kill -9 сейчас с Postgres? Спасибо за понимание.

voretaq7с ответ охватывает ключевые моменты, в том числе правильный способ завершить бэкенд но я хотел бы добавить еще немного пояснения.

kill -9 (т.е. SIGKILL) никогда и никогда не должно быть вашим первым выбором по умолчанию. Это должно быть вашим последним средством, когда процесс не отвечает на свои обычные запросы на завершение работы и SIGTERM (kill -15) не повлиял. Это верно в отношении Pg и почти всего остального.

kill -9 не дает убитому процессу вообще никакой возможности произвести очистку.

Что касается PostgreSQL, Pg видит поддержку, которая прервана kill -9 как подкрепленный крах. Он знает, что бэкэнд мог повредить разделяемую память - потому что вы могли прервать его на полпути, например, записав страницу в shm или изменив ее - так что он завершает и перезапускает все остальные серверы когда он замечает, что серверная часть внезапно исчезла и завершилась с ненулевым кодом ошибки.

Вы увидите это в журналах.

Если кажется, что это не причинит вреда, это потому, что Pg перезапускает все после сбоя, и ваше приложение полностью восстанавливается после потерянных соединений. Это не очень хорошая идея. Если нет ничего другого, сбои серверной части менее хорошо протестированы, чем нормально функционирующие части Pg, и гораздо более сложны / разнообразны, поэтому шансы на ошибку, скрывающуюся в обработке сбоев и восстановлении серверной части, выше.

Кстати, если вы kill -9 почтмейстер затем удалить postmaster.pid и запустите его снова, не проверяя каждый postgres бэкэнд ушел, могут случиться очень плохие вещи. Это может легко произойти, если вы случайно убили почтмейстера вместо серверной части, увидели, что база данных перестала работать, попытались перезапустить ее, удалили «устаревший» файл .pid, когда перезапуск не удался, и попытались перезапустить его снова. Это одна из причин, по которой вам следует избегать размахивания руками kill -9 вокруг Pg, и не следует удалять postmaster.pid.

Демонстрация:

Чтобы увидеть, что именно происходит, когда вы kill -9 бэкэнд, попробуйте эти простые шаги. Откройте два терминала, откройте psql в каждом и при каждом запуске SELECT pg_backend_pid();. В другом терминале kill -9 один из PID. Теперь беги SELECT pg_backend_pid(); снова в обоих сеансах psql. Обратите внимание, как они обе потеряли связи?

Сессия 1, которую мы убили:

$ 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)

Сессия 2, на которой был нанесен побочный ущерб:

$ 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)

Смотри как обе сессии были прерваны? Вот почему ты не kill -9 бэкэнд.

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
НЕТ! ПЛОХОЙ! ОТХОДИТЕ ОТ ОБРАТНОЙ СТАЛИ!

Серьезно - не убивайте бэкенды Postgres подобным образом - могут произойти УЖАСНЫЕ вещи (даже со всеми улучшениями стабильности, которые были сделаны после 7.x дней), которые могут испортить всю вашу БД, и ваш разработчик совершенно прав, разжевывая вы за это делаете.

На самом деле есть благословенный и одобренный способ сделать это из Postgres - Это даже в Руководство Postgres хотя этот пост SO лучше объясняет это ...

SELECT pg_cancel_backend(pid)
Отправляет отмену (SIGINT) на указанный бэкэнд, который отменяет текущий выполняющийся запрос.

select pg_terminate_backend(pid)
Отправляет завершение (SIGTERM) к указанному бэкэнду, который отменяет запрос и прерывает бэкэнд (разрывая его соединение).

Идентификаторы бэкэнда можно получить из pg_stat_activity стол (или ps)

Убить клиентский процесс PostgreSQL должно быть нормально. Если вы убьете процесс демона PostgreSQL, вас могут отругать.

Поскольку у демонов SQL также есть внутренние средства управления процессами, лучше всего сначала попробовать использовать этот канал.

Видеть Остановить (долгое) выполнение SQL-запроса в PostgreSQL ... из StackOverflow.