Zmień tabelę w bazach danych produkcji na żywo


24

Jak większość „popularnych” systemów baz danych (MySQL, Postgres ...) obsługuje zmienianie tabel w bazach danych na żywo (takich jak dodawanie, usuwanie lub zmiana typu kolumn)?

Wiem, że poprawnym sposobem jest tworzenie kopii zapasowej wszystkich harmonogramów przestojów, a następnie wprowadzanie zmian.

Ale ... czy jakiś obecny system baz danych obsługuje robienie tych rzeczy „on-line” bez zatrzymywania czegokolwiek? (być może opóźniając zapytania odnoszące się do właśnie zmienianej / usuwanej kolumny)

A co się stanie, gdy po prostu ALTER TABLE...uruchomię działającą bazę danych na żywo? Czy wszystko się kończy, kiedy to się dzieje? Czy dane mogą ulec uszkodzeniu? itp.

Ponownie mam na myśli głównie Postgres lub MySQL, ponieważ to właśnie się spotykam.

(I tak, za każdym razem, gdy musiałem to zrobić, zanim zrobiłem to „we właściwy sposób”, wykonując kopie zapasowe, planując przestoje itp.… Ale chcę tylko wiedzieć, czy można to zrobić i to „szybko i szybko” brudne ”lub jeśli istnieje system DB, który faktycznie obsługuje zmiany schematu„ szybkie, aktywne i brudne ”)


Ktoś właśnie zasugerował zmianę schematu online dla MySQL ze skryptu Facebooka (z tutorialem tutaj i źródłem tutaj ) ... wydaje się być dobrym sposobem na zautomatyzowanie zestawu „hackich” sposobów, aby to zrobić ... w którym ktoś kiedykolwiek go używał coś przypomina produkcję?


3
Uwaga: określony „poprawny sposób” dotyczy MySQL, a nie PostgreSQL. „Właściwy sposób” w PostgreSQL jest zazwyczaj bardzo łatwy, choć może być zaangażowany. Zastosowanie pg_reorgmoże pomóc w trudniejszych scenariuszach.
Sean,

Chciałbym mieć szczegółowy film na ten temat, w którym ktoś wyjaśnia jak najwięcej strategii.
Sandeepan Nath

Odpowiedzi:


22

Kiedy ALTER TABLEwydasz w PostgreSQL , zajmie ACCESS EXCLUSIVEblokadę, która blokuje wszystko, w tymSELECT . Jednak ta blokada może być dość krótki, jeśli tabela nie wymaga ponownego pisania, brak nowych UNIQUE, CHECKlub FOREIGN KEYograniczenia potrzeba drogich skanów pełnej tabeli, aby sprawdzić, itd.

W razie wątpliwości możesz po prostu spróbować! Wszystkie DDL w PostgreSQL są transakcyjne, więc całkiem dobrze jest anulować i ALTER TABLEjeśli trwa to zbyt długo i zaczyna wstrzymywać inne zapytania. Poziomy blokady wymagane przez różne polecenia są udokumentowane na stronie blokowania .

Niektóre normalnie powolne operacje można przyspieszyć, aby były bezpieczne bez przestojów. Na przykład, jeśli masz tabelę ti chcesz zmienić kolumnę customercode integer NOT NULLna, textponieważ klient zdecydował, że wszystkie kody klientów muszą teraz zaczynać się od X, możesz napisać:

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

... ale to zablokowałoby cały stół do ponownego zapisu. Podobnie jak dodanie kolumny z DEFAULT. Można to zrobić w kilku krokach, aby uniknąć długiej blokady, ale aplikacje muszą być w stanie poradzić sobie z tymczasową duplikacją:

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

Zapobiegnie to tylko zapisom w ttrakcie procesu; nazwa zamka EXCLUSIVEjest nieco zwodnicza, ponieważ wyklucza wszystko opróczSELECT ; ACCESS EXCLUSIVEtryb jest jedynym, który wyklucza absolutnie everyting. Zobacz tryby blokady . Istnieje ryzyko, że operacja ta może zostać przywrócona do impasu z powodu wymaganej przez aktualizację blokady ALTER TABLE, ale w najgorszym wypadku trzeba to zrobić ponownie.

Można nawet uniknąć tej blokady i zrobić całość na żywo, tworząc funkcję wyzwalania na tktóry ilekroć INSERTalbo UPDATEprzychodzi, automatycznie zapełnia customercode_newz customercode.

Istnieją również wbudowane narzędzia, takie jak CREATE INDEX CONCURRENTLYi ALTER TABLE ... ADD table_constraint_using_indexzaprojektowane w taki sposób, aby umożliwić DBA skrócenie wyłącznych czasów blokowania poprzez wolniejsze wykonywanie pracy w sposób przyjazny dla współbieżności.

pg_reorgNarzędzie lub jego następca pg_repackmoże być stosowany w przypadku niektórych działań restrukturyzacyjnych oraz stołowych.


1
Kluczową rzeczą w tym, co powiedział @Craig, było „jeśli nie wymaga to ponownego pisania”. Korzystanie z an ALTER TABLE t ADD COLUMN i INTjest szybką operacją (zwykle <1ms) po uzyskaniu blokady. Zdobycie blokady może jednak ustawiać kolejki połączeń, więc nie jest to „darmowe” ... chociaż jest lepsze na świecie niż to, co musisz zrobić w MySQL. Dodanie NOT NULLograniczenia jest trudniejsze, a nie ze względu na serce.
Sean

Wydaje się, że konsensus pg_repackjest ulepszonym następcą pg_reorg.
Erwin Brandstetter,

Dobra odpowiedź, jeśli chodzi o dodanie kolumny z domyślnym (lub obliczonym) sposobem mniej „blokującym” jest utworzenie całej nowej tabeli, zablokowanie starej tabeli w celu wstawienia / aktualizacji / usunięcia, ale zezwalając na wybranie i wypełnienie nowej. Na koniec wydaj krótką blokadę wyłączności na starym stole, aby ją wybrać, usuń ją i zmień nazwę nowego na stary. W zależności od twojego scenariusza możesz nawet zapełnić nowy bez blokowania wstawek w starym i wydawać tę wyłączną blokadę tylko podczas rozwiązywania różnicy (mam nadzieję, że po prostu wstawiam kilka nowych rekordów)
Jean

7

Percona ma własne narzędzie do wykonywania zmian schematu online

Narzędzie to nazywa się zmiana schematu pt-online

Obejmuje wyzwalacze, więc proszę uważnie przeczytać dokumentację.

Według Dokumentacji wykonano główne operacje

  • Kontrola poczytalności
  • Wydzielanie
  • Zmiana schematu online
    • Utwórz i zmień tabelę tymczasową
    • Przechwyć zmiany z tabeli do tabeli tymczasowej
    • Skopiuj wiersze z tabeli do tabeli tymczasowej
    • Zsynchronizuj tabelę i tabelę tymczasową
    • Zamień / zmień nazwę tabeli i tabeli tymczasowej
    • Sprzątać

dzięki, wydaje się być „sprzedaną” wersją podejścia Facebooka,
któremu

pt-online-schemat-zmiana jest zdecydowanie preferowanym sposobem na zrobienie tego, jeśli prowadzisz własny serwer MySQL. Począwszy od Percona Tools 2.2 (niestety) nie obsługują one RDS / Aurora w AWS. pt-online-schema-change wstawia wyzwalacz w tabeli źródłowej, aby skopiować wiersze (niski priorytet dla MyISAM) do docelowego table_temp i wykonuje pojedyncze szybkie blokowanie upuszczania i zmiany nazwy na końcu, gdy wszystkie wiersze są zsynchronizowane między źródłem a miejscem docelowym stoły
phpguru

6

Wyłączenie systemu i wykonanie wszystkich zmian naraz może być bardzo ryzykowne. Jeśli coś pójdzie nie tak i często tak się dzieje, nie ma łatwego powrotu.

Jako programista Agile czasami potrzebuję refaktoryzować tabele bez żadnych przestojów, ponieważ tabele te są modyfikowane i odczytywane.

Poniższe podejście wiąże się z niskim ryzykiem, ponieważ zmiany dokonuje się w kilku etapach niskiego ryzyka, które bardzo łatwo wycofać:

  • Upewnij się, że wszystkie moduły uzyskujące dostęp do tabeli są dobrze objęte automatycznymi testami.
  • Utwórz nowy stół. Zmień wszystkie procedury, które modyfikują starą tabelę, tak aby modyfikowały zarówno stare, jak i nowe tabele.
  • Przeprowadź migrację istniejących danych do nowej struktury. Zrób to małymi partiami, aby nie miało to poważnego wpływu na ogólną wydajność serwera.
  • Sprawdź, czy migracja danych zakończyła się powodzeniem.
  • Przekieruj niektóre procedury wyboru ze starej tabeli do nowych. Użyj automatycznych testów, aby upewnić się, że zmienione moduły są nadal poprawne. Upewnij się, że ich wydajność jest akceptowalna. Wdróż zmienione procedury.
  • Powtarzaj poprzedni krok, aż wszystkie raporty wykorzystają nową tabelę.
  • Zmień procedury modyfikujące tabele, aby miały dostęp tylko do nowej tabeli.
  • Zarchiwizuj stary stół i usuń go z systemu.

Stosowaliśmy to podejście wiele razy, aby zmieniać duże tabele produkcji na żywo bez przestojów, bez żadnych problemów.


3
świetnie ... ale właśnie tego rodzaju „bólu” chcę uniknąć :)
NeuronQ,

@NeuronQ „ Nie ma łatwej drogi powrotnej ” - jest w Postgres: po prostu umieść wszystko w transakcji i rollbackjeśli coś pójdzie nie tak.
a_horse_w_no_name

2

Tak, wiele nowoczesnych baz danych pozwala po prostu dodać kolumnę lub zmienić charakterystykę kolumny, na przykład dodając lub usuwając wartość zerową.

Jeśli upuścisz kolumnę, dane zostaną utracone, ale strach przed korupcją jest niewielki.



-1

Aby odpowiedzieć na pytanie o to, co dzieje się z ALTER TABLEinstrukcją, zależy to od zakresu zmian. W szczególnych przypadkach, jeśli dodasz nową kolumnę, przynajmniej w MS SQL Server, silnik utworzy tymczasową kopię tabeli, jednocześnie tworząc nową definicję tabeli, a następnie wstawi tam dane z powrotem. Na czas zmiany tabela byłaby zatem niedostępna dla użytkowników.

Przykład konkretnych operacji na serwerze MSSQL znajduje się tutaj: http://support.microsoft.com/kb/956176/en-us

Zakładam, że inne RMDB mają podobne metody, chociaż dokładna implementacja byłaby czymś, co musiałbyś zweryfikować z dokumentacją dostawcy.


-1 Jest to całkowicie niepoprawne w przypadku SQL Server: „Jeśli dodasz nową kolumnę, przynajmniej w MS SQL Server, silnik utworzy tymczasową kopię tabeli, jednocześnie tworząc nową definicję tabeli, a następnie wstawi dane z powrotem tam ”
AK

@AlexKuznetsov - pomyślałem, że poprzednia linia, a także link do niektórych z wymienionych przypadków wyjaśniłby, że nie zawsze tak się dzieje. Zmieniłem zdanie, aby lepiej to odzwierciedlić.
SchmitzIT

1
Wspominasz zachowanie GUI, SSMS, a nie samego SQL Servera. Po twoim linku radzimy używać T-SQL bezpośrednio do wprowadzania zmian w DDL. SSMS nie jest bardzo dobrym narzędziem do zmiany DDL.
AK

@AlexKuznetsov - czytam ten artykuł, mówiąc, że wiąże się z nim ryzyko, ale nie zniechęcam. W każdym razie nie podłączyłem tego artykułu do bitu GUI, ale jako wskazanie niektórych operacji, które prowadzą do instrukcji ALTER prowadzącej do utworzenia tabeli tymczasowej z powodu zmian w podstawowej strukturze danych. Nie testowałem, czy dokładnie to samo dotyczy wydania instrukcji bezpośrednio z T-SQL, ale wydaje mi się, że proces jest dość podobny i że SL Server wykonuje pracę za kulisami.
SchmitzIT

Możesz uruchomić Profiler, bezpośrednio wykonać instrukcję ALTER TABLE i zobaczyć, co się dzieje. Następnie możesz zmienić tabelę za pomocą okna dialogowego i zobaczyć na własne oczy wykonywane polecenia.
AK
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.