summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Wlodarek <gregory.wlodarek@mongodb.com>2020-12-03 16:18:11 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-12-14 02:33:20 +0000
commit2146f93edb068f8020666cb0c495fc555a49415c (patch)
tree9c5bfa71f9f74cfc886f57a9a3dfc60e4ba8d4c6
parentb45c07c6174d3ac6c100453ab6d56ab7ee5dedb6 (diff)
downloadmongo-2146f93edb068f8020666cb0c495fc555a49415c.tar.gz
SERVER-52950 Avoid calculating oplog stones when recoverFromOplogAsStandalone=true as the OplogCapMaintainerThread is not running
(cherry picked from commit 3be0c64532e121780dd11788fa3db4a9089b008c)
-rw-r--r--jstests/noPassthrough/check_for_oplog_cap_maintainer_thread.js69
-rw-r--r--src/mongo/db/storage/oplog_cap_maintainer_thread.cpp1
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp8
3 files changed, 77 insertions, 1 deletions
diff --git a/jstests/noPassthrough/check_for_oplog_cap_maintainer_thread.js b/jstests/noPassthrough/check_for_oplog_cap_maintainer_thread.js
new file mode 100644
index 00000000000..68756be3bbe
--- /dev/null
+++ b/jstests/noPassthrough/check_for_oplog_cap_maintainer_thread.js
@@ -0,0 +1,69 @@
+/**
+ * Checks that the oplog cap maintainer thread is started and the oplog stones calculation is
+ * performed under normal startup circumstances. Both of these operations should not be done when
+ * starting up with any of the following modes:
+ * - readonly
+ * - repair
+ * - recoverFromOplogAsStandalone
+ *
+ * @tags: [requires_replication, requires_persistence]
+ */
+(function() {
+"use strict";
+
+// Verify that the oplog cap maintainer thread is running under normal circumstances.
+jsTestLog("Testing single node replica set mode");
+const rst = new ReplSetTest({nodes: 1, nodeOptions: {setParameter: {logLevel: 1}}});
+rst.startSet();
+rst.initiate();
+
+const primary = rst.getPrimary();
+checkLog.containsJson(primary, 5295000); // OplogCapMaintainerThread started.
+checkLog.containsJson(primary, 22382); // Oplog stones calculated.
+
+rst.stopSet(/*signal=*/null, /*forRestart=*/true);
+
+// A subset of startup options prevent the oplog cap maintainer thread from being started. These
+// startup options are currently limited to readOnly, recoverFromOplogAsStandalone and repair.
+function verifyOplogCapMaintainerThreadNotStarted(log) {
+ const threadRegex = new RegExp("\"id\":5295000");
+ const oplogStonesRegex = new RegExp("\"id\":22382");
+
+ assert(!threadRegex.test(log));
+ assert(!oplogStonesRegex.test(log));
+}
+
+jsTestLog("Testing readOnly mode");
+clearRawMongoProgramOutput();
+let conn = MongoRunner.runMongod({
+ dbpath: primary.dbpath,
+ noCleanData: true,
+ queryableBackupMode: "", // readOnly
+ setParameter: {logLevel: 1},
+});
+assert(conn);
+MongoRunner.stopMongod(conn);
+verifyOplogCapMaintainerThreadNotStarted(rawMongoProgramOutput());
+
+jsTestLog("Testing recoverFromOplogAsStandalone mode");
+clearRawMongoProgramOutput();
+conn = MongoRunner.runMongod({
+ dbpath: primary.dbpath,
+ noCleanData: true,
+ setParameter: {recoverFromOplogAsStandalone: true, logLevel: 1},
+});
+assert(conn);
+MongoRunner.stopMongod(conn);
+verifyOplogCapMaintainerThreadNotStarted(rawMongoProgramOutput());
+
+jsTestLog("Testing repair mode");
+clearRawMongoProgramOutput();
+conn = MongoRunner.runMongod({
+ dbpath: primary.dbpath,
+ noCleanData: true,
+ repair: "",
+ setParameter: {logLevel: 1},
+});
+assert(!conn);
+verifyOplogCapMaintainerThreadNotStarted(rawMongoProgramOutput());
+}());
diff --git a/src/mongo/db/storage/oplog_cap_maintainer_thread.cpp b/src/mongo/db/storage/oplog_cap_maintainer_thread.cpp
index fefa3744e6b..b0835b67386 100644
--- a/src/mongo/db/storage/oplog_cap_maintainer_thread.cpp
+++ b/src/mongo/db/storage/oplog_cap_maintainer_thread.cpp
@@ -93,6 +93,7 @@ bool OplogCapMaintainerThread::_deleteExcessDocuments() {
}
void OplogCapMaintainerThread::run() {
+ LOGV2_DEBUG(5295000, 1, "Oplog cap maintainer thread started", "threadName"_attr = _name);
ThreadClient tc(_name, getGlobalServiceContext());
while (!globalInShutdownDeprecated()) {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
index f1d127e7744..9daa54a7282 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp
@@ -915,8 +915,14 @@ void WiredTigerRecordStore::checkSize(OperationContext* opCtx) {
}
void WiredTigerRecordStore::postConstructorInit(OperationContext* opCtx) {
+ // When starting up with recoverFromOplogAsStandalone=true, the readOnly flag is initially set
+ // to false to allow oplog recovery to run and perform its necessary writes. After recovery is
+ // complete, the readOnly flag gets flipped to true. Because of this subtlety, we avoid
+ // calculating the oplog stones when recoverFromOplogAsStandalone=true as the RecordStore
+ // construction for the oplog happens before the readOnly flag gets flipped to true.
if (NamespaceString::oplog(ns()) &&
- !(storageGlobalParams.repair || storageGlobalParams.readOnly)) {
+ !(storageGlobalParams.repair || storageGlobalParams.readOnly ||
+ repl::ReplSettings::shouldRecoverFromOplogAsStandalone())) {
_oplogStones = std::make_shared<OplogStones>(opCtx, this);
}