diff options
author | Benety Goh <benety@mongodb.com> | 2022-08-27 07:59:58 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-31 12:12:05 +0000 |
commit | daaff3b1445848a645e2ab883d6836b37ffc8a83 (patch) | |
tree | c352252478b2112356739fb6c3fb0286e490644f | |
parent | 0c4e155bf4652a629658758e0869b3c22ad597cf (diff) | |
download | mongo-daaff3b1445848a645e2ab883d6836b37ffc8a83.tar.gz |
SERVER-68477 TTL monitor skips indexes with NaN expireAfterSeconds
(cherry-picked from commit 14c07b53186ee88497abd0ba492d2d9157891718)
(cherry picked from commit 7d76329f8915ec80ba07c07e4a0adbc7fd187107)
-rw-r--r-- | jstests/noPassthrough/ttl_expire_nan.js | 45 | ||||
-rw-r--r-- | src/mongo/db/ttl.cpp | 15 |
2 files changed, 54 insertions, 6 deletions
diff --git a/jstests/noPassthrough/ttl_expire_nan.js b/jstests/noPassthrough/ttl_expire_nan.js new file mode 100644 index 00000000000..5d26b214487 --- /dev/null +++ b/jstests/noPassthrough/ttl_expire_nan.js @@ -0,0 +1,45 @@ +/** + * Tests TTL indexes with NaN for 'expireAfterSeconds'. + * + * Existing TTL indexes from older versions of the server may contain a NaN for the duration. + * Newer server versions (5.0+) normalize the TTL duration to 0. + * + * @tags: [ + * requires_replication, + * ] + */ +(function() { +'use strict'; + +const rst = new ReplSetTest({ + nodes: [{}, {rsConfig: {votes: 0, priority: 0}}], + nodeOptions: {setParameter: {ttlMonitorSleepSecs: 5}}, +}); +rst.startSet(); +rst.initiate(); + +let primary = rst.getPrimary(); +const db = primary.getDB('test'); +const coll = db.t; + +assert.commandWorked(coll.createIndex({t: 1}, {expireAfterSeconds: NaN})); +assert.commandWorked(coll.insert({_id: 0, t: ISODate()})); + +// Wait for "TTL indexes require the expire field to be numeric, skipping TTL job" log message. +checkLog.containsJson(primary, 22542, {ns: coll.getFullName()}); + +// TTL index should be replicated to the secondary with a NaN 'expireAfterSeconds'. +const secondary = rst.getSecondary(); +checkLog.containsJson(secondary, 20384, { + namespace: coll.getFullName(), + properties: (spec) => { + jsTestLog('TTL index on secondary: ' + tojson(spec)); + return isNaN(spec.expireAfterSeconds); + } +}); + +assert.eq( + coll.countDocuments({}), 1, 'ttl index with NaN duration should not remove any documents.'); + +rst.stopSet(); +})(); diff --git a/src/mongo/db/ttl.cpp b/src/mongo/db/ttl.cpp index bc76b345f40..8da9e1ee46a 100644 --- a/src/mongo/db/ttl.cpp +++ b/src/mongo/db/ttl.cpp @@ -175,12 +175,15 @@ const IndexDescriptor* getValidTTLIndex(OperationContext* opCtx, } BSONElement secondsExpireElt = spec[IndexDescriptor::kExpireAfterSecondsFieldName]; - if (!secondsExpireElt.isNumber()) { - LOGV2_ERROR(22542, - "TTL indexes require the expire field to be numeric, skipping TTL job", - "field"_attr = IndexDescriptor::kExpireAfterSecondsFieldName, - "type"_attr = typeName(secondsExpireElt.type()), - "index"_attr = spec); + if (!secondsExpireElt.isNumber() || secondsExpireElt.isNaN()) { + 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(), + "field"_attr = IndexDescriptor::kExpireAfterSecondsFieldName, + "type"_attr = typeName(secondsExpireElt.type()), + "index"_attr = spec); return nullptr; } return desc; |