uccidere -9 un processo postgres


25

Una query SELECT di postgres ha esaurito il controllo sul nostro server DB e ha iniziato a consumare tonnellate di memoria e scambiare fino a quando il server ha esaurito la memoria. Ho trovato il processo particolare tramite ps aux | grep postgresed eseguito kill -9 pid. Ciò ha ucciso il processo e la memoria liberata come previsto. Il resto del sistema e le query postgres sembravano essere inalterate. Questo server esegue Postgres 9.1.3 su SLES 9 SP4.

Tuttavia, uno dei nostri sviluppatori mi ha distrutto per aver ucciso un processo di Postgres kill -9, dicendo che avrebbe eliminato l'intero servizio di Postgres. In realtà no. L'ho fatto prima di una manciata di volte e non ho visto effetti collaterali negativi.

Detto questo, e dopo ulteriori letture, sembra che kill pidsenza le bandiere sia il modo preferito per uccidere un processo postgres in fuga, ma per altri utenti nella comunità postgres, sembra anche che Postgres sia "migliorato" nel corso degli anni in modo tale che kill -9su una singola query il processo / thread non è più una condanna a morte.

Qualcuno può illuminarmi sul modo corretto di uccidere un processo postgres in fuga e quanto sia disastroso (o benigno) l'utilizzo kill -9di Postgres in questi giorni? Grazie per la comprensione.

Risposte:


31

La risposta di voretaq7 copre i punti chiave, incluso il modo corretto di terminare i back-end, ma vorrei aggiungere qualche spiegazione in più.

kill -9(ad es. SIGKILL) non dovrebbe mai e poi mai essere il tuo default di prima scelta . Dovrebbe essere la tua ultima risorsa quando il processo non risponde alle sue normali richieste di arresto e un SIGTERM( kill -15) non ha avuto effetto. Questo è vero per Pg e praticamente tutto il resto.

kill -9 non dà al processo ucciso alcuna possibilità di eseguire alcuna pulizia.

Quando si tratta di PostgreSQL, Pg vede un backup che termina con kill -9un arresto anomalo del backup . Sa che il back-end potrebbe aver danneggiato la memoria condivisa - perché potresti averlo interrotto a metà scrivendo una pagina in shm o modificandone una, ad esempio - quindi termina e riavvia tutti gli altri backend quando nota che un back-end è improvvisamente scomparso ed è uscito con un codice di errore diverso da zero.

Lo vedrai riportato nei registri.

Se sembra non fare alcun danno, questo perché Pg sta riavviando tutto dopo l'incidente e l'applicazione si sta riprendendo dalle connessioni perse in modo pulito. Questo non lo rende una buona idea. Se nient'altro gli arresti di back-end sono meno testati rispetto alle parti di Pg che funzionano normalmente e sono molto più complicati / vari, quindi le possibilità di un bug in agguato nella gestione e nel ripristino degli arresti di back-end sono maggiori.

A proposito, se kill -9il postmaster lo rimuove postmaster.pide lo riavvia senza assicurarsi che ogni postgresbackend sia sparito, possono succedere cose molto brutte . Ciò potrebbe facilmente accadere se il postmaster fosse stato accidentalmente ucciso anziché un back-end, si fosse verificato un errore nel database, si fosse tentato di riavviarlo, si fosse rimosso il file .pid "non aggiornato" quando il riavvio non fosse riuscito e si fosse tentato di riavviarlo nuovamente. Questo è uno dei motivi per cui dovresti evitare di agitare kill -9attorno a Pg e non dovresti eliminarlo postmaster.pid.

Una dimostrazione:

Per vedere esattamente cosa succede quando si è kill -9un backend, provare questi semplici passaggi. Apri due terminali, apri psql in ciascuno e in ogni corsa SELECT pg_backend_pid();. In un altro terminale kill -9uno dei PID. Ora esegui di nuovo SELECT pg_backend_pid();in entrambe le sessioni psql. Notate come entrambi hanno perso le loro connessioni?

Sessione 1, che abbiamo ucciso:

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

Sessione 2, che era un danno collaterale:

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

Vedi come sono state interrotte entrambe le sessioni? Ecco perché non sei kill -9un backend.


1
Tutte le risposte molto buone qui, e molto umiliante potrei aggiungere. Potrei contrassegnarli tutti come accettati, ma @Craig Ringer ha alcuni punti extra qui e lo guida davvero bene. Grazie ancora SF per avermi ripulito dalle mie cattive abitudini!
Banjer,

2
@Craig: che risposta superba; e per includere una dimostrazione, vorrei poter votare questo 100x. Sono uno sviluppatore di software che lavora quotidianamente con PG e dai giorni 6.x e la tua risposta è perfetta! Bello!
Kilo,

2
Bella risposta. Un addendum: se hai un processo di backend che non morirà assolutamente - non con pg_terminate_backend, non con un riavvio dello stack del server, non con nulla, puoi ucciderlo come vuoi, ma assicurati di avere un backup funzionante del tuo database. Puoi farlo in un paio di modi: puoi usare pg_basebackupo simili (o semplicemente rsynce pg_start\stop_backup) per eseguire il backup della tua directory di dati (prova i backup prima di continuare!), Oppure puoi usare pg_dump[all]per salvare i tuoi dati. Solo allora dovresti considerare kill -9, o riavviare, o altro.
Zac B,

1
@ZacB Sì, e se lo uccidi assicurati che tutti i backend muoiano. Soprattutto, non cancellare maipostmaster.pid . Mai.
Craig Ringer,

29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
NO! MALE! PASSARE LONTANO DAL BACKEND!

Scherzi a parte - Non uccidere in questo modo i backend di Postgres - TERRIBILI possono succedere cose (anche con tutti i miglioramenti della stabilità che sono stati apportati dai giorni 7.x) che possono rovinare l'intero DB e lo sviluppatore ha ragione a masticare sei fuori per fare questo.

Esiste, in effetti, un modo benedetto e approvato di farlo dall'interno di Postgres - È anche nel manuale di Postgres, anche se quel post SO fa un lavoro migliore nel spiegarlo ...

SELECT pg_cancel_backend(pid)
Invia un SIGINTsegnale cancel ( ) al backend specificato, che annulla la query attualmente in esecuzione.

select pg_terminate_backend(pid)
Invia un SIGTERMsegnale terminate ( ) al back-end specificato, che annulla la query e interrompe il back-end (interrompendo la connessione).

Gli ID backend possono essere ottenuti dalla pg_stat_activitytabella (o ps)


4
Nel caso in cui qualcuno si kill -9stia chiedendo delle cose terribili, dato che non è dissimile da spegnere improvvisamente il sistema per quanto riguarda il processo ucciso: Pg è molto tollerante nei crash del backend (come a kill -9) e non dovrebbe mai esserci corruzione dei dati. Ci sarà corruzione se uccidi il postmaster , rimuovi postmaster.pid e lo riavvii senza prima uccidere ogni backend. Che sarà distruggere la vostra base di dati, ma richiede molto di più di un semplice kill -9ad un backend. kill -9non dà al postmaster il tempo di uccidere i backend, motivo per cui è pericoloso.
Craig Ringer,

2
... come un caso di consulenza d'emergenza che ho avuto la scorsa settimana. Hanno danneggiato gravemente il loro database, perso due giorni di lavoro perché i loro backup non funzionavano (e non hanno testato automaticamente i loro ripristini), sono rimasti inattivi per 48 ore. Non cancellare postmaster.pid.
Craig Ringer,

8

Uccidere un processo client PostgreSQL dovrebbe andare bene. Uccidere un processo daemon PostgreSQL potrebbe farti rimproverare.

Poiché i daemon SQL hanno anche controlli di processo interni, il modo migliore è provare prima a utilizzare quel canale.

Vedi Stop (long) query SQL in esecuzione in PostgreSQL ... da StackOverflow.


4
kill -9non dovrebbe mai essere la scelta predefinita in ogni caso, è l'ultima risorsa. Invia un SIGTERMcon kill -TERMo semplice kille se il destinatario non risponde dopo un po ', solo allora dovresti considerare kill -KILL( kill -9).
Craig Ringer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.