diff options
Diffstat (limited to 'src/mongo/db/ttl.cpp')
| -rw-r--r-- | src/mongo/db/ttl.cpp | 167 |
1 files changed, 17 insertions, 150 deletions
diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp index dd89ea3e866..ee9b801882a 100644 --- a/src/mongo/db/ttl.cpp +++ b/src/mongo/db/ttl.cpp @@ -36,12 +36,10 @@ #include "mongo/base/counter.h" #include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/user_name.h" -#include "mongo/db/catalog/coll_mod.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/index_catalog.h" -#include "mongo/db/catalog/index_key_validate.h" #include "mongo/db/client.h" #include "mongo/db/commands/fsync_locked.h" #include "mongo/db/commands/server_status_metric.h" @@ -53,7 +51,6 @@ #include "mongo/db/ops/insert.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/record_id_helpers.h" -#include "mongo/db/repl/replica_set_aware_service.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/repl/tenant_migration_access_blocker_registry.h" #include "mongo/db/s/operation_sharding_state.h" @@ -65,7 +62,6 @@ #include "mongo/db/ttl_gen.h" #include "mongo/logv2/log.h" #include "mongo/s/grid.h" -#include "mongo/stdx/thread.h" #include "mongo/util/background.h" #include "mongo/util/concurrency/idle_thread_block.h" #include "mongo/util/log_with_sampling.h" @@ -179,11 +175,6 @@ public: LOGV2(3684101, "Finished shutting down TTL collection monitor thread"); } - /** - * Invoked when the node enters the primary state. - */ - void onStepUp(); - private: /** * Gets all TTL specifications for every collection and deletes expired documents. @@ -220,11 +211,7 @@ private: // The collection was dropped. auto nss = collectionCatalog->lookupNSSByUUID(opCtx, uuid); if (!nss) { - if (info.isClustered()) { - ttlCollectionCache.deregisterTTLClusteredIndex(uuid); - } else { - ttlCollectionCache.deregisterTTLIndexByName(uuid, info.getIndexName()); - } + ttlCollectionCache.deregisterTTLInfo(uuid, info); continue; } @@ -338,18 +325,18 @@ private: return; } - if (coll->getRequiresTimeseriesExtendedRangeSupport()) { - return; - } - ResourceConsumption::ScopedMetricsCollector scopedMetrics(opCtx, nss.db().toString()); const auto& collection = coll.getCollection(); - if (info.isClustered()) { - deleteExpiredWithCollscan(opCtx, ttlCollectionCache, collection); - } else { - deleteExpiredWithIndex(opCtx, ttlCollectionCache, collection, info.getIndexName()); - } + stdx::visit( + visit_helper::Overloaded{ + [&](const TTLCollectionCache::ClusteredId&) { + deleteExpiredWithCollscan(opCtx, ttlCollectionCache, collection); + }, + [&](const TTLCollectionCache::IndexName& indexName) { + deleteExpiredWithIndex(opCtx, ttlCollectionCache, collection, indexName); + }}, + info); } /** @@ -382,13 +369,13 @@ private: const CollectionPtr& collection, std::string indexName) { if (!collection->isIndexPresent(indexName)) { - ttlCollectionCache->deregisterTTLIndexByName(collection->uuid(), indexName); + ttlCollectionCache->deregisterTTLInfo(collection->uuid(), indexName); return; } BSONObj spec = collection->getIndexSpec(indexName); if (!spec.hasField(IndexDescriptor::kExpireAfterSecondsFieldName)) { - ttlCollectionCache->deregisterTTLIndexByName(collection->uuid(), indexName); + ttlCollectionCache->deregisterTTLInfo(collection->uuid(), indexName); return; } @@ -426,12 +413,9 @@ private: } BSONElement secondsExpireElt = spec[IndexDescriptor::kExpireAfterSecondsFieldName]; - if (!secondsExpireElt.isNumber() || secondsExpireElt.isNaN()) { + if (!secondsExpireElt.isNumber()) { LOGV2_ERROR(22542, - "TTL indexes require the expire field to be numeric and not a NaN, " - "skipping TTL job", - "ns"_attr = collection->ns(), - "uuid"_attr = collection->uuid(), + "TTL indexes require the expire field to be numeric, skipping TTL job", "field"_attr = IndexDescriptor::kExpireAfterSecondsFieldName, "type"_attr = typeName(secondsExpireElt.type()), "index"_attr = spec); @@ -541,14 +525,15 @@ private: auto expireAfterSeconds = collOptions.expireAfterSeconds; if (!expireAfterSeconds) { - ttlCollectionCache->deregisterTTLClusteredIndex(collection->uuid()); + ttlCollectionCache->deregisterTTLInfo(collection->uuid(), + TTLCollectionCache::ClusteredId{}); return; } LOGV2_DEBUG( 5400704, 1, "running TTL job for clustered collection", logAttrs(collection->ns())); - const auto startId = makeCollScanStartBound(collection, Date_t{}); + const auto startId = makeCollScanStartBound(collection, Date_t::min()); const auto expirationDate = safeExpirationDate(opCtx, collection, *expireAfterSeconds); const auto endId = makeCollScanEndBound(collection, expirationDate); @@ -616,122 +601,4 @@ void shutdownTTLMonitor(ServiceContext* serviceContext) { } } -void TTLMonitor::onStepUp() { - stdx::thread([]() mutable { - ThreadClient tc("InvalidTTLIndexFixer", getGlobalServiceContext()); - AuthorizationSession::get(cc())->grantInternalAuthorization(&cc()); - const auto opCtxCtr = cc().makeOperationContext(); - auto opCtx = opCtxCtr.get(); - auto&& ttlCollectionCache = TTLCollectionCache::get(opCtx->getServiceContext()); - auto ttlInfos = ttlCollectionCache.getTTLInfos(); - for (const auto& [uuid, infos] : ttlInfos) { - auto collectionCatalog = CollectionCatalog::get(opCtx); - if (collectionCatalog->isCollectionAwaitingVisibility(uuid)) { - continue; - } - - // The collection was dropped. - auto nss = collectionCatalog->lookupNSSByUUID(opCtx, uuid); - if (!nss) { - continue; - } - - if (nss->isTemporaryReshardingCollection() || nss->isDropPendingNamespace()) { - continue; - } - - try { - uassertStatusOK(userAllowedWriteNS(opCtx, *nss)); - - for (const auto& info : infos) { - // Skip clustered indexes with TTL. This includes time-series collections. - if (info.isClustered()) { - continue; - } - if (!info.isExpireAfterSecondsNaN()) { - continue; - } - - auto indexName = info.getIndexName(); - LOGV2(6847700, - "Running collMod to fix TTL index with NaN 'expireAfterSeconds'.", - "ns"_attr = *nss, - "uuid"_attr = uuid, - "name"_attr = indexName, - "expireAfterSecondsNew"_attr = - index_key_validate::kExpireAfterSecondsForInactiveTTLIndex); - - // Compose collMod command to amend 'expireAfterSeconds' to same value that - // would be used by listIndexes() to convert the NaN value in the catalog. - CollModIndex collModIndex; - collModIndex.setName(StringData{indexName}); - collModIndex.setExpireAfterSeconds(mongo::durationCount<Seconds>( - index_key_validate::kExpireAfterSecondsForInactiveTTLIndex)); - CollMod collModCmd{*nss}; - collModCmd.getCollModRequest().setIndex(collModIndex); - - // processCollModCommand() will acquire MODE_X access to the collection. - BSONObjBuilder builder; - uassertStatusOK(processCollModCommand( - opCtx, {nss->db().toString(), uuid}, collModCmd, &builder)); - auto result = builder.obj(); - LOGV2( - 6847701, - "Successfully fixed TTL index with NaN 'expireAfterSeconds' using collMod", - "ns"_attr = *nss, - "uuid"_attr = uuid, - "name"_attr = indexName, - "result"_attr = result); - } - } catch (const DBException& ex) { - LOGV2_ERROR(6835901, - "Error checking TTL job on collection during step up", - logAttrs(*nss), - "error"_attr = ex); - continue; - } - } - }) - .detach(); -} - -namespace { - -/** - * Runs on primaries and secondaries. Forwards replica set events to the TTLMonitor. - */ -class TTLMonitorService : public ReplicaSetAwareService<TTLMonitorService> { -public: - static TTLMonitorService* get(ServiceContext* serviceContext); - TTLMonitorService() = default; - -private: - void onStartup(OperationContext* opCtx) override {} - void onInitialDataAvailable(OperationContext* opCtx, bool isMajorityDataAvailable) override {} - void onShutdown() override {} - void onStepUpBegin(OperationContext* opCtx, long long term) override {} - void onStepUpComplete(OperationContext* opCtx, long long term) override { - auto ttlMonitor = TTLMonitor::get(opCtx->getServiceContext()); - if (!ttlMonitor) { - // Some test fixtures might not install the TTLMonitor. - return; - } - ttlMonitor->onStepUp(); - } - void onStepDown() override {} - void onBecomeArbiter() override {} -}; - -const auto _ttlMonitorService = ServiceContext::declareDecoration<TTLMonitorService>(); - -const ReplicaSetAwareServiceRegistry::Registerer<TTLMonitorService> _ttlMonitorServiceRegisterer( - "TTLMonitorService"); - -// static -TTLMonitorService* TTLMonitorService::get(ServiceContext* serviceContext) { - return &_ttlMonitorService(serviceContext); -} - -} // namespace - } // namespace mongo |
