вбивати -9 процес постгресу


25

Постгрес SELECT-запит вийшов з-під контролю на нашому сервері БД і почав з’їдати тонни пам’яті та поміняти місцями, поки у сервера не вичерпалося пам’яті. Я знайшов конкретний процес через ps aux | grep postgresі побіг kill -9 pid. Це вбило процес, і пам'ять звільнилася, як очікувалося. Решта системних запитів та запитів постгресів не вплинули. Цей сервер працює за postgres 9.1.3 на SLES 9 SP4.

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

Зважаючи на це, і після подальшого читання, схоже, що kill pidбез прапорів є кращим способом вбити втікаючий постгресовий процес, але для інших користувачів у спільноті постгресів це також звучить як постграси "покращилися" з роками так, що kill -9за окремим запитом / потоком запиту вже не є смертним вироком.

Чи може хтось просвітити мене належним чином, щоб убити відбіг постгресового процесу, а також про те, наскільки згубним (або доброякісним) kill -9є використання Postgres в наші дні? Дякуємо за розуміння.

Відповіді:


31

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бекенд.


1
Тут усі дуже хороші відповіді, і я можу додати дуже принизливі. Я міг би відзначити їх усіма як прийняті, але у @Craig Ringer є кілька додаткових балів, і він дійсно приводить його в дію. Ще раз дякую SF, що очистив мене від моїх шкідливих звичок!
Банджер

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

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 - жахливі речі можуть трапитися (навіть при всіх покращеннях стабільності, що були зроблені з 7x днів), які можуть зірвати весь ваш БД, і ваш розробник цілком правильно жує. Ви не робите це.

Насправді є благословенний і схвалений спосіб зробити це в межах Postgres - Це навіть у посібнику з Postgres, хоча ця посада ТА робить кращу роботу з її пояснення ...

SELECT pg_cancel_backend(pid)
Надсилає SIGINTсигнал cancel ( ) на вказаний бекенд, який скасовує поточний запущений запит.

select pg_terminate_backend(pid)
Надсилає SIGTERMсигнал закінчення ( ) на вказаний бекенд, який скасовує запит і перериває бекенд (припиняючи його з'єднання).

Ідентифікатори вихідного дня можна отримати з pg_stat_activityтаблиці (або ps)


4
Якщо хтось цікавиться страшними речами, враховуючи, що kill -9це не відрізняється від раптового вимкнення системи, що стосується вбитого процесу: Pg дуже толерантний до аварійних збоїв (як-от 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.