ALTER TABLE
Zapytanie rozpoczęliśmy kilka godzin temu i dopiero niedawno zdaliśmy sobie sprawę (za pośrednictwem pg_stat_activity
), że czeka ono na zamek. Odkryliśmy inne zapytanie, które trzyma blokadę tabeli, którą chcemy zmienić, i nie pozwalając jej odejść.
Nasze zapytanie jest „prostym” zapytaniem (zmiana typu danych kolumny), ale działa na ogromnej tabeli.
Zamiast zabić proces, który utrzymuje zamek, zdecydowaliśmy, że wolimy go zabić ALTER TABLE
.
Zrobiliśmy nie zawinąć ALTER TABLE
w transakcji.
O ile rozumiem, fakt, że nasze zapytanie czeka na zamek, oznacza, że zawsze czekał na zamek i nigdy niczego nie zmienił.
Czy to prawda? Czy możemy bezpiecznie anulować nasze ALTER TABLE
zapytanie? Czy jest możliwe, że zapytanie już coś zmodyfikowało, a anulowanie go pozostawiłoby naszą bazę danych w jakimś stanie w połowie?
PS: Plan jest anulować za pomocą SELECT pg_cancel_backend(pid);
. Jeśli to zły pomysł, daj mi znać.
źródło
Odpowiedzi:
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.
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()
ipg_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.
(niesamowite, aby upewnić się, że migracje schematów przebiegają razem albo wcale). Powiedziałeś jednak:
To w porządku dla jednego polecenia - z dokumentów ,
Więc anulowanie tego
ALTER TABLE
, albo przezpg_cancel_backend()
albo Ctrl-C wydane z kontrolnego polecenia psql, będzie miało podobny efekt, jakbyś to zrobił(choć, jak miejmy nadzieję, zobaczycie, anulowanie tego kosztownego
ALTER TABLE
może uratować bazę danych przed niepotrzebnym szlifowaniem, jeśli tylko idzieszROLLBACK
).źródło
Aby rozwinąć poprawną i doskonałą odpowiedź Josha:
Tak.
Byłoby bezpieczne, nawet gdyby było w trakcie przepisywania tabeli .
Jeśli chcesz, możesz po prostu zamknąć cały serwer PostgreSQL lub maszynę, na której działa, zrestartować go i wszystko będzie dobrze. DDL w PostgreSQL jest transakcyjny i bezpieczny w przypadku awarii.
Operacje DDL są rejestrowane przez WAL i gwarantuje się, że można je przywrócić lub zakończyć po przywróceniu po awarii lub przerwie.
źródło