Duplikatów migracji bazy danych łatwiej uniknąć, gdy zmiany schematu są wdrażane jako jeden jawny etap wdrożenia, a nie podczas uruchamiania każdego kontenera aplikacji.
Zapobiegawcze podejście polega na wyznaczeniu jednego właściciela migracji, jednego zestawu danych uwierzytelniających i jednego sygnału ukończenia, zanim nowe repliki zaczną obsługiwać ruch. Kontenery aplikacji internetowej i workerów powinny móc się restartować bez uzyskiwania uprawnień do zmian schematu, wdrożenie powinno czekać na pomyślne zakończenie zadania migracji, a zmiany schematu należy projektować tak, aby stare i nowe wersje aplikacji mogły przez krótki czas współistnieć. Eliminuje to wyścig zamiast jedynie liczyć na to, że każda replika jako pierwsza zauważy tę samą historię migracji.
Usuń polecenia migracji ze standardowego uruchamiania aplikacji
Sprawdź entrypoint obrazu, polecenie Compose, polecenie workera, wrapper health checka i skrypt wdrożeniowy pod kątem automatycznych wywołań migracji. Aplikacja powinna móc się zrestartować bez modyfikowania schematu, chyba że restart jest celowo wybranym etapem migracji.
Artykuł Octopus dotyczący wdrożeń wskazuje, że migracje wymagają oddzielnego cyklu życia, zamiast być powiązane z uruchamianiem każdego procesu mikrousługi.
Pozostaw plik binarny migracji dostępny tam, gdzie jest potrzebny, ale nie wywołuj go jednocześnie z entrypointu aplikacji internetowej i drugiego zadania. Jeden jawnie wyznaczony właściciel jest łatwiejszy do audytowania niż kilka ścieżek uruchamiania zależnych od blokad frameworka.
Uruchamiaj jedno zadanie migracji przed wdrożeniem
Utwórz jednorazowe zadanie korzystające z tych samych plików migracji co wydanie. Powinno ono kończyć się pomyślnie dopiero wtedy, gdy docelowa baza danych osiągnie oczekiwany stan schematu. Uzależnij wdrożenie aplikacji od tego wyniku.
Aktualny przewodnik wdrożeniowy pokazuje, jak jedno zadanie uruchamia się przed wdrożeniem, zamiast pozwalać każdej replice rywalizować podczas startu.
Nie skaluj zadania migracji tak jak usługi aplikacji. Zadanie powinno mieć jednego wykonawcę dla każdej docelowej bazy danych, ograniczony czas działania, logi oraz wyraźny stan niepowodzenia, który blokuje nową wersję aplikacji.
Uzależnij uruchamianie aplikacji od pomyślnej migracji
Kontenery aplikacji internetowej i workerów powinny czekać na potwierdzenie pomyślnego zakończenia etapu migracji, ale nie powinny ponownie wykonywać migracji. Zależność dotyczy wyniku, a nie ponownego wykonania zmiany schematu.
Wzorzec wdrożeniowy Andrew Locka zakłada, że pody aplikacji czekają na migrację, podczas gdy logika migracji pozostaje scentralizowana.
W przypadku niewielkiego stosu na domowym serwerze tę samą zasadę można wdrożyć za pomocą dedykowanej usługi Compose i kontrolowanego skryptu wdrożeniowego. Mechanizm powinien być na tyle prosty, aby nieudana migracja wyraźnie zatrzymywała wdrożenie.
Stosuj zgodne wstecznie zmiany schematu podczas okresu współistnienia
Wdrożenia kroczące mogą przez pewien czas uruchamiać stare i nowe wersje aplikacji korzystające z jednej bazy danych. Unikaj migracji, która usuwa lub zmienia nazwę pola, zanim stara wersja przestanie go używać.
Niedawny przewodnik dotyczący migracji bez przestojów zaleca najpierw rozszerzać, a dopiero potem zawężać, aby dodatnie zmiany schematu zostały wdrożone przed destrukcyjnym sprzątaniem.
W razie potrzeby podziel duże zmiany na etapy rozszerzania, uzupełniania danych, przełączenia i zawężania. Zadanie migracji nie powinno tworzyć schematu rozumianego wyłącznie przez nowy kontener, gdy stare repliki nadal obsługują żądania.
Nie udostępniaj replikom aplikacji danych uwierzytelniających do migracji
Jeśli to możliwe, używaj konta bazy danych z uprawnieniami do zmian schematu wyłącznie w jednorazowym etapie migracji. Standardowe kontenery aplikacji powinny mieć węższy zakres uprawnień, obejmujący tylko odczyt i zapis danych potrzebnych aplikacji.
Artykuł Liquibase dotyczący wdrożeń opisuje, dlaczego zmiany bazy danych powinny należeć do automatyzacji, zapewniającej kontrolowane i powtarzalne stosowanie zmian.
Takie rozdzielenie zmniejsza ryzyko przypadkowego uruchomienia migracji nawet po restarcie lub zwielokrotnieniu procesu aplikacji. Przechowuj uprzywilejowane dane uwierzytelniające w ścieżce sekretów wdrożeniowych, a nie w środowisku zwykłej, długotrwale działającej usługi.
Sprawdź, czy wdrożenie nie zastosuje partii zmian dwukrotnie
Przetestuj wdrożenie w tymczasowej bazie danych lub na przywróconej migawce, uruchamiając wiele replik aplikacji, restartując je i ponownie wykonując polecenie wdrożeniowe. Etap migracji powinien rozpoznać istniejący stan schematu bez ponownego wprowadzania zmian.
JetBrains podsumowuje zasadę operacyjną jako uruchamianie migracji jako etapu wdrożenia przed standardowym uruchomieniem aplikacji.
Polityka zapobiegania jest kompletna, gdy restarty aplikacji nie mogą modyfikować schematu, jedna nieudana migracja blokuje wydanie, a wielokrotne wykonanie wdrożenia pozostawia bazę danych bez zmian. Powiązany artykuł ZimaSpace na temat diagnozowania duplikatów migracji stanowi ścieżkę naprawczą, jeśli do podwójnego wykonania już doszło.
Wsparcie i wskazówki
Więcej do przeczytania

Czy Plex może współdzielić kartę graficzną z innym kontenerem Dockera?
Plex i inny kontener często mogą korzystać z tego samego układu GPU, ale należy przetestować obsługę sterowników, mapowanie urządzeń, obciążenie silnika wideo, pamięć oraz...

Jak ustalić, czy błąd Plex pochodzi od klienta, czy od serwera
Odtwórz ten sam przypadek na innym kliencie, porównaj ścieżkę sesji, a następnie zbierz dowody z serwera dopiero wtedy, gdy zakres analizy wskaże, gdzie faktycznie...

Jak skonfigurować pamięć podręczną Plex i tymczasową pamięć na transkodowane pliki
Chroń trwały stan Plex, umieszczając tymczasowe pliki transkodowania na odpowiedniej pamięci lokalnej, a następnie zweryfikuj czyszczenie, ilość wolnego miejsca i zachowanie podczas ponownego uruchamiania.

