# Migrering

## Vad det är

En migrering är en planerad flytt av något som redan används, till en ny version
eller en ny plattform. Den sker i steg, och till sist avvecklas det gamla. Det
som flyttas kan vara en hel arbetslast, en applikation, en mängd data eller den
struktur som datan ligger i. Det som skiljer en migrering från en ombyggnad är
att systemet används hela vägen: användare, poster och integrationer följer med,
och den gamla versionen fortsätter arbeta tills den nya har tagit över.

Ordet används om arbete i två storlekar, och ofta säger ingen vilken av dem som
avses.

I stor skala är det en flytt till en ny plattform eller en ny huvudversion.
Microsofts Cloud Adoption Framework beskriver att flytta arbetslaster till
Azure, från egna servrar eller från ett annat moln, som fem steg: planera,
förbered arbetslasterna, genomför, optimera och avveckla källan. Esris kunder
flyttar sina kartor och data från ArcMap till ArcGIS Pro. En Next.js-applikation
går från Pages Router till App Router, där `getServerSideProps` ger vika för
datahämtning inuti Server Components. Ett PostgreSQL-kluster går över till en ny
huvudversion, som ofta ändrar uppbyggnaden av systemtabellerna, så datan måste
föras över med `pg_upgrade` eller med en dump och en återställning.

I liten skala är en migrering en enda versionerad ändring av strukturen i en
databas, sparad som en fil i repot och körd av ett verktyg i en fast ordning.
Django kallar sina migreringar ett versionshanteringssystem för databasschemat:
varje fil beskriver en ändring i modellerna, committas tillsammans med koden och
körs i samma ordning på utvecklarens dator, i staging och i produktion. GitLab
levererar batchvisa bakgrundsmigreringar som skriver om stora tabeller en del i
taget efter en uppgradering, till exempel när heltalskolumner görs om till
`bigint` innan värdena slår i taket. En datamigrering hör också hemma här: den
ändrar raderna i stället för kolumnerna, till exempel genom att fylla ett nytt
fält utifrån två gamla.

Det här är en idé i två storlekar. Båda har ett känt utgångsläge, en ordnad
följd av steg, ett mål och en väg tillbaka om ett steg går snett. En
plattformsflytt innehåller oftast schemamigreringar, och en lång rad
schemamigreringar är med åren en plattform som byts ut bit för bit under dem som
använder den.

## Varför det spelar roll

Programvara lever längre än det den är byggd på. Molnavtal omförhandlas, ramverk
byter modell, och leverantörer avvecklar produkter. Ett system som ska leva
i tio år migreras flera gånger under de tio åren, så hur väl ett team migrerar
betyder till slut mer än hur väl det valde den första plattformen.

1. **Mellanläget är där kostnaden hamnar.** Så länge en del av systemet körs på
   den gamla plattformen och en del på den nya måste båda driftas, övervakas och
   hållas i takt. Cloud Adoption Framework uppmanar teamen att hålla den
   perioden kort och att flytta komponenter som är direkt beroende av varandra i samma
   våg.
2. **En databas går inte att driftsätta på nytt.** Kod kan byggas om och bytas
   ut; raderna i produktion kan inte det. Schemamigreringar gör en
   strukturändring i en databas i drift till en fil som kan granskas, testas mot en kopia, köras i
   ordning och för de flesta ändringar rullas tillbaka. Alternativet är ett
   produktionsschema som ser ut så som den senaste personen med en konsol
   lämnade det.
3. **En planerad flytt går att ångra.** Cloud Adoption Framework kräver att
   kriterier och rutiner för återgång ligger fast innan en migrering börjar, att
   återgången är testad och att det finns go/no-go-kontrollpunkter längs vägen.

Avvägningarna ligger i själva omställningen. Cloud Adoption Framework skiljer
mellan migrering med driftstopp och migrering med nästan noll driftstopp, där
data replikeras löpande och bytet sker i slutet. För en ny huvudversion av
PostgreSQL kortar `pg_upgrade` omställningen: verktyget hoppar över den dump och
återställning som en sådan uppgradering vanligtvis kräver genom att återanvända
de befintliga datafilerna, och med `--link`, som inte kopierar några filer, går
det ännu mycket snabbare.

## Så ser det ut i praktiken

Tre projekt på den här webbplatsen visar begreppet i tre storlekar, från en hel
plattform ned till ordningen på filerna i ett enda repo.

Det största var en flytt bort från en molnleverantör. En kunds AWS-miljö var
överdimensionerad, och arbetet började med att skära ned i stället för att
flytta: dubblerade och onödiga tjänster togs bort, och det som var kvar
dimensionerades efter verklig efterfrågan. Först då
[flyttades arbetslasterna från AWS till en mer kostnadseffektiv hostinglösning](/sv/portfolio/a-tenth-of-the-cloud-bill-and-nothing-lost/),
i etapper, så att den löpande verksamheten aldrig märkte migreringen under sig.
Eftersom nedskärningen kom först fanns det mindre att flytta. Budgetkostnaderna
sjönk ungefär tiofalt, utan någon som helst förlust av produktivitet.

Det andra var ett byte av databasmotor med en ny design i andra änden. Databasen
i en geografisk kartapplikation gick från MSSQL till PostgreSQL med tillägget
PostGIS, och målet var inte en kopia av den gamla strukturen.
[Ett nytt schema utformades för spatiala data](/sv/portfolio/improved-gis-map-performance-10x-on-postgresql/),
med GiST- och SP-GiST-index och strikta främmande nycklar och
CHECK-villkor som upprätthåller valideringsregler för spatiala koordinater. Över
50 miljoner spatiala poster flyttades in via ETL-pipelines som transformerade
dem till EPSG:4326. En flytt till en ny design är chansen att skriva in datans
regler i själva schemat. Sidan anger att prestandan för spatiala databasfrågor
blev 10 gånger bättre och att CPU-belastningen i backend minskade med 65 %.

Det tredje är den lilla skalan, underhållen i flera år. En plattforms schema är
summan av
[1 022 migreringar, numrerade från 036 till 1102](/sv/portfolio/1022-migrations-behind-a-schema-drift-gate/),
och sidan kallar ordningsdisciplinen kring dem oglamorös och inte
förhandlingsbar. Historiken i repot är en beskrivning av produktion, och den
stämmer bara så länge varje databas, från en nyskapad utvecklarkopia till en
återställning från säkerhetskopia, kan byggas upp igen genom att historiken
spelas upp från första till sista fil.

## Var det går fel

Omställningen får planeringen, medan problemen gärna samlas i veckorna runt den,
i fyra igenkännbara former.

**Två system går sida vid sida längre än planerat.** Flytten stannar halvvägs,
bitarna som återstår är de svåra, och teamet driftar båda plattformarna i
månader. Användarna känner skarven: Next.js-guiden påpekar att en övergång
mellan en sida under Pages Router och en sida under App Router är en hård
navigering, och att `next/link` inte förhämtar mellan de två. Håll vågorna små,
och gör varje nästa steg billigt. En frontend här flyttar sina sidor till
[en gemensam fabrik som laddar varje sida med en enda rundtur](/sv/portfolio/built-the-next-js-16-frontend-ssr-ssg-and-csr/),
så att varje sida som flyttas ärver beteendet.

**En omställning utan väg tillbaka.** Vissa steg ändrar källan lika väl som
målet. Med `pg_upgrade --link` har det nya klustret, så snart det har startats,
skrivit till filer som det gamla delar, och det gamla klustret måste då
återställas från säkerhetskopia. Esri varnar för att en datamängd som har
uppgraderats för ArcGIS Pro kanske inte längre går att använda i ArcMap, och ber
användarna ta en kopia först. I Django ger en `RunSQL`-operation utan omvänd SQL
ett `IrreversibleError` i samma ögonblick som någon migrerar bakåt. Bestäm
kriterierna för återgång före första steget, öva vägen tillbaka och gör den till
en kontroll: ett repo här har en kontrollmotor vars validerare bland annat
verifierar
[att en migrering går att rulla tillbaka](/sv/portfolio/built-a-268-check-guard-engine-for-the-repo/).

**En migrering som redan har körts redigeras.** Migreringsverktyg registrerar
vilka filer som har körts och hoppar över dem från och med då. Ändrar du en fil
efter att den har nått produktion behåller produktion den gamla versionen, medan
varje ny databas får den nya: två scheman under en och samma historik. Låt körda
migreringar vara och rätta dem med en ny; ett bygge som spelar upp hela
historiken från en tom databas och jämför resultatet med en migrerad kopia
fångar avvikelsen.

**Den uppgraderade databasen är långsam första dagen.** `pg_upgrade` för över
det mesta av planerarens statistik, men inte allt, och planeraren gissar på
resten tills den har byggts upp igen. Kontrolläget `--check` ändrar ingenting
och kan köras medan den gamla servern fortfarande betjänar användare, så kör det
först, och bygg upp den saknade statistiken direkt efter uppgraderingen innan du
samlar in resten:

```sh
pg_upgrade --check -b "$OLD/bin" -B "$NEW/bin" -d "$OLD/data" -D "$NEW/data"
pg_upgrade -b "$OLD/bin" -B "$NEW/bin" -d "$OLD/data" -D "$NEW/data"
vacuumdb --all --analyze-in-stages --missing-stats-only
vacuumdb --all --analyze-only
```

## Läs mer

- [Plan your migration](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/migrate/)
  — Microsofts metod för att flytta arbetslaster till Azure: vågor, val av
  omställning och planering av återgång.
- [Migrations](https://docs.djangoproject.com/en/stable/topics/migrations/) —
  Djangos guide till versionerade schemaändringar, hur de rullas tillbaka och
  datamigreringar.
- [pg_upgrade](https://www.postgresql.org/docs/current/pgupgrade.html) —
  uppgraderingsverktyget i PostgreSQL, med kontrolläge, länkläge, återgång och
  statistikstegen efteråt.
- [How to migrate from Pages to the App Router](https://nextjs.org/docs/app/guides/migrating/app-router-migration)
  — så flyttar du en Next.js-applikation till den nya routern en sida i taget.
- [Migrate existing work](https://doc.esri.com/en/arcgis-pro/latest/get-started/migrate-existing-work.html)
  — vad som följer med från ArcMap till ArcGIS Pro, vad som måste konverteras
  och vad du bör kopiera först.
- [Check migrations before upgrade](https://docs.gitlab.com/update/background_migrations/)
  — hur GitLabs batchvisa bakgrundsmigreringar skriver om stora tabeller efter
  en uppgradering och hur du ser att de är klara.

<https://engineer.company/sv/glossary/migration/>
