Målet med det här inlägget är att lära oss om de olika sätten för datamigrering i MongoDB som kan hjälpa oss att skriva skript som ändrar din databas genom att lägga till nya dokument, modifiera befintliga.
Om du kommer hit för första gången, ta en titt på prequel Self-Hosted MongoDB.
Okej då, för att välja där vi slutade, låt oss börja med datamigreringen i MongoDB.
Nu skulle de grundläggande stegen för att migrera data från en MongoDB till en annan vara:
- Skapa en zippad säkerhetskopia av befintlig data
- Dumpa data i en ny DB
Detta är väldigt enkelt när källdatabasen inte är online eftersom vi vet att det inte kommer att skapas/uppdateras några nya dokument under migreringsprocessen. Låt oss först titta på enkel migrering innan vi dyker in i livescenariot.
Migrera från en offlinedatabas i MongoDB
Skapa en säkerhetskopia
Vi kommer att använda ett befintligt verktygsprogram mongodump för att skapa databasbackupen.
Kör det här kommandot i källdatabasservern
mongodump --host="hostname:port" \
--username="username" --password="password" \
--authenticationDatabase "admin" \
--db="db name" --collection="collection name" --query='json' \
--forceTableScan -v --gzip --out ./dump
--host
:Källans MongoDB-värdnamn tillsammans med porten. Standardinställningen är localhost:27017
. Om det är en anslutningssträng kan du använda det här alternativet —-uri="mongodb://username:password@host1[:port1]..."
--username
:Anger ett användarnamn som ska autentiseras till en MongoDB-databas som använder autentisering.
--password
:Anger ett lösenord för autentisering till en MongoDB-databas som använder autentisering.
--authenticationDatabase
:Anger autentiseringsdatabasen där angivet --username
har skapats.
Om du inte anger en autentiseringsdatabas eller en databas som ska exporteras, antar mongodump att administratörsdatabasen har användarens autentiseringsuppgifter.
--db
:Anger vilken databas som ska säkerhetskopieras från. Om du inte anger en databas, samlar mongodump in från alla databaser i det här fallet.
Alternativt kan du också ange databasen direkt i URI-anslutningssträngen, dvs.
mongodb://username:password@uri/dbname
.
Tillhandahåller en anslutningssträng samtidigt som du använder--db
och ange motstridig information kommer att resultera i ett fel .
--collection
:Anger en samling som ska säkerhetskopieras. Om du inte anger en samling kopierar det här alternativet alla samlingar i den angivna databasen eller instansen till dumpfilerna.
--query
:Tillhandahåller ett JSON-dokument som en fråga som valfritt begränsar dokumenten som ingår i utdata från mongodump.
Du måste bifoga frågedokumentet med enkla citattecken ('{ ... }')
för att säkerställa att den inte interagerar med din miljö.
Frågan måste vara i Extended JSON v2-format (antingen avslappnat eller kanoniskt/strikt läge), inklusive att omge fältnamnen och operatorerna inom citattecken t.ex. '{ "created_at": { "\$gte": ISODate(...) } }'
.
För att använda
--query
alternativet måste du också ange--collection
alternativ.
--forceTableScan
:Tvingar mongodump att skanna datalagret direkt. Vanligtvis sparar mongodump poster som de visas i indexet för _id
fält.
Om du anger en fråga
--query
, kommer mongodump att använda det lämpligaste indexet för att stödja den frågan.
Därför kan du inte använda--forceTableScan
med--query
alternativ .
--gzip
:Komprimerar utmatningen. Om mongodump matar ut till dumpkatalogen, komprimerar den nya funktionen de enskilda filerna. Filerna har suffixet .gz
.
--out
:Anger katalogen där mongodump kommer att skriva BSON
filer för de dumpade databaserna. Som standard sparar mongodump utdatafiler i en katalog som heter dump i den aktuella arbetskatalogen.
Återställa säkerhetskopian
Vi kommer att använda ett verktygsprogram som heter mongorestore
för att återställa databassäkerhetskopian.
Kopiera backupkatalogdumpen till den nya databasinstansen och kör följande kommando:
mongorestore --uri="mongodb://user:password@host:port/?authSource=admin" \
--drop --noIndexRestore --gzip -v ./dump
Ersätt autentiseringsuppgifterna med de nya databasuppgifterna. Ta bort linjen i föregående steg, --authenticationDatabase
alternativet anges i URI-strängen.
Använd också --gzip
om det används när du skapar säkerhetskopian.
--drop
:Innan du återställer samlingarna från den dumpade säkerhetskopian, släpper du samlingarna från måldatabasen. Den tar inte bort samlingar som inte finns i säkerhetskopian.--noIndexRestore
:Förhindrar mongorestore från att återställa och bygga index som specificerats i motsvarande mongodump-utdata.
Om du vill ändra namnet på databasen under återställningen kan du göra det med
--nsFrom="old_name.*" --nsTo="new_name.*"
alternativ.
Det kommer dock inte att fungera om du skulle migrera medoplogs
vilket är ett krav vid migrering från en onlineinstans.
Migrera från en onlinedatabas i MongoDB
Den enda utmaningen med att migrera från en onlinedatabas är att inte kunna pausa uppdateringarna under migreringen. Så här är översikten över stegen,
- Kör en första massmigrering med
oplogs
fånga - Kör ett synkroniseringsjobb för att minska fördröjningen av databasanslutningsväxling
Nu, för att fånga
oplogs
, måste en replikuppsättning initieras i käll- och måldatabaserna. Detta beror på attoplogs
hämtas frånlocal.oplog.rs
namnutrymme, som skapas efter initialisering av en replikuppsättning.
Du kan följa den här guiden för att konfigurera en replikuppsättning.
Initial migrering med Oplog Capture
Oplogs, med enkla ord, är operationsloggarna som skapas per operation i databasen. De representerar ett partiellt dokumenttillstånd eller, med andra ord, databastillståndet. Så vi kommer att fånga alla uppdateringar i vår gamla databas under migreringsprocessen med dessa oplogs
.
Kör mongodump-programmet med följande alternativ,
mongodump --uri=".../?authSource=admin" \
--forceTableScan --oplog \
--gzip -v --out ./dump
--oplog
:Skapar en fil med namnet oplog.bson
som en del av mongodump
produktion. oplog.bson
filen, som ligger på den översta nivån i utdatakatalogen, innehåller oplog
poster som inträffar under mongodump-operationen. Den här filen ger en effektiv ögonblicksbild av tillståndet för vår databasinstans.
Återställ data med oplog replay
För att spela om oplogarna krävs en speciell roll. Låt oss skapa och tilldela rollen till databasanvändaren som används för migrering.
Skapa rollen
db.createRole({
role: "interalUseOnlyOplogRestore",
privileges: [
{
resource: { anyResource: true },
actions: [ "anyAction" ]
}
],
roles: []
})
Tilldela rollen
db.grantRolesToUser(
"admin",
[{ role:"interalUseOnlyOplogRestore", db:"admin" }]
);
Nu kan du återställa med mongorestore-programmet med följande alternativ,
mongorestore --uri="mongodb://admin:.../?authSource=admin" \
--oplogReplay
--gzip -v ./dump
I ovanstående kommando använder du samma användare admin
som rollen var förknippad med.
--oplogReplay
:Efter att ha återställt databasdumpen, spelar upp oplogposterna från en bson-fil igen och återställer databasen till punkt-i-tids-säkerhetskopian som hämtats med mongodumpen --oplog
kommando.
Reducerande fördröjning för databasanslutning
Okej, än så länge är vi klara med de flesta tunga lyften. Det enda som återstår är att upprätthålla överensstämmelse mellan databaserna under anslutningsbytet i våra applikationsservrar.
Om du kör MongoDB version 3.6+ är det bättre att välja Change Stream-metoden, som är en händelsebaserad mekanism som introduceras för att fånga ändringar i din databas på ett optimerat sätt. Här är en artikel som täcker det https://www.mongodb.com/blog/post/an-introduction-to-change-streams
Kolla in det generiska synkroniseringsskriptet, som du kan köra som ett CRON-jobb varje minut.
Uppdatera variablerna i det här skriptet och kör som
$ ./delta-sync.sh from_epoch_in_milliseconds
# from_epoch_in_milliseconds is automatically picked with every iteration if not supplied
Eller så kan du ställa in ett cron-jobb för att köra detta varje minut.
* * * * * ~/delta-sync.sh
Utdata kan övervakas med följande kommando (jag kör RHEL 8, se din OS-guide för cron-utdata)
$ tail -f /var/log/cron | grep CRON
Detta är ett exempel på synkroniseringslogg.
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 stoppa det här skriptet efter att ha verifierat att inga fler oplogs
skapas, d.v.s. när källan DB gick offline.
Detta avslutar den kompletta självvärdade MongoDB-datamigreringsguiden. Om du vill lära dig mer om MongoDB här är en användbar resurs om hur du använder MongoDB som datakälla i goLang.