Dubbele databasemigraties zijn gemakkelijker te voorkomen wanneer schemawijzigingen als één expliciete implementatiestap worden uitgevoerd, in plaats van tijdens het opstarten van elke app-container.
Het preventieve ontwerp geeft migraties één eigenaar, één set inloggegevens en één voltooiingssignaal voordat nieuwe replica's verkeer beginnen te verwerken. Zorg dat web- en worker-containers zonder rechten voor schemawijzigingen kunnen herstarten, laat de uitrol wachten op een succesvolle migratietaak en ontwerp schemawijzigingen zo dat de oude en nieuwe app-versies kort naast elkaar kunnen bestaan. Daarmee elimineer je de raceconditie, in plaats van er alleen maar op te hopen dat elke replica als eerste dezelfde migratiegeschiedenis opmerkt.
Verwijder migratieopdrachten uit het normale opstartproces van de app
Controleer het entrypoint van de image, de Compose-opdracht, de worker-opdracht, de healthcheck-wrapper en het implementatiescript op automatische migratieaanroepen. De applicatie moet kunnen herstarten zonder het schema te wijzigen, tenzij die herstart onderdeel is van de bewust gekozen migratiestap.
Een implementatieartikel van Octopus betoogt dat migraties een afzonderlijke levenscyclus nodig hebben in plaats van aan het opstarten van elk microserviceproces te worden gekoppeld.
Houd het migratieprogramma beschikbaar waar dat nodig is, maar roep het niet aan vanuit zowel het web-entrypoint als een tweede taak. Eén expliciete eigenaar is gemakkelijker te controleren dan meerdere opstartpaden die allemaal afhankelijk zijn van vergrendeling door het framework.
Voer één migratietaak vóór de implementatie uit
Maak een eenmalige taak die dezelfde migratiebestanden als de release gebruikt en alleen succesvol wordt afgesloten nadat de doeldatabase de verwachte schemastatus heeft bereikt. Laat de uitrol van de applicatie afhankelijk zijn van dat resultaat.
Een actuele uitrolhandleiding laat zien hoe één taak vóór de uitrol wordt uitgevoerd, in plaats van dat elke replica tijdens het opstarten een race veroorzaakt.
Schaal de migratietaak niet op zoals de app-service. De taak moet per doeldatabase één uitvoerende eigenaar, een begrensde time-out, logboeken en een duidelijke mislukte status hebben die de nieuwe app-versie blokkeert.
Laat het opstarten van de applicatie afhangen van een geslaagde migratie
Laat nieuwe web- en worker-containers wachten totdat de migratiefase succes meldt, maar laat niet elke wachtende container de migratie opnieuw uitvoeren. De afhankelijkheid betreft het resultaat, niet het nogmaals uitvoeren van de schemawijziging.
Het implementatiepatroon van Andrew Lock gebruikt app-pods die op de migratie wachten, terwijl de migratielogica gecentraliseerd blijft.
Voor een kleine thuisserverstack kan hetzelfde principe worden geïmplementeerd met een speciale Compose-service en een gecontroleerd implementatiescript. Houd het mechanisme eenvoudig genoeg zodat een mislukte migratie de uitrol zichtbaar stopt.
Gebruik achterwaarts compatibele schemawijzigingen tijdens de overlap
Bij uitrol zonder downtime kunnen oude en nieuwe applicatieversies tijdelijk dezelfde database gebruiken. Vermijd een migratie die een veld verwijdert of hernoemt voordat de oude versie het niet meer gebruikt.
Een recente handleiding voor migraties zonder downtime adviseert eerst uit te breiden en daarna te verkleinen, zodat toevoegende schemawijzigingen worden doorgevoerd voordat destructieve opschoning plaatsvindt.
Splits grote wijzigingen indien nodig op in de fasen uitbreiden, bijvullen, omschakelen en verkleinen. De migratietaak mag geen schema creëren dat alleen de nieuwe container begrijpt terwijl oude replica's nog verzoeken verwerken.
Houd migratie-inloggegevens buiten app-replica's
Gebruik waar praktisch een databaseaccount met rechten voor schemawijzigingen uitsluitend voor de eenmalige migratiefase. Normale app-containers moeten de beperktere lees- en schrijfrechten behouden die nodig zijn voor applicatiegegevens.
Een implementatieartikel van Liquibase beschrijft dat databasewijzigingen bij automatisering horen, met gecontroleerde en herhaalbare toepassing van wijzigingen.
Deze scheiding maakt het minder waarschijnlijk dat migraties per ongeluk worden uitgevoerd, zelfs wanneer een app-proces wordt herstart of gedupliceerd. Bewaar de verhoogde inloggegevens in het geheime pad van de implementatie, niet in de omgeving van de normale langlopende service.
Controleer dat de uitrol de batch niet twee keer kan toepassen
Test de implementatie in een tijdelijke database of een herstelde snapshot door meerdere app-replica's te starten, ze te herstarten en de implementatieopdracht opnieuw uit te voeren. De migratiefase moet de bestaande schemastatus melden zonder deze een tweede keer te wijzigen.
JetBrains vat de operationele regel samen als migraties uitvoeren als implementatiestap vóór het normale opstarten van de applicatie.
Het preventiebeleid is compleet wanneer herstarts van de app het schema niet kunnen wijzigen, één mislukte migratie de release blokkeert en herhaalde uitvoering van de uitrol de database ongewijzigd laat. Het gerelateerde ZimaSpace-artikel over diagnose van dubbele migraties is de herstelroute als dubbele uitvoering al heeft plaatsgevonden.
Ondersteuning & Tips
Meer om te lezen

Kan Plex een GPU delen met een andere Docker-container?
Plex en een andere container kunnen vaak dezelfde GPU gebruiken, maar je moet de driverondersteuning, apparaattoewijzing, belasting van de video-engine, het geheugengebruik en het...

Hoe je kunt bepalen of een Plex-fout door de client of de server wordt veroorzaakt
Reproduceer hetzelfde item op een andere client, vergelijk het sessiepad en verzamel pas serverbewijs nadat de scope heeft uitgewezen waar de fout daadwerkelijk zit.

Plex-cache en tijdelijke opslag voor transcodering configureren
Bescherm de permanente Plex-status door tijdelijke transcodebestanden op geschikte lokale opslag te plaatsen en controleer vervolgens het opruimen, de beschikbare ruimte en het gedrag...

