O ile rozumiem, fakt, że nasze zapytanie czeka na zamek, oznacza, że zawsze czekał na zamek i nigdy niczego nie zmienił.
Racja - jeśli widzisz, że pg_stat_activity.waiting jest „prawdziwe” dla ALTER TABLE, to prawie na pewno oznacza, że cierpliwie czeka na blokadę ACCESS EXCLUSIVE na docelowym stole i jego prawdziwą pracę (przepisanie tabeli w razie potrzeby, zmiana katalogów , przebudowywanie indeksów itp.) jeszcze się nie rozpoczęło.
Czy możemy bezpiecznie anulować zapytanie ALTER TABLE? Czy jest możliwe, że zapytanie już coś zmodyfikowało, a anulowanie go pozostawiłoby naszą bazę danych w jakimś stanie w połowie?
Anulowanie zapytań (lub, równoważnie, wycofanie transakcji) w PostgreSQL nie wiąże się z żadnym ryzykiem uszkodzenia bazy danych, które mogło zostać wystraszone w niektórych innych bazach danych (np. Przerażające ostrzeżenie na dole tej strony). Właśnie dlatego osoby niebędące superużytkownikami w najnowszych wersjach mogą swobodnie korzystać pg_cancel_backend()
i pg_terminate_backend()
zabijać własne zapytania działające w innych backendach - można z nich bezpiecznie korzystać bez obaw o uszkodzenie bazy danych. W końcu PostgreSQL musi być przygotowany na poradzenie sobie z każdym procesem ginięcia, np. SIGKILL z zabójcy OOM, zamknięcie serwera itp. Do tego właśnie służy dziennik WAL .
Być może widzieliście również, że w PostgreSQL można wykonywać większość poleceń DDL zagnieżdżonych w transakcji (wielowyrazowej), np.
BEGIN;
ALTER TABLE foo ...;
ALTER TABLE bar ...;
-- more stuff
COMMIT; -- or ROLLBACK; if you've changed your mind
(niesamowite, aby upewnić się, że migracje schematów przebiegają razem albo wcale). Powiedziałeś jednak:
Zrobiliśmy nie zawinąć ALTER TABLE
w transakcji.
To w porządku dla jednego polecenia - z dokumentów ,
PostgreSQL faktycznie traktuje każdą instrukcję SQL jako wykonywaną w ramach transakcji. Jeśli nie wydasz polecenia BEGIN, każda pojedyncza instrukcja ma niejawne BEGIN i (jeśli się powiedzie) COMMIT owinięte wokół niego. Grupa instrukcji otoczona BEGIN i COMMIT jest czasem nazywana blokiem transakcji.
Więc anulowanie tego ALTER TABLE
, albo przez pg_cancel_backend()
albo Ctrl-C wydane z kontrolnego polecenia psql, będzie miało podobny efekt, jakbyś to zrobił
BEGIN;
ALTER TABLE ... ;
ROLLBACK;
(choć, jak miejmy nadzieję, zobaczycie, anulowanie tego kosztownego ALTER TABLE
może uratować bazę danych przed niepotrzebnym szlifowaniem, jeśli tylko idziesz ROLLBACK
).