MCPcopy Create free account
hub / github.com/documentdb/documentdb / DeleteExpiredRowsForIndexCore

Function DeleteExpiredRowsForIndexCore

pg_documentdb/src/ttl/ttl_index.c:602–845  ·  view source on GitHub ↗

Deletes the rows that have expired for the given table name and ttl entry information. * It deletes the number of items specified on the batchSize that have expired based on the index entry expiry value. * If ttlMetricsContext is not NULL, records metrics via the RecordTtlMetric hook. */

Source from the content-addressed store, hash-verified

600 * It deletes the number of items specified on the batchSize that have expired based on the index entry expiry value.
601 * If ttlMetricsContext is not NULL, records metrics via the RecordTtlMetric hook. */
602static uint64
603DeleteExpiredRowsForIndexCore(char *tableName, TtlIndexEntry *indexEntry, int64
604 currentTime, int32 batchSize, instr_time startTime, int
605 budget, bool *isTaskTimeBudgetExceeded,
606 void *ttlMetricsContext)
607{
608 /* Per-batch timer for TTL deletion */
609 instr_time batchStart;
610 INSTR_TIME_SET_CURRENT(batchStart);
611
612 int32 defaultBatchSize = (SkipRepeatDeleteForUnOrderedIndex &&
613 !indexEntry->indexIsOrdered) ?
614 MaxTTLBatchSizeUnorderedIndex : MaxTTLDeleteBatchSize;
615 int32 ttlDeleteBatchSize = (batchSize != -1) ? batchSize :
616 defaultBatchSize;
617 pgbson *indexKeyDocument = DatumGetPgBson(indexEntry->indexKeyDatum);
618 pgbson *indexPfe = (indexEntry->indexPfeDatum != (Datum) 0) ?
619 DatumGetPgBson(indexEntry->indexPfeDatum) : NULL;
620
621 /* TTL expireAfterSeconds is an int32 but we cast it as int64 to avoid overflow in milliseconds calculation */
622 int64 indexExpiryMilliseconds = (int64) indexEntry->indexExpireAfterSeconds * 1000L;
623 bson_iter_t pathSpecIter;
624 PgbsonInitIterator(indexKeyDocument, &pathSpecIter);
625 bson_iter_next(&pathSpecIter);
626 const char *indexKey = bson_iter_key(&pathSpecIter);
627
628 /*
629 * Note that the TTL condition is repeated here, once for selecting a batch of records and once more while deleting.
630 * The reason is that the SELECT subquery won't lock the records for update, so by the time we DELETE them, the records
631 * could have been concurrently updated for them to come out of expiry window. Deleting those record won't be correct.
632 * Hence we repeat the expiry condition once again in the DELETE statement.
633 *
634 * As a side comment, we use the SELECT subquery to select a batch of records, because "DELETE" does not support LIMIT
635 * (it's a Postgres limitation).
636 *
637 * An index can have a partial filter expression (pfe) specified during creation which is also applicable for TTL index. We apply
638 * the pfe predicate while selecting and deleting the expired records.
639 */
640
641 StringInfo cmdStrDeleteRows = makeStringInfo();
642
643 /* optimization for unsharded collection to avoid 2PC */
644 appendStringInfo(cmdStrDeleteRows,
645 "DELETE FROM %s.%s"
646 " WHERE ctid IN (SELECT ctid FROM %s.%s"
647 " WHERE %s.bson_dollar_lt(document, $1::%s) ",
648 ApiDataSchemaName, tableName,
649 ApiDataSchemaName, tableName,
650 ApiCatalogSchemaName, FullBsonTypeName);
651
652 int argCount = 1;
653
654 /*
655 * In the SQL query above, we provide the corresponding TTL index as a hint for the TTL task query.
656 * Even though it's called a hint, by design it forces the use of the specified index.
657 *
658 * As an additional note IndexOnly scans are not allowed for retrieving ctids.
659 */

Callers 1

delete_expired_rowsFunction · 0.85

Calls 9

PgbsonInitIteratorFunction · 0.85
PgbsonWriterInitFunction · 0.85
PgbsonWriterAppendValueFunction · 0.85
PgbsonWriterGetPgbsonFunction · 0.85
CastPgbsonToByteaFunction · 0.85
SetGUCLocallyFunction · 0.85
IsTaskTimeBudgetExceededFunction · 0.85
RecordTtlMetricFunction · 0.85

Tested by

no test coverage detected