TTL Indexes
Nesta página
Observação
Se você estiver removendo documentos para economizar nos custos de armazenamento, considere o Online Archive no MongoDB Atlas. O Online Archive arquiva automaticamente dados acessados com pouca frequência em buckets S3 totalmente gerenciados para uma divisão econômica dos dados em níveis.
Os índices TTL são índices especiais de campo único que o MongoDB pode usar para remover automaticamente documentos de uma collection após um determinado período de tempo ou em um horário específico. A expiração de dados é útil para determinados tipos de informações, como dados de eventos gerados por máquina, registros e informações de sessão, que só precisam persistir em um banco de dados por um período de tempo finito.
Você pode criar e gerenciar índices TTL na IU para implantações hospedadas no MongoDB Atlas.
Criar um Índice TTL
Aviso
Depois de criar um índice TTL, ele poderá ter um grande número de documentos qualificados para excluir de uma só vez. Essa grande carga de trabalho pode causar problemas de desempenho no servidor. Para evitar esses problemas, planeje criar o índice fora do horário comercial ou exclua documentos qualificados em lotes antes de criar o índice para documentos futuros.
Para criar um índice TTL, utilize createIndex()
. Especifique um campo de índice que seja um tipo de data ou um array que contenha valores de tipo de data. Use a opção expireAfterSeconds
para especificar um valor de TTL em segundos.
O valor expireAfterSeconds
do índice TTL deve estar dentro de 0
e 2147483647
inclusive.
Por exemplo, para criar um índice TTL no campo lastModifiedDate
da collection eventlog
com um valor TTL de 3600
segundos, use a seguinte operação em mongosh
:
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 } )
A partir do MongoDB 6.3, você pode criar índices TTL parciais em coleções de séries temporais. Esses índices usam a collection timeField
como campo chave e exigem uma expressão de filtro parcial em metaField
.
As coleções de séries temporais incluem um campo expireAfterSeconds
opcional. Se você não definir expireAfterSeconds
, um índice TTL com partialFilterExpression
permitirá definir um período de expiração para documentos que correspondem ao filtro. Se você definir expireAfterSeconds
, um índice TTL parcial permitirá que você defina um período de expiração diferente e mais curto para documentos correspondentes. Você só pode criar um partialFilterExpression
no metaField
.
Importante
Se o valor expireAfterSeconds
da collection for menor que expireAfterSeconds
do índice TTL parcial, a collection excluirá os documentos após o período mais curto, portanto o índice TTL não terá efeito.
Se uma coleção de séries temporais contiver documentos com timeField
registros de data e hora anteriores a 1970-01-01T00:00:00.000Z
ou posteriores a 2038-01-19T03:14:07.000Z
, nenhum documento será excluído da coleção pelo recurso TTL "time to live".
Esta coleção de séries temporais de dados climáticos exclui documentos após 24 horas:
db.createCollection( "weather24h", { timeseries: { timeField: "timestamp", metaField: "sensor", granularity: "hours" }, expireAfterSeconds: 86400 } )
Este índice TTL exclui documentos do sensor climático da sede do MongoDB NYC após 1 hora, em vez de 24 horas:
db.eventlog.createIndex( { "timestamp": 1 }, { partialFilterExpression: { "sensor": { $eq: "40.761873, -73.984287" } } }, { expireAfterSeconds: 3600 } )
Converter um índice de campo único não TTL em um índice TTL
A partir do MongoDB 5.1, você pode adicionar a opção expireAfterSeconds
a um índice de campo único existente. Para alterar um índice de campo único não TTL para um índice TTL, utilize o comando de banco de dados collMod
:
db.runCommand({ "collMod": <collName>, "index": { "keyPattern": <keyPattern>, "expireAfterSeconds": <number> } })
O exemplo a seguir converte um índice de campo único não TTL com o padrão { "lastModifiedDate": 1 }
em um índice TTL:
db.runCommand({ "collMod": "tickets", "index": { "keyPattern": { "lastModifiedDate": 1 }, "expireAfterSeconds": 100 } })
Altere o valor expireAfterSeconds
para um índice TTL
To change the expireAfterSeconds
value for a TTL Index, use the collMod
database command:
db.runCommand({ "collMod": <collName>, "index": { "keyPattern": <keyPattern>, "expireAfterSeconds": <number> } })
O exemplo a seguir altera o valor expireAfterSeconds
de um índice com o padrão { "lastModifiedDate": 1 }
na collection tickets
:
db.runCommand({ "collMod": "tickets", "index": { "keyPattern": { "lastModifiedDate": 1 }, "expireAfterSeconds": 100 } })
Importante
Considere o seguinte antes de atualizar o parâmetro expireAfterSeconds
de um índice TTL:
Alterar o parâmetro
expireAfterSeconds
não aciona uma reconstrução completa do índice. No entanto, reduzir o valor deexpireAfterSeconds
pode tornar muitos documentos elegíveis para exclusão imediata, potencialmente causando problemas de desempenho devido ao aumento das operações de exclusão.A abordagem recomendada é excluir manualmente os documentos em pequenos lotes antes de atualizar o índice TTL. Isso ajuda a controlar o impacto em seu cluster.
A exclusão de muitos documentos pode fragmentar os arquivos de armazenamento, afetando ainda mais o desempenho. Talvez seja necessário executar o comando compact em sua coleção ou realizar uma sincronização inicial para recuperar espaço e otimizar o armazenamento.
Comportamento
Expiração de dados
Os índices TTL expiram os documentos após o número especificado de segundos ter passado desde o valor do campo indexado. O limite de expiração é o valor do campo indexado mais o número especificado de segundos.
Se o campo for uma array e houver vários valores de data no índice, o MongoDB utilizará o mais baixo (mais antigo) valor de data na array para calcular o limite de expiração.
Para coleções de séries temporais, os índices TTL também removem um bucket de dados quando todos os documentos dentro dele expiram. Isso é igual ao limite superior do carimbo de data/hora do bucket, mais o valor expireAfterSeconds
. Por exemplo, se um bucket cobrir dados até 2023-03-27T18:29:59Z
e expireAfterSeconds
for 300, o índice TTL expirará o bucket após 2023-03-27T18:34:59Z
.
Se o campo indexado em um documento não contiver um ou mais valores de data, o documento não expirará.
Se um documento não contiver o campo indexado, ele não expirará.
Excluir operações
Um thread de background em mongod
lê os valores no índice e remove documentos expirados da collection.
As operações de exclusão em andamento executadas pelo thread TTL aparecem na saída db.currentOp()
. À medida que o thread TTL exclui documentos, a métrica de status do servidor metrics.ttl.deletedDocuments
é incrementada.
A partir do MongoDB 6.1:
Para melhorar a eficiência, o MongoDB pode agrupar várias exclusões de documentos em lote.
Os resultados
explain
do comando contêm um novoBATCHED_DELETE
estágio para exclusões de documentos em lote.
Se uma coleção de séries temporais contiver documentos com timeField
registros de data e hora anteriores a 1970-01-01T00:00:00.000Z
ou posteriores a 2038-01-19T03:14:07.000Z
, nenhum documento será excluído da coleção pelo recurso TTL "time to live".
Processo de exclusão
O processo de exclusão em segundo plano do TTL verifica se há documentos expirados em cada índice TTL. Para cada índice TTL, o processo em segundo plano exclui documentos até que uma das seguintes condições seja atendida:
O processo exclui 50000 documentos do índice atual.
O processo gasta um segundo para excluir documentos do índice atual.
Todos os documentos expirados são excluídos do índice atual.
Em seguida, o processo passa para o próximo índice. Depois que o processo passar por cada índice TTL uma vez, o subpass atual será concluído e um novo subpass é começado para verificar os documentos expirados restantes. Uma passagem estará concluída quando o monitor TTL tiver excluído todos os possíveis documentos candidatos de todos os índices TTL.
Além disso, o processo interrompe o ciclo de exclusão atual a cada 60 segundos para evitar a perda de muito tempo com uma única exclusão grande. Quando isso acontecer, o subpasse atual termina, e um novo subpasse começa.
Passes e subpasses são rastreados nas métricas de status do servidormetrics.ttl.passes
e metrics.ttl.subPasses
, respectivamente.
Tempo da operação de exclusão
O MongoDB começa a remover documentos expirados ou buckets de séries temporais assim que o índice termina de ser construído no primary. Para obter mais informações sobre o processo de construção de índices, consulte Construções de índices em coleções preenchidas.
O índice TTL não garante que os dados expirados sejam excluídos imediatamente após a expiração. Pode haver um atraso entre o momento em que um documento expira e o momento em que o MongoDB remove o documento do banco de dados.
A tarefa no background que remove documentos expirados é executada a cada 60 segundos. Como resultado, os documentos podem permanecer numa collection durante o período entre a expiração do documento e a execução da tarefa no background. O MongoDB começa a excluir documentos de 0 a 60 segundos após a conclusão do índice.
Como a duração da operação de remoção depende do volume de trabalho da sua instância mongod
, os dados expirados podem existir por algum tempo além do período de 60 segundos entre as execuções da tarefa no background.
As operações de exclusão iniciadas pela tarefa TTL são executadas em primeiro plano, como outras exclusões.
Conjuntos de réplicas
Nos membros do conjunto de réplicas, o thread TTL no background exclui documentos apenas quando um membro está no estado primary. O thread TTL no background fica ocioso quando um membro está no estado secundário. Os membros secundários replicam as operações de exclusão do primary.
Suporte para queries
Um índice TTL suporta queries da mesma forma que os índices não TTL.
mongod no modo autônomo
O monitor TTL é interrompido quando mongod
é executado no modo autônomo, e a coleção system.local.replset
contém dados. Se você retirar um nó do conjunto de réplicas do conjunto de réplicas e executá-lo como independente, o monitor TTL será desativado.
Restrições
Os índices TTL são índices de campo único. Índices compostos não suportam TTL e ignoram a opção
expireAfterSeconds
.O campo
_id
não suporta índices TTL.A partir do MongoDB 7.0, você pode criar um índice TTL parcial em
metaField
de uma coleção de séries temporais. Nas versões anteriores do MongoDB, você só pode criar um índice TTL paratimeField
de uma coleção de séries temporais.Você não pode usar
createIndex()
para alterar o valor deexpireAfterSeconds
de um índice existente. Em vez disso, use o comando de banco de dadoscollMod
. Para obter detalhes, consulte Alterar o valorexpireAfterSeconds
para um índice TTL.Se já existir um índice de campo único não TTL para um campo, você não poderá criar um índice TTL no mesmo campo, pois não poderá criar índices que tenham a mesma especificação de chave e difiram apenas pelas opções. Para alterar um índice de campo único não TTL para um índice TTL, utilize o comando de banco de dados
collMod
.