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

Perguntas frequentes: simultaneidade

Nesta página

O MongoDB permite que vários clientes leiam e escrevam os mesmos dados. Para garantir consistência, o MongoDB usa o bloqueio eo controle de concorrência para evitar que os clientes modifiquem os mesmos dados simultaneamente. As gravações em um único documento ocorrem na íntegra ou não ocorrem e os clientes sempre veem dados consistentes.

O MongoDB usa bloqueio multigranular [1] que permite que as operações sejam bloqueadas em nível global, de banco de dados ou de collection e que mecanismos de armazenamento individuais implementem seu próprio controle de concorrência abaixo do nível da collection (por exemplo, no nível do documento no WiredTiger).

O MongoDB usa travas de leitor-gravador que permitem que leitores simultâneos tenham acesso compartilhado a um recurso, como um banco de dados ou uma collection.

Além de um modo de bloqueio compartilhado (S) para leituras e um modo de bloqueio exclusivo (X) para operações de gravação, os modos de intenção compartilhada (IS) e intenção exclusiva (IX) indicam uma intenção de ler ou gravar um recurso usando um bloqueio de granularidade mais fina. Ao bloquear em uma determinada granularidade, todos os níveis superiores são bloqueados usando um bloqueio de intenção.

Por exemplo, ao bloquear uma collection para gravação (usando o modo X), tanto o bloqueio do banco de dados correspondente quanto o bloqueio global devem ser bloqueados no modo de intenção exclusiva (IX). Um único banco de dados pode ser bloqueado simultaneamente nos modos IS e IX, mas um bloqueio exclusivo (X) não pode coexistir com nenhum outro modo, e um bloqueio compartilhado (S) só pode coexistir com bloqueios compartilhados por intenção (IS).

As travas são justas e contêm solicitação de trava para leituras e gravações em fila. No entanto, para otimizar a taxa de transferência, quando uma solicitação de trava é concedida, todas as outras compatíveis são concedidas ao mesmo tempo, potencialmente liberando as travas antes que uma solicitação conflitante seja executada. Por exemplo, considere uma situação em que uma trava X acabou de ser liberada e a fila de conflitos contém estas travas:

IS → IS → X → X → S → IS

Na ordem estrita primeiro a entrar, primeiro a sair (FIFO), apenas os dois primeiros modos IS seriam concedidos. Em vez disso, o MongoDB concederá todos os modos IS e S e, quando todos eles forem drenados, ele concederá X, mesmo que novas solicitações IS ou S tenham sido enfileiradas nesse meio tempo. Como uma concessão sempre moverá todas as outras solicitações para a frente na fila, nenhuma solicitação é possível.

Na saída db.serverStatus() e db.currentOp(), os modos de bloqueio são representados da seguinte forma:

Modo de bloqueio
Descrição

R

Representa bloqueio compartilhado (S).

W

Representa bloqueio exclusivo (X).

r

Representa bloqueio de Intent Shared (IS).

w

Representa bloqueio Intent Exclusive (IX).

[1] Consulte a página da Wikipedia sobre Bloqueio de granularidade múltipla para obter mais informações.

Para a maioria das operações de leitura e escrita, o WiredTiger usa controle de concorrência otimista. WiredTiger usa apenas bloqueios de intenção nos níveis de banco de dados e coleção. Quando o mecanismo de armazenamento detecta conflitos entre duas operações, uma incorrerá em um conflito de gravação fazendo com que o MongoDB repita essa operação de forma transparente.

Algumas operações globais, normalmente operações de curta duração envolvendo vários bancos de dados, ainda exigem uma bloqueio global de "instância". Outras operações, como renameCollection, ainda exigem uma bloqueio de banco de dados de dados exclusiva em determinadas circunstâncias.

Para gerar relatórios sobre informações de utilização de bloqueios, use qualquer um destes métodos:

Especificamente, o documento locks na saída de serverStatus ou o campo locks no current operation reporting fornece informações sobre os tipos de trava e a quantidade de contenções de trava em sua instânciamongod.

Na saída db.serverStatus() e db.currentOp(), os modos de bloqueio são representados da seguinte forma:

Modo de bloqueio
Descrição

R

Representa bloqueio compartilhado (S).

W

Representa bloqueio exclusivo (X).

r

Representa bloqueio de Intent Shared (IS).

w

Representa bloqueio Intent Exclusive (IX).

Para encerrar uma operação, utilize db.killOp().

Em algumas situações, operações de leitura e gravação podem gerar suas travas.

Operações de leitura e gravação de longa duração, como queries, atualizações e exclusões, geram bloqueios sob várias condições. As operações do MongoDB também podem gerar bloqueios entre modificações individuais de documentos em operações de gravação que afetam vários documentos.

Para mecanismos de armazenamento que oferecem suporte ao controle de concorrência no nível de documento, como o WiredTiger, a produção não é necessária ao acessar o armazenamento, pois os bloqueios de intenção, mantidos em nível global, de banco de dados e de collection, não bloqueiam outros leitores e gravadores. No entanto, as operações gerarão periodicamente para:

  • evitar transações de armazenamento de longa duração, pois elas podem exigir a retenção de uma grande quantidade de dados na memória;

  • servir como ponto de interrupção para que você possa encerrar operações de longa duração;

  • permitir operações que exigem acesso exclusivo a uma collection, como descartar e criar índices/collections.

A tabela a seguir lista algumas operações e os tipos de bloqueios que elas usam para mecanismos de armazenamento de bloqueio em nível de documento:

(operação)
Database
collection

Emitir uma query

r (Intenção compartilhada)

r (Intenção compartilhada)

Insert data

w (Intenção exclusiva)

w (Intenção exclusiva)

Remover dados

w (Intenção exclusiva)

w (Intenção exclusiva)

Update data

w (Intenção exclusiva)

w (Intenção exclusiva)

Fazer aggregation

r (Intenção compartilhada)

r (Intenção compartilhada)

Crie um índice

W (Exclusiva)

Listar collections

r (Intenção compartilhada)

Mapear-Reduzir

W (Exclusivo) e R (Compartilhado)

w (Intenção exclusiva) e r (Intenção compartilhada)

Observação

A criação de um índice requer uma bloqueio exclusiva (W) em uma collection. No entanto, a bloqueio não é mantida durante toda a duração do processo de construção do índice.

Para obter mais informações, consulte Index Builds on PopulatedCollections.

Alguns comandos administrativos podem bloquear exclusivamente um banco de dados por longos períodos de tempo. Para clusters grandes, considere colocar a instância mongod offline para que os clientes não sejam afetados. Por exemplo, se um mongod fizer parte de um conjunto de réplicas, coloque o mongod offline e deixe que outros nós do conjunto de réplicas processem as solicitações enquanto a manutenção é realizada.

Essas operações administrativas exigem um bloqueio exclusivo no nível do banco de dados por períodos prolongados:

Além disso, o comando renameCollection e o método de shell db.collection.renameCollection() correspondente utilizam as seguintes travas:

Comando
Bloquear comportamento

renameCollection Comando de banco de dados

Ao renomear uma collection dentro do mesmo banco de dados, o comando renameCollection usará uma trava exclusiva (W) nas collections de origem e destino.

Se o namespace de destino estiver em um banco de dados diferente da collection de origem, o comando renameCollection usará um bloqueio exclusivo (W) no banco de dados de destino ao renomear uma collection entre bancos de dados e bloqueará outras operações nesse banco de dados até que ela seja concluída.

renameCollection() método ajudante de shell

O método renameCollection() usa uma bloqueio exclusiva (W) nas collections de origem e destino e não pode mover uma collection entre bancos de dados.

Essas operações administrativas exigem uma trava exclusiva no nível da collection:

Essas operações do MongoDB podem obter e manter um bloqueio em mais de um banco de dados:

(operação)
Comportamento

Essas operações obtêm apenas um bloqueio de coleção exclusivo (W) em vez de um bloqueio exclusivo global.

Esta operação obtém um bloqueio exclusivo (W) no banco de banco de dados de destino, um bloqueio compartilhado (r) de intenção no banco de banco de dados de origem e um bloqueio compartilhado (S) na coleção de origem ao renomear uma coleção entre bancos de dados.

Ao renomear uma collection no mesmo banco de dados, a operação requer apenas bloqueios exclusivos (W) nas collections de origem e destino.

Essa operação obtém apenas um bloqueio exclusivo (W) na coleção oplog em vez de um bloqueio exclusivo global.

A fragmentação melhora a simultaneidade ao distribuir collections em diversas instâncias mongod, permitindo que servidores de shards (especificamente, processos mongos) sejam executados simultaneamente com as instâncias mongod downstream.

Em um cluster fragmentado, os bloqueios se aplicam a cada fragmento individual, não a todo o cluster; ou seja, cada instância mongod é independente das outras no cluster fragmentado e usa seus próprios bloqueios. As operações em uma instância mongod não bloqueiam as operações em nenhuma outra.

Com conjuntos de réplicas, quando o MongoDB grava em uma collection no primary, também grava no oplog do primary, que é uma collection especial no banco de dados local. Portanto, o MongoDB deve bloquear o banco de dados da collection e o banco de dados local. O mongod deve bloquear ambos os bancos de dados ao mesmo tempo para mantê-los consistentes e garantir que as operações de gravação, mesmo com replicação, sejam tudo ou nada.

Ao gravar em um conjunto de réplicas, o escopo da trava se aplica ao primary.

Na replicação, o MongoDB não aplica gravações em série a secundários. Os secundários coletam entradas de oplog em lotes e depois aplicam esses lotes em paralelo. As gravações são aplicadas na ordem em que aparecem no oplog.

Lê que os secundários de destino leem de um snapshot WiredTiger dos dados se o secundário estiver passando por replicação. Isso permite que a leitura ocorra simultaneamente com a replicação, ao mesmo tempo em que garante uma visualização consistente dos dados.

Porque um único documento pode conter dados relacionados que, de outra forma ser modelado em tabelas pai-filho separadas em um esquema relacional, as operações atômicas de documento único do MongoDB já fornecem semântica de transações que atende às necessidades de integridade de dados da maioria dos aplicativos. Um ou mais campos podem ser escritos em uma única operação, incluindo em vários subdocumentos e elementos de uma array. As garantias fornecidas pelo MongoDB garantem o isolamento completo como o documento é atualizado; qualquer erro faz com que a operação seja revertida eque os clientes recebam uma visão consistente do documento.

Para situações que exigem atomicidade de leituras e escritos em vários documentos (em uma única coleção ou várias coleções), o MongoDB suporta transações distribuídas, incluindo transações em conjuntos de réplicas e clusters fragmentados.

Para obter mais informações, consulte transações.

Importante

Na maioria dos casos, uma transação distribuída incorre em um custo de desempenho maior do que as gravações de um único documento, e a disponibilidade de transações distribuídas não deve substituir o design eficaz do esquema. Em muitos cenários, o modelo de dados desnormalizado (documentos e arrays incorporados) continuará a ser ideal para seus dados e casos de uso. Ou seja, para muitos cenários, modelar seus dados adequadamente minimizará a necessidade de transações distribuídas.

Para considerações adicionais sobre o uso de transações (como limite de tempo de execução e limite de tamanho do oplog), consulte também Considerações de produção.

Dependendo da read concern, os clientes podem ver os resultados das gravações antes que elas sejam duráveis. Para controlar se a leitura dos dados pode ser revertida ou não, os clientes podem usar a opção readConcern.

Novidades na versão 5.0.

Uma operação de leitura sem bloqueio é executada imediatamente: ela não é bloqueada quando outra operação tem um bloqueio de gravação exclusivo (X) na collection.

A partir do MongoDB 5.0, as seguintes operações de leitura não são bloqueadas quando outra operação mantém um bloqueio de escrita exclusivo (X) na collection:

Ao escrever em uma collection, mapReduce e aggregate mantêm uma trava exclusiva de intenção (IX). Portanto, se uma trava X exclusiva já estiver mantida em uma collection, as operações de escrita mapReduce e aggregate serão bloqueadas.

Para obter mais informações, consulte:

Voltar

Indexes