diff options
author | Benety Goh <benety@mongodb.com> | 2020-01-08 14:05:59 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-04-12 17:53:25 +0000 |
commit | 46d92ea10a90b8d1330f9e42e90783419598abd8 (patch) | |
tree | f178afd181f73b459a2527618446ff31ef872677 | |
parent | 54e29d8dcca0b3d73898a384b57c516728edbcd2 (diff) | |
download | mongo-46d92ea10a90b8d1330f9e42e90783419598abd8.tar.gz |
SERVER-44821 accessing db.system.profile and currentOp storage stats should not conflict with slow oplog application
(cherry picked from commit 87bcfd4931e002bcfdb563d58bde06e32aca1d8d)
-rw-r--r-- | jstests/noPassthrough/currentop_secondary_slow_op.js | 64 | ||||
-rw-r--r-- | src/mongo/db/commands/dbcommands_d.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/curop.cpp | 3 |
3 files changed, 70 insertions, 0 deletions
diff --git a/jstests/noPassthrough/currentop_secondary_slow_op.js b/jstests/noPassthrough/currentop_secondary_slow_op.js new file mode 100644 index 00000000000..66e83520056 --- /dev/null +++ b/jstests/noPassthrough/currentop_secondary_slow_op.js @@ -0,0 +1,64 @@ +/** + * Confirms slow currentOp logging does not conflict with applying an oplog batch. + * @tags: [requires_replication] + */ +(function() { +"use strict"; + +const rst = new ReplSetTest({ + nodes: [ + {}, + { + // Disallow elections on secondary. + rsConfig: { + priority: 0, + votes: 0, + }, + slowms: 30000, // Don't log slow operations on secondary. + }, + ] +}); +const nodes = rst.startSet(); +rst.initiate(); + +const primary = rst.getPrimary(); +const testDB = primary.getDB('test'); +const coll = testDB.getCollection('test'); + +assert.commandWorked(coll.insert({_id: 'a'})); + +const secondary = rst.getSecondary(); +const secondaryDB = secondary.getDB(testDB.getName()); +assert.commandWorked(secondaryDB.adminCommand({ + configureFailPoint: 'hangAfterCollectionInserts', + mode: 'alwaysOn', + data: { + collectionNS: coll.getFullName(), + first_id: 'b', + }, +})); + +try { + assert.commandWorked(coll.insert({_id: 'b'})); + checkLog.contains(secondary, + 'hangAfterCollectionInserts fail point enabled for ' + coll.getFullName()); + + jsTestLog('Running currentOp() with slow operation logging.'); + // Lower slowms to make currentOp() log slow operation while the secondary is procesing the + // commitIndexBuild oplog entry during oplog application. + // Use admin db on secondary to avoid lock conflict with inserts in test db. + const secondaryAdminDB = secondaryDB.getSiblingDB('admin'); + const profileResult = assert.commandWorked(secondaryAdminDB.setProfilingLevel(0, {slowms: -1})); + jsTestLog('Configured profiling to always log slow ops: ' + tojson(profileResult)); + const currentOpResult = assert.commandWorked(secondaryAdminDB.currentOp()); + jsTestLog('currentOp() with slow operation logging: ' + tojson(currentOpResult)); + assert.commandWorked( + secondaryAdminDB.setProfilingLevel(profileResult.was, {slowms: profileResult.slowms})); + jsTestLog('Completed currentOp() with slow operation logging.'); +} finally { + assert.commandWorked( + secondaryDB.adminCommand({configureFailPoint: 'hangAfterCollectionInserts', mode: 'off'})); +} + +rst.stopSet(); +})(); diff --git a/src/mongo/db/commands/dbcommands_d.cpp b/src/mongo/db/commands/dbcommands_d.cpp index f94edb2992f..626247acb3b 100644 --- a/src/mongo/db/commands/dbcommands_d.cpp +++ b/src/mongo/db/commands/dbcommands_d.cpp @@ -120,6 +120,9 @@ protected: const bool readOnly = (profilingLevel < 0 || profilingLevel > 2); const LockMode dbMode = readOnly ? MODE_S : MODE_X; + // Accessing system.profile collection should not conflict with oplog application. + ShouldNotConflictWithSecondaryBatchApplicationBlock shouldNotConflictBlock( + opCtx->lockState()); AutoGetDb ctx(opCtx, dbName, dbMode); Database* db = ctx.getDb(); diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp index b95b61b83fc..9d26d1c206c 100644 --- a/src/mongo/db/curop.cpp +++ b/src/mongo/db/curop.cpp @@ -443,6 +443,9 @@ bool CurOp::completeAndLogOperation(OperationContext* opCtx, // We can get here and our lock acquisition be timed out or interrupted, log a // message if that happens. try { + // Retrieving storage stats should not be blocked by oplog application. + ShouldNotConflictWithSecondaryBatchApplicationBlock shouldNotConflictBlock( + opCtx->lockState()); Lock::GlobalLock lk(opCtx, MODE_IS, Date_t::now() + Milliseconds(500), |