O objetivo deste post é conhecer as várias formas de migração de dados no MongoDB que podem nos ajudar a escrever scripts que alterem seu banco de dados adicionando novos documentos, modificando os existentes.
Se você está vindo aqui pela primeira vez, dê uma olhada no prequel Self-Hosted MongoDB.
Tudo bem então, começando de onde paramos, vamos começar com a migração de dados no MongoDB.
Agora, as etapas básicas para migrar dados de um MongoDB para outro seriam:
- Crie um backup compactado dos dados existentes
- Despeje os dados em um novo banco de dados
Isso é muito simples quando o banco de dados de origem não está online porque sabemos que não haverá nenhum documento novo criado/atualizado durante o processo de migração. Vamos examinar a migração simples primeiro antes de mergulhar no cenário ao vivo.
Migrando de um banco de dados offline no MongoDB
Criando um backup
Vamos usar um programa utilitário existente mongodump para criar o backup do banco de dados.
Execute este comando no servidor de banco de dados de origem
mongodump --host="hostname:port" \
--username="username" --password="password" \
--authenticationDatabase "admin" \
--db="db name" --collection="collection name" --query='json' \
--forceTableScan -v --gzip --out ./dump
--host
:o nome do host MongoDB de origem junto com a porta. O padrão é localhost:27017
. Se for uma string de conexão, você pode usar esta opção —-uri="mongodb://username:password@host1[:port1]..."
--username
:especifica um nome de usuário para autenticação em um banco de dados MongoDB que usa autenticação. --password
:especifica uma senha para autenticação em um banco de dados MongoDB que usa autenticação. --authenticationDatabase
:Especifica o banco de dados de autenticação onde o --username
especificado foi criado.
Se você não especificar um banco de dados de autenticação ou um banco de dados para exportar, o mongodump assume que o banco de dados admin contém as credenciais do usuário.
--db
:especifica o banco de dados do qual fazer um backup. Se você não especificar um banco de dados, o mongodump coletará de todos os bancos de dados nesta instância.
Alternativamente, você também pode especificar o banco de dados diretamente na string de conexão URI, ou seja,mongodb://username:password@uri/dbname
.
Fornecendo uma string de conexão enquanto também usa--db
e especificar informações conflitantes resultará em um erro .
--collection
:Especifica uma coleção para backup. Se você não especificar uma coleção, esta opção copiará todas as coleções no banco de dados ou instância especificada para os arquivos de despejo. --query
:fornece um documento JSON como uma consulta que limita opcionalmente os documentos incluídos na saída do mongodump. Você deve colocar o documento de consulta entre aspas simples
('{ ... }')
para garantir que ele não interaja com seu ambiente.A consulta deve estar no formato Extended JSON v2 (modo relaxado ou canônico/estrito), incluindo os nomes dos campos e operadores entre aspas, por exemplo,
'{ "created_at": { "\$gte": ISODate(...) } }'
.
Para usar o--query
opção, você também deve especificar o--collection
opção.
--forceTableScan
:Força o mongodump a varrer o armazenamento de dados diretamente. Normalmente, o mongodump salva as entradas conforme aparecem no índice do _id
campo.
Se você especificar uma consulta--query
, o mongodump usará o índice mais apropriado para oferecer suporte a essa consulta.
Portanto, você não pode usar--forceTableScan
com a--query
opção .
--gzip
:Comprime a saída. Se o mongodump for enviado para o diretório de despejo, o novo recurso compactará os arquivos individuais. Os arquivos têm o sufixo .gz
. --out
:Especifica o diretório onde o mongodump gravará BSON
arquivos para os bancos de dados despejados. Por padrão, o mongodump salva os arquivos de saída em um diretório chamado dump no diretório de trabalho atual. Restaurando o backup
Usaremos um programa utilitário chamado
mongorestore
para restaurar o backup do banco de dados. Copie o dump do diretório de backup para a nova instância do Database e execute o seguinte comando:
mongorestore --uri="mongodb://user:password@host:port/?authSource=admin" \
--drop --noIndexRestore --gzip -v ./dump
Substitua as credenciais pelas novas credenciais do banco de dados. Unline na etapa anterior, o
--authenticationDatabase
A opção é especificada na string URI. Além disso, use
--gzip
se usado durante a criação do backup. --drop
:antes de restaurar as coleções do backup despejado, elimine as coleções do banco de dados de destino. Ele não descarta coleções que não estão no backup.--noIndexRestore
:Impede que o mongorestore restaure e construa índices conforme especificado na saída do mongodump correspondente.
Se você deseja alterar o nome do banco de dados durante a restauração, pode fazê-lo usando--nsFrom="old_name.*" --nsTo="new_name.*"
opções.
No entanto, não funcionará se você migrar comoplogs
que é um requisito na migração de uma instância online.
Migrando de um banco de dados online no MongoDB
O único desafio com a migração de um banco de dados online é não poder pausar as atualizações durante a migração. Então aqui está a visão geral das etapas,
- Execute uma migração inicial em massa com
oplogs
capturar - Execute um trabalho de sincronização para reduzir a latência do switch de conexão do banco de dados
Agora, para capturaroplogs
, um conjunto de réplicas deve ser inicializado nos bancos de dados de origem e destino. Isso ocorre porque osoplogs
são capturados delocal.oplog.rs
namespace, que é criado após a inicialização de um conjunto de réplicas.
Você pode seguir este guia para configurar um conjunto de réplicas.
Migração inicial com captura de Oplog
Oplogs, em palavras simples, são os logs de operação criados por operação no banco de dados. Eles representam um estado parcial do documento ou, em outras palavras, o estado do banco de dados. Então, vamos capturar quaisquer atualizações em nosso banco de dados antigo durante o processo de migração usando esses
oplogs
. Execute o programa mongodump com as seguintes opções,
mongodump --uri=".../?authSource=admin" \
--forceTableScan --oplog \
--gzip -v --out ./dump
--oplog
:Cria um arquivo chamado oplog.bson
como parte do mongodump
saída. O oplog.bson
arquivo, localizado no nível superior do diretório de saída, contém oplog
entradas que ocorrem durante a operação mongodump. Esse arquivo fornece um instantâneo pontual eficaz do estado de nossa instância de banco de dados. Restaure os dados com repetição de oplog
Para reproduzir os oplogs, é necessária uma função especial. Vamos criar e atribuir a função ao usuário do banco de dados que está sendo usado para migração.
Crie a função
db.createRole({
role: "interalUseOnlyOplogRestore",
privileges: [
{
resource: { anyResource: true },
actions: [ "anyAction" ]
}
],
roles: []
})
Atribuir a função
db.grantRolesToUser(
"admin",
[{ role:"interalUseOnlyOplogRestore", db:"admin" }]
);
Agora você pode restaurar usando o programa mongorestore com as seguintes opções,
mongorestore --uri="mongodb://admin:.../?authSource=admin" \
--oplogReplay
--gzip -v ./dump
No comando acima, usando o mesmo usuário
admin
com quem o papel estava associado. --oplogReplay
:Depois de restaurar o dump do banco de dados, reproduz as entradas oplog de um arquivo bson e restaura o banco de dados para o backup point-in-time capturado com o mongodump --oplog
comando. Atenuando a latência do switch de conexão do banco de dados
Tudo bem, até agora terminamos a maior parte do trabalho pesado. A única coisa que resta é manter a consistência entre os bancos de dados durante a troca de conexão em nossos servidores de aplicativos.
Se você estiver executando o MongoDB versão 3.6+, é melhor optar pela abordagem Change Stream, que é um mecanismo baseado em eventos introduzido para capturar alterações em seu banco de dados de maneira otimizada. Aqui está um artigo que cobre https://www.mongodb.com/blog/post/an-introduction-to-change-streams
Confira o script de sincronização genérico, que você pode executar como um trabalho CRON a cada minuto.
Atualize as variáveis neste script e execute como
$ ./delta-sync.sh from_epoch_in_milliseconds
# from_epoch_in_milliseconds is automatically picked with every iteration if not supplied
Ou você pode configurar um cron job para executar isso a cada minuto.
* * * * * ~/delta-sync.sh
A saída pode ser monitorada com o seguinte comando (estou executando o RHEL 8, consulte o guia do sistema operacional para obter a saída do cron)
$ tail -f /var/log/cron | grep CRON
Este é um log de sincronização de amostra.
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!)
Você pode parar este script depois de verificar que não há mais
oplogs
estão sendo criados, ou seja, quando o banco de dados de origem ficou offline. Isso conclui o guia completo de migração de dados do MongoDB auto-hospedado. Se você quiser aprender mais sobre o MongoDB, aqui está um recurso útil sobre como usar o MongoDB como fonte de dados no goLang.