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 TABLE
transazione.
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 TABLE
può salvare il database da un sacco di rettifiche inutili se lo fai solo ROLLBACK
).