From c4a4f082a3b9a83bed69a86af53a0a905b9e287b Mon Sep 17 00:00:00 2001 From: Jordi Serra Torrens Date: Fri, 20 Oct 2023 15:26:05 +0000 Subject: [PATCH] Repro SERVER-82353 --- jstests/noPassthrough/foo.js | 55 +++++++++++++++++++++++++++++++ src/mongo/s/commands/strategy.cpp | 2 ++ 2 files changed, 57 insertions(+) create mode 100644 jstests/noPassthrough/foo.js diff --git a/jstests/noPassthrough/foo.js b/jstests/noPassthrough/foo.js new file mode 100644 index 00000000000..b2397d27ac9 --- /dev/null +++ b/jstests/noPassthrough/foo.js @@ -0,0 +1,55 @@ +import {configureFailPoint} from "jstests/libs/fail_point_util.js"; + +(function() { +'use strict'; +const dbName = 'test'; +const collName = 'foo'; +const ns = dbName + '.' + collName; + +const st = new ShardingTest({mongos: 1, shards: 2}); + +st.adminCommand({enableSharding: dbName, primaryShard: st.shard0.shardName}); + +const coll = st.getDB(dbName)[collName]; +coll.insert({x: 1, c: 0}); + +// Set a failpoint that will block transactions on mongos right after if has chosen their +// 'atClusterTime'. +const mongos = st.s; +let fp = configureFailPoint(mongos, 'hangAfterSettingTransactionDefaultAtClusterTime'); + +// Start multi-document txn that will increment 'c' by one for the document with x=1. +let awaitResult = startParallelShell(() => { + let session = db.getMongo().startSession(); + let coll = session.getDatabase('test')['foo']; + + session.startTransaction({readConcern: {level: 'snapshot'}}); + const updateResult = assert.commandWorked(coll.update({x: 1}, {$inc: {c: 1}})); + + // Note: We'd expect one document to have been updated. But because of the bug being repro'd + // here, none was! + jsTest.log("--DEBUG-- updateResult: " + tojson(updateResult)); + // assert.eq(1, updateResult.nModified); + + // We'd also expect a find within the transaction to see the documents, but it doesn't. + // assert.eq(1, coll.find().itcount()); + + session.commitTransaction(); +}, mongos.port); + +// Wait to hit the failpoint on mongos. +fp.wait(); + +// Run movePrimary. +assert.commandWorked(mongos.adminCommand({movePrimary: dbName, to: st.shard1.shardName})); + +// Unset the failpoint. +fp.off(); +awaitResult(); + +// Check document 'c' has been incremented to 1. +// Note: Because of the bug being repro'd, it Will fail here. +assert.eq(1, coll.findOne({x: 1}).c); + +st.stop(); +})(); diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp index a643d23f06d..2f60c6ce34a 100644 --- a/src/mongo/s/commands/strategy.cpp +++ b/src/mongo/s/commands/strategy.cpp @@ -129,6 +129,7 @@ namespace mongo { namespace { MONGO_FAIL_POINT_DEFINE(hangBeforeCheckingMongosShutdownInterrupt); +MONGO_FAIL_POINT_DEFINE(hangAfterSettingTransactionDefaultAtClusterTime); const auto kOperationTime = "operationTime"_sd; /** @@ -208,6 +209,7 @@ Future invokeInTransactionRouter(TransactionRouter::Router& txnRouter, std::shared_ptr invocation) { auto opCtx = rec->getOpCtx(); txnRouter.setDefaultAtClusterTime(opCtx); + hangAfterSettingTransactionDefaultAtClusterTime.pauseWhileSet(); return runCommandInvocation(rec, std::move(invocation)) .tapError([rec = std::move(rec)](Status status) { -- 2.34.1