È sicuro annullare una query ALTER TABLE PostgreSQL in attesa di un blocco?


10

Abbiamo iniziato una ALTER TABLEquery ore fa e solo recentemente ci siamo resi conto (tramite pg_stat_activity) che è in attesa di un blocco. Abbiamo scoperto l'altra query che contiene un blocco sul tavolo che vogliamo modificare e non lasciarlo andare.

La nostra query è una query "semplice" (modifica di un tipo di dati di colonna), ma è in esecuzione su una tabella di grandi dimensioni.

Invece di uccidere il processo che sta trattenendo il blocco, abbiamo deciso che preferiremmo uccidere il ALTER TABLE.

Non abbiamo concluso la ALTER TABLEtransazione.

Per quanto ho capito, il fatto che la nostra query sia in attesa di un blocco significa che è sempre stato in attesa di un blocco e non ha mai cambiato nulla.

È vero? È sicuro per noi annullare definitivamente la nostra ALTER TABLEdomanda? O è possibile che la query abbia già modificato qualcosa e la sua cancellazione lascerebbe il nostro database in uno stato a metà strada di qualche tipo?

PS: il piano è di annullarlo usando SELECT pg_cancel_backend(pid);. Se questa è una cattiva idea, per favore fatemi sapere.


1
Dovrebbe andare bene per cancellare la tabella ALTER. PostgreSQL ha un DDL transazionale e dovresti essere lasciato nello stesso stato come se non avessi eseguito ALTER TABLE.
Josh Kupershmidt,

Quindi, quando dici che PostgreSQL ha una transazione DDL, significa che qualsiasi query che modifica lo schema viene essenzialmente eseguita all'interno di una transazione?
JMTyler,

1
Nel tuo caso, ALTER TABLE è "essenzialmente eseguito all'interno di una transazione", dal momento che hai detto "Non abbiamo avvolto ALTER TABLE in una transazione". Se volessi, potresti scrivere INIZIA; ALTER TABLE foo ...; Barra ALTER TABLE ...; eccetera. ; COMMETTERE; - questa è la vera caratteristica killer di PostgreSQL con DDL transazionale. Ma per la tua situazione immediata, sì, ALTER TABLE da solo può essere annullato in modo sicuro e verrà ripristinato come se non fosse mai successo.
Josh Kupershmidt,

Grazie mille per le tue risposte rapide! Questa è un'ottima informazione. Potresti pubblicarlo come risposta in modo che io possa contrassegnarlo come accettato?
JMTyler,

Risposte:


13

Per quanto ho capito, il fatto che la nostra query sia in attesa di un blocco significa che è sempre stato in attesa di un blocco e non ha mai cambiato nulla.

Giusto - se vedi che pg_stat_activity.waiting è "vero" per un ALTER TABLE, ciò significa quasi sicuramente che sta aspettando pazientemente il blocco ACCESS EXCLUSIVE sulla sua tabella di destinazione e il suo vero lavoro (riscrivendo la tabella se necessario, cambiando i cataloghi , ricostruzione di indici, ecc.) non è ancora iniziata.

È sicuro per noi annullare definitivamente la nostra query ALTER TABLE? O è possibile che la query abbia già modificato qualcosa e la sua cancellazione lascerebbe il nostro database in uno stato a metà strada di qualche tipo?

L'annullamento di query (o, equivalentemente, il rollback di una transazione) in PostgreSQL non presenta alcun rischio di corruzione del database che potresti essere stato spaventato da alcuni altri database (ad esempio l' avvertimento terrificante in fondo a questa pagina). Ecco perché i non utenti super, nelle ultime versioni, sono liberi di usare pg_cancel_backend()e pg_terminate_backend()di uccidere le proprie query in esecuzione su altri back-end: sono sicuri da usare senza preoccuparsi della corruzione del database. Dopotutto, PostgreSQL deve essere pronto a gestire qualsiasi processo venga ucciso, ad esempio SIGKILL dal killer OOM, l'arresto del server, ecc. Ecco a cosa serve il registro WAL .

Potresti anche aver visto che in PostgreSQL è possibile eseguire la maggior parte dei comandi DDL nidificati all'interno di una transazione (multiistruzione), ad es.

BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind

(fantastico per assicurarsi che le migrazioni dello schema vadano o tutte insieme o per niente.) Hai detto, però:

Non abbiamo concluso la ALTER TABLEtransazione.

Va bene per un singolo comando: dai documenti ,

PostgreSQL in realtà considera ogni istruzione SQL come eseguita all'interno di una transazione. Se non si emette un comando BEGIN, ogni singola istruzione ha un BEGIN implicito e (in caso di successo) COMMIT attorno ad esso. Un gruppo di istruzioni circondato da BEGIN e COMMIT viene talvolta chiamato blocco delle transazioni.

Quindi annullando quello ALTER TABLE, tramite pg_cancel_backend()o un Ctrl-C emesso dal prompt di controllo psql, avrà un effetto simile come se avessi fatto

BEGIN;
ALTER TABLE ... ;
ROLLBACK;

(anche se, come si spera, puoi vedere, l'annullamento di quel costoso ALTER TABLEpuò salvare il database da un sacco di rettifiche inutili se lo fai solo ROLLBACK).


5

Per approfondire la risposta corretta ed eccellente di Josh:

È sicuro per noi annullare definitivamente la nostra query ALTER TABLE?

Sì.

Sarebbe sicuro anche se fosse nel mezzo di riscrivere il tavolo .

Se lo desideri, puoi semplicemente arrestare l'intero server PostgreSQL, o in effetti la macchina su cui gira, riavviarlo e tutto andrebbe bene. DDL in PostgreSQL è transazionale e sicuro.

Le operazioni DDL vengono registrate tramite WAL ed è garantito che possano essere ripristinate o completate al ripristino dopo un arresto anomalo o l'interruzione.


3
Solo una nota su "potresti semplicemente arrestare l'intero server PostgreSQL, o in effetti la macchina su cui gira, riavviarlo e tutto andrebbe bene" - abbastanza vero fintanto che hai hardware affidabile che non mente su fsync , wiki.postgresql.org/wiki/Reliable_Writes
Josh Kupershmidt

2
@JoshKupershmidt Certo, ma non è specifico per DDL. Se hai problemi di sincronizzazione, non sei sicuro per tutto .
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.