summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2020-01-08 14:05:59 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-04-12 17:53:25 +0000
commit46d92ea10a90b8d1330f9e42e90783419598abd8 (patch)
treef178afd181f73b459a2527618446ff31ef872677
parent54e29d8dcca0b3d73898a384b57c516728edbcd2 (diff)
downloadmongo-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.js64
-rw-r--r--src/mongo/db/commands/dbcommands_d.cpp3
-rw-r--r--src/mongo/db/curop.cpp3
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),