Målet med dette indlæg er at lære om de forskellige måder at migrere på i MongoDB, som kan hjælpe os med at skrive scripts, der ændrer din database ved at tilføje nye dokumenter, ændre eksisterende.
Hvis du kommer her for første gang, så tag et kig på prequel Self-Hosted MongoDB.
Okay så, hvorfra vi slap, lad os komme i gang med datamigreringen i MongoDB.
Nu vil de grundlæggende trin til at migrere data fra en MongoDB til en anden være:
- Opret en zippet sikkerhedskopi af de eksisterende data
- Dump dataene i en ny DB
Dette er meget ligetil, når kildedatabasen ikke er online, fordi vi ved, at der ikke vil blive oprettet/opdateret nye dokumenter under migreringsprocessen. Lad os først se på simpel migrering, før vi dykker ind i live-scenariet.
Migrering fra en offlinedatabase i MongoDB
Oprettelse af en sikkerhedskopi
Vi kommer til at bruge et eksisterende hjælpeprogram mongodump til at oprette databasesikkerhedskopien.
Kør denne kommando i kildedatabaseserveren
mongodump --host="hostname:port" \
--username="username" --password="password" \
--authenticationDatabase "admin" \
--db="db name" --collection="collection name" --query='json' \
--forceTableScan -v --gzip --out ./dump
--host
:Kilde MongoDB-værtsnavnet sammen med porten. Den er som standard localhost:27017
. Hvis det er en forbindelsesstreng, kan du bruge denne mulighed —-uri="mongodb://username:password@host1[:port1]..."
--username
:Angiver et brugernavn, der skal godkendes til en MongoDB-database, der bruger godkendelse.
--password
:Angiver en adgangskode, der skal godkendes til en MongoDB-database, der bruger godkendelse.
--authenticationDatabase
:Angiver godkendelsesdatabasen, hvor den angivne --username
er blevet oprettet.
Hvis du ikke angiver en godkendelsesdatabase eller en database, der skal eksporteres, antager mongodump, at administratordatabasen har brugerens legitimationsoplysninger.
--db
:Specificerer den database, der skal tages en sikkerhedskopi fra. Hvis du ikke angiver en database, indsamler mongodump fra alle databaser i dette tilfælde.
Alternativt kan du også angive databasen direkte i URI-forbindelsesstrengen, dvs. mongodb://username:password@uri/dbname
.
Giver en forbindelsesstreng, mens du også bruger --db
og angivelse af modstridende oplysninger vil resultere i en fejl .
--collection
:Specificerer en samling, der skal sikkerhedskopieres. Hvis du ikke angiver en samling, kopierer denne mulighed alle samlinger i den angivne database eller instans til dumpfilerne.
--query
:Giver et JSON-dokument som en forespørgsel, der valgfrit begrænser de dokumenter, der er inkluderet i outputtet af mongodump.
Du skal vedlægge forespørgselsdokumentet i enkelte anførselstegn ('{ ... }')
for at sikre, at den ikke interagerer med dit miljø.
Forespørgslen skal være i Extended JSON v2-format (enten afslappet eller kanonisk/streng mode), herunder omsluttende feltnavne og operatorer i anførselstegn, f.eks. '{ "created_at": { "\$gte": ISODate(...) } }'
.
For at bruge --query
mulighed, skal du også angive --collection
mulighed.
--forceTableScan
:Tvinger mongodump til at scanne datalageret direkte. Typisk gemmer mongodump poster, som de vises i indekset for _id
Mark.
Hvis du angiver en forespørgsel --query
, vil mongodump bruge det mest passende indeks til at understøtte denne forespørgsel.
Du kan derfor ikke bruge --forceTableScan
med --query
mulighed .
--gzip
:Komprimerer outputtet. Hvis mongodump udsender til dump-mappen, komprimerer den nye funktion de individuelle filer. Filerne har suffikset .gz
.
--out
:Specificerer den mappe, hvor mongodump vil skrive BSON
filer til de dumpede databaser. Som standard gemmer mongodump outputfiler i en mappe med navnet dump i den aktuelle arbejdsmappe.
Gendannelse af sikkerhedskopien
Vi vil bruge et hjælpeprogram kaldet mongorestore
til gendannelse af databasesikkerhedskopien.
Kopiér backup-mappedumpen til den nye databaseinstans, og kør følgende kommando:
mongorestore --uri="mongodb://user:password@host:port/?authSource=admin" \
--drop --noIndexRestore --gzip -v ./dump
Erstat legitimationsoplysningerne med de nye databaselegitimationsoplysninger. Fjern linje i det foregående trin, --authenticationDatabase
indstilling er angivet i URI-strengen.
Brug også --gzip
hvis det bruges under oprettelse af sikkerhedskopien.
--drop
:Før du gendanner samlingerne fra den dumpede sikkerhedskopi, sletter du samlingerne fra måldatabasen. Den taber ikke samlinger, der ikke er i sikkerhedskopien.--noIndexRestore
:Forhindrer mongorestore i at gendanne og bygge indekser som specificeret i den tilsvarende mongodump-output.
Hvis du vil ændre navn på databasen under gendannelse, kan du gøre det ved at bruge --nsFrom="old_name.*" --nsTo="new_name.*"
muligheder.
Det vil dog ikke fungere, hvis du skulle migrere med oplogs
hvilket er et krav ved migrering fra en onlineinstans.
Migrering fra en onlinedatabase i MongoDB
Den eneste udfordring med at migrere fra en onlinedatabase er ikke i stand til at sætte opdateringerne på pause under migreringen. Så her er oversigten over trinene,
- Kør en indledende massemigrering med
oplogs
fange - Kør et synkroniseringsjob for at mindske forsinkelsen i databaseforbindelsens switch
Nu for at fange oplogs
, skal et replikasæt initialiseres i kilde- og destinationsdatabaserne. Dette skyldes, at oplogs
er fanget fra local.oplog.rs
navneområde, som oprettes efter initialisering af et replikasæt.
Du kan følge denne vejledning for at konfigurere et replikasæt.
Initial migration med Oplog Capture
Oplogs er i enkle ord de operationslogfiler, der er oprettet pr. operation i databasen. De repræsenterer en delvis dokumenttilstand eller med andre ord databasetilstanden. Så vi vil fange eventuelle opdateringer i vores gamle database under migreringsprocessen ved hjælp af disse oplogs
.
Kør mongodump-programmet med følgende muligheder,
mongodump --uri=".../?authSource=admin" \
--forceTableScan --oplog \
--gzip -v --out ./dump
--oplog
:Opretter en fil med navnet oplog.bson
som en del af mongodump
produktion. oplog.bson
fil, placeret i det øverste niveau af output-mappen, indeholder oplog
poster, der opstår under mongodump-operationen. Denne fil giver et effektivt øjebliksbillede af tilstanden af vores databaseforekomst.
Gendan dataene med oplog replay
For at genspille oplogs kræves en særlig rolle. Lad os oprette og tildele rollen til databasebrugeren, der bruges til migrering.
Opret rollen
db.createRole({
role: "interalUseOnlyOplogRestore",
privileges: [
{
resource: { anyResource: true },
actions: [ "anyAction" ]
}
],
roles: []
})
Tildel rollen
db.grantRolesToUser(
"admin",
[{ role:"interalUseOnlyOplogRestore", db:"admin" }]
);
Nu kan du gendanne ved hjælp af mongorestore-programmet med følgende muligheder,
mongorestore --uri="mongodb://admin:.../?authSource=admin" \
--oplogReplay
--gzip -v ./dump
I ovenstående kommando skal du bruge den samme bruger admin
hvem rollen var tilknyttet.
--oplogReplay
:Efter gendannelse af databasedumpen, genafspiller oplog-posterne fra en bson-fil og gendanner databasen til punkt-i-tids-sikkerhedskopien, der er gemt med mongodumpen --oplog
kommando.
Afbødende ventetid på databaseforbindelsesskift
Okay, indtil videre er vi færdige med det meste af de tunge løft. Det eneste, der er tilbage, er at opretholde overensstemmelse mellem databaserne under forbindelsesskiftet i vores applikationsservere.
Hvis du kører MongoDB version 3.6+, er det bedre at gå efter Change Stream-tilgangen, som er en hændelsesbaseret mekanisme introduceret til at fange ændringer i din database på en optimeret måde. Her er en artikel, der dækker det https://www.mongodb.com/blog/post/an-introduction-to-change-streams
Tjek det generiske synkroniseringsscript, som du kan køre som et CRON-job hvert minut.
Opdater variablerne i dette script og kør som
$ ./delta-sync.sh from_epoch_in_milliseconds
# from_epoch_in_milliseconds is automatically picked with every iteration if not supplied
Eller du kan konfigurere et cron-job til at køre dette hvert minut.
* * * * * ~/delta-sync.sh
Outputtet kan overvåges med følgende kommando (jeg kører RHEL 8, se din OS-guide for cron-output)
$ tail -f /var/log/cron | grep CRON
Dette er et eksempel på en synkroniseringslog.
CMD (~/cron/dsync.sh)
CMDOUT (INFO: Updated log registry to use new timestamp on next run.)
CMDOUT (INFO: Created sync directory: /home/ec2-user/cron/dump/2020-11-03T19:01:01Z)
CMDOUT (Fetching oplog in range [2020-11-03T19:00:01Z - 2020-11-03T19:01:01Z])
CMDOUT (2020-11-03T19:01:02.319+0000#011dumping up to 1 collections in parallel)
CMDOUT (2020-11-03T19:01:02.334+0000#011writing local.oplog.rs to /home/ec2-user/cron/dump/2020-11-03T19:01:01Z/local/oplog.rs.bson.gz)
CMDOUT (2020-11-03T19:01:04.943+0000#011local.oplog.rs 0)
CMDOUT (2020-11-03T19:01:04.964+0000#011local.oplog.rs 0)
CMDOUT (2020-11-03T19:01:04.964+0000#011done dumping local.oplog.rs (0 documents))
CMDOUT (INFO: Dump success!)
CMDOUT (INFO: Replaying oplogs...)
CMDOUT (2020-11-03T19:01:05.030+0000#011using write concern: &{majority false 0})
CMDOUT (2020-11-03T19:01:05.054+0000#011will listen for SIGTERM, SIGINT, and SIGKILL)
CMDOUT (2020-11-03T19:01:05.055+0000#011connected to node type: standalone)
CMDOUT (2020-11-03T19:01:05.055+0000#011mongorestore target is a directory, not a file)
CMDOUT (2020-11-03T19:01:05.055+0000#011preparing collections to restore from)
CMDOUT (2020-11-03T19:01:05.055+0000#011found collection local.oplog.rs bson to restore to local.oplog.rs)
CMDOUT (2020-11-03T19:01:05.055+0000#011found collection metadata from local.oplog.rs to restore to local.oplog.rs)
CMDOUT (2020-11-03T19:01:05.055+0000#011restoring up to 4 collections in parallel)
CMDOUT (2020-11-03T19:01:05.055+0000#011replaying oplog)
CMDOUT (2020-11-03T19:01:05.055+0000#011applied 0 oplog entries)
CMDOUT (2020-11-03T19:01:05.055+0000#0110 document(s) restored successfully. 0 document(s) failed to restore.)
CMDOUT (INFO: Restore success!)
Du kan stoppe dette script efter at have bekræftet, at der ikke er flere oplogs
bliver oprettet, dvs. da kilde-DB gik offline.
Dette afslutter den komplette selv-hostede MongoDB-datamigreringsvejledning. Hvis du vil lære mere om MongoDB, er her en nyttig ressource til, hvordan du bruger MongoDB som datakilde i goLang.