diff options
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); } |