Remover fragmentos de um cluster fragmentado
Para remover umfragmento , você deve garantir que os dados do fragmento sejam migrados para os fragmentos restantes no cluster. Este procedimento descreve como migrar dados com segurança e remover um fragmento.
Sobre esta tarefa
Criar, fragmentar ou mover coleções durante a execução desse procedimento pode causar interrupções e levar a resultados inesperados.
Não use esse procedimento para migrar um cluster inteiro para um novo hardware. Para migrar, consulte Migrar um cluster fragmentado autogerenciado para hardware diferente.
Quando você remove um fragmento em um cluster com uma distribuição desigual de fragmentos, o balanceador primeiro remove os fragmentos do fragmento de drenagem e, em seguida, equilibra a distribuição desigual de fragmentos restante.
A remoção de um shard pode fazer com que um cursor de fluxo de alteração aberto feche e o cursor de fluxo de alteração fechado pode não ser totalmente retomável.
Você pode reiniciar um cluster com segurança durante um processo de remoção de fragmentos. Se você reiniciar um cluster durante um processo contínuo de drenagem , a drenagem continuará automaticamente após a reinicialização dos componentes do cluster. O MongoDB registra o status de drenagem do fragmento na coleção
config.shards
.
Antes de começar
Este procedimento utiliza o método
sh.moveCollection()
para mover as collections para fora do shard removido. Antes de iniciar este procedimento, revise as considerações e requisitos domoveCollection
para entender o comportamento do comando.Para remover um fragmento, primeiro conecte-se a uma das instâncias
mongos
do cluster usandomongosh
.
Passos
Verifique se o balanceador está habilitado
Para migrar dados de um shard, o processo do balanceador deve estar habilitado. Para verificar o estado do balanceador , use o método sh.getBalancerState()
:
sh.getBalancerState()
Se a operação retornar true
, o balanceador estará habilitado.
Se a operação retornar false
, consulte Habilitar o Balancer.
Determine o nome do shard a ser removido
Para localizar o nome do shard, execute o comando listShards
:
db.adminCommand( { listShards: 1 } )
O campo shards._id
contém o nome do fragmento.
Remova chunks do fragmento
Execute o comando removeShard
para o shard que você deseja remover:
db.adminCommand( { removeShard: "<shardName>" } )
Observação
mongos
converte a write concern do comando removeShard
para "majority"
.
A operação removeShard
retorna:
{ "msg" : "draining started successfully", "state" : "started", "shard" : "<shardName>", "note" : "you need to drop or movePrimary these databases", "dbsToMove" : [ "db1", "db2" ], "ok" : 1, "operationTime" : Timestamp(1575398919, 2), "$clusterTime" : { "clusterTime" : Timestamp(1575398919, 2), "signature" : { "hash" : BinData(0,"Oi68poWCFCA7b9kyhIcg+TzaGiA="), "keyId" : NumberLong("6766255701040824328") } } }
O fragmento entra no estado draining
e o balanceador começa a migrar blocos do fragmento removido para outros fragmentos no cluster. Essas migrações ocorrem lentamente para evitar um impacto grave no cluster geral. Dependendo da capacidade da rede e da quantidade de dados, essa operação pode levar de alguns minutos a vários dias para ser concluída.
Dica
Enquanto o shard estiver no estado draining
, você pode utilizar o comando reshardCollection para redistribuir dados fora do shard removido.
Mover dados com reshardCollection
pode ser mais rápido do que esperar que o balanceador migre os blocos. O cluster garante que os dados não sejam colocados em nenhum shard de drenagem . Não é possível executar as operações moveCollection
e reshardCollection
simultaneamente.
Listar namespaces de collection fragmentados
Para retornar uma lista de namespaces de collections fragmentadas, use o estágio $shardedDataDistribution
e projeto o campo ns
:
use admin db.aggregate( [ { $shardedDataDistribution: { } }, { $project: { ns: 1 } } ] )
Registre a saída para fazer referência mais tarde neste tutorial.
Mover coleções para fora do fragmento
Para cada banco de dados de dados no cluster, exceto admin e config, execute estas etapas:
Listar as collections de banco de dados de dados
Liste as collections no banco de banco de dados, omitindo os seguintes tipos de collections:
Collections internas que suportam CSFLE
Collections do sistema
Coleções de séries temporais
Visualizações
use <databaseName> db.getCollectionInfos( { $and: [ { type: { $nin: [ "view", "timeseries" ] } }, { name: { $not: { $regex: "^system\." } } }, { name: { $not: { $regex: "^enxcol_\..*(\.esc|\.ecc|\.ecoc|\.ecoc\.compact)$" } } } ] }, { nameOnly: true } ) Mover collections necessárias
Para cada collection retornada por
getCollectionInfos()
, execute as etapas a seguir.Observação
Somente uma operação
moveCollection
pode estar em andamento por vez. Conclua todas as subetapas antes de passar para a próxima collection.Determine se a coleção precisa ser movida.
Execute o estágio de agregação
$collStats
e projeto os camposns
eshard
:db.<collName>.aggregate( [ { $collStats: { } }, { $project: { ns: 1, shard: 1 } } ] ) Se algum dos critérios a seguir for atendido, pule a collection e retorne à etapa
i
para a próxima collection no banco de banco de dados:O campo
ns
está presente na saída$shardedDataDistribution
da etapa 4.O campo
shard
não é o shard que está sendo removido.
Se nenhum dos critérios anteriores for atendido, continue para a etapa
ii
para a collection atual.Mova a collection.
Para mover a coleção, execute
sh.moveCollection()
na coleção:sh.moveCollection( "<namespace>.<collection>", "<ID of recipient shard>" ) Observação
moveCollection
falhará se você executar o comando em um namespace fragmentado. Se você receber esta mensagem de erro, ignore-a e retorne à etapai
para a próxima coleção.Retorne à etapa
i
para cada coleção no banco de banco de dados.
Repetir o procedimento para outros bancos de dados
Repita a etapa 6, Move collections off of the shard (e subetapas) para cada banco de dados de dados no cluster.
Alterar fragmento primário
Execute o método db.printShardingStatus()
:
db.printShardingStatus()
Na seção databases
da saída de comando, marque o campo database.primary
. Se o campo primary
for o fragmento removido, você deverá mover o primário desse banco de dados para um fragmento diferente.
Para alterar o fragmento primário de um banco de dados, execute o comando movePrimary
.
Aviso
Quando você executa movePrimary
, todas as collections que não foram movidas na etapa Move collections off of the shard ficam indisponíveis durante o processo movePrimary
.
db.adminCommand( { movePrimary: <dbName>, to: <shardName> } )
Verificar o status da migração
Para verificar o progresso da migração, execute removeShard
do banco de banco de dados admin
novamente:
db.adminCommand( { removeShard: "<shardName>" } )
Na saída, o campo remaining
inclui estes campos:
Campo | Descrição |
---|---|
chunks | Número de chunks atualmente restantes no shard |
dbs | Número de bancos de dados cujo fragmento primário é o shard. Estes bancos de dados são especificados no campo de saída dbsToMove . |
jumboChunks | Do número total de Se Depois que a sinalização |
Continue verificando o status do comando removeShard
até que o número de blocos restantes seja 0.
db.adminCommand( { removeShard: "<shardName>" } )
Finalize a remoção de fragmentos
Para finalizar o processo de remoção de shard, execute novamente o comando removeShard
:
db.adminCommand( { removeShard: <shardName> } )
Observação
Operações de DDL
Se você remover um fragmento enquanto o cluster executa uma operação DDL (uma operação que modifica uma collection como reshardCollection
), a operação removeShard
será executada após a conclusão da operação DDL simultânea.
Se o fragmento for removido, a saída do comando será semelhante ao seguinte:
{ msg: 'removeshard completed successfully', state: 'completed', shard: '<shardName>', ok: 1, '$clusterTime': { clusterTime: Timestamp({ t: 1721941519, i: 7 }), signature: { hash: Binary.createFromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAA=', 0), keyId: Long('0') } }, operationTime: Timestamp({ t: 1721941519, i: 7 }) }