Amazon DocumentDB
Do básico ao avançado, nas versões 5.0 a 8.0: arquitetura, compatibilidade, modelagem e índices, alta disponibilidade, backup,
segurança, monitoramento e análise de performance (console da AWS e scripts) e um guia de troubleshooting por sintoma. Cada tópico traz explicação,
exemplos de mongosh e AWS CLI e links para a documentação oficial da AWS.
mongosh rodam por instância; para investigar um nó específico conecte no instance endpoint dele.db.runCommand({getEngineVersion:1}): 1.x = 3.6, 2.x = 4.0, 3.x = 5.0, 4.x = 8.0.Fundamentos
O que é o DocumentDB, como ele é montado e como conectar
O Amazon DocumentDB (with MongoDB compatibility) é um banco de dados de documentos totalmente gerenciado pela AWS. Você usa os mesmos drivers, ferramentas e (em grande parte) o mesmo código que usaria com o MongoDB, mas a AWS cuida de provisionamento, patches, backup, replicação e recuperação de falhas.
explain() diferentes, write concern sempre durável). Antes de migrar, valide o seu código com a lista de APIs suportadas.O DocumentDB tem quatro versões principais em circulação. A versão indica o nível de compatibilidade com a API do MongoDB e o conjunto de recursos do motor.
| Versão | Engine (getEngineVersion) | Compatível com | Lançamento | Situação |
|---|---|---|---|---|
| 3.6 | 1.x.x | MongoDB 3.6 | 09/01/2019 | Fim do suporte padrão em 30/03/2026; Extended Support até 30/03/2029 (pago) |
| 4.0 | 2.x.x | MongoDB 4.0 | 09/11/2020 | Suporte padrão |
| 5.0 | 3.x.x | MongoDB 5.0 | 01/03/2023 | Suporte padrão; minors 5.0.0 (LTS) e 5.0.1 |
| 8.0 | 4.x.x | MongoDB 8.0 (aceita também apps em APIs 6.0 e 7.0) | 14/11/2025 | Versão mais recente |
A partir da 5.0 o versionamento tem quatro níveis (major.major.minor.patch): a versão major define a compatibilidade, a minor traz recursos e correções e é atualizada manualmente, e o patch traz correções críticas aplicadas na janela de manutenção.
db.runCommand({ getEngineVersion: 1 })
// { engineVersion: "4.x.x", ok: 1 } // 4.x.x = DocumentDB 8.0
5.0.0. Para criar um cluster 8.0 é preciso informar --engine-version 8.0.0 explicitamente. Em produção, sempre fixe a versão.Um cluster DocumentDB tem de 0 a 16 instâncias e um único volume de armazenamento. Uma instância é a primária (aceita leitura e escrita) e as demais são réplicas (somente leitura, até 15).
- Alta disponibilidade: falha do primário promove uma réplica (tipicamente em cerca de 30 segundos).
- Cache sobrevive a reinícios: o cache de páginas roda em processo separado do banco.
- Sem crash recovery longo: não há replay de redo log; o reinício é rápido.
- Escala de leitura: adicionar uma réplica leva minutos, independentemente do tamanho dos dados.
BufferCacheHitRatio).| Endpoint | Para que serve | Exemplo |
|---|---|---|
| Cluster endpoint | Sempre aponta para a instância primária atual; segue o failover. Use em modo replica set. | meu-cluster.cluster-xxxx.us-east-1.docdb.amazonaws.com:27017 |
| Reader endpoint | Balanceia conexões (não requisições) entre as réplicas. | meu-cluster.cluster-ro-xxxx.us-east-1.docdb.amazonaws.com:27017 |
| Instance endpoint | Uma instância específica. Evite em produção; útil para análises pontuais em uma réplica dedicada. | minha-instancia.xxxx.us-east-1.docdb.amazonaws.com:27017 |
rs0 (não pode ser alterado). Conectar no cluster endpoint com replicaSet=rs0 habilita read preference, read concern e write concern, e faz o driver acompanhar instâncias adicionadas ou removidas. Para espalhar leituras entre réplicas, use readPreference=secondaryPreferred em vez de depender do reader endpoint.mongodb://USUARIO:SENHA@meu-cluster.cluster-xxxx.us-east-1.docdb.amazonaws.com:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
directConnection=true falham. Os exemplos oficiais de conexão usam retryWrites=false; mantenha esse parâmetro se o seu driver ligar retryable writes por padrão.| Tipo | Quando usar | Pontos de atenção |
|---|---|---|
| Instance-based (regional) | Padrão. Um primário, até 15 réplicas, volume até 128/256 TiB. | Você escolhe classe e quantidade de instâncias. |
| Elastic cluster | Escrita e leitura em escala de milhões de operações por segundo e petabytes, com sharding gerenciado. | Protocolo compatível com MongoDB 5.0; não disponível na 8.0; sem vários recursos (veja a seção de elastic clusters). |
| Global cluster | Um primário em uma região e até 10 regiões secundárias somente leitura (DR e leitura local). | Não suportado na 3.6; sem db.t3, db.t4g e db.r4. |
| Serverless (DCU) | Cargas variáveis ou imprevisíveis; capacidade ajusta em frações de 0,5 DCU. | Defina capacidade mínima e máxima; veja a seção de serverless. |
A classe define CPU e memória e, junto com ela, limites rígidos de conexões, cursors e transações abertas. Valores para as versões 5.0 e 8.0 (as classes R5, R6G e R8G compartilham os mesmos limites por tamanho):
| Tamanho | Memória (GiB) | Conexões (todas) | Cursors | Transações abertas | Conexões ativas |
|---|---|---|---|---|---|
| T3.medium / T4G.medium | 4 | 1.000 | 30 | 50 | 102 |
| large | 16 | 3.400 | 450 | 200 | 1.100 |
| xlarge | 32 | 7.000 | 450 | 400 | 2.700 |
| 2xlarge | 64 | 14.200 | 450 | 800 | 4.500 |
| 4xlarge | 128 | 28.400 | 760 | 1.600 | 4.500 |
| 8xlarge | 256 | 60.000 | 1.520 | 3.200 | 4.500 |
| 12xlarge | 384 | 60.000 | 2.280 | 4.800 | 4.500 |
| 16xlarge | 512 | 60.000 | 3.040 | 6.400 | 4.500 |
| R8G 24xlarge / 48xlarge | 768 / 1.536 | 60.000 | 4.560 / 9.120 | 9.600 | 4.500 |
Famílias disponíveis: R8G (Graviton4), R6G e R6GD (com NVMe), R5, R4 (somente 3.6), além das burstable T4G e T3 e da classe serverless. A disponibilidade varia por região.
O DocumentDB roda somente dentro de uma VPC: não existe endpoint público. A criptografia em trânsito (TLS) é habilitada por padrão em clusters novos.
# 1. Baixar o bundle de certificados da AWS wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem # 2. Conectar (a partir de uma EC2/Cloud9/Lambda na mesma VPC) mongosh "mongodb://USUARIO@meu-cluster.cluster-xxxx.us-east-1.docdb.amazonaws.com:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false"
localhost, o que exige relaxar a validação de hostname apenas nesse cenário.Versões 5.0 a 8.0
Novidades, diferenças entre versões e como atualizar
- Compatibilidade com drivers MongoDB 5.0 e limite de armazenamento de 128 TiB.
- Client-side Field Level Encryption (FLE): campos são cifrados no cliente antes de chegar ao cluster.
- Autenticação por identidade IAM (usuários e roles IAM, sem senha), disponível em clusters instance-based 5.0.
- Vector search (HNSW e IVFFlat) para IA generativa e busca semântica.
- Configuração de armazenamento I/O-optimized (cobrança sem I/O por requisição).
- Índices com
$elemMatchno primeiro nível de aninhamento passam a usar index scan; novos operadores$dateAdde$dateSubtract. - Versões minor: a 5.0.1 adicionou
$rand,$pow,$dateToParts,$dateFromParts, a métrica de conexões ativas e as métricas por comando no CloudWatch (AvgDuration,P100Duration,MaxConcurrent). - Change streams em instâncias secundárias (inclusive em global clusters).
hello substitui isMaster; SecondaryDelaySecs substitui slaveDelay; a projeção $ passa a retornar só o campo casado; $regex junto com $options na query retorna erro; $indexOfCP retorna -1 quando não encontra. Teste a aplicação antes do upgrade.- Compatibilidade com drivers MongoDB 8.0 (apps em APIs 6.0 e 7.0 continuam suportadas).
- Query planner v3: estende as otimizações a estágios de aggregation e a
distinct, com otimizações de pipeline (subir$match, unir$lookupe$unwind, distinct scans em índices de baixa cardinalidade). A AWS cita ganhos de até 7x em latência de consultas. - Collation e views (requerem o planner v3).
- Novos estágios:
$replaceWith,$vectorSearch,$merge,$set,$unset,$bucket; e operadores$pow,$rand,$dateTrunc. - Compressão de documentos por dicionário (Zstandard): ligada por padrão em coleções novas; opções
zstd,lz4ounone. - Text index v2 e build paralelo de índices vetoriais (até 30x mais rápido).
- Armazenamento até 256 TiB.
- TLS 1.2 ou superior obrigatório. TLS 1.0 e 1.1 deixam de ser aceitos.
- Change streams com eventos expandidos (
createCollectionecreateIndexesviashowExpandedEvents) e$changeStreamSplitLargeEvent, a partir da engine 8.0.2.
| Aspecto | 5.0 | 8.0 |
|---|---|---|
| Query planner padrão | Planner v1 | Planner v3 |
| Compressão | Configurável por coleção | Ligada por padrão (Zstd); "enabled" deixa de ser valor válido |
| Collation / views | Não | Sim (planner v3) |
| TLS | TLS 1.0 a 1.3 (1.2+ a partir da 5.0.1) | Somente 1.2 ou superior |
| Limite de armazenamento | 128 TiB | 256 TiB |
| Elastic clusters | Suportado | Não suportado |
| Recurso | 3.6 | 4.0 | 5.0 | 8.0 |
|---|---|---|---|---|
| Transações ACID | Não | Sim | Sim | Sim |
| Change streams em collection | Sim | Sim | Sim | Sim |
| Change streams em database/cluster e startAtOperationTime | Não | Sim | Sim | Sim |
| Retenção de change streams | 24 h | até 7 dias | até 7 dias | até 7 dias |
| Change streams em réplicas | Não | Não | Sim | Sim |
| Client-side FLE | Não | Não | Sim | Sim |
| Autenticação IAM | Não | Não | Sim | Ver doc |
| Vector search | Não | Não | Sim | Sim (inclui $vectorSearch) |
| I/O-optimized | Não | Não | Sim | Sim |
| Versões minor | Não | Não | Sim | Sim |
| Global clusters | Não | Sim | Sim | Sim |
| Performance Insights | Sim | Sim | Sim | Sim |
| Collation, views e planner v3 | Não | Não | Não | Sim |
| Armazenamento máximo | 128 TiB | 128 TiB | 128 TiB | 256 TiB |
| Classes R4 | Sim | Não | Não | Não |
| Versão | Lançamento | Fim do suporte padrão | Extended Support (ano 1) | Extended Support (ano 3) | Fim do Extended Support |
|---|---|---|---|---|---|
| 3.6 | 09/01/2019 | 30/03/2026 | 31/03/2026 | 31/03/2028 | 30/03/2029 |
| 4.0 | 09/11/2020 | N/A | N/A | N/A | N/A |
| 5.0 | 01/03/2023 | N/A | N/A | N/A | N/A |
| 8.0 | 14/11/2025 | N/A | N/A | N/A | N/A |
Depois do fim do suporte padrão você pode continuar na versão pagando uma taxa de Extended Support (o preço aumenta ao longo dos anos). Versões minor podem chegar ao fim do suporte padrão antes da major correspondente; a 5.0.0 é uma release LTS.
O MVU (major version upgrade) in-place mantém endpoints, armazenamento e tags e não tem custo adicional. O cluster fica indisponível durante o processo e reinicia várias vezes; não há downgrade (só restaurando o snapshot pré-upgrade).
| Origem | Destinos suportados |
|---|---|
| 3.6 | Qualquer minor publicada de 5.0 ou 8.0 |
| 4.0 | Qualquer minor publicada de 5.0 ou 8.0 |
| 5.0.0 / 5.0.1 | 8.0.0, 8.0.1, 8.0.2 |
| 5.0.2 | 8.0.2 |
Checklist antes de começar
- Crie um snapshot manual (o upgrade também cria um automático
preupgrade-...). - Teste em um clone do cluster para medir tempo e achar incompatibilidades.
- Troque instâncias
db.r4.*por R5 ou mais novas; escale instâncias burstable (T3/T4G) para pelo menosdb.r5.large/db.r6g.large. - Aplique manutenções de SO pendentes e tenha um parameter group da versão de destino.
- De 5.0 para 8.0: revise índices parciais com
$typeempartialFilterExpression(tipos binData, bool, date, double, decimal, array ou código numérico) - eles fazem o upgrade falhar; remova e recrie depois. - Nomes de coleção com 58 ou mais caracteres e contagem de índices acima do limite da instância bloqueiam o pré-check.
aws docdb modify-db-cluster \ --db-cluster-identifier meu-cluster \ --allow-major-version-upgrade \ --engine-version 8.0.0 \ --db-cluster-parameter-group-name meu-param-group-8-0 \ --apply-immediately \ --region us-east-1 # Acompanhar o progresso aws docdb describe-events --source-identifier meu-cluster --source-type db-cluster --duration 120
Depois do upgrade
- Aguarde o evento "Index metadata refresh process completed" (pode levar de minutos a duas horas). Não faça reboot, failover nem scale da instância nesse intervalo.
- Tire um snapshot manual do cluster já atualizado.
- De 3.6 ou 4.0: reconstrua índices com
reIndexpara ganhar a manutenção melhorada da 5.0+. - Atualize drivers para aproveitar novos recursos (collation, views e Zstd na 8.0).
- Global clusters e elastic clusters não suportam MVU in-place; para global clusters remova as secundárias, atualize e recrie.
Modelagem, Índices e Recursos de Dados
Como estruturar documentos, indexar e usar os recursos do motor
Em um banco de documentos você agrupa no mesmo documento o que é lido junto (embedding) e usa referências para relações grandes, muito compartilhadas ou que crescem sem limite.
| Limite | Valor |
|---|---|
| Tamanho do documento | 16 MiB |
| Profundidade de aninhamento | 200 níveis (instance-based) |
| Tamanho da chave de índice | 2.048 bytes |
| Índices por coleção | 64 |
| Chaves em um índice composto | 32 |
| Coleções / bancos por cluster | 100.000 / 100.000 |
| Tamanho de coleção (sem índices) | 32 TiB |
| Nome da coleção | 1 a 255 caracteres (5.0+); 1 a 57 (4.0 e anteriores) |
| Escritas em um único batch | 100.000 |
_ids previsíveis quando precisar de acesso direto. Escritas são atômicas por documento.pedidoId e data.Tipos suportados: único campo, composto, multikey (arrays), TTL, sparse, parcial, unique, text, 2dsphere e vector. Índices são a principal alavanca de desempenho (e de custo de I/O).
// Índice composto criado em background (não bloqueia escritas)
db.pedidos.createIndex({ clienteId: 1, criadoEm: -1 }, { background: true })
// Listar e remover
db.pedidos.getIndexes()
db.pedidos.dropIndex("clienteId_1_criadoEm_-1")
// Reconstruir sem downtime (recupera espaço e melhora índices vindos de 3.6/4.0)
db.pedidos.reIndex()
background: true, o índice toma um lock exclusivo de escrita na coleção até terminar. Em produção, sempre crie em background e acompanhe o progresso.Regras de ouro
- Seletividade: indexe campos em que cada valor aparece em no máximo ~1% dos documentos. Índices de baixa cardinalidade (booleanos, dia da semana) raramente são escolhidos pelo planner e só custam espaço e I/O.
- Quantidade: cada índice adiciona uma escrita por insert/update/delete. Como diretriz, mantenha cinco ou menos por coleção.
- Crie os índices antes de importar grandes volumes (a ferramenta index-tool do repositório amazon-documentdb-tools extrai e recria índices).
- Revise periodicamente índices não usados (
$indexStats) e consultas sem índice (profiler).
Um índice TTL remove documentos automaticamente após um intervalo. A remoção é feita por um processo em background (ttl_monitor) e é best effort: não há garantia de quando o documento será apagado.
// Expira sessões 24h depois de criadoEm
db.sessoes.createIndex({ criadoEm: 1 }, { expireAfterSeconds: 86400 })
drop() da mais antiga. Dropar uma coleção não gera I/O e é mais rápido que o TTL, principalmente acima de 1 TB.O DocumentDB suporta os principais estágios e operadores de aggregation; a lista cresce a cada versão (veja as listas de novidades da 4.0, 5.0 e 8.0). O limite é de 500 estágios por pipeline.
db.pedidos.aggregate([
{ $match: { status: "PAGO", criadoEm: { $gte: ISODate("2026-01-01") } } }, // primeiro: reduz o volume
{ $group: { _id: "$clienteId", total: { $sum: "$valor" } } },
{ $sort: { total: -1 } },
{ $limit: 10 }
])
- Coloque
$match(e$limitquando possível) no início do pipeline para que as etapas seguintes processem menos documentos. - Na 4.0+,
$lookupconsegue usar índice; garanta índice no campo de junção da coleção "from". - Na 8.0, o planner v3 otimiza pipelines (pull-up de
$match, coalescência de$lookup/$unwind); valide comexplaindepois do upgrade. - Antes de migrar, rode a compat-tool do amazon-documentdb-tools para achar operadores não suportados.
A partir da 4.0 é possível executar transações ACID envolvendo vários documentos, instruções, coleções e bancos. O número de transações abertas é limitado por instância (por exemplo, 200 em uma large e 400 em uma xlarge).
const s = db.getMongo().startSession();
s.startTransaction();
try {
const dbs = s.getDatabase("loja");
dbs.contas.updateOne({ _id: 1 }, { $inc: { saldo: -100 } });
dbs.contas.updateOne({ _id: 2 }, { $inc: { saldo: 100 } });
s.commitTransaction();
} catch (e) {
s.abortTransaction();
throw e;
} finally {
s.endSession();
}
TransactionsOpen contra TransactionsOpenLimit e use batch (insertMany/updateMany) quando atomicidade entre documentos não for necessária.Change streams entregam a sequência ordenada de eventos de uma coleção, banco ou cluster. São desabilitados por padrão e precisam ser habilitados por coleção (ou banco, ou cluster).
// Habilitar para uma coleção
db.adminCommand({ modifyChangeStreams: 1, database: "loja", collection: "pedidos", enable: true })
// Habilitar para todas as coleções de um banco
db.adminCommand({ modifyChangeStreams: 1, database: "loja", collection: "", enable: true })
// Consumir
const cur = db.getSiblingDB("loja").pedidos.watch([], { fullDocument: "updateLookup" })
while (cur.hasNext()) printjson(cur.next())
- Retenção: 3 horas por padrão, ajustável de 1 hora a 7 dias com o parâmetro
change_stream_log_retention_duration. - Réplicas: na 5.0+ é possível ler change streams de instâncias secundárias (use read preference
secondary). - Eventos grandes: eventos acima de 16 MB falham na leitura; na 8.0.2+ use
$changeStreamSplitLargeEvent. - Custo: o recurso gera I/O de leitura e escrita e armazenamento (
ChangeStreamLogSize). Desligue se não usa. - Para retomar, guarde o
resumeTokenou opostBatchResumeToken.
Text index oferece busca de texto completa dentro do próprio cluster; na 8.0 existe o text index v2, com mais tokens. Vector search (5.0+) permite armazenar embeddings e buscar por similaridade para RAG, recomendação e busca semântica.
// Índice vetorial HNSW (até 2.000 dimensões indexadas)
db.produtos.createIndex(
{ embedding: "vector" },
{ name: "idx_embedding", vectorOptions: { type: "hnsw", dimensions: 1536, similarity: "cosine", m: 16, efConstruction: 64 } }
)
// Consulta clássica (5.0+)
db.produtos.aggregate([{ $search: { vectorSearch: { vector: consulta, path: "embedding", similarity: "cosine", k: 5, efSearch: 40 } } }])
// Operador $vectorSearch (8.0+)
db.produtos.aggregate([{ $vectorSearch: { index: "idx_embedding", path: "embedding", queryVector: consulta, limit: 5, numCandidates: 40, exact: false } }])
- HNSW é o indicado para a maioria dos casos (sem etapa de treinamento, melhor recall); IVFFlat usa
listseprobes. - Sem índice o DocumentDB faz busca exata (recall perfeito, mas lenta). Até 16.000 dimensões podem ser armazenadas sem índice.
- Ajuste
efSearch(HNSW) ouprobes(IVFFlat): valores maiores melhoram o recall e custam latência. - Índices vetoriais não combinam com compound, sparse ou partial.
Operação e Alta Disponibilidade
Failover, backup, parâmetros, custo e topologias avançadas
Com pelo menos uma réplica, o DocumentDB detecta a falha, promove a réplica e atualiza o CNAME do cluster endpoint. O failover costuma levar cerca de 30 segundos. Sem réplica, ele tenta recriar a instância na mesma AZ (best effort).
- Tiers de promoção (0 a 15): a réplica de menor número é promovida; empate resolve pela instância mais próxima em tamanho do primário anterior.
- Use réplicas da mesma classe do primário e em AZs diferentes.
- Para produção: três ou mais instâncias em três AZs (duas instâncias em duas AZs é o mínimo exigido pelo SLA).
- A aplicação deve reconectar com retentativa e backoff e usar o cluster endpoint em modo replica set.
# Testar failover (promove a réplica indicada) aws docdb failover-db-cluster \ --db-cluster-identifier meu-cluster \ --target-db-instance-identifier minha-replica-1 # Definir a prioridade de promoção de uma instância aws docdb modify-db-instance --db-instance-identifier minha-replica-1 --promotion-tier 0 --apply-immediately
- Escritas: só no primário e sempre duráveis (seis cópias antes do ack). O write concern é efetivamente
w:3, j:truee não pode ser reduzido;wtimeouté ignorado. - Leituras no primário: fortemente consistentes em operação normal (read-after-write).
- Leituras em réplicas: eventualmente consistentes, normalmente com lag inferior a 100 ms, na ordem em que foram escritas.
- Isolamento: leituras só retornam dados duráveis; não há dirty read.
| Read preference | Comportamento | Quando usar |
|---|---|---|
| primary | Tudo no primário; falha se ele estiver indisponível | Prioridade em read-after-write |
| primaryPreferred | Primário; réplica em failover | Consistência com alguma tolerância a falhas |
| secondary | Somente réplicas | Relatórios e análises que não devem tocar o primário |
| secondaryPreferred | Réplicas; primário se não houver réplica | Escalar leituras mantendo disponibilidade (recomendado como padrão) |
| nearest | Menor latência medida | Latência mínima, ciente de consistência eventual |
Parâmetros vivem em cluster parameter groups. O grupo default.docdbX.Y não pode ser modificado: crie um customizado e associe ao cluster.
| Parâmetro | Efeito | Valores |
|---|---|---|
| tls | Criptografia em trânsito | enabled, disabled, fips-140-3, tls1.2+, tls1.3+ (estático: exige reboot) |
| audit_logs | Auditoria de eventos | none, ddl, dml_read, dml_write, all (ou combinações) |
| profiler | Profiler de consultas lentas | enabled, disabled |
| profiler_threshold_ms | Limite para logar uma operação | 50 a INT_MAX (padrão 100) |
| profiler_sampling_rate | Fração das operações lentas registradas | 0.0 a 1.0 (padrão 1.0) |
| change_stream_log_retention_duration | Retenção dos change streams | 3.600 a 604.800 s (1 h a 7 dias) |
| ttl_monitor | Liga/desliga a remoção por TTL | enabled, disabled |
aws docdb create-db-cluster-parameter-group --db-cluster-parameter-group-name meu-param-group-8-0 \ --db-parameter-group-family docdb8.0 --description "Parametros do cluster 8.0" aws docdb modify-db-cluster-parameter-group --db-cluster-parameter-group-name meu-param-group-8-0 \ --parameters ParameterName=audit_logs,ParameterValue=ddl,ApplyMethod=immediate aws docdb describe-db-cluster-parameters --db-cluster-parameter-group-name meu-param-group-8-0 \ --query "Parameters[*].[ParameterName,ParameterValue,ApplyType]" --output table
| Standard | I/O-optimized | |
|---|---|---|
| Cobrança de I/O | Por requisição (varia no mês) | Sem cobrança por I/O (custo previsível) |
| Indicado quando | I/O é menos de ~25% do custo total do cluster | I/O passa de ~25% do custo total ou há carga intensa de I/O |
| Disponível | Todas as versões | A partir da 5.0 (instance-based) |
| Troca | Voltar a Standard a qualquer momento | Para I/O-optimized, uma vez a cada 30 dias; sem downtime nem reboot |
# Criar já em I/O-optimized aws docdb create-db-cluster --db-cluster-identifier meu-cluster --engine docdb --engine-version 8.0.0 \ --storage-type iopt1 ... # Converter um cluster existente aws docdb modify-db-cluster --db-cluster-identifier meu-cluster --storage-type iopt1 --apply-immediately
VolumeReadIOPs e VolumeWriteIOPs e o Cost Explorer (com tags de alocação de custo) para comparar o custo de I/O com o total do cluster antes de trocar.No serverless, a instância escala dentro de uma faixa que você define, em passos de 0,5 DCU (cada DCU equivale a cerca de 2 GiB de memória). A cobrança é por segundo de capacidade consumida.
- MinCapacity: mínimo 0,5 DCU. Considere valores maiores se o working set precisa caber em memória e para escalar mais rápido.
- MaxCapacity: de 1,0 a 256 DCUs.
- Mínimos recomendados: Performance Insights, 2 DCUs; global clusters, 8 DCUs (região primária). Com mínimo igual ou abaixo de 1,0 DCU, limites de conexões ativas, cursors e transações ficam reduzidos (use 1,5 ou mais se precisar).
- Readers em promotion tier 0 ou 1 acompanham o writer; a partir do tier 2 escalam de forma independente.
- Se a instância bate repetidamente no teto, o status vira
incompatible-parameters(reinícios por falta de memória): aumente MaxCapacity/MinCapacity ou reduza a carga.
aws docdb modify-db-cluster --db-cluster-identifier meu-cluster \ --serverless-v2-scaling-configuration MinCapacity=2,MaxCapacity=32 # Adicionar uma instância serverless (confirme os parâmetros na referência da CLI da sua versão) aws docdb create-db-instance --db-instance-identifier meu-cluster-sv-1 \ --db-instance-class db.serverless --engine docdb --db-cluster-identifier meu-cluster
Elastic clusters distribuem dados e carga em shards gerenciados, eliminando a escolha de instâncias. Falam o protocolo de rede do MongoDB 5.0 e não existem na 8.0.
| Limite | Valor |
|---|---|
| Shards por cluster | 32 |
| Armazenamento por cluster | até 4 PiB (dados bem distribuídos pela shard key) |
| vCPU por shard | até 64 |
| Conexões ao cluster | o menor entre 300.000 e shards x conexões do vCPU por shard |
| Coleções shardadas / não shardadas | 1.000 / 100.000 |
| Clusters elastic por região | 20 (1.024 vCPU somados) |
- Uma região primária (escrita) e até 10 regiões secundárias somente leitura; replicação por infraestrutura dedicada, normalmente em menos de 1 segundo.
- RTO típico abaixo de 1 minuto na promoção de uma secundária; RPO medido em segundos (depende do lag de rede no momento da falha).
- Secundárias podem ter até 16 réplicas e servir change streams, aliviando o primário.
- Limites: não suportado na 3.6; sem db.t3, db.t4g e db.r4; switchover e failover global não funcionam com versões de engine diferentes entre regiões; um cluster secundário não pode ser parado; MVU in-place não é suportado (remova as secundárias, atualize e recrie).
| Componente | Cobrança | Como reduzir |
|---|---|---|
| Instâncias | Por hora, por segundo de uso (mínimo de 10 minutos) | Right-size com BufferCacheHitRatio e CPU; serverless para carga variável; pare clusters de dev |
| I/O | Por 1 milhão de requisições (Standard) | Mais memória (cache hit), menos índices, I/O-optimized se I/O > ~25% do custo |
| Armazenamento | Por GiB/mês, conforme o uso real | Drop de coleções antigas, compressão (8.0), rolling collections |
| Backup | Por GiB/mês acima do gratuito | Retenção alinhada ao RPO; apague snapshots manuais antigos |
| Transferência | Por GB entre regiões/internet | Manter app e cluster na mesma região/AZ |
- Crie alertas de billing em 50% e 75% do orçamento mensal.
- Desative TTL e change streams que não são usados (geram I/O).
- Uma instância única sem réplicas serve para dev/teste (durabilidade já é do storage), mas não tem HA.
- Na 3.6, o custo de armazenamento segue o "high water mark"; da 4.0 em diante o espaço liberado reduz o volume alocado.
Backup e Restore
Backups contínuos, snapshots, point-in-time restore, cópias e estratégia de recuperação
O DocumentDB faz backup contínuo e incremental do volume do cluster para um bucket S3 gerenciado pela AWS, sem impacto de desempenho e sem janela de bloqueio. Sobre esse mecanismo existem quatro formas de ter uma cópia dos seus dados:
| Tipo | Como é criado | Granularidade de restore | Retenção | Quando usar |
|---|---|---|---|---|
| Backup contínuo (PITR) | Automático, contínuo e incremental | Qualquer segundo da janela, até aproximadamente os últimos 5 minutos | 1 a 35 dias (padrão 1) | Erro humano, corrupção lógica, DROP acidental |
| Snapshot automático | Diário, na janela de backup | O instante do snapshot | Segue a retenção; apagado junto com o cluster | Restore rápido a partir de um ponto diário |
| Snapshot manual | Sob demanda (console, CLI, API) | O instante em que foi tirado | Até você apagar (não some com o cluster) | Antes de deploys e upgrades; arquivamento; cópia entre regiões e contas |
| Dump lógico (mongodump) | Você executa a ferramenta | Banco ou coleção, a qualquer momento | Onde você guardar | Portabilidade, migração, restore seletivo, outro destino |
Além do snapshot diário, o serviço registra continuamente as mudanças do volume durante todo o período de retenção. A combinação "snapshot completo mais registro incremental" é o que permite parar em qualquer segundo.
dia 1 dia 2 dia 3 ... hoje |-- snapshot --|-- snapshot --|-- snapshot --|~~~ registro contínuo ~~~> (últimos ~5 min não restauráveis) <-------------- janela restaurável (retenção: 1 a 35 dias) -------------------> Restore para 2026-10-12T14:55:00Z: snapshot mais próximo anterior + replay das mudanças até 14:55:00
| Entra no cluster restaurado | Não entra (você recria ou reassocia) |
|---|---|
| Bancos, coleções, documentos e índices | Instâncias (no console você escolhe; na CLI crie com create-db-instance) |
| Usuários e papéis criados dentro do banco (estão nos dados) | Parameter group do cluster de origem (vem o padrão) |
| Criptografia em repouso (cluster criptografado gera restore criptografado) | Alarmes do CloudWatch, assinaturas de eventos, dashboards |
| Configuração básica do cluster (rede, porta, retenção) | Estado de execução: conexões abertas, cursors, cache aquecido |
- Sem impacto no cluster: o backup contínuo roda na camada de armazenamento e não consome CPU nem I/O das suas instâncias.
- Atraso final: o último instante restaurável fica alguns minutos atrás do relógio (
LatestRestorableTime); não dá para restaurar "agora" exato. - Fora da retenção não há PITR: se o erro foi descoberto depois do vencimento, só restam snapshots manuais ou cópias.
- Exclusão do cluster apaga o contínuo: sem snapshot final ou manual, não há como restaurar depois que o cluster é apagado.
- Cópia entre versões: restaurar para outra versão major não é suportado (3.6 para 4.0, por exemplo); mudança de versão é migração ou upgrade in-place.
pedidos às 14:07 UTC. Você restaura o PITR para 14:06:30 em um cluster temporário, valida, exporta a coleção com mongodump e reimporta na produção; depois descarta o temporário.- Retenção: de 1 a 35 dias (um cluster novo começa com 1). Alinhe ao seu RPO e ao tempo que leva para descobrir um erro.
- Janela de backup: horário do dia em que os snapshots automáticos são criados; escolha um horário de menor carga.
- Nomes: snapshots automáticos seguem o padrão
rds:NOME_DO_CLUSTER-aaaa-mm-dd-hh-mm. - Exclusão: não é possível apagar um snapshot automático manualmente; eles somem com o cluster ou ao vencer a retenção.
- Janela restaurável: o intervalo entre
EarliestRestorableTimeeLatestRestorableTimedo cluster.
# Ajustar a retenção e a janela de backup aws docdb modify-db-cluster --db-cluster-identifier meu-cluster \ --backup-retention-period 14 --preferred-backup-window 03:00-03:30 --apply-immediately # Ver até onde é possível restaurar (UTC) aws docdb describe-db-clusters --db-cluster-identifier meu-cluster \ --query "DBClusters[0].[BackupRetentionPeriod,PreferredBackupWindow,EarliestRestorableTime,LatestRestorableTime]" --output table
Regras da janela de backup
- Se você não definir, o serviço atribui uma janela de 30 minutos escolhida ao acaso dentro de um bloco de 8 horas da região.
- Se o snapshot precisar de mais tempo que a janela, o processo continua até terminar.
- A janela de backup não pode se sobrepor à janela de manutenção semanal do cluster.
- O cluster precisa estar no estado available para o snapshot automático ser tirado; ele também não é tirado enquanto uma cópia de snapshot do mesmo cluster está em andamento na região.
BackupRetentionPeriodStorageUsed cresce com o volume do cluster e com a quantidade de mudanças no período. Veja o tópico de custos de backup antes de subir a retenção.| Automático | Manual | |
|---|---|---|
| Criação | Pelo serviço, todo dia, na janela de backup | Sob demanda (console, CLI, API) |
| Conteúdo | Backup completo do cluster; incremental dentro da retenção | Backup completo no momento em que foi tirado |
| Nome | Padrão rds:cluster-aaaa-mm-dd-hh-mm | Você escolhe (o serviço não acrescenta data) |
| Exclusão | Não pode apagar manualmente; some com o cluster | Só some quando você apaga; sobrevive à exclusão do cluster |
| Compartilhar | Não (copie para um manual primeiro) | Sim, com outras contas (criptografado ou não) |
| Restaurar | Para qualquer ponto da retenção (PITR) ou para o snapshot | Para o momento em que foi tirado |
| Cota | - | 100 por região |
# Criar (inclua data no nome: o serviço não faz isso por você) aws docdb create-db-cluster-snapshot --db-cluster-identifier meu-cluster \ --db-cluster-snapshot-identifier meu-cluster-pre-deploy-20261013 # Listar e acompanhar o status (precisa estar "available") aws docdb describe-db-cluster-snapshots --db-cluster-identifier meu-cluster --snapshot-type manual \ --query "DBClusterSnapshots[*].[DBClusterSnapshotIdentifier,Status,SnapshotCreateTime,PercentProgress]" --output table # Apagar aws docdb delete-db-cluster-snapshot --db-cluster-snapshot-identifier meu-cluster-pre-deploy-20261013 # Excluir o cluster guardando um snapshot final aws docdb delete-db-cluster --db-cluster-identifier meu-cluster \ --no-skip-final-snapshot --final-db-snapshot-identifier meu-cluster-final-20261013
O PITR cria um novo cluster com os dados exatamente como estavam no instante escolhido, dentro do período de retenção. Nunca restaura "por cima" do cluster original: ele continua intacto, o que permite comparar e recuperar dados com segurança.
| Aspecto | O que acontece |
|---|---|
| Janela | Entre EarliestRestorableTime e LatestRestorableTime (o último costuma ficar uns 5 minutos atrás) |
| Fuso horário | Sempre UTC (por exemplo 2026-10-12T14:55:00Z) |
| Resultado | Novo cluster (identificador novo, que não pode existir) |
| Instâncias | Pela CLI, só o cluster é criado: adicione instâncias com create-db-instance quando o cluster estiver available (o console já pede classe e quantidade) |
| Configuração | Igual à do cluster de origem, exceto o parameter group: o novo cluster vem com o parameter group padrão |
| Opções | Instância, VPC, subnet group, security groups, porta, tipo de armazenamento (standard ou iopt1), exportação de logs, tags e deletion protection |
| Restrição de versão | Não é possível restaurar 3.6 para 4.0; mudar de versão é migração (DMS, dump/restore ou upgrade in-place) |
Pelo console
- Console do DocumentDB > Clusters > selecione o cluster.
- Actions > Restore to point in time.
- Escolha a data e a hora (entre o earliest e o latest restore time).
- Defina identificador do cluster, classe e número de instâncias, tipo de armazenamento.
- Em Show advanced settings, ajuste rede, porta, exportação de logs, tags e deletion protection.
- Create cluster e aguarde o status available.
Pela CLI
# Para o último instante restaurável aws docdb restore-db-cluster-to-point-in-time \ --db-cluster-identifier meu-cluster-pitr \ --source-db-cluster-identifier meu-cluster \ --use-latest-restorable-time # Para um instante específico (UTC) aws docdb restore-db-cluster-to-point-in-time \ --db-cluster-identifier meu-cluster-pitr \ --source-db-cluster-identifier meu-cluster \ --restore-to-time 2026-10-12T14:55:00Z # Aguardar o cluster ficar disponível until [ "$(aws docdb describe-db-clusters --db-cluster-identifier meu-cluster-pitr \ --query 'DBClusters[0].Status' --output text)" = "available" ]; do sleep 30; done # Criar as instâncias do cluster restaurado aws docdb create-db-instance --db-instance-identifier meu-cluster-pitr-1 \ --db-instance-class db.r6g.large --engine docdb \ --db-cluster-identifier meu-cluster-pitr
--restore-to-time e --use-latest-restorable-time são mutuamente exclusivos; o horário precisa ser anterior ao último restaurável. Com --restore-type copy-on-write (clone) não se informa --restore-to-time.Checklist depois do restore
- Associar o parameter group correto ao novo cluster (ele vem com o padrão) e reiniciar se houver parâmetros estáticos (por exemplo
tls). - Conferir security groups, subnet group, criptografia e deletion protection.
- Reativar exportação de logs de auditoria e profiler, e o Performance Insights nas instâncias.
- Validar os dados (contagens, amostras e índices) antes de redirecionar a aplicação.
- Ajustar a retenção de backup do novo cluster e criar alarmes (o cluster novo não herda os alarmes do CloudWatch).
- Recriar usuários e permissões só se o instante restaurado for anterior à criação deles.
- A restauração sempre cria um cluster novo; não é possível restaurar sobre um cluster existente.
- Pela CLI, só o cluster é criado: crie ao menos uma instância depois que ele estiver available.
- Snapshot criptografado exige acesso à chave KMS e só pode virar cluster criptografado. Um snapshot sem criptografia pode ser restaurado para um cluster criptografado informando
--kms-key-id. - Snapshot compartilhado: pela CLI/API informe o ARN do snapshot como identificador.
- O cluster restaurado recebe o parameter group padrão e as configurações de rede que você indicar.
aws docdb restore-db-cluster-from-snapshot \ --db-cluster-identifier meu-cluster-restaurado \ --snapshot-identifier meu-cluster-pre-deploy-20261013 \ --engine docdb \ --db-subnet-group-name meu-subnet-group \ --vpc-security-group-ids sg-0abc123 \ --storage-type standard # Depois que o cluster estiver available aws docdb create-db-instance --db-instance-identifier meu-cluster-restaurado-1 \ --db-instance-class db.r6g.large --engine docdb --db-cluster-identifier meu-cluster-restaurado
O clone é um novo cluster que aponta para as mesmas páginas de armazenamento do original. Nenhum dado é copiado na criação: só quando o original ou o clone alteram uma página é que ela passa a existir em duas versões (copy-on-write). Por isso o clone é rápido e barato em comparação com restaurar um snapshot.
| Aspecto | Detalhe |
|---|---|
| Conteúdo | Os dados do último instante restaurável do cluster de origem |
| Custo | Instâncias do clone + armazenamento só do que divergir do original |
| Origem | O cluster precisa ter pelo menos uma instância |
| Escopo | Mesma conta e mesma região (sem clone entre contas ou regiões) |
| Rede | Pode ficar em outra VPC, desde que as subnets mapeiem as mesmas AZs |
| Quantidade | Vários clones do mesmo cluster e clones de clones; após 15 clones o seguinte é uma cópia completa |
| Independência | Apagar o cluster de origem não afeta os clones |
| Criptografia | Origem criptografada gera clone criptografado |
| Instâncias | Pelo console o clone nasce com uma instância; pela CLI você cria as instâncias depois |
aws docdb restore-db-cluster-to-point-in-time \ --source-db-cluster-identifier meu-cluster \ --db-cluster-identifier meu-cluster-clone \ --restore-type copy-on-write \ --use-latest-restorable-time # Quando o clone estiver available, crie a instância (pode ser menor que a de produção) aws docdb create-db-instance --db-instance-identifier meu-cluster-clone-1 \ --db-instance-class db.r6g.large --engine docdb \ --db-cluster-identifier meu-cluster-clone
- Bons usos: testar upgrade de versão e mudança de parameter group, ensaiar migração de dados, rodar relatórios pesados ou exportações sem tocar a produção, criar ambientes de teste com dados reais.
- Não é backup: o clone compartilha o volume; ele não protege contra exclusão lógica já replicada nem contra perda do cluster inteiro. Use snapshots e PITR para recuperação.
- Dados reais: um clone de produção contém dados reais; aplique as mesmas regras de acesso, criptografia e mascaramento se o destino for desenvolvimento.
- Limpeza: apague clones quando terminar; o custo de instância continua enquanto existirem.
A matriz abaixo compara todas as formas de ter uma cópia dos dados. "Indicado" é o uso natural da técnica; "Possível" funciona com ressalvas; "Evite" é uma má escolha para aquele critério.
| Técnica | Granularidade (RPO) | Escopo | Rapidez de recuperação | Custo | Outra região | Outra conta | Impacto no cluster |
|---|---|---|---|---|---|---|---|
| PITR (backup contínuo) | Segundos | Cluster inteiro (novo cluster) | Minutos a horas; depende do volume | Dentro da retenção contratada | Não direto | Não direto | Nenhum |
| Snapshot automático | 1 por dia | Cluster inteiro | Minutos a horas | Incluído na retenção | Via cópia | Via cópia para manual | Nenhum |
| Snapshot manual | Ponto fixo (o instante da criação) | Cluster inteiro | Minutos a horas | Cobrado fora da retenção | Cópia entre regiões | Compartilhamento | Nenhum relatado |
| Clone (copy-on-write) | Instante atual | Cluster inteiro | Muito rápida (sem copiar dados) | Só divergência + instâncias | Não | Não | Leitura pesada no clone usa o mesmo armazenamento; teste |
| mongodump / mongorestore | Instante "borrado" se houver escrita | Banco ou coleção (seletivo) | Lenta em bases grandes (reinsere e reindexa) | I/O + armazenamento do arquivo | Sim (são arquivos) | Sim | Lê o cluster; rode em uma réplica |
| mongoexport / mongoimport | Instante atual | Coleção | Lenta | I/O | Sim | Sim | Lê o cluster |
| Global cluster (replicação, não backup) | Segundos (RPO) | Cluster inteiro | RTO típico abaixo de 1 min | Cluster extra em outra região | Sim | Não | Mínimo |
Quando evitar cada técnica
| Técnica | Não use quando |
|---|---|
| PITR | O erro foi descoberto depois da retenção, o cluster foi apagado sem snapshot final, ou você precisa do dado em outra região/conta. |
| Snapshot automático | Você precisa de uma granularidade menor que 1 dia (use PITR) ou precisa compartilhar o ponto (copie para manual). |
| Snapshot manual | Você precisa recuperar uma única coleção com rapidez (restaure em cluster temporário e extraia, ou use dump). |
| Clone | O objetivo é proteção contra perda (o clone depende do mesmo armazenamento) ou o destino é outra região ou conta. |
| mongodump | A base é muito grande e o RTO é curto, ou há muita escrita e você precisa de consistência de um instante (prefira snapshot ou PITR). |
| mongoexport | Você quer backup fiel: JSON e CSV perdem tipos BSON; use mongodump. |
| Global cluster | O problema é erro lógico: a replicação replica a exclusão para a região secundária. Use PITR ou snapshots. |
| Cenário | Técnica | Por quê |
|---|---|---|
| Alguém apagou ou alterou dados há horas e você sabe o horário | PITR até pouco antes do erro | Granularidade de segundos dentro da retenção |
| Voltar exatamente ao estado de um deploy ou upgrade | Restore do snapshot manual tirado antes | Ponto fixo e nomeado |
| Recuperar só uma coleção ou alguns documentos | PITR ou snapshot em cluster temporário + mongodump/mongorestore ou script | Não sobrescreve a produção |
| Ambiente de teste idêntico à produção, rápido e barato | Clone (copy-on-write) | Compartilha o volume e só paga pelo que divergir |
| Recuperação de desastre de região | Copiar snapshots para outra região (ou global cluster) e restaurar lá | Backups não saem da região sozinhos |
| Entregar dados a outra conta ou outro time | Compartilhar snapshot manual | Evita dump/restore |
| Migrar de versão, topologia ou para outro destino | mongodump/mongorestore ou DMS | Portável e independente do motor |
# Clone: usa o último instante restaurável e compartilha o volume (copy-on-write) aws docdb restore-db-cluster-to-point-in-time \ --db-cluster-identifier meu-cluster-clone --source-db-cluster-identifier meu-cluster \ --restore-type copy-on-write --use-latest-restorable-time
mongodump --db --collection e reimporte na produção. Faça o restore para um nome novo de coleção primeiro e compare antes de sobrescrever.Copiar
- Cópia na mesma região ou entre regiões (cada cópia entre regiões é um snapshot completo).
- Copiar é também a forma de transformar um snapshot automático em manual (para guardar além da retenção ou compartilhar).
- Criptografia: snapshot criptografado só gera cópia criptografada; entre regiões é preciso informar uma chave KMS da região de destino. Não é possível criptografar a cópia de um snapshot sem criptografia.
- Parameter group: a cópia não leva o parameter group; crie um equivalente na região de destino e associe depois do restore.
- Limites: até 5 cópias em andamento por região de destino e por conta; cópias entre regiões podem levar horas e entrar em fila. Só apague o snapshot de origem quando o destino estiver available.
# Executar na região de DESTINO aws docdb copy-db-cluster-snapshot --region sa-east-1 \ --source-db-cluster-snapshot-identifier arn:aws:rds:us-east-1:123456789012:cluster-snapshot:meu-cluster-pre-deploy-20261013 \ --target-db-cluster-snapshot-identifier meu-cluster-dr-20261013 \ --source-region us-east-1 \ --kms-key-id arn:aws:kms:sa-east-1:123456789012:key/CHAVE-DO-DESTINO \ --copy-tags
Compartilhar
- Só snapshots manuais (copie o automático antes). Até 20 contas; snapshots sem criptografia podem ser públicos (evite: qualquer conta teria seus dados).
- Criptografado: não pode ser público e não pode usar a chave KMS padrão da conta; compartilhe também a chave (key policy com a conta de destino e a ação
kms:CreateGrant). - A conta de destino pode copiar o snapshot ou restaurar direto dele (informando o ARN).
aws docdb modify-db-cluster-snapshot-attribute \ --db-cluster-snapshot-identifier meu-cluster-pre-deploy-20261013 \ --attribute-name restore --values-to-add '["111122223333"]'
As ferramentas do MongoDB funcionam com o DocumentDB e são a opção quando você precisa de arquivos sob seu controle: migrar entre versões ou topologias, restaurar uma única coleção, enviar dados a outro ambiente ou guardar em outro destino.
| Ferramenta | Uso | Dica de desempenho |
|---|---|---|
| mongodump | Backup binário (BSON) de bancos e coleções | --numParallelCollections: comece com um worker por vCPU do primário |
| mongorestore | Restaura um dump do mongodump | --numInsertionWorkersPerCollection: idem, um por vCPU |
| mongoexport | Exporta em JSON, CSV ou TSV (legível por pessoas e máquinas) | Sem paralelismo nativo; rode vários jobs em coleções diferentes |
| mongoimport | Importa JSON, CSV ou TSV | --numInsertionWorkers para paralelizar |
# Dump de um banco (rode a partir de uma EC2 na VPC) mongodump --ssl --host="meu-cluster.cluster-xxxx.us-east-1.docdb.amazonaws.com:27017" \ --sslCAFile global-bundle.pem --username=USUARIO --password="$SENHA" \ --db=loja --out=/backup/loja-20261013 --numParallelCollections 4 # Restore mongorestore --ssl --host="meu-cluster-novo.cluster-xxxx.us-east-1.docdb.amazonaws.com:27017" \ --sslCAFile global-bundle.pem --username=USUARIO --password="$SENHA" \ --numParallelCollections 4 /backup/loja-20261013
| Métrica (CloudWatch) | O que representa |
|---|---|
| BackupRetentionPeriodStorageUsed | Armazenamento dos backups contínuos dentro da retenção. Depende do tamanho do volume e do volume de mudanças; para cobrança, não passa do tamanho do volume vezes os dias de retenção |
| SnapshotStorageUsed | Snapshots manuais fora da retenção (os tirados dentro da retenção e os automáticos não contam) |
| TotalBackupStorageBilled | BackupRetentionPeriodStorageUsed + SnapshotStorageUsed - armazenamento gratuito (igual ao tamanho do volume por um dia) |
Exemplo: cluster de 100 GiB, 1 dia de retenção e 1 snapshot manual fora da retenção: 100 GiB (contínuo) + 100 GiB (snapshot) - 100 GiB (gratuito) = 100 GiB faturados. As métricas são calculadas por cluster, de forma independente.
- Reduza a retenção ao mínimo que atenda ao RPO.
- Apague snapshots manuais que não são mais necessários (inclusive cópias entre regiões).
- Um snapshot manual dentro da retenção não aumenta a fatura de backup.
- Restaurar e dump/restore geram I/O; clones só geram custo quando divergem do original.
aws cloudwatch get-metric-statistics --namespace AWS/DocDB --metric-name TotalBackupStorageBilled \ --dimensions Name=DBClusterIdentifier,Value=meu-cluster \ --start-time $(date -u -d '-7 days' +%FT%TZ) --end-time $(date -u +%FT%TZ) \ --period 86400 --statistics Average
| Topologia | O que vale para backup |
|---|---|
| Instance-based (regional) | Tudo o que está nesta fase: contínuo/PITR, snapshots automáticos e manuais, cópia, compartilhamento e clone |
| Elastic cluster | Não há point-in-time restore nem clonagem; use snapshots (a cota de snapshots manuais é de 20 por região) e backup lógico quando precisar de mais controle. AWS Backup não é suportado |
| Global cluster | Cada região tem seu cluster; a replicação dá RPO em segundos para falha de região, mas não protege contra erro lógico. Mantenha PITR e snapshots em cada cluster regional |
| Serverless | Mesmo modelo do instance-based: backup contínuo e snapshots no volume do cluster |
| Decisão | Orientação |
|---|---|
| RPO | PITR cobre segundos dentro da retenção. Para além disso, snapshots manuais ou cópias entre regiões definem o RPO. |
| RTO | Meça: restaurar cria um cluster novo e exige instâncias, parâmetros e troca de endpoint. Documente o tempo real em um exercício. |
| Retenção | Pelo menos o tempo que o seu time leva para perceber um erro (ex.: 7 a 14 dias). Máximo de 35. |
| Marcos | Snapshot manual antes de deploys, migrações de dados e upgrades; nomeado com data e motivo. |
| Fora da região | Cópia periódica para outra região (com chave KMS de lá) ou global cluster, conforme a exigência de DR. |
| Fora da conta | Para ransomware ou erro de operação: compartilhar/copiar para uma conta de backup separada. |
| Testes | Restaure periodicamente, valide contagens e índices e cronometre. Backup nunca restaurado é hipótese. |
Script: snapshot manual datado e limpeza dos antigos
#!/usr/bin/env bash
# Uso: ./docdb-snapshot-rotate.sh CLUSTER [DIAS_PARA_MANTER]
# Cria um snapshot manual datado e APAGA os manuais antigos que sigam o padrão CLUSTER-manual-*
set -euo pipefail
CLUSTER="${1:?informe o cluster}"
KEEP_DAYS="${2:-30}"
STAMP=$(date -u +%Y%m%d-%H%M)
aws docdb create-db-cluster-snapshot \
--db-cluster-identifier "$CLUSTER" \
--db-cluster-snapshot-identifier "${CLUSTER}-manual-${STAMP}" > /dev/null
echo "Snapshot criado: ${CLUSTER}-manual-${STAMP}"
# GNU date. No macOS use: date -u -v-${KEEP_DAYS}d +%Y-%m-%dT%H:%M:%SZ
CUTOFF=$(date -u -d "-${KEEP_DAYS} days" +%Y-%m-%dT%H:%M:%SZ)
aws docdb describe-db-cluster-snapshots --db-cluster-identifier "$CLUSTER" --snapshot-type manual \
--query "DBClusterSnapshots[?starts_with(DBClusterSnapshotIdentifier, '${CLUSTER}-manual-') && SnapshotCreateTime<'${CUTOFF}'].DBClusterSnapshotIdentifier" \
--output text | tr '\t' '\n' | while read -r SNAP; do
[ -n "$SNAP" ] || continue
echo "Apagando $SNAP"
aws docdb delete-db-cluster-snapshot --db-cluster-snapshot-identifier "$SNAP" > /dev/null
done
echo para ver o que seria removido, e agende fora do horário de deploys (EventBridge, cron).Exercício de restore (roteiro)
- Restaure o PITR ou o snapshot mais recente em um cluster temporário com instância pequena.
- Aguarde available e crie a instância; cronometre cada etapa.
- Conecte e valide: contagem de documentos por coleção, índices e uma amostra de dados críticos.
- Registre o tempo total (RTO medido) e os problemas encontrados.
- Apague o cluster temporário (e os snapshots que ele gerou) para não gerar custo.
Segurança
Rede, criptografia, autenticação, controle de acesso e auditoria
- Rede: o cluster vive em subnets privadas (DB subnet group). Restrinja o security group à porta do cluster e às fontes necessárias.
- Criptografia em trânsito: controlada pelo parâmetro
tls. Na 8.0 e na 5.0.1+ só TLS 1.2 ou superior;fips-140-3está disponível em regiões específicas a partir da 5.0. - Criptografia em repouso: com chave do AWS KMS, definida na criação do cluster; cobre dados, backups, snapshots e réplicas.
- Certificados: acompanhe a rotação de CA e mantenha o bundle
global-bundle.pematualizado nos clientes. - Proteção: ligue deletion protection e tire snapshot final antes de apagar clusters.
aws docdb create-db-cluster --db-cluster-identifier meu-cluster --engine docdb --engine-version 8.0.0 \ --master-username admin --master-user-password "$SENHA" \ --storage-encrypted --kms-key-id alias/docdb-prod \ --deletion-protection \ --db-subnet-group-name meu-subnet-group --vpc-security-group-ids sg-0abc123 \ --db-cluster-parameter-group-name meu-param-group-8-0
- Usuário primário criado com o cluster: use só para administração.
- Usuários da aplicação com papéis mínimos por banco (
read,readWrite, papéis personalizados). - Autenticação IAM (5.0): usuários e roles IAM entram no banco no
$externalcom o mecanismoMONGODB-AWS, sem senha. Não vale para o usuário primário. Em Node.js use driver 6.13.1 ou superior; em Python instalepymongo[aws]. - Segredos: guarde senhas no AWS Secrets Manager (com rotação) em vez de em arquivos de ambiente.
// Usuário de aplicação com permissão em um banco
use loja
db.createUser({ user: "app_pedidos", pwd: passwordPrompt(), roles: [ { role: "readWrite", db: "loja" } ] })
// Usuário IAM (5.0)
use $external
db.createUser({ user: "arn:aws:iam::123456789012:role/app-pedidos", mechanisms: ["MONGODB-AWS"],
roles: [ { role: "readWrite", db: "loja" } ] })
mongodb://meu-cluster.cluster-xxxx.us-east-1.docdb.amazonaws.com:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false&authSource=%24external&authMechanism=MONGODB-AWS
A auditoria é opcional e desligada por padrão. Ela registra autenticação, autorização, DDL, DML (leitura e escrita) e gestão de usuários e exporta para o CloudWatch Logs. Ela é diferente do CloudTrail, que audita chamadas da API da AWS (cluster, instância, snapshot) e está sempre ligado.
- Em um parameter group customizado, defina
audit_logs(ddl,dml_read,dml_writeouall). - Habilite a exportação do log
auditno cluster. - Consulte em
/aws/docdb/NOME_DO_CLUSTER/auditno CloudWatch Logs.
aws docdb modify-db-cluster-parameter-group --db-cluster-parameter-group-name meu-param-group-8-0 \
--parameters ParameterName=audit_logs,ParameterValue=ddl,ApplyMethod=immediate
aws docdb modify-db-cluster --db-cluster-identifier meu-cluster \
--cloudwatch-logs-export-configuration '{"EnableLogTypes":["audit"]}'
setAuditConfig para filtrar por comando, usuário ou namespace antes de ir ao CloudWatch.Client-side field level encryption (5.0+): o driver cifra campos sensíveis (CPF, cartão) antes de enviar, com chaves no KMS. O servidor nunca vê o texto claro.
Monitoramento e Análise de Performance
Métricas, alarmes, Performance Insights, profiler e scripts
| Pergunta | Ferramenta | Onde |
|---|---|---|
| O cluster está saudável agora? (CPU, memória, conexões, lag) | Métricas do CloudWatch | Console do DocumentDB > instância > aba Monitoring; CloudWatch > Metrics > DocDB |
| O que está consumindo carga do banco? Por que há espera? | Performance Insights | Console do DocumentDB > Performance Insights (escolha a instância) |
| Quais consultas são lentas e por quê? | Profiler + CloudWatch Logs Insights | Log group /aws/docdb/CLUSTER/profiler |
| O que está rodando agora? Quem bloqueia quem? | currentOp / killOp | mongosh na instância |
| A consulta usa índice? Qual o plano? | explain() | mongosh |
| Quanto cada índice/coleção custa? Cache hit? | collStats / $indexStats | mongosh |
| Quem acessou ou alterou o quê? | Audit logs | Log group /aws/docdb/CLUSTER/audit |
| Quem mudou o cluster na AWS? | CloudTrail e eventos do DocumentDB | CloudTrail; console > Events |
explain() e currentOp no mongosh.As métricas ficam no namespace AWS/DocDB, com as dimensões DBInstanceIdentifier, DBClusterIdentifier e DBClusterIdentifier + Role (WRITER/READER). A granularidade é de 1 minuto (as Volume*IOPs são reportadas a cada 5 minutos).
Recursos e capacidade
| Métrica | Significado | Como usar |
|---|---|---|
| CPUUtilization | % de CPU da instância | Acima de 80% sustentado: otimize consultas, distribua leitura em réplicas ou aumente a instância |
| FreeableMemory | RAM disponível (bytes) | Abaixo de 10% da memória total com frequência: escale a instância |
| SwapUsage | Swap em uso | Deve ficar em ou perto de zero |
| BufferCacheHitRatio | % de requisições servidas pelo cache | Queda indica working set maior que a memória (mais I/O e latência) |
| IndexBufferCacheHitRatio | % de requisições de índice servidas pelo cache | Índices fora de memória aumentam I/O |
| DatabaseConnections / Max / Limit | Conexões abertas, máximo no minuto e limite da instância | Alarme perto do limite; revise maxPoolSize e pooling |
| DatabaseConnectionsActiveMax | Máximo de conexões ativas (executando operação) | Compare com o limite de conexões ativas da classe |
| DatabaseCursors / Max / Limit / TimedOut | Cursors abertos e limite | Cursors não fechados consomem memória |
| TransactionsOpen / Max / Limit | Transações abertas e limite | Transações longas seguram garbage collection |
| LowMemThrottleQueueDepth, LowMemNumOperationsThrottled | Requisições enfileiradas/limitadas por falta de memória | Qualquer valor sustentado: escale a instância |
| VolumeBytesUsed | Armazenamento usado pelo cluster | Tendência e planejamento de custo |
| FreeLocalStorage | Disco local para temporários e logs | Dependente da classe; relevante em ordenações grandes |
Latência, I/O e rede
| Métrica | Significado | Como usar |
|---|---|---|
| ReadLatency / WriteLatency | Tempo médio por I/O de disco | Compare com a sua baseline |
| ReadIOPS / WriteIOPS | I/O por segundo (1 min) | Correlacione com inserts na instância primária |
| VolumeReadIOPs / VolumeWriteIOPs | I/O faturado no volume (5 min, agregado das instâncias) | Base da conta de I/O; divida por 300 para IOPS médio |
| DiskQueueDepth | Operações de I/O esperando | Fila persistente indica gargalo de I/O |
| ReadThroughput / WriteThroughput | Bytes/s lidos e escritos em disco | |
| NetworkThroughput, StorageNetworkThroughput | Tráfego com clientes e com o volume | A soma dos dois deve ficar abaixo do limite de rede da classe |
| DBInstanceReplicaLag, DBClusterReplicaLagMaximum/Minimum | Lag da réplica (ms) | Em geral abaixo de 100 ms; picos em alta escrita |
Operações, comandos e manutenção
| Métrica | Significado | Como usar |
|---|---|---|
| OpcountersQuery/Insert/Update/Delete/Getmore/Command | Operações por tipo (1 min) | Em cluster ocioso ~50 é normal (health checks) |
| DocumentsInserted/Updated/Deleted/Returned | Documentos afetados ou retornados | Documentos retornados muito acima das operações indica queries amplas |
| Command.find / .aggregate / .update ... (.AvgDuration, .P100Duration, .MaxConcurrent) | Latência média, máxima e concorrência por comando (5.0.1+) | Mostra qual comando domina a carga e a latência de cauda |
| TTLDeletedDocuments | Documentos removidos por TTL | Explica pico de I/O de delete |
| TransactionsStarted / Committed / Aborted | Ciclo das transações | Aborts frequentes indicam conflito ou timeout |
| ChangeStreamLogSize | Tamanho do log de change streams | Faz parte do armazenamento e do custo |
| AvailableMVCCIds | Escritas restantes antes de modo somente leitura | Alarme em 900 milhões (5.0+) ou 1,3 bilhão (3.6/4.0) |
| LongestActiveGCRuntime | Duração do GC ativo mais longo (s) | Compare com o histórico em gcRuntimeStats |
| BackupRetentionPeriodStorageUsed, SnapshotStorageUsed, TotalBackupStorageBilled | Armazenamento de backup | Custo de backup acima do gratuito |
| CPUCreditBalance, CPUCreditUsage (T3/T4G) | Créditos de CPU | Saldo em zero = CPU estrangulada |
Console do DocumentDB
- Abra o console em Amazon DocumentDB > Clusters.
- Expanda o cluster e clique na instância (writer ou reader) que quer analisar.
- Abra a aba Monitoring: gráficos de CPU, memória, conexões, IOPS, latência e lag. Ajuste o intervalo (1 h a semanas).
- Compare writer vs reader: leituras distribuídas? lag? CPU equilibrada?
- Abra o Performance Insights (se habilitado; escolha a instância) para ver carga por espera, consulta, host e aplicação.
- Em Events veja failovers, reinícios, manutenções e eventos de upgrade.
Console do CloudWatch
- Metrics > All metrics > DocDB > escolha a dimensão (por instância, por cluster, por papel).
- Selecione as métricas, ajuste Statistic (Average, Maximum) e Period (1 min).
- Combine métricas no mesmo gráfico (por exemplo,
CPUUtilization+DatabaseConnections+OpcountersCommand). - Salve em um Dashboard e crie Alarms a partir do gráfico.
- Em Logs Insights consulte os log groups
/aws/docdb/CLUSTER/profilere/aws/docdb/CLUSTER/audit.
| Alarme | Métrica | Limiar inicial | Ação |
|---|---|---|---|
| CPU alta | CPUUtilization (Average, 5 min x 3) | > 80% | Otimizar consultas, usar réplicas, escalar |
| Pouca memória | FreeableMemory | < 10% da memória da classe | Escalar instância |
| Swap | SwapUsage | > 0 de forma sustentada | Escalar instância |
| Conexões | DatabaseConnectionsMax vs DatabaseConnectionsLimit | > 80% do limite | Revisar pooling/maxPoolSize |
| Cursors / transações | DatabaseCursorsMax, TransactionsOpenMax | > 80% do limite | Fechar cursors, encurtar transações |
| Estrangulamento por memória | LowMemNumOperationsThrottled | > 0 | Escalar instância |
| Lag de réplica | DBInstanceReplicaLag | Acima da sua baseline (ex.: > 1.000 ms) | Investigar escrita em massa ou réplica subdimensionada |
| MVCC | AvailableMVCCIds (Minimum) | < 900.000.000 (5.0+) / < 1.300.000.000 (3.6, 4.0) | Escalar, reduzir escritas, investigar coleções com MVCCIdScale alto |
| Armazenamento | VolumeBytesUsed | Crescimento fora do esperado | Revisar bloat, TTL e índices |
# CPU > 80% por 15 min na instância aws cloudwatch put-metric-alarm \ --alarm-name docdb-meu-cluster-1-cpu-alta \ --namespace AWS/DocDB --metric-name CPUUtilization \ --dimensions Name=DBInstanceIdentifier,Value=meu-cluster-1 \ --statistic Average --period 300 --evaluation-periods 3 \ --threshold 80 --comparison-operator GreaterThanThreshold \ --alarm-actions arn:aws:sns:us-east-1:123456789012:alertas-banco # FreeableMemory < 10% de uma db.r6g.large (16 GiB = ~1,6 GiB) aws cloudwatch put-metric-alarm \ --alarm-name docdb-meu-cluster-1-memoria-baixa \ --namespace AWS/DocDB --metric-name FreeableMemory \ --dimensions Name=DBInstanceIdentifier,Value=meu-cluster-1 \ --statistic Average --period 300 --evaluation-periods 3 \ --threshold 1717986918 --comparison-operator LessThanThreshold \ --alarm-actions arn:aws:sns:us-east-1:123456789012:alertas-banco # MVCC (métrica no nível do cluster; confirme a dimensão no console) aws cloudwatch put-metric-alarm \ --alarm-name docdb-meu-cluster-mvcc \ --namespace AWS/DocDB --metric-name AvailableMVCCIds \ --dimensions Name=DBClusterIdentifier,Value=meu-cluster \ --statistic Minimum --period 300 --evaluation-periods 1 \ --threshold 900000000 --comparison-operator LessThanThreshold \ --alarm-actions arn:aws:sns:us-east-1:123456789012:alertas-banco
O Performance Insights mostra o DBLoad em Average Active Sessions (AAS): quantas sessões, em média, estão ativas ao mesmo tempo. Cada sessão ativa pode estar em CPU ou esperando algo; é isso que o gráfico separa. Disponível em clusters instance-based 3.6, 4.0, 5.0 e 8.0, com retenção de até 7 dias.
| Estado de espera | O que indica |
|---|---|
| CPU | Sessões esperando CPU. Se DBLoad passa da linha de Max vCPU e a espera dominante é CPU, a instância está saturada |
| IO | Sessões esperando I/O: working set maior que a memória ou muitas leituras de disco |
| Latch | Espera por paginar o buffer pool: scans grandes, COLLSCAN ou buffer pool pequeno para o working set |
| BufferLock | Espera por lock de página compartilhada; piora com cursors abertos segurando páginas |
| DocumentLock | Muitas escritas concorrentes no mesmo documento (hot document) |
| CollectionLock | Operações DDL na coleção |
| SystemLock | Consultas longas, transações longas ou alta concorrência |
| LowMemThrottle | Pressão de memória; considere escalar a instância |
| BackgroundActivity | Processos internos (garbage collection, por exemplo) |
| Other | Interno; se persistir, considere encerrar a consulta |
Como analisar no console
- No console, abra Performance Insights, escolha a instância e o período.
- No gráfico Database load, compare a barra com a linha Max vCPU.
- Fatie a carga por Waits para ver o gargalo dominante.
- Fatie por Top queries para achar a consulta responsável; por Hosts e Applications para achar a origem.
- Dê zoom no pico e cruze com deploys, jobs e eventos do cluster.
# Habilitar o Performance Insights em uma instância (confirme os parâmetros na referência da CLI) aws docdb modify-db-instance --db-instance-identifier meu-cluster-1 --enable-performance-insights --apply-immediately # DBLoad como métrica do CloudWatch (publicada somente se houver carga) aws cloudwatch get-metric-statistics --namespace AWS/DocDB --metric-name DBLoad \ --dimensions Name=DBInstanceIdentifier,Value=meu-cluster-1 \ --start-time $(date -u -d '-3 hours' +%FT%TZ) --end-time $(date -u +%FT%TZ) \ --period 300 --statistics Average
- Outras métricas publicadas:
DBLoadCPUeDBLoadNonCPU. - Consultas com mais de 1.024 bytes não são agregadas. Não disponível em GovCloud. Em serverless exige mínimo de 2 DCUs.
- Os counters do Performance Insights podem ser consultados via função de métrica
DB_PERF_INSIGHTSdo CloudWatch.
O profiler fica desabilitado por padrão. Quando ligado, registra no CloudWatch Logs as operações acima de um limiar, com comando, tempo, plano e metadados do cliente. Suporta aggregate, count, delete, distinct, find, findAndModify, insert e update.
- Tenha um parameter group customizado.
- Defina
profiler=enabled,profiler_threshold_mseprofiler_sampling_rate. - Associe o grupo ao cluster e habilite a exportação do log
profiler.
aws docdb modify-db-cluster-parameter-group --db-cluster-parameter-group-name meu-param-group-8-0 \
--parameters ParameterName=profiler,ParameterValue=enabled,ApplyMethod=immediate \
ParameterName=profiler_threshold_ms,ParameterValue=500,ApplyMethod=immediate \
ParameterName=profiler_sampling_rate,ParameterValue=1.0,ApplyMethod=immediate
aws docdb modify-db-cluster --db-cluster-identifier meu-cluster \
--db-cluster-parameter-group-name meu-param-group-8-0 \
--cloudwatch-logs-export-configuration '{"EnableLogTypes":["profiler"]}'
batchSize grande nas consultas que quer capturar.Consultas úteis no CloudWatch Logs Insights
# 10 operações mais lentas em uma coleção filter ns = "loja.pedidos" | sort millis desc | limit 10 # Updates acima de 60 ms filter op = "update" and millis > 60 # Tudo que fez varredura de coleção filter planSummary = "COLLSCAN" # Ranking por namespace e tipo de operação stats count(*) as n, avg(millis) as media_ms, max(millis) as max_ms by ns, op | sort media_ms desc | limit 20
Todos os comandos abaixo rodam por instância: conecte-se na instância que quer investigar (instance endpoint) quando o assunto for CPU, locks ou cache daquele nó.
Operações lentas ou bloqueadas
// Operações rodando há mais de 10 s ou esperando recurso
db.adminCommand({
aggregate: 1,
pipeline: [
{ $currentOp: { allUsers: true, idleConnections: false } },
{ $match: { $or: [ { secs_running: { $gt: 10 } }, { WaitState: { $exists: true } } ] } },
{ $project: { _id: 0, opid: 1, ns: 1, secs_running: 1, WaitState: 1, blockedOn: 1, command: 1 } }
],
cursor: {}
})
// Encerrar uma operação
db.adminCommand({ killOp: 1, op: 24646 })
Se a operação tem WaitState, há contenção. Com blockedOn preenchido, siga a cadeia de opid até o início. Estados Latch, SystemLock, BufferLock, BackgroundActivity e Other apontam tarefas internas.
Visão agregada do sistema (rode periodicamente e guarde)
db.adminCommand({
aggregate: 1,
pipeline: [
{ $currentOp: { allUsers: true, idleConnections: true } },
{ $group: { _id: { desc: "$desc", ns: "$ns", WaitState: "$WaitState" }, count: { $sum: 1 } } }
],
cursor: {}
})
Plano de consulta
db.runCommand({ explain: { find: "pedidos", filter: { clienteId: 42 } } })
// "stage": "COLLSCAN" -> varredura completa; crie índice
// "stage": "IXSCAN" -> usa índice
// Forçar um índice
db.pedidos.find({ clienteId: 42 }).hint("clienteId_1")
hint() para testar.Cache, uso de índices e bloat
// Contadores de operações, scans e cache hit da coleção
db.pedidos.stats()
// collScans vs idxScans; cacheStats.collHitRatio / idxHitRatio; opCounter
// Uso de cada índice (ops = 0 em carga estável sugere índice sem uso)
db.pedidos.aggregate([{ $indexStats: {} }]).pretty()
// Espaço não usado (bloat) e estatísticas de garbage collection
db.runCommand({ collStats: "pedidos" })
// unusedStorageSize, documentFragmentStats, gcRuntimeStats, MVCCIdStats
// Cursors abertos e versão do motor
db.runCommand("listCursors")
db.runCommand({ getEngineVersion: 1 })
Script de linha de comando que imprime média e máximo das principais métricas de uma instância nas últimas N horas. Requer AWS CLI v2 configurada e permissão cloudwatch:GetMetricStatistics.
#!/usr/bin/env bash
# Uso: ./docdb-metrics.sh NOME_DA_INSTANCIA [HORAS] [REGIAO]
set -euo pipefail
INST="${1:?informe o DBInstanceIdentifier}"
HOURS="${2:-3}"
REGION="${3:-${AWS_REGION:-us-east-1}}"
# GNU date. No macOS use: START=$(date -u -v-${HOURS}H +%Y-%m-%dT%H:%M:%SZ)
START=$(date -u -d "-${HOURS} hours" +%Y-%m-%dT%H:%M:%SZ)
END=$(date -u +%Y-%m-%dT%H:%M:%SZ)
METRICS="CPUUtilization FreeableMemory SwapUsage BufferCacheHitRatio IndexBufferCacheHitRatio DatabaseConnections DatabaseCursors \
ReadLatency WriteLatency ReadIOPS WriteIOPS DiskQueueDepth DBInstanceReplicaLag OpcountersQuery OpcountersInsert OpcountersUpdate \
DocumentsReturned LowMemNumOperationsThrottled TransactionsOpen"
printf '%-34s %16s %16s\n' METRICA MEDIA MAXIMO
for M in $METRICS; do
aws cloudwatch get-metric-statistics --region "$REGION" --namespace AWS/DocDB \
--metric-name "$M" \
--dimensions Name=DBInstanceIdentifier,Value="$INST" \
--start-time "$START" --end-time "$END" --period 300 \
--statistics Average Maximum --query 'Datapoints[].[Average,Maximum]' --output text |
awk -v m="$M" '{ s+=$1; n++; if ($2>mx || n==1) mx=$2 }
END { if (n) printf "%-34s %16.2f %16.2f\n", m, s/n, mx;
else printf "%-34s %16s %16s\n", m, "-", "-" }'
done
FreeableMemory sai em bytes e as latências em segundos. Compare writer e reader rodando o script uma vez para cada instância.Script que descobre as instâncias do cluster (writer e readers) e gera um CSV com média e máximo das métricas no período, usando get_metric_data.
#!/usr/bin/env python3
"""Uso: python docdb_report.py NOME_DO_CLUSTER [HORAS] > relatorio.csv"""
import csv
import datetime as dt
import sys
import boto3
cluster = sys.argv[1]
hours = int(sys.argv[2]) if len(sys.argv) > 2 else 3
docdb = boto3.client("docdb")
cw = boto3.client("cloudwatch")
METRICS = [
"CPUUtilization", "FreeableMemory", "SwapUsage", "BufferCacheHitRatio", "DatabaseConnections", "DatabaseCursors",
"ReadLatency", "WriteLatency", "ReadIOPS", "WriteIOPS", "DiskQueueDepth", "DBInstanceReplicaLag",
"OpcountersQuery", "OpcountersInsert", "OpcountersUpdate", "LowMemNumOperationsThrottled",
]
end = dt.datetime.now(dt.timezone.utc)
start = end - dt.timedelta(hours=hours)
members = docdb.describe_db_clusters(DBClusterIdentifier=cluster)["DBClusters"][0]["DBClusterMembers"]
out = csv.writer(sys.stdout)
out.writerow(["instancia", "papel", "metrica", "media", "maximo"])
for m in members:
inst = m["DBInstanceIdentifier"]
role = "writer" if m["IsClusterWriter"] else "reader"
queries = []
for i, name in enumerate(METRICS):
for stat in ("Average", "Maximum"):
queries.append({
"Id": f"m{i}_{stat[:3].lower()}",
"MetricStat": {
"Metric": {
"Namespace": "AWS/DocDB",
"MetricName": name,
"Dimensions": [{"Name": "DBInstanceIdentifier", "Value": inst}],
},
"Period": 300,
"Stat": stat,
},
})
values = {}
pages = cw.get_paginator("get_metric_data").paginate(
MetricDataQueries=queries, StartTime=start, EndTime=end
)
for page in pages:
for r in page["MetricDataResults"]:
values.setdefault(r["Id"], []).extend(r["Values"])
for i, name in enumerate(METRICS):
avg = values.get(f"m{i}_ave", [])
mx = values.get(f"m{i}_max", [])
out.writerow([
inst, role, name,
round(sum(avg) / len(avg), 2) if avg else "",
round(max(mx), 2) if mx else "",
])
Script JavaScript para o mongosh que reúne em uma execução: versão do motor, operações lentas ou bloqueadas, cursors e, por coleção, tamanho, espaço não usado, scans sem índice e hit ratio de cache. Rode uma vez em cada instância (writer e readers).
// mongosh "mongodb://USUARIO@INSTANCIA:27017/?tls=true&tlsCAFile=global-bundle.pem&directConnection=true" --quiet --file docdb-health.js
const SLOW_SECS = 10;
const admin = db.getSiblingDB("admin");
print("== Versão do motor ==");
printjson(admin.runCommand({ getEngineVersion: 1 }));
print("\n== Operações lentas ou bloqueadas (> " + SLOW_SECS + "s ou WaitState) ==");
const ops = admin.adminCommand({
aggregate: 1,
pipeline: [
{ $currentOp: { allUsers: true, idleConnections: false } },
{ $match: { $or: [ { secs_running: { $gt: SLOW_SECS } }, { WaitState: { $exists: true } } ] } },
{ $project: { _id: 0, opid: 1, ns: 1, secs_running: 1, WaitState: 1, blockedOn: 1 } }
],
cursor: {}
}).cursor.firstBatch;
print(ops.length ? tojson(ops) : "nenhuma");
print("\n== Cursors abertos ==");
printjson(admin.runCommand("listCursors"));
print("\n== Coleções (maiores primeiro) ==");
const rows = [];
admin.adminCommand({ listDatabases: 1 }).databases.forEach(function (d) {
if (["admin", "local", "config"].includes(d.name)) return;
const dbh = db.getSiblingDB(d.name);
dbh.getCollectionInfos({ type: "collection" }).forEach(function (c) {
const s = dbh.runCommand({ collStats: c.name });
if (!s.ok) return;
rows.push({
ns: d.name + "." + c.name,
docs: s.count,
sizeMB: +(s.size / 1048576).toFixed(1),
storageMB: +(s.storageSize / 1048576).toFixed(1),
unusedPct: s.unusedStorageSize ? s.unusedStorageSize.unusedPercent : null,
idxMB: +(s.totalIndexSize / 1048576).toFixed(1),
collScans: s.collScans, idxScans: s.idxScans,
collHit: s.cacheStats ? s.cacheStats.collHitRatio : null,
idxHit: s.cacheStats ? s.cacheStats.idxHitRatio : null
});
});
});
rows.sort(function (a, b) { return b.storageMB - a.storageMB; });
rows.slice(0, 25).forEach(function (r) { printjson(r); });
print("\n== Atenção ==");
rows.forEach(function (r) {
if (r.unusedPct !== null && r.unusedPct > 30) print("bloat > 30%: " + r.ns + " (" + r.unusedPct + "%)");
if (r.collScans > 0 && r.idxScans === 0) print("só COLLSCAN: " + r.ns);
if (r.collHit !== null && r.collHit < 90) print("cache hit baixo: " + r.ns + " (" + r.collHit + "%)");
});
collStats varre metadados de todas as coleções; em clusters com muitas coleções, filtre por banco. Contadores de scans e de cache são zerados a cada reinício ou mudança de instância.Veja também as ferramentas do repositório awslabs/amazon-documentdb-tools: compat-tool (procura operadores não suportados em logs ou código), index-tool (migra só os índices) e performance (incluindo o prism, análise de clusters e coleções).
- Defina o sintoma e a janela de tempo (lento sempre? só em um horário? após um deploy?).
- Métricas: CPU, FreeableMemory, BufferCacheHitRatio, conexões, latências, IOPS, lag. Compare com a baseline e com writer vs reader.
- Performance Insights: o DBLoad passou de Max vCPU? Qual espera domina (CPU, IO, Latch, locks)? Qual consulta, host e aplicação?
- Profiler (Logs Insights): ranking por
nseop; filtreCOLLSCANe as maioresmillis. - mongosh:
explaindas consultas campeãs,$indexStatsecollStatsdas coleções envolvidas,currentOppara bloqueios. - Ação: índice faltante, reescrita de consulta,
$matchno início do pipeline, distribuir leitura em réplicas, encurtar transações, fechar cursors, ajustar pool de conexões, e só então escalar instância. - Valide: repita as métricas e o profiler depois da mudança e registre o resultado.
| Sintoma dominante | Provável causa | Primeira ação |
|---|---|---|
| CPU alta, espera CPU | Consultas sem índice, agregações pesadas, concorrência alta | Achar COLLSCAN; criar índice; usar réplicas; escalar |
| Espera IO/Latch, BufferCacheHitRatio baixo | Working set maior que a memória | Revisar índices; instância com mais RAM; separar análises em réplica |
| Espera DocumentLock | Muitas escritas no mesmo documento | Reestruturar modelo (evitar hot document) |
| LowMemThrottle / FreeableMemory baixo | Pressão de memória, batches concorrentes grandes | Escalar; reduzir concorrência de batch |
| Replica lag alto | Escrita em massa ou réplica subdimensionada | Agendar cargas; instância maior; checar cursors longos |
| Conexões no limite | Pool grande demais, muitos clientes | Reduzir maxPoolSize; proxy/pooling; instância maior |
Troubleshooting
Sintomas comuns, causas prováveis, diagnóstico e correção
| Causa provável | Como confirmar | Correção |
|---|---|---|
| Conectando da internet ou do laptop (não há endpoint público) | O cluster está em subnets privadas; o IP resolvido é privado | Túnel SSH por EC2 na VPC, VPN, Direct Connect ou peering |
| Outra região | Compare a região do endpoint com a da EC2 | Mesma região ou conectividade entre regiões via peering/Transit Gateway |
| Outra VPC sem peering | VpcId do cluster diferente do da EC2 | VPC peering ou Transit Gateway e rotas |
| Security group bloqueia a porta | Regras de entrada do security group do cluster | Liberar a porta (27017) para o SG/CIDR da aplicação |
| Endpoint digitado errado | Erro de getaddrinfo / host desconhecido | Copiar o endpoint correto do console ou da CLI |
# Teste de porta a partir da máquina que conecta nc -zv meu-cluster.cluster-xxxx.us-east-1.docdb.amazonaws.com 27017 # Endpoint e porta corretos aws docdb describe-db-clusters --db-cluster-identifier meu-cluster --query 'DBClusters[*].[Endpoint,ReaderEndpoint,Port]' # VPC e security groups aws docdb describe-db-clusters --db-cluster-identifier meu-cluster --query 'DBClusters[*].[VpcSecurityGroups[*].VpcSecurityGroupId]'
- Falha de handshake/CA desconhecida: use o
global-bundle.pematual e confira que o driver aponta para ele (tlsCAFile). - Cliente antigo na 8.0 ou na 5.0.1+: só TLS 1.2 ou superior é aceito; atualize driver/runtime. TLS 1.0 e 1.1 falham.
- Cluster com
tls=disablede cliente exigindo TLS (ou o inverso): alinhe o parâmetrotlse a connection string; mudança exige reboot. - Authentication failed: confira
authSource(normalmenteadmin), senha com caracteres especiais (faça URL-encode) e mecanismo SCRAM. - IAM:
authSource=%24externaleauthMechanism=MONGODB-AWS; no Python instalepymongo[aws]; no Node.js use driver 6.13.1+; lembre que o usuário primário não usa IAM. Limite de requisições ao STS pode causar throttling: reduza a taxa de novas conexões.
# Validar o handshake TLS openssl s_client -connect meu-cluster.cluster-xxxx.us-east-1.docdb.amazonaws.com:27017 -CAfile global-bundle.pem -brief </dev/null
- Causa comum: conexão direta a uma instância (instance endpoint) ou modo single do driver; após failover o nó deixa de ser primário.
- Correção: conecte no cluster endpoint com
replicaSet=rs0; não fixe instance endpoints em produção. - Leitura não vai para réplicas: falta
readPreference=secondaryPreferredou a conexão não está em modo replica set. - Java driver 3.7.x: com
applyToClusterSettingse um único host, o modo vira SINGLE e ignora read preference. Use connection string comreplicaSetou forceClusterConnectionMode.MULTIPLE. - Reconexão: implemente retry com backoff exponencial para erros transitórios; o DNS do cluster endpoint pode levar alguns segundos para refletir o failover.
- Confirme em CPUUtilization (por instância). Só o writer? Só um reader? Todos?
- No Performance Insights, veja a consulta e a espera dominantes.
- No mongosh, liste operações longas e a visão agregada de
currentOp; procureCOLLSCANcomexplain. - Verifique
BufferCacheHitRatio: leitura de disco também pressiona a CPU.
| Situação | Ação |
|---|---|
| Primário alto, réplicas baixas | Distribuir leitura com secondaryPreferred |
| Causa é carga de escrita | Instância maior (mais vCPU); batch (insertMany/updateMany); revisar índices em excesso |
| Todas as instâncias altas com leitura em réplicas | Adicionar réplicas (até 15) e otimizar consultas |
| Picos por job/análise | Mover para uma réplica dedicada (instance endpoint) ou horário de baixa |
| Após upgrade major | Aguardar o refresh de metadados de índice (até algumas horas) antes de escalar |
Quando a instância sofre pressão de memória, o resource governor do DocumentDB estrangula requisições para proteger processos críticos. Operações podem ficar em fila e até expirar.
- Sinais:
FreeableMemoryabaixo de 10%,SwapUsageacima de zero,LowMemThrottleQueueDeptheLowMemNumOperationsThrottledcrescendo, esperaLowMemThrottleno Performance Insights. - Causas: instância pequena para o working set, muitos cursors abertos, batches concorrentes de insert/update, agregações grandes, índices em excesso.
- Ações: escalar a classe; reduzir concorrência de batch; fechar cursors; revisar/remover índices; em serverless, subir MinCapacity/MaxCapacity.
- Habilite o profiler com limiar alto e vá reduzindo.
- No Logs Insights, filtre
planSummary = "COLLSCAN"e ordene pormillis. - No mongosh, rode
explainda consulta e crie o índice no campo do filtro (combackground: true). - Confirme com
explain(IXSCAN) e com a queda decollScansemstats().
- Consulta usa índice mas continua lenta: seletividade baixa ou muitos documentos retornados; use projeção e
limit. - O otimizador escolhe COLLSCAN mesmo havendo índice: comum em coleções pequenas; teste com
hint(). - Pipeline lento:
$matchno início, índice no campo de$lookup, e na 8.0 valide o plano do planner v3. - Ordenação grande sem índice: crie índice cobrindo o
sort.
Rode o currentOp filtrando por WaitState. A origem do bloqueio aparece em blockedOn (um opid ou INTERNAL).
| WaitState | Interpretação | Ação |
|---|---|---|
| CollectionLock | DDL na coleção (criação de índice em foreground, drop, rename) | Aguardar ou reprogramar DDL; criar índices em background |
| DocumentLock | Escritas concorrentes no mesmo documento | Ajustar modelo; evitar contadores em um único documento |
| BufferLock | Cursors ou transações segurando páginas | Fechar cursors; encurtar transações |
| SystemLock / Latch | Consultas longas, alta concorrência ou paginação do buffer | Achar e tratar consultas longas; mais memória |
| BackgroundActivity / Other | Processo interno (GC, manutenção) | Se persistir, killOp na consulta afetada e repetir depois |
db.adminCommand({ killOp: 1, op: 24646 }) // opid obtido no currentOp
- Limites rígidos por classe (ex.: 3.400 conexões em uma
large); acompanheDatabaseConnectionscontraDatabaseConnectionsLimit. - maxPoolSize: o total de conexões é (instâncias da aplicação) x (maxPoolSize) x (nós do replica set). Reduza o pool ou use um proxy/serviço compartilhado.
- Funções Lambda: crie o cliente fora do handler e reaproveite; limite a concorrência.
- Cursors: há cota por instância (ex.: 450 em uma
large); feche cursors, não deixe iteradores abertos e use batch size adequado. Cursors ociosos consomem memória; liste comlistCursors. - Contagem diferente: o
serverStatuspode mostrar até 10 conexões a mais que o CloudWatch (health checks internos).
db.runCommand("listCursors")
// Conexões por origem
db.adminCommand({ aggregate: 1, pipeline: [{ $currentOp: { allUsers: true, idleConnections: true } },
{ $group: { _id: "$client", n: { $sum: 1 } } }, { $sort: { n: -1 } }, { $limit: 10 }], cursor: {} })
- Normal: lag típico inferior a 100 ms; picos durante escrita intensa.
- Causas: escrita em massa (migração, backfill), réplica menor que o primário, consultas longas ou cursors abertos na réplica, pressão de memória.
- Diagnóstico:
DBInstanceReplicaLagpor instância eDBClusterReplicaLagMaximum; compare CPU eBufferCacheHitRatioda réplica. - Correção: réplicas da mesma classe do primário; espalhar cargas em lotes menores; mover análises pesadas para uma réplica dedicada; em serverless, subir a capacidade mínima dos readers.
- Aplicação: leituras que exigem read-after-write devem ir ao primário (
primary).
O DocumentDB usa MVCC: cada atualização cria uma nova versão, e o garbage collection remove as antigas e recicla os MVCC IDs (contador finito de 1,8 bilhão). Se o GC não acompanha, o cluster desperdiça espaço e, no limite, entra em modo somente leitura até os IDs serem reciclados.
| Sinal | Onde ver | Referência |
|---|---|---|
| AvailableMVCCIds baixo | CloudWatch (cluster) | Alarme: < 900 milhões (5.0+) ou < 1,3 bilhão (3.6/4.0); saudável acima de 1,5 bilhão |
| LongestActiveGCRuntime alto | CloudWatch | Compare com gcRuntimeStats |
| MVCCIdScale alto na coleção | collStats | Manter abaixo de 0,3 |
| unusedStorageSize / deadDocFragmentsPercent | collStats | Bloat; atenção acima de 10 a 15% de fragmentos mortos |
O que fazer
- Escalar a instância dá mais recursos ao GC enquanto a aplicação segue operando.
- Reduzir escritas nas coleções com MVCCIdScale alto; agrupe em batch (
insertMany/updateManyusam menos MVCC IDs). - Eliminar transações longas e cursors abertos: eles fixam o horizonte de limpeza.
- Não é possível forçar o GC manualmente.
- Bloat: o espaço só volta recarregando a coleção (dump/restore ou migração com switchover); para índices use
reIndex. - Evite apagar muito de uma vez e prefira rolling collections (drop) a deletes em massa.
db.runCommand({ collStats: "pedidos" })
// Veja: MVCCIdStats.MVCCIdScale, gcRuntimeStats, documentFragmentStats, unusedStorageSize
- Foreground bloqueia escritas: sempre use
{ background: true }em produção. - Tempo: depende do tamanho da coleção, da classe e da carga concorrente; crie índices fora do pico e acompanhe no
currentOp. - Migração: crie os índices antes de importar dados (index-tool).
- Limites: 64 índices por coleção, 32 chaves por índice composto, chave de até 2.048 bytes.
- Vetorial: o build HNSW paralelo existe na 8.0 (até 30x mais rápido); na 5.0 o build é serial.
db.pedidos.createIndex({ clienteId: 1, criadoEm: -1 }, { background: true })
// Acompanhar
db.adminCommand({ aggregate: 1, pipeline: [{ $currentOp: { allUsers: true } },
{ $match: { "command.createIndexes": { $exists: true } } }], cursor: {} })
| Problema | Causa | Solução |
|---|---|---|
| Pré-check falhou: nome de coleção com 58+ caracteres | Limite de nome em versões anteriores | Renomear a coleção e repetir |
| Pré-check falhou: contagem de índices | Limite por tipo de instância (ex.: 3 mil em t4g.medium, 10 mil em t3.medium) | Escalar a instância e repetir |
| Falha na 5.0 para 8.0 | Índice parcial com $type em tipos não suportados | Remover o índice, atualizar, recriar |
| Upgrade falhou e fez rollback | Evento "cluster is in a state that cannot be upgraded" | Cluster volta ao estado anterior; abrir chamado antes de repetir |
| CPU alta e consultas lentas após o upgrade | Refresh de metadados de índice em andamento (até ~2 h) | Aguardar o evento de conclusão; sem reboot/failover/scale; abrir chamado se passar de 3 h |
| Comportamento de consulta diferente | Diferenças funcionais entre versões | Revisar lista de diferenças da versão de destino e testar |
| Tema | Sintoma | Causa e solução |
|---|---|---|
| Change streams | Não chegam eventos | Habilite com modifyChangeStreams na coleção/banco; confira $listChangeStreams |
| Change streams | Resume falha ou fica lento | Token fora da retenção (padrão 3 h): aumente change_stream_log_retention_duration; prefira postBatchResumeToken |
| Change streams | Erro de leitura com evento grande | Evento acima de 16 MB: $changeStreamSplitLargeEvent (8.0.2+) ou reduza o documento |
| Change streams | Réplica atrasa | Monitore DBInstanceReplicaLag e o cache hit da réplica |
| TTL | Documentos não somem no horário | Best effort: depende de carga e tamanho; verifique ttl_monitor e TTLDeletedDocuments |
| TTL | Pico de I/O e custo | Muitas remoções de uma vez: apagar o expirado antes de criar o índice; considerar rolling collections |
| Serverless | Instância não desce até a capacidade mínima | Performance Insights, carga, volume grande ou readers em tier 0/1; ver tiers e reiniciar se necessário |
| Serverless | Status incompatible-parameters | Reinícios por falta de memória: subir MinCapacity/MaxCapacity ou reduzir a carga |
- Identificadores: cluster, instância(s), região, versão do motor (
getEngineVersion) e versão do driver. - Janela de tempo (UTC) do problema e se há evento no console (failover, manutenção, upgrade).
- Gráficos das métricas do período (CPU, memória, conexões, latência, lag) e, se habilitado, do Performance Insights.
- Consultas envolvidas (do profiler) com
explainecollStatsdas coleções. - O que já foi tentado e o efeito observado.
incompatible-parameters persistente, AvailableMVCCIds caindo mesmo após escalar, e falhas de pré-check que você não consegue explicar.Referência
Quotas, comandos de CLI e links oficiais
| Recurso | Quota padrão (por conta/região) |
|---|---|
| Clusters | 40 |
| Instâncias | 40 |
| Réplicas por cluster | 15 |
| Parameter groups do cluster | 50 |
| Snapshots manuais | 100 |
| Subnet groups | 50 |
| Subnets por subnet group | 20 |
| Assinaturas de eventos | 20 |
| Tags por recurso | 50 |
| Security groups por instância | 5 |
| Usuários por cluster | 1.000 |
| Elastic clusters / vCPU somados | 20 / 1.024 |
| Snapshots manuais de elastic | 20 |
Várias quotas são ajustáveis pelo Service Quotas. Os limites por instância (conexões, cursors, transações) e por cluster/coleção estão nas seções de fundamentos e modelagem.
| Identificadores e nomes | Regra |
|---|---|
| Cluster/instância | 1 a 63 letras, números ou hífens; começa com letra; sem hífen no fim nem hífens consecutivos |
| Banco | 1 a 63 caracteres |
| Senha do usuário primário | 8 a 100 caracteres ASCII, exceto / " @ |
| Parameter group | 1 a 255 caracteres alfanuméricos |
| Tarefa | Comando |
|---|---|
| Listar clusters | aws docdb describe-db-clusters |
| Listar instâncias | aws docdb describe-db-instances |
| Versões de motor disponíveis | aws docdb describe-db-engine-versions --engine docdb |
| Criar cluster | aws docdb create-db-cluster --engine docdb --engine-version 8.0.0 ... |
| Adicionar instância | aws docdb create-db-instance --db-instance-class db.r6g.large --engine docdb --db-cluster-identifier ... |
| Alterar classe da instância | aws docdb modify-db-instance --db-instance-identifier ... --db-instance-class ... --apply-immediately |
| Reboot / failover | aws docdb reboot-db-instance / aws docdb failover-db-cluster |
| Parar / iniciar cluster | aws docdb stop-db-cluster / aws docdb start-db-cluster |
| Snapshot manual | aws docdb create-db-cluster-snapshot |
| Restaurar (snapshot / PITR) | aws docdb restore-db-cluster-from-snapshot / restore-db-cluster-to-point-in-time |
| Upgrade major | aws docdb modify-db-cluster --allow-major-version-upgrade --engine-version ... |
| Parâmetros | aws docdb modify-db-cluster-parameter-group / describe-db-cluster-parameters |
| Eventos | aws docdb describe-events --source-type db-cluster --source-identifier ... |
| Exportar logs | aws docdb modify-db-cluster --cloudwatch-logs-export-configuration ... |
| Clonar | aws docdb restore-db-cluster-to-point-in-time --restore-type copy-on-write ... |
aws docdb (o serviço compartilha tecnologia de gestão com o RDS, mas tem sua própria CLI).