Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/ / /

Refragmentar uma collection

Nesta página

  • Requisitos
  • Limitações
  • Processo de refragmentação
  • Inicie a operação de refragmentação.
  • Monitore a operação de refragmentação.
  • Conclua a operação de refragmentação.
  • Inicie o bloqueio das gravações com antecedência para forçar a conclusão da refragmentação
  • Abortar operação de refragmentação
  • Comportamento
  • Duração mínima de uma operação de refragmentação
  • Gravações repetíveis
  • Erro de Case
  • Valores duplicados de _id

Novidades na versão 5.0.

A chave de fragmento ideal permite que o MongoDB distribua documentos uniformemente em todo o cluster, ao mesmo tempo em que facilita padrões de consultas comuns. Uma chave de fragmento abaixo do ideal pode levar a problemas de desempenho ou dimensionamento devido à distribuição desigual de dados. A partir do MongoDB 5.0, você pode alterar a chave de fragmento de uma coleção para mudar a distribuição de seus dados em um cluster.

Observação

Antes de refragmentar sua coleção, leia Solucionar problemas de chaves de Shard para obter informações sobre problemas comuns de desempenho e dimensionamento e conselhos sobre como corrigi-los.

Antes de refragmentar sua collection, certifique-se de atender aos seguintes requisitos:

  • Seu aplicativo pode tolerar um período de dois segundos em que a collection que está sendo refragmentada bloqueia as gravações. Durante o período em que as gravações são bloqueadas, seu aplicativo experimenta um aumento na latência. Se seu volume de trabalho não tolerar esse requisito, considere ajustar sua chave de shard.

  • Seu banco de dados atende aos seguintes requisitos de recursos:

    • Espaço de armazenamento disponível: certifique-se de que seu cluster tenha espaço em disco suficiente disponível para refragmentação. Se os documentos na collection refragmentada forem distribuídos uniformemente em todo o cluster, cada fragmento (shard) consumirá cerca de 1,2 vezes o tamanho total da collection dividido pelo número de fragmentos para armazenamento em disco.

      Observação

      A refragmentação requer espaço em disco adicional porque o processo cria uma nova coleção com dados distribuídos entre fragmentos de acordo com a nova chave do fragmento. Consulte Processo de refragmentação para obter mais informações.

    • E/S: certifique-se de que sua capacidade de E/S esteja abaixo de 50%.

    • Carga da CPU: certifique-se de que a carga da CPU esteja abaixo de 80%.

    Importante

    Esses requisitos não são exigidos pelo banco de dados. Uma falha na alocação de recursos suficientes pode resultar em:

    • o banco de dados ficar sem espaço e desligando

    • redução do desempenho

    • a operação de refragmentação demora mais que o esperado

    Se o seu aplicativo tiver períodos com menos tráfego, refaça a fragmentação da sua collection durante esse período, se possível.

  • Você deve executar uma destas tarefas:

    As seguintes queries retornam um erro se o filtro de query não incluir ambos a chave de shard atual ou um campo exclusivo (como _id):

    Para um desempenho ideal, recomendamos que você também reescreva outras queries para incluir a nova chave de shard.

    Quando a operação de refragmentação for concluída, você poderá remover a chave de shard antiga das consultas.

  • Nenhuma construção de índice está em andamento. Use db.currentOp() para verificar qualquer construção de índice está em execução:

    db.adminCommand(
    {
    currentOp: true,
    $or: [
    { op: "command", "command.createIndexes": { $exists: true } },
    { op: "none", "msg" : /^Index Build/ }
    ]
    }
    )

    No documento de resultado, se o valor do campo inprog for uma array vazia, não haverá nenhuma construção de índice em andamento:

    {
    inprog: [],
    ok: 1,
    '$clusterTime': { ... },
    operationTime: <timestamp>
    }

Observação

A refragmentação é um processo de gravação intensiva que pode gerar taxas maiores de oplog. Talvez você queira:

  • definir um tamanho fixo de oplog para prevenir o crescimento ilimitado do oplog.

  • aumentar o tamanho do oplog para minimizar a chance de um ou mais nós secundários se tornarem obsoletos.

Consulte a documentação Conjunto de réplicas do Oplog para obter mais detalhes.

  • Somente uma coleção pode ser refragmentada de cada vez.

  • writeConcernMajorityJournalDefault deve ser true.

  • Para refragmentar uma collection que tenha uma restrição de exclusividade, a nova chave de shard deve satisfazer os requisitos de índice únicos para quaisquer índices únicos existentes.

  • Os comandos a seguir e os métodos de shell correspondentes não são compatíveis com a collection que está sendo refragmentada enquanto a operação de refragmentação está em andamento:

  • Os seguintes comandos e métodos não são suportados no cluster enquanto a operação de refragmentação está em andamento:

    Aviso

    Usar qualquer um dos comandos anteriores durante uma operação de refragmentação faz com que a operação de refragmentação falhe.

  • Se a collection a ser refragmentada usar Atlas Search, o índice de pesquisa ficará indisponível quando a operação de refragmentação for concluída. Você precisa refragmentar manualmente o índice de pesquisa assim que a operação de refragmentação for concluída.

  • Você não pode refragmentar uma collection de séries temporais fragmentada.

Importante

É altamente recomendável que você verifique as Limitações e leia a seção Processo de refragmentação na íntegra antes de refragmentar sua coleção.

Em uma operação de refragmentação de collection, um fragmento (shard) pode ser um:

  • doador, que atualmente armazena chunks para a coleção fragmentada.

  • receptor, que armazena novos chunks para a coleção fragmentada com base nas chaves de Shard e nas zonas.

Um shard pode ser doador e um receptor ao mesmo tempo. O conjunto de shards do doador é idêntico aos shards do receptor, a menos que você use zonas.

O servidor de configuração primário é sempre o gerenciador de refragmentação e inicia cada fase da operação de refragmentação.

1

Enquanto conectado ao mongos, emita um comando reshardCollection que especifica a collection a ser refragmentada e a nova chave de shard:

db.adminCommand({
reshardCollection: "<database>.<collection>",
key: <shardkey>
})

O MongoDB define o número máximo de segundos para bloquear gravações para dois segundos e inicia a operação de refragmentação.

2

Para monitorar a operação de refragmentação, você pode usar o estágio de pipeline$currentOp:

db.getSiblingDB("admin").aggregate([
{ $currentOp: { allUsers: true, localOps: false } },
{
$match: {
type: "op",
"originatingCommand.reshardCollection": "<database>.<collection>"
}
}
])

Observação

Para ver os valores atualizados, você precisa executar continuamente o pipeline anterior.

As saídas do pipeline $currentOp:

  • totalOperationTimeElapsedSecs: tempo de operação decorrido em segundos

  • remainingOperationTimeEstimatedSecs: tempo restante estimado para a operação de refragmentação atual. É retornado como -1 quando uma nova operação de refragmentação é iniciada.

    Começando no:

    • MongoDB 5.0, mas antes do MongoDB 6.1, o remainingOperationTimeEstimatedSecs só está disponível em um shard de receptor durante uma operação de refragmentação.

    • MongoDB 6.1, remainingOperationTimeEstimatedSecs também está disponível no coordenador durante uma operação de refragmentação.

    A operação de refragmentação executa estas fases na ordem:

    1. A fase do clonagem duplica os dados da collection atual.

    2. A fase de atualização aplica quaisquer operações de gravação pendentes à collection refragmentada.

    remainingOperationTimeEstimatedSecs está definido para uma estimativa de tempo pessimista:

    • A estimativa de tempo da fase de recuperação é definida como o tempo da fase de clonagem, que é um tempo relativamente longo.

    • Na prática, se houver apenas algumas operações de escrita pendentes, o tempo de fase de recuperação real é relativamente curto.

[
{
shard: '<shard>',
type: 'op',
desc: 'ReshardingRecipientService | ReshardingDonorService | ReshardingCoordinatorService <reshardingUUID>',
op: 'command',
ns: '<database>.<collection>',
originatingCommand: {
reshardCollection: '<database>.<collection>',
key: <shardkey>,
unique: <boolean>,
collation: { locale: 'simple' }
},
totalOperationTimeElapsedSecs: <number>,
remainingOperationTimeEstimatedSecs: <number>,
...
},
...
]
3

Durante todo o processo de refragmentação, o tempo estimado para concluir a operação de refragmentação (remainingOperationTimeEstimatedSecs) diminui. Quando o tempo estimado é inferior a dois segundos,a MongoDB bloqueia as gravações e conclui a operação de refragmentação. Até que o tempo estimado para concluir a operação de refragmentação seja inferior a dois segundos, a operação de refragmentação não bloqueia gravações por padrão. Durante o período em que as gravações são bloqueadas, seu aplicativo experimenta um aumento na latência.

Depois que o processo de refragmentação for concluído, o comando de refragmentação retornará ok: 1.

{
ok: 1,
'$clusterTime': {
clusterTime: <timestamp>,
signature: {
hash: Binary(Buffer.from("0000000000000000000000000000000000000000", "hex"), 0),
keyId: <number>
}
},
operationTime: <timestamp>
}

Para ver se a operação de refragmentação foi concluída com sucesso, verifique a saída do método sh.status():

sh.status()

A saída do método sh.status() contém uma subseção para o databases. Se a refragmentação tiver sido concluída com êxito, a saída listará a nova chave de shard para a collection:

databases
[
{
database: {
_id: '<database>',
primary: '<shard>',
partitioned: false,
version: {
uuid: <uuid>,
timestamp: <timestamp>,
lastMod: <number>
}
},
collections: {
'<database>.<collection>': {
shardKey: <shardkey>,
unique: <boolean>,
balancing: <boolean>,
chunks: [],
tags: []
}
}
}
...
]

Observação

Se a coleção refragmentada usar Atlas Search, o índice de pesquisa ficará indisponível quando a operação de refragmentação for concluída. Você precisa refragmentar manualmente o índice de pesquisa assim que a operação de refragmentação for concluída.

Você pode forçar manualmente a conclusão da operação de refragmentação emitindo o comando commitReshardCollection. Isso é útil se a estimativa de tempo atual para concluir a operação de refragmentação for uma duração aceitável para que sua collection bloqueie gravações. O comando commitReshardCollection bloqueia as gravações antecipadamente e força a conclusão da operação de refragmentação. O comando tem a seguinte sintaxe:

db.adminCommand({
commitReshardCollection: "<database>.<collection>"
})

Você pode cancelar a operação de refragmentação durante qualquer estágio da operação de refragmentação, mesmo após executar o commitReshardCollection, até que os shards estejam totalmente atualizados.

Por exemplo, se a estimativa de duração da indisponibilidade de gravação não diminuir, você poderá cancelar a operação de refragmentação com o comando abortReshardCollection:

db.adminCommand({
abortReshardCollection: "<database>.<collection>"
})

Depois de cancelar a operação, você pode tentar novamente a operação de refragmentação em uma janela de tempo com menor volume de gravação. Se isso não for possível, adicione mais shards antes de tentar novamente.

A duração mínima de uma operação de refragmentação é sempre de cinco minutos.

As Retryable Writes iniciadas antes ou durante a refragmentação podem ser repetidas durante e após a collection ter sido refragmentada por até cinco minutos. Após cinco minutos, talvez você não consiga encontrar o resultado definitivo da gravação e as tentativas subsequentes de repetir a gravação falharão com o erro IncompleteTransactionHistory.

A operação de refragmentação falhará se _id valores não forem globalmente exclusivos para evitar a corrupção dos dados da collection. Valores _id duplicados também podem impedir a migração bem-sucedida de chunks. Se houver documentos com valores _id duplicados, copie os dados de cada um deles em um novo documento e, em seguida, exclua os documentos duplicados.

← Refinar uma chave de fragmento