L'obiettivo di questo post è conoscere i vari modi di migrazione dei dati in MongoDB che possono aiutarci a scrivere script che cambiano il tuo database aggiungendo nuovi documenti, modificando quelli esistenti.
Se vieni qui per la prima volta, dai un'occhiata al prequel Self-Hosted MongoDB.
Bene, allora, riprendendo da dove eravamo rimasti, iniziamo con la migrazione dei dati in MongoDB.
Ora, i passaggi di base per migrare i dati da un MongoDB a un altro sarebbero:
- Crea un backup compresso dei dati esistenti
- Scarica i dati in un nuovo DB
Questo è molto semplice quando il database di origine non è online perché sappiamo che non ci saranno nuovi documenti creati/aggiornati durante il processo di migrazione. Diamo un'occhiata alla migrazione semplice prima di immergerci nello scenario live.
Migrazione da un database offline in MongoDB
Creazione di un backup
Useremo un programma di utilità esistente mongodump per creare il backup del database.
Esegui questo comando nel server del database di origine
mongodump --host="hostname:port" \
--username="username" --password="password" \
--authenticationDatabase "admin" \
--db="db name" --collection="collection name" --query='json' \
--forceTableScan -v --gzip --out ./dump
--host
:il nome host MongoDB di origine insieme alla porta. Il valore predefinito è localhost:27017
. Se è una stringa di connessione puoi usare questa opzione —-uri="mongodb://username:password@host1[:port1]..."
--username
:specifica un nome utente per l'autenticazione in un database MongoDB che utilizza l'autenticazione.
--password
:specifica una password per l'autenticazione in un database MongoDB che utilizza l'autenticazione.
--authenticationDatabase
:specifica il database di autenticazione in cui è specificato il --username
è stato creato.
Se non specifichi un database di autenticazione o un database da esportare, mongodump presume che il database di amministrazione contenga le credenziali dell'utente.
--db
:specifica il database da cui eseguire un backup. Se non specifichi un database, mongodump raccoglie da tutti i database in questa istanza.
In alternativa, puoi anche specificare il database direttamente nella stringa di connessione URI, ad esempio mongodb://username:password@uri/dbname
.
Fornire una stringa di connessione mentre si utilizza anche --db
e specificando informazioni in conflitto comporterà un errore .
--collection
:specifica una raccolta di cui eseguire il backup. Se non specifichi una raccolta, questa opzione copia tutte le raccolte nel database o nell'istanza specificata nei file di dump.
--query
:fornisce un documento JSON come query che facoltativamente limita i documenti inclusi nell'output di mongodump.
Devi racchiudere il documento della query tra virgolette singole ('{ ... }')
per garantire che non interagisca con l'ambiente.
La query deve essere in formato JSON v2 esteso (modalità rilassata o canonica/rigorosa), includendo i nomi dei campi e gli operatori tra virgolette, ad es. '{ "created_at": { "\$gte": ISODate(...) } }'
.
Per utilizzare --query
opzione, devi anche specificare il --collection
opzione.
--forceTableScan
:Forza mongodump a scansionare direttamente l'archivio dati. In genere, mongodump salva le voci così come appaiono nell'indice del _id
campo.
Se specifichi una query --query
, mongodump utilizzerà l'indice più appropriato per supportare quella query.
Quindi, non puoi usare --forceTableScan
con il --query
opzione .
--gzip
:comprime l'output. Se mongodump esce nella directory dump, la nuova funzionalità comprime i singoli file. I file hanno il suffisso .gz
.
--out
:Specifica la directory in cui mongodump scriverà BSON
file per i database di cui è stato eseguito il dump. Per impostazione predefinita, mongodump salva i file di output in una directory denominata dump nella directory di lavoro corrente.
Ripristino del backup
Useremo un programma di utilità chiamato mongorestore
per ripristinare il backup del database.
Copia il dump della directory di backup nella nuova istanza del database ed esegui il comando seguente:
mongorestore --uri="mongodb://user:password@host:port/?authSource=admin" \
--drop --noIndexRestore --gzip -v ./dump
Sostituire le credenziali con le nuove credenziali del database. Slinea nel passaggio precedente, il --authenticationDatabase
l'opzione è specificata nella stringa URI.
Inoltre, usa --gzip
se utilizzato durante la creazione del backup.
--drop
:prima di ripristinare le raccolte dal backup di cui è stato eseguito il dump, elimina le raccolte dal database di destinazione. Non elimina le raccolte che non sono nel backup.--noIndexRestore
:Impedisce a mongorestore di ripristinare e creare indici come specificato nell'output mongodump corrispondente.
Se desideri modificare il nome del database durante il ripristino, puoi farlo utilizzando --nsFrom="old_name.*" --nsTo="new_name.*"
opzioni.
Tuttavia, non funzionerà se dovessi migrare con oplogs
che è un requisito nella migrazione da un'istanza online.
Migrazione da un database online in MongoDB
L'unico problema con la migrazione da un database online non è in grado di sospendere gli aggiornamenti durante la migrazione. Quindi ecco la panoramica dei passaggi,
- Esegui una migrazione in blocco iniziale con
oplogs
cattura - Esegui un processo di sincronizzazione per mitigare la latenza del cambio di connessione al database
Ora, per acquisire oplogs
, è necessario inizializzare un set di repliche nei database di origine e di destinazione. Questo perché gli oplogs
vengono acquisiti da local.oplog.rs
namespace, che viene creato dopo l'inizializzazione di un set di repliche.
Puoi seguire questa guida per configurare un set di repliche.
Migrazione iniziale con Oplog Capture
Gli oplog, in parole semplici, sono i log delle operazioni creati per operazione nel database. Rappresentano uno stato del documento parziale o, in altre parole, lo stato del database. Quindi acquisiremo tutti gli aggiornamenti nel nostro vecchio database durante il processo di migrazione utilizzando questi oplogs
.
Esegui il programma mongodump con le seguenti opzioni,
mongodump --uri=".../?authSource=admin" \
--forceTableScan --oplog \
--gzip -v --out ./dump
--oplog
:Crea un file chiamato oplog.bson
come parte del mongodump
produzione. Il oplog.bson
file, che si trova nel livello più alto della directory di output, contiene oplogs
voci che si verificano durante l'operazione mongodump. Questo file fornisce un'efficace snapshot point-in-time dello stato della nostra istanza di database.
Ripristina i dati con la riproduzione oplog
Per riprodurre gli oplog, è richiesto un ruolo speciale. Creiamo e assegniamo il ruolo all'utente del database utilizzato per la migrazione.
Crea il ruolo
db.createRole({
role: "interalUseOnlyOplogRestore",
privileges: [
{
resource: { anyResource: true },
actions: [ "anyAction" ]
}
],
roles: []
})
Assegna il ruolo
db.grantRolesToUser(
"admin",
[{ role:"interalUseOnlyOplogRestore", db:"admin" }]
);
Ora puoi ripristinare utilizzando il programma mongorestore con le seguenti opzioni,
mongorestore --uri="mongodb://admin:.../?authSource=admin" \
--oplogReplay
--gzip -v ./dump
Nel comando precedente, utilizzando lo stesso utente admin
a cui era associato il ruolo.
--oplogReplay
:Dopo aver ripristinato il dump del database, riproduce le voci oplog da un file bson e ripristina il database sul backup point-in-time acquisito con mongodump --oplog
comando.
Mitigazione della latenza del cambio di connessione al database
Va bene, finora abbiamo finito con la maggior parte del lavoro pesante. L'unica cosa che rimane è mantenere la coerenza tra i database durante il cambio di connessione nei nostri server delle applicazioni.
Se stai eseguendo MongoDB versione 3.6+, è meglio optare per l'approccio Change Stream, che è un meccanismo basato su eventi introdotto per acquisire le modifiche nel tuo database in modo ottimizzato. Ecco un articolo che lo copre https://www.mongodb.com/blog/post/an-introduction-to-change-streams
Dai un'occhiata allo script di sincronizzazione generico, che puoi eseguire come processo CRON ogni minuto.
Aggiorna le variabili in questo script ed esegui come
$ ./delta-sync.sh from_epoch_in_milliseconds
# from_epoch_in_milliseconds is automatically picked with every iteration if not supplied
Oppure puoi impostare un processo cron per eseguirlo ogni minuto.
* * * * * ~/delta-sync.sh
L'output può essere monitorato con il seguente comando (sto eseguendo RHEL 8, fare riferimento alla guida del sistema operativo per l'output cron)
$ tail -f /var/log/cron | grep CRON
Questo è un registro di sincronizzazione di esempio.
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!)
Puoi interrompere questo script dopo aver verificato che non ci siano più oplogs
vengono creati, ovvero quando il DB di origine è andato offline.
Questo conclude la guida completa alla migrazione dei dati MongoDB self-hosted. Se vuoi saperne di più su MongoDB, ecco una risorsa utile su come utilizzare MongoDB come origine dati in goLang.