Originally written for Percona Blog in January, 2023 – MongoDB – Converting Replica Set to Standalone
Um dos motivos para usar o MongoDB é sua facilidade em escalar sua estrutura, seja como um Replica Set (scale-up) ou como um Sharded Cluster (scale-out).
Embora o processo inverso seja um pouco mais complicado em ambientes shardeds, ele também pode ser realizado.
Entre as possibilidades, você pode:
- Reduzir o número de shards no seu Sharded Cluster, conforme documentado aqui.
- Reduzir o número de nós em um Replica Set, conforme detalhado aqui.
- Converter um Replica Set em um Sharded Cluster (e vice-versa), conforme documentado em Sharded Cluster to Replica Set.
Até aqui, tudo bem.
Mas, se por algum motivo o projeto MongoDB que começou como um Replica Set não precisa mais dessa estrutura e agora um servidor Standalone atende aos requisitos, surge a questão:
- É possível converter um Replica Set para um servidor Standalone?
- Se sim, qual é o procedimento para realizar essa configuração?
Este artigo guiará você pelos passos necessários para converter um Replica Set em um servidor Standalone.
Observações:
Antes de começar o processo, é importante mencionar que não é recomendável usar uma configuração Standalone em servidores de produção, pois toda a disponibilidade dependerá de um único ponto, aumentando o risco de falhas.
Outra observação é que essa atividade exige downtime, pois será necessário remover o parâmetro de replicação, algo que não pode ser feito com o processo do banco em execução.
Por fim, para evitar alterações nos dados durante o procedimento, recomenda-se interromper as operações de escrita realizadas pela aplicação.
Ao final do processo, também será necessário ajustar a string de conexão para refletir a nova configuração.
How To:
O ambiente de teste utilizado para este artigo é uma configuração padrão de Replica Set com três nós, conforme mostrado no status de replicação:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[ { "_id" : 0, "name" : "node1:27017", "stateStr" : "PRIMARY" }, { "_id" : 1, "name" : "node2:27017", "stateStr" : "SECONDARY", }, { "_id" : 2, "name" : "node3:27017", "stateStr" : "SECONDARY", ] |
O nó PRIMARY será a nossa fonte confiável de dados e se tornará o servidor Standalone ao final do processo.
Se você prefere que outro nó seja o Standalone e ele ainda não for o nó Primário, certifique-se de promovê-lo antes de iniciar o procedimento.
- 1. Removendo os secundários:
No nó Primário, remova os nós node2
e node3
:
1 2 |
rs0:PRIMARY> rs.remove("node2:27017") rs0:PRIMARY> rs.remove("node3:27017") |
Nota: Caso o seu Replica Set possua mais de três nós, o processo é o mesmo. Apenas o nó primário deve permanecer no Replica Set nesta etapa.
Após a remoção o status esperado deve ser:
1 2 3 4 5 6 7 8 9 |
rs0:PRIMARY> rs.status().members [ { "_id" : 0, "name" : "node1:27017", "stateStr" : "PRIMARY", "self" : true } ] |
- 2.Alterando a configuração:
Embora node2
e node3
já não façam parte do Replica Set, pare o processo mongod
nos respectivos servidores para garantir que os dados fiquem seguros para possíveis recuperações:
1 2 |
node2-shell> systemctl stop mongod node3-shell> systemctl stop mongod |
No nó primário, remova o parâmetro de replicação do arquivo de configuração. Edite o arquivo mongo.conf e comente ou remova as linhas:
1 2 |
#replication: # replSetName: "rs0" |
Nota: Caso você inicie o MongoDB pela linha de comando, remova a opção --replSet
.
Quando feito, reinicie o serviço no primário:
1 |
node1-shell> systemctl restart mongod |
- 3. Removendo objetos de replicação:
Quando você se conectar ao nó PRIMARY convertido para Standalone, o MongoDB exibirá o seguinte aviso:
Document(s) exist in ‘system.replset’, but started without –replSet. Database contents may appear inconsistent…
Esse aviso ocorre porque a configuração do Replica Set ainda está presente no banco de dados local
(em local.system.replset
). O que foi feito até o momento foi apenas a remoção dos antigos nós secundários e a remoção do parâmetro de Replica Set. Todo o metadata relacionado ainda existe dentro do banco de dados primário.
1 2 3 4 5 6 7 8 9 |
mongo> use local switched to db local mongo> show collections oplog.rs replset.election replset.minvalid startup_log system.replset |
Para remover esse aviso, você deve excluir o objeto antigo de Replica Set em local.system.replset
.
O
local.system.replset
contém o objeto de configuração do conjunto de réplicas como seu único documento. Para exibir as informações de configuração do objeto, emitars.conf()
demongosh
. Você também pode fazer query desta coleção diretamente.
No entanto, é importante destacar que o local.system.replset
é um objeto do sistema, e não há uma Role padrão que permita remover objetos desse tipo – a menos que você crie uma Role personalizada que conceda a permissão anyAction
em anyResource
ao usuário, ou atribua o papel interno __system
ao usuário.
⚠️ Nota: Ambas as opções concedem acesso irrestrito a todos os recursos do sistema e são destinadas apenas para uso interno. Não utilize essas permissões, exceto em circunstâncias excepcionais.
Dito isto.
Para este processo, criaremos um novo usuário temporário com o privilégio __system
, que poderá ser removido posteriormente após a execução da ação.
- 4. Criando o usuário temporário:
1 2 3 4 5 6 7 8 |
mongo > db.getSiblingDB("admin").createUser({ user: "dba_system", // Nome do usuário que está sendo criado pwd: "sekret", // Senha do usuário roles: [{ db: "admin", // Banco de dados onde a Role será atribuído role: "__system" // Role especial que concede acesso completo ao sistema }] }); |
- 5. Removendo o objeto:
Primeiro conecte-se utilizando o usuário criado, e em seguida remova o metadata relacionado a configuração do Replica Set:
1 2 |
mongo> use local; // Troca para o banco de dados local mongo> db.system.replset.remove({}) // Remove o objeto de configuração do Replica Set |
Saída de confirmação esperada:
- 6. Removendo o usuário temporário:
Uma vez finalizado a remoção do metadata, desconecte-se do usuário temporário criado. Em seguida, com o usuário admistrativo remova o "dba_system"
:
1 |
mongo> db.dropUser("dba_system") // Exclui o usuário temporário criado |
- 7. Reiniciando o serviço:
Reinicie o serviço mongod
para aplicar as alterações:
1 |
shell> systemctl restart mongod |
Uma vez reconectado ao servidor, o aviso não será exibido novamente, e o servidor estará pronto! 🎉
- 8. Orientação para Conexão:
Certifique-se de ajustar a string de conexão na aplicação e nos clientes, apontando apenas para o servidor Standalone.
Conclusão:
O processo de conversão, em geral, é simples e não deve apresentar grandes problemas. No entanto, é essencial destacar que é fortemente recomendado testar e executar este procedimento em um ambiente de teste ou desenvolvimento. Caso planeje utilizá-lo em produção, lembre-se das observações feitas anteriormente.
Se tiver alguma dúvida, fique à vontade para entrar em contato na seção de comentários abaixo!
Até mais!