summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2022-08-04 01:59:59 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-04 02:38:05 +0000
commitbcf69685f033632e55780c36d64fb28574044f87 (patch)
treec84a9e39a30a20c09d32a12480949d6d15cb08ab
parent9f3fe4b1546b6b3ab09345905a3163f19771cc70 (diff)
downloadmongo-bcf69685f033632e55780c36d64fb28574044f87.tar.gz
SERVER-68359 TTL monitor skips indexes with NaN expireAfterSeconds
-rw-r--r--jstests/noPassthrough/ttl_expire_nan.js43
-rw-r--r--src/mongo/db/ttl.cpp9
2 files changed, 48 insertions, 4 deletions
diff --git a/jstests/noPassthrough/ttl_expire_nan.js b/jstests/noPassthrough/ttl_expire_nan.js
new file mode 100644
index 00000000000..31d31070bda
--- /dev/null
+++ b/jstests/noPassthrough/ttl_expire_nan.js
@@ -0,0 +1,43 @@
+/**
+ * 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();
+
+const primary = rst.getPrimary();
+const db = primary.getDB('test');
+const coll = db.t;
+
+assert.commandWorked(coll.insert({_id: 0, t: ISODate()}));
+assert.commandWorked(coll.createIndex({t: 1}, {expireAfterSeconds: NaN}));
+
+// Wait for "TTL indexes require the expire field to be numeric, skipping TTL job" log message.
+checkLog.contains(
+ primary,
+ "TTL indexes require the expireAfterSeconds field to be to be numeric and not a NaN, " +
+ "skipping TTL job. ns: " + coll.getFullName());
+
+// TTL index should be replicated to the secondary with a NaN 'expireAfterSeconds'.
+const secondary = rst.getSecondary();
+checkLog.contains(
+ secondary, /index build: starting on test.t properties: .*name.*t_1.*expireAfterSeconds.*nan/);
+
+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 0028008680a..611eaedb45d 100644
--- a/src/mongo/db/ttl.cpp
+++ b/src/mongo/db/ttl.cpp
@@ -231,10 +231,11 @@ private:
}
BSONElement secondsExpireElt = idx[secondsExpireField];
- if (!secondsExpireElt.isNumber()) {
- error() << "ttl indexes require the " << secondsExpireField << " field to be "
- << "numeric but received a type of " << typeName(secondsExpireElt.type())
- << ", skipping ttl job for: " << idx;
+ if (!secondsExpireElt.isNumber() || secondsExpireElt.isNaN()) {
+ error() << "TTL indexes require the expireAfterSeconds field to be to be numeric and "
+ "not a NaN, skipping TTL job. ns: "
+ << collectionNSS << "; field: " << secondsExpireField
+ << "; type: " << typeName(secondsExpireElt.type()) << "; index: " << idx;
return;
}