убить -9 процесс postgres


25

Запрос 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 в эти дни? Спасибо за понимание.

Ответы:


31

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

kill -9(то есть SIGKILL) никогда не должно быть вашим выбором по умолчанию . Это должно быть вашим последним средством, когда процесс не отвечает на свои обычные запросы на отключение и a 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бэкэнд.


1
Все очень хорошие ответы здесь и очень унизительно, я мог бы добавить. Я мог бы пометить их всех как принятых, но у @Craig Ringer есть несколько дополнительных баллов, которые действительно помогают ему. Еще раз спасибо SF за то, что вычистил меня от вредных привычек!
Banjer

2
@Craig: Какой превосходный ответ; и чтобы включить демонстрацию, я хотел бы проголосовать до 100 раз. Я разработчик программного обеспечения, который работает с PG ежедневно и с 6.x дней, и ваш ответ на месте! Ницца!
Кило

2
Хороший ответ. Приложение: если у вас есть бэкэнд-процесс, который абсолютно не умрет - ни с помощью pg_terminate_backend, ни с перезапуском стека серверов, ни с чем, вы можете убить его как угодно, но убедитесь, что у вас есть рабочая резервная копия вашей базы данных. Вы можете сделать это несколькими способами: вы можете использовать pg_basebackupили подобное (или просто rsyncи pg_start\stop_backup) для резервного копирования вашего каталога данных (тестируйте резервные копии перед продолжением!), Или вы можете использовать, pg_dump[all]чтобы спасти ваши данные. Только тогда вы должны рассмотреть kill -9, или перезагрузку, или что-то еще.
Зак Б

1
@ZacB Да, и если ты убьешь это, удостоверься, что все бэкэнды умирают. Самое главное, никогда не удаляйте postmaster.pid. Когда-либо.
Крейг Рингер,

29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
НЕТ! ПЛОХО! ШАГ ВНЕ ОТ БАКЕНДА!

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

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

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

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

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


4
На случай, если кто-нибудь задумается об ужасных вещах, учитывая, что kill -9это не похоже на внезапное отключение системы в том, что касается убитого процесса: Pg очень терпимо относится к сбоям бэкэнда (например, a kill -9), и никогда не должно быть повреждения данных. Там будет находиться с коррупцией , если вы убиваете почтмейстер , удалить postmaster.pid и перезапустить его , не убивая также каждый бэкенд первым. Это будет уничтожить вашу базу данных, но занимает много больше , чем просто kill -9с внутренним сервером. kill -9не дает почтмейстеру времени убивать бэкэндов, поэтому это опасно.
Крейг Рингер

2
... как случай экстренной консультации, которую я имел на прошлой неделе. Сильно повредил их базу данных, потерял два дня работы из-за сбоя их резервного копирования (и они не проводили автоматическое тестирование своих восстановлений), не работал 48 часов. Не удаляйте postmaster.pid.
Крейг Рингер

8

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

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

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


4
kill -9в любом случае никогда не должно быть вашим выбором по умолчанию, это последнее средство. Отправить SIGTERMс kill -TERMили простой, killи если получатель не отвечает через некоторое время, только тогда вы должны рассмотреть kill -KILL( kill -9).
Крейг Рингер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.