summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2022-08-26 14:04:18 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-09-11 12:20:07 +0000
commit26fc0d8a01086fb47377db6564ea5267cdd00aa6 (patch)
treea815f24d9da25d4ecb851f9fd0e1c3b649d709b9
parent02a6f50be29f295d36a8c86f1e3f6c21587bb04d (diff)
downloadmongo-26fc0d8a01086fb47377db6564ea5267cdd00aa6.tar.gz
SERVER-68477 add startup warning for TTL indexes with NaN 'expireAfterSeconds'
(partially cherry-picked from commit abdedd367e2f331816354563f8ae95f6bb35c51d) (cherry picked from commit 5d21e0115edb120873c8beac2901e03a76ccfc00)
-rw-r--r--jstests/noPassthrough/ttl_expire_nan_warning_on_startup.js46
-rw-r--r--src/mongo/db/catalog/index_catalog_impl.cpp14
2 files changed, 60 insertions, 0 deletions
diff --git a/jstests/noPassthrough/ttl_expire_nan_warning_on_startup.js b/jstests/noPassthrough/ttl_expire_nan_warning_on_startup.js
new file mode 100644
index 00000000000..d4b1d41f1fe
--- /dev/null
+++ b/jstests/noPassthrough/ttl_expire_nan_warning_on_startup.js
@@ -0,0 +1,46 @@
+/**
+ * Tests that a server containing a TTL index with NaN for 'expireAfterSeconds'
+ * will log a warning on startup.
+ *
+ * @tags: [
+ * requires_persistence,
+ * requires_replication,
+ * ]
+ */
+(function() {
+'use strict';
+
+load('jstests/noPassthrough/libs/index_build.js');
+
+const rst = new ReplSetTest({nodes: [{}, {rsConfig: {votes: 0, priority: 0}}]});
+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()}));
+
+// Force checkpoint in storage engine to ensure index is part of the catalog in
+// in finished state at startup.
+rst.awaitReplication();
+let secondary = rst.getSecondary();
+assert.commandWorked(secondary.adminCommand({fsync: 1}));
+
+// Restart the secondary and check for the startup warning in the logs.
+secondary = rst.restart(secondary);
+rst.waitForState(secondary, ReplSetTest.State.SECONDARY);
+
+// Wait for "Found an existing TTL index with NaN 'expireAfterSeconds' in the catalog" log message.
+checkLog.containsJson(secondary, 6852200, {
+ ns: coll.getFullName(),
+ spec: (spec) => {
+ jsTestLog('TTL index on secondary at startup: ' + tojson(spec));
+ return isNaN(spec.expireAfterSeconds);
+ }
+});
+
+rst.stopSet();
+})();
diff --git a/src/mongo/db/catalog/index_catalog_impl.cpp b/src/mongo/db/catalog/index_catalog_impl.cpp
index 35a3a74c3b0..6be0b560bf9 100644
--- a/src/mongo/db/catalog/index_catalog_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_impl.cpp
@@ -205,6 +205,20 @@ Status IndexCatalogImpl::init(OperationContext* opCtx, Collection* collection) {
auto descriptor = std::make_unique<IndexDescriptor>(_getAccessMethodName(keyPattern), spec);
+ // TTL indexes with NaN 'expireAfterSeconds' cause problems in multiversion settings.
+ if (spec.hasField(IndexDescriptor::kExpireAfterSecondsFieldName)) {
+ if (spec[IndexDescriptor::kExpireAfterSecondsFieldName].isNaN()) {
+ LOGV2_OPTIONS(6852200,
+ {logv2::LogTag::kStartupWarnings},
+ "Found an existing TTL index with NaN 'expireAfterSeconds' in the "
+ "catalog.",
+ "ns"_attr = collection->ns(),
+ "uuid"_attr = collection->uuid(),
+ "index"_attr = indexName,
+ "spec"_attr = spec);
+ }
+ }
+
// TTL indexes are not compatible with capped collections.
// Note that TTL deletion is supported on capped clustered collections via bounded
// collection scan, which does not use an index.