Doppelte Datenbankmigrationen lassen sich leichter verhindern, wenn Schemaänderungen als ein expliziter Bereitstellungsschritt ausgeführt werden und nicht beim Start jedes App-Containers.
Bei diesem präventiven Ansatz gibt es einen Verantwortlichen für Migrationen, einen Satz von Zugangsdaten und ein Abschluss-Signal, bevor neue Replikate den Datenverkehr bedienen. Web- und Worker-Container können ohne Berechtigungen zur Änderung des Schemas neu gestartet werden, der Rollout wartet auf einen erfolgreichen Migrationsjob, und Schemaänderungen werden so geplant, dass alte und neue App-Versionen kurzzeitig parallel funktionieren. Dadurch wird die Race-Condition beseitigt, anstatt lediglich darauf zu hoffen, dass jedes Replikat zuerst dieselbe Migrationshistorie erkennt.
Migrationsbefehle aus dem normalen App-Start entfernen
Prüfe den Image-Entrypoint, den Compose-Befehl, den Worker-Befehl, den Healthcheck-Wrapper und das Bereitstellungsskript auf automatische Migrationsaufrufe. Die Anwendung sollte neu gestartet werden können, ohne das Schema zu verändern, es sei denn, dieser Neustart ist der bewusst gewählte Migrationsschritt.
Ein Bereitstellungsartikel von Octopus argumentiert, dass Migrationen einen eigenen Lebenszyklus benötigen, statt an den Start jedes Microservice-Prozesses gekoppelt zu sein.
Halte die Migrations-Binärdatei dort verfügbar, wo sie benötigt wird, aber rufe sie nicht sowohl aus dem Web-Entrypoint als auch aus einem zweiten Job auf. Ein explizit festgelegter Verantwortlicher lässt sich leichter prüfen als mehrere Startpfade, die alle von Framework-Sperren abhängen.
Einen Migrationsjob vor der Bereitstellung ausführen
Erstelle einen einmalig ausgeführten Job, der dieselben Migrationsdateien wie das Release verwendet und erst dann erfolgreich beendet wird, wenn die Zieldatenbank den erwarteten Schemazustand erreicht hat. Mache den App-Rollout von diesem Ergebnis abhängig.
Ein aktueller Rollout-Leitfaden zeigt, wie ein Job vor dem Rollout ausgeführt wird, anstatt jedes Replikat beim Start miteinander konkurrieren zu lassen.
Skaliere die Migrationsaufgabe nicht wie den App-Service. Der Job sollte pro Zieldatenbank genau einen Ausführungsverantwortlichen, ein begrenztes Zeitlimit, Logs und einen eindeutig fehlgeschlagenen Status haben, der die neue App-Version blockiert.
Den App-Start an den Migrationserfolg koppeln
Lass neue Web- und Worker-Container warten, bis die Migrationsphase Erfolg meldet, aber lass nicht jeden wartenden Container die Migration selbst erneut ausführen. Abhängig ist der Start vom Ergebnis, nicht von einer weiteren Ausführung der Schemaänderung.
Das Bereitstellungsmuster von Andrew Lock verwendet App-Pods, die auf die Migration warten, während die Migrationslogik zentral bleibt.
Bei einem kleinen Home-Server-Stack lässt sich dasselbe Prinzip mit einem dedizierten Compose-Service und einem kontrollierten Bereitstellungsskript umsetzen. Halte den Mechanismus einfach genug, damit eine fehlgeschlagene Migration den Rollout sichtbar stoppt.
Während der Überschneidung abwärtskompatible Schemaänderungen verwenden
Bei schrittweisen Bereitstellungen können alte und neue Anwendungsversionen vorübergehend auf dieselbe Datenbank zugreifen. Vermeide Migrationen, die ein Feld entfernen oder umbenennen, bevor die alte Version es nicht mehr verwendet.
Ein aktueller Leitfaden zu Migrationen ohne Ausfallzeit empfiehlt zuerst zu erweitern und erst danach zu reduzieren, damit additive Schemaänderungen vor der destruktiven Bereinigung eingespielt werden.
Teile umfangreiche Änderungen bei Bedarf in die Phasen Erweitern, Nachbefüllen, Umschalten und Reduzieren auf. Der Migrationsjob sollte kein Schema erzeugen, das nur der neue Container versteht, während alte Replikate noch Anfragen bedienen.
Migrationszugangsdaten aus App-Replikaten heraushalten
Verwende nach Möglichkeit nur für die einmalig ausgeführte Migrationsphase ein Datenbankkonto mit Berechtigungen zur Schemaänderung. Normale App-Container sollten weiterhin die eingeschränkteren Lese- und Schreibberechtigungen verwenden, die für Anwendungsdaten erforderlich sind.
Ein Bereitstellungsartikel zu Liquibase beschreibt, dass Datenbankänderungen in die Automatisierung gehören und kontrolliert sowie wiederholbar angewendet werden sollten.
Durch diese Trennung wird eine versehentliche Ausführung von Migrationen weniger wahrscheinlich, selbst wenn ein App-Prozess neu gestartet oder dupliziert wird. Speichere die privilegierten Zugangsdaten im Secret-Pfad der Bereitstellung und nicht in der Umgebung des normalen, dauerhaft laufenden Dienstes.
Überprüfen, dass der Rollout den Batch nicht zweimal anwenden kann
Teste die Bereitstellung in einer temporären Datenbank oder einem wiederhergestellten Snapshot, indem du mehrere App-Replikate startest, sie neu startest und den Bereitstellungsbefehl erneut ausführst. Die Migrationsphase sollte den bestehenden Schemazustand melden, ohne ihn ein zweites Mal zu verändern.
JetBrains fasst die Betriebsregel so zusammen: Migrationen als Bereitstellungsschritt ausführen, bevor die normale Anwendung startet.
Die Präventionsrichtlinie ist vollständig, wenn App-Neustarts das Schema nicht verändern können, eine fehlgeschlagene Migration das Release blockiert und wiederholte Rollouts die Datenbank unverändert lassen. Der zugehörige ZimaSpace-Artikel zur Diagnose doppelter Migrationen ist der Wiederherstellungsweg, falls die doppelte Ausführung bereits erfolgt ist.
Support & Tipps
Mehr zum Lesen

Kann Plex eine GPU mit einem anderen Docker-Container gemeinsam nutzen?
Plex und ein weiterer Container können häufig auf dieselbe GPU zugreifen, aber du musst die Treiberunterstützung, die Gerätezuordnung, die Auslastung der Video-Engine, den Speicher...

So erkennst du, ob ein Plex-Fehler vom Client oder vom Server verursacht wird
Reproduziere dasselbe Element auf einem anderen Client, vergleiche den Sitzungspfad und sammle Serverbelege erst, nachdem der Geltungsbereich dir gezeigt hat, wo der Fehler tatsächlich...

So konfigurierst du den Plex-Cache und den temporären Transcodierungs-Speicher
Schütze den persistenten Plex-Zustand, indem du temporäre Transcodierungsdateien auf geeignetem lokalem Speicher ablegst, und überprüfe anschließend die Bereinigung, den freien Speicherplatz und das Verhalten...

