summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Kneiser <matt.kneiser@mongodb.com>2023-04-11 13:34:49 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-04-11 14:12:02 +0000
commita2722330e5a975b9692e69f744a9769006ff94ea (patch)
treec9b563aafd07fb7d97a63ad432fc16676e216eb6
parent37d4178a7aa5038a78ae073468d6d0d037e1434c (diff)
downloadmongo-a2722330e5a975b9692e69f744a9769006ff94ea.tar.gz
SERVER-75799 Re-insert locks into lock-free dbhash
-rw-r--r--jstests/concurrency/fsm_workloads/dbhash_test.js89
-rw-r--r--src/mongo/db/commands/dbhash.cpp13
2 files changed, 95 insertions, 7 deletions
diff --git a/jstests/concurrency/fsm_workloads/dbhash_test.js b/jstests/concurrency/fsm_workloads/dbhash_test.js
new file mode 100644
index 00000000000..d2a1822f763
--- /dev/null
+++ b/jstests/concurrency/fsm_workloads/dbhash_test.js
@@ -0,0 +1,89 @@
+/**
+ * Tests dbHash collisions in WT with full validation.
+ * dbHash should not experience races on data, or EBUSY errors in the storage engine.
+ * @tags: [
+ * requires_wiredtiger,
+ * requires_replication,
+ * ]
+ */
+
+"use strict";
+
+load("jstests/concurrency/fsm_workload_helpers/state_transition_utils.js");
+
+const dbPrefix = jsTestName() + '_db_';
+
+var $config = (function() {
+ let states = {
+ init: function(db, collName) {
+ jsTestLog("init tid: " + this.tid);
+ },
+ dbHash: function(db, collName) {
+ jsTestLog("dbHash: " + db + "." + collName + " tid: " + this.tid);
+ jsTestLog("dbHash begin opTime:" + tojson(this.opTime));
+ let dbHashRes = assert.commandWorked(db.collName.runCommand({
+ dbHash: 1,
+ $_internalReadAtClusterTime: Timestamp(this.opTime['t'], this.opTime['i'])
+ }));
+ jsTestLog("dbHash done" + dbHashRes.timeMillis);
+ },
+ fullValidation: function(db, collName) {
+ jsTestLog("fullValidation: " + db + "." + collName + " tid: " + this.tid);
+ let res = assert.commandWorked(db.collName.validate({full: true}));
+ jsTestLog("fullValidation done: " + db + "." + collName + " " + this.tid);
+ assert(res.valid);
+ },
+ };
+
+ const setSyncDelay = function(db, delay) {
+ jsTestLog("setSyncDelay: ", delay);
+ assert.commandWorked(db.adminCommand({setParameter: 1, syncdelay: delay}));
+ };
+
+ const setup = function(db, collName) {
+ jsTestLog("Creating:" + db + "." + collName + " tid: " + this.tid);
+ let x = 'x'.repeat(20 * 1024); // 20KB
+
+ let bulk = db.collName.initializeOrderedBulkOp();
+ for (let i = 0; i < 80; i++) {
+ bulk.insert({_id: x + i.toString()});
+ }
+ assertAlways.commandWorked(bulk.execute());
+
+ this.opTime =
+ assert
+ .commandWorked(db.runCommand(
+ {insert: collName, documents: [{x: 1}], writeConcern: {w: "majority"}}))
+ .operationTime;
+ jsTestLog("dbHash opTime:" + tojson(this.opTime));
+
+ // Avoid filling the cache by flushing on a shorter interval
+ setSyncDelay(db, 10);
+
+ jsTestLog("Creating done:" + db + "." + collName);
+ };
+
+ const teardown = function(db, collName) {
+ setSyncDelay(db, 60);
+ };
+
+ const standardTransition = {
+ dbHash: 0.5,
+ fullValidation: 0.5,
+ };
+
+ const transitions = {
+ init: standardTransition,
+ dbHash: {dbHash: 0.8, fullValidation: 0.2},
+ fullValidation: {dbHash: 0.2, fullValidation: 0.8},
+ };
+
+ return {
+ threadCount: 5,
+ iterations: 2,
+ setup: setup,
+ states: states,
+ teardown: teardown,
+ transitions: transitions,
+ };
+})();
diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp
index 312b513de88..01ac594fe80 100644
--- a/src/mongo/db/commands/dbhash.cpp
+++ b/src/mongo/db/commands/dbhash.cpp
@@ -253,13 +253,10 @@ public:
boost::optional<AutoGetDb> autoDb;
if (isPointInTimeRead) {
- // (Ignore FCV check): This feature flag doesn't have any upgrade/downgrade concerns.
- if (!feature_flags::gPointInTimeCatalogLookups.isEnabledAndIgnoreFCVUnsafe()) {
- // We only need to lock the database in intent mode and then collection in intent
- // mode as well to ensure that none of the collections get dropped. This is no
- // longer necessary with point-in-time catalog lookups.
- autoDb.emplace(opCtx, dbName, MODE_IS);
- }
+ // We only need to lock the database in intent mode and then collection in intent
+ // mode as well to ensure that none of the collections get dropped.
+ // TODO:SERVER-75848 Make this lock-free
+ autoDb.emplace(opCtx, dbName, MODE_IS);
} else {
// We lock the entire database in S-mode in order to ensure that the contents will not
// change for the snapshot when not reading at a timestamp.
@@ -351,6 +348,8 @@ public:
!minSnapshot || *readTimestamp >= *minSnapshot);
}
} else {
+ // TODO:SERVER-75848 Make this lock-free
+ Lock::CollectionLock clk(opCtx, *nss, MODE_IS);
coll = catalog->establishConsistentCollection(
opCtx,
{dbName, uuid},