Solucionando Erros Comuns de Comandos MongoDB de Forma Eficaz
Solucione erros comuns de comandos MongoDB no mongosh, incluindo problemas de sintaxe, autenticação, conexão, escrita e réplica.
Solucionando Erros Comuns de Comandos MongoDB de Forma Eficaz
Os erros de comando do MongoDB são mais fáceis de corrigir quando você diminui o ritmo e identifica onde a falha está ocorrendo. O mongosh falhou ao analisar o que você digitou? O servidor rejeitou o comando porque o usuário não tem uma função? O cliente se conectou ao banco de dados errado? O primário está indisponível? Esses são problemas diferentes, mesmo que todos apareçam como texto vermelho no shell.
Gosto de começar com três verificações: a qual servidor estou conectado, qual banco de dados estou usando e qual usuário estou autenticado?
db.getName()
db.hello()
db.runCommand({ connectionStatus: 1 })
Esses comandos evitam muita depuração desperdiçada. Muitos "erros de comando MongoDB" são, na verdade, erros de contexto: executar um comando administrativo no banco de dados errado, autenticar contra o authSource errado ou testar contra um secundário quando você pretendia escrever no primário.
Compreendendo as Categorias de Erros de Comando MongoDB
Os erros de comando MongoDB podem ser geralmente categorizados em alguns tipos principais:
- Erros de Sintaxe: Comandos malformados que o shell ou driver do MongoDB não consegue analisar.
- Erros de Permissão: Tentativas de realizar operações sem os privilégios de usuário necessários.
- Erros Operacionais: Problemas que surgem durante a execução de um comando, como problemas de rede, limitações de recursos ou inconsistências de dados.
- Erros de Conexão: Problemas ao estabelecer uma conexão com o servidor MongoDB.
Erros Comuns de Sintaxe e Soluções
Erros de sintaxe são geralmente os mais diretos de corrigir, geralmente decorrentes de erros de digitação, caracteres ausentes ou uso incorreto de parâmetros. O shell do MongoDB (mongosh) geralmente é bom em fornecer mensagens de erro informativas para esses problemas.
1. Nomes de Campos Inválidos ou Estrutura de Documento Inválida
Ao inserir ou atualizar documentos, usar nomes de campos incorretos ou uma estrutura de documento inválida pode levar a erros.
Exemplo de Erro:
db.users.insertOne({ "bad\u0000field": "Alice" })
// MongoServerError: The dotted field 'bad\u0000field' ... is not valid for storage
Explicação: Os nomes de campos do MongoDB não podem conter um caractere nulo. Nomes de campos com hífens, como "email-address", são permitidos, embora possam ser estranhos de consultar porque você precisa colocá-los entre aspas. O problema real é um caractere inválido ou uma estrutura que o MongoDB não pode armazenar.
Solução:
Revise cuidadosamente os nomes de campos gerados por importações, entrada do usuário ou código de serialização. Escolha uma convenção de nomenclatura consistente, como emailAddress ou email_address, e valide os dados antes que eles cheguem ao MongoDB.
> db.users.insertOne({ name: "Alice", age: 30, emailAddress: "[email protected]" })
{ acknowledged: true, insertedId: ObjectId('...') }
2. Vírgulas Ausentes ou Extras
Semelhante ao JavaScript, os comandos do shell do MongoDB são sensíveis ao posicionamento correto de vírgulas dentro de objetos e arrays.
Exemplo de Erro:
db.products.insertOne({ name: "Laptop", price: 1200,, })
// SyntaxError: Unexpected token
Solução:
Remova a vírgula extra. Garanta uma formatação consistente para legibilidade.
> db.products.insertOne({ name: "Laptop", price: 1200 })
{ acknowledged: true, insertedId: ObjectId('...') }
3. Sintaxe de Comando Incorreta (ex.: find vs. findOne)
Usar o comando errado ou fornecer argumentos na ordem incorreta também pode resultar em erros.
Exemplo:
db.inventory.find({ item: "notebook" }, { qty: 1, size: 1, _id: 0 })
// Este comando é sintaticamente correto para find, mas se você pretendia encontrar apenas um documento:
Solução:
Se você pretende recuperar apenas um único documento, use findOne. find retorna um cursor, enquanto findOne retorna o próprio documento.
> db.inventory.findOne({ item: "notebook" }, { qty: 1, size: 1, _id: 0 })
{
qty: 20,
size: { h: 14, w: 21, uom: "cm" },
... // outros campos se a projeção não os excluiu e eles não são projetados especificamente
}
Erros Comuns de Permissão
Erros de permissão geralmente ocorrem quando um usuário tenta realizar uma operação para a qual não possui as funções ou privilégios necessários.
1. Privilégios Insuficientes para Executar Comando
Esta mensagem de erro é explícita sobre a falta de permissões.
Exemplo de Erro:
> db.adminCommand({ listDatabases: 1 })
Error: listDatabases requires authentication
Explicação: listDatabases é um comando administrativo que requer autenticação e os privilégios corretos. Um usuário pode ser válido para um banco de dados de aplicação, mas ainda assim incapaz de inspecionar toda a implantação.
Solução:
- Autentique com credenciais apropriadas: Conecte-se ao MongoDB usando um usuário que tenha as funções necessárias. Para
listDatabases, você pode precisar se conectar como administrador.
Em seguida, tente o comando novamente:mongosh "mongodb://<adminUser>:<adminPassword>@<host>:<port>/admin?authSource=admin"db.adminCommand({ listDatabases: 1 }) - Conceda Funções: Se você é um administrador de banco de dados, conceda as funções necessárias ao usuário que está enfrentando o problema.
// Exemplo: Concedendo a função readAnyDatabase ao usuário 'myUser' no banco de dados 'admin' use admin db.grantRolesToUser("myUser", [ { role: "readAnyDatabase", db: "admin" } ])
2. Operação de Escrita Negada
Tentativa de inserir, atualizar ou excluir documentos em uma coleção ou banco de dados sem permissões de escrita.
Exemplo de Erro:
> db.myCollection.insertOne({ name: "Test" })
WriteError: Not enough privileges to execute on "myCollection" with operation "insert"
Solução:
- Autentique como um usuário com privilégios de escrita para o banco de dados/coleção de destino.
- Conceda funções de escrita (ex.:
readWrite,dbOwner) ao usuário. - Verifique o banco de dados no prompt. Um usuário com
readWriteconcedido emappdbnão tem automaticamente acesso de escrita emtest, mesmo que o nome da coleção seja o mesmo.
Autenticação e Erros de authSource
Erros de autenticação geralmente parecem confusos porque os usuários do MongoDB pertencem a um banco de dados de autenticação específico. Muitos usuários de aplicação são criados no banco de dados da aplicação. Usuários administradores são frequentemente criados em admin.
Se você vir:
MongoServerError: Authentication failed.
verifique a string de conexão antes de alterar senhas:
mongosh "mongodb://appUser:secret@db01:27017/appdb?authSource=appdb"
Se o usuário foi criado em admin, use:
mongosh "mongodb://adminUser:secret@db01:27017/appdb?authSource=admin"
O caminho do banco de dados após o host (/appdb) é o banco de dados padrão que seu shell abre. authSource é onde o MongoDB procura pela conta de usuário. Misturar esses é uma causa comum de falhas de login após migrar de um banco de dados de desenvolvimento local para um servidor seguro.
Você pode confirmar os usuários autenticados atuais com:
db.runCommand({ connectionStatus: 1 })
Erros Operacionais Comuns e Soluções
Erros operacionais podem ser mais complexos, muitas vezes relacionados ao estado da implantação do MongoDB, problemas de rede ou restrições de recursos.
1. Tempo Limite de Rede ou Conexão Recusada
Esses erros indicam que o cliente não conseguiu estabelecer ou manter uma conexão com o servidor MongoDB.
Exemplo de Erro (Lado do Cliente):
Error: connect ECONNREFUSED 127.0.0.1:27017
Explicação: O cliente tentou se conectar ao host e porta especificados, mas a conexão foi recusada. Isso pode significar que o servidor MongoDB não está em execução, está em execução em uma porta diferente ou um firewall está bloqueando a conexão.
Solução:
- Verifique o status do servidor MongoDB: Certifique-se de que o processo
mongodestá em execução no servidor.- No Linux:
sudo systemctl status mongodousudo service mongod status - No macOS (usando Homebrew):
brew services list - No Windows: Verifique o aplicativo Serviços.
- No Linux:
- Verifique a configuração do MongoDB: Confirme que o
mongodestá configurado para ouvir no endereço IP e porta corretos (padrão é27017). Verifique o arquivomongod.conf. - Regras de firewall: Certifique-se de que nenhum firewall (nível de servidor ou rede) esteja bloqueando o tráfego na porta do MongoDB.
- String de conexão correta: Verifique novamente sua string de conexão em busca de erros de digitação no host e na porta.
Para conjuntos de réplicas, inclua o nome do conjunto de réplicas quando seu driver esperar por ele:
mongosh "mongodb://db01:27017,db02:27017,db03:27017/appdb?replicaSet=rs0"
Se o DNS estiver envolvido, teste o nome de host exato da máquina cliente:
nc -vz db01.example.com 27017
Uma conexão bem-sucedida do próprio servidor de banco de dados não prova que servidores de aplicação, executores de CI ou hosts bastiões podem alcançá-lo.
2. Limite de Tamanho de Documento Excedido
Os documentos do MongoDB têm um limite máximo de tamanho BSON (atualmente 16MB).
Exemplo de Erro:
> db.largeDocs.insertOne({ data: "... string muito grande ..." })
Error: BSONObj size: 17000000 bytes is too large, max 16777216 bytes
Solução:
- Divida documentos grandes: Divida o documento grande em documentos menores e relacionados. Use referências (ex.:
ObjectId) para vinculá-los. - Use GridFS: Para armazenar arquivos binários grandes (como imagens ou vídeos) que excedem o limite de tamanho do documento, use a especificação GridFS do MongoDB.
- Evite arrays ilimitados: Um documento que cresce para sempre, como um documento de usuário com cada evento incorporado para sempre, eventualmente se tornará lento ou atingirá limites. Armazene registros filhos de alto volume em sua própria coleção.
3. Erros de Preocupação de Escrita (Write Concern)
As preocupações de escrita especificam as garantias de confirmação exigidas do MongoDB para operações de escrita. Se essas garantias não forem atendidas dentro de um tempo limite, ocorre um erro de preocupação de escrita.
Exemplo:
// Exemplo de uma operação de escrita com uma preocupação de escrita específica
db.myCollection.insertOne({ name: "Item" }, { writeConcern: { w: "majority", wtimeout: 1000 } });
Erro Potencial:
WriteConcernError: waiting for replication timed out
Explicação: A operação de escrita falhou porque o número necessário de nós (neste caso, majority) não confirmou a escrita dentro do wtimeout especificado (1000ms).
Solução:
- Investigue a saúde do conjunto de réplicas: Verifique a saúde e o status do seu conjunto de réplicas MongoDB. Os nós estão atrasados? Existem problemas de rede entre os nós?
- Aumente
wtimeout: Se a latência de rede temporária ou atrasos de replicação forem a causa, você pode considerar aumentar o valor dewtimeout, mas isso deve ser feito com cautela, pois pode mascarar problemas subjacentes. - Revise a preocupação de escrita: Certifique-se de que o nível de preocupação de escrita (
w) seja apropriado para as necessidades da sua aplicação.w: 1(o padrão) requer confirmação apenas do primário, o que é menos propenso a problemas de tempo limite, mas oferece menos garantia de durabilidade.
4. Erros de "Não é Primário" ou Preferência de Leitura
As escritas devem ir para o primário em um conjunto de réplicas. Se seu shell ou aplicação estiver conectado a um secundário e você tentar escrever, poderá ver um erro semelhante a:
MongoServerError: not primary
Verifique onde você está conectado:
db.hello()
Se isWritablePrimary for falso, conecte-se através de uma URI de conjunto de réplicas adequada ou direcione as escritas para o primário. Para leituras, decida se leituras secundárias são aceitáveis para sua aplicação. Leituras secundárias podem estar desatualizadas, portanto, não as habilite apenas para silenciar um erro, a menos que leituras desatualizadas sejam seguras para esse caso de uso.
5. Erros de Chave Duplicada
Erros de chave duplicada geralmente significam que um índice único está fazendo seu trabalho.
E11000 duplicate key error collection: app.users index: email_1 dup key
Não "corrija" isso descartando o índice único, a menos que a regra de exclusividade esteja realmente errada. Primeiro, identifique o índice:
db.users.getIndexes()
Em seguida, decida se a aplicação deve atualizar o documento existente, rejeitar a duplicata ou usar um upsert:
db.users.updateOne(
{ email: "[email protected]" },
{ $set: { lastLoginAt: new Date() } },
{ upsert: true }
)
Com upserts, certifique-se de que o filtro corresponda à chave única com a qual você se importa. Um filtro solto ainda pode criar duplicatas em um campo único diferente e falhar.
6. Erros de Operadores de Consulta
Alguns erros vêm do uso de operadores de atualização ou consulta no lugar errado.
Isso está errado para atualizações do tipo substituição:
db.users.updateOne(
{ email: "[email protected]" },
{ lastLoginAt: new Date() }
)
O MongoDB trata esse segundo documento como um documento de substituição. Se você pretendia alterar um campo, use $set:
db.users.updateOne(
{ email: "[email protected]" },
{ $set: { lastLoginAt: new Date() } }
)
Essa distinção é importante porque as atualizações de substituição podem remover campos que não estão incluídos no documento de substituição.
Uma Rotina Prática de Depuração
Quando um comando falha, capture o erro exato e então responda a estas perguntas em ordem:
O
mongoshestá conectado ao host esperado?db.hello().meEstou usando o banco de dados esperado?
db.getName()Estou autenticado e com quais funções?
db.runCommand({ connectionStatus: 1 })Isso é um erro de análise, um erro de servidor ou um erro de preocupação de escrita?
Erros de análise geralmente aparecem antes do comando chegar ao servidor. Erros de permissão, chave duplicada, não primário, validação e preocupação de escrita vêm do MongoDB após ele avaliar o comando.
O mesmo comando funciona com um documento mínimo?
Se uma inserção pequena funciona, mas a inserção real falha, inspecione a forma do documento, tamanho, nomes de campos, validação de esquema e índices únicos.
A falha depende do nó?
Problemas de conjunto de réplicas e cluster fragmentado podem aparecer apenas em certos nós ou através de certos roteadores. Para clusters fragmentados, o tráfego da aplicação deve normalmente passar pelo
mongos, não diretamente para os membros do fragmento.
Lendo os Logs Sem Adivinhar
Os logs do MongoDB geralmente explicam o motivo do lado do servidor mais claramente do que a saída do shell. Em instalações Linux de pacote, verifique os logs do serviço:
journalctl -u mongod --since "30 minutes ago"
ou o caminho do log do MongoDB configurado em mongod.conf.
Procure por mensagens em torno do mesmo timestamp do comando que falhou. Pistas úteis incluem falhas de autenticação, redefinições de conexão, operações lentas, mudanças de estado de replicação, erros de disco cheio e falhas de validação de esquema.
Para consultas lentas ou com falha, explain() é mais útil do que adivinhar:
db.orders.find({ customerId: 123, status: "open" }).explain("executionStats")
Se a consulta escaneia um grande número de documentos para retornar alguns resultados, o comando pode estar sintaticamente correto, mas operacionalmente caro. Isso não é um problema do shell; é um problema de indexação ou forma de consulta.
Melhores Práticas para Prevenir Erros de Comando
- Use
mongoshe seus recursos: Aproveite o preenchimento com tab, histórico de comandos e mensagens de erro claras fornecidas pelo Shell MongoDB moderno. - Entenda seu modelo de dados: Projete seu esquema e estruturas de documento cuidadosamente para evitar problemas como documentos superdimensionados ou consultas ineficientes.
- Implemente autenticação e autorização adequadas: Defina usuários com o menor privilégio necessário para suas funções.
- Monitore sua implantação: Verifique regularmente os logs do MongoDB, métricas de desempenho e status do conjunto de réplicas para identificar proativamente problemas potenciais.
- Teste comandos: Antes de implantar comandos ou alterações complexas em produção, teste-os completamente em um ambiente de desenvolvimento ou homologação.
- Mantenha o MongoDB atualizado em um cronograma planejado: Versões mais recentes podem incluir correções de bugs e mudanças de comportamento. Leia as notas de versão e teste as atualizações antes da implantação em produção.
A maioria dos erros de comando do MongoDB se torna gerenciável quando você separa problemas de sintaxe do shell, contexto de autenticação, autorização, topologia e forma dos dados. Comece provando onde você está conectado e quem você é. Em seguida, deixe a mensagem de erro exata apontá-lo para a próxima camada, em vez de reescrever o comando aleatoriamente.