From 290a3eb8380d22810e0e51c1946f6c558783d196 Mon Sep 17 00:00:00 2001 From: seanzimm <102551488+seanzimm@users.noreply.github.com> Date: Tue, 27 Jan 2026 11:04:36 -0500 Subject: [PATCH] SERVER-106239: Relax assertion requirements for transaction readonly values (#46876) GitOrigin-RevId: b1f08e2c9805c6bff8bf22728327ac72f5f14e4e --- ...kports_required_for_multiversion_tests.yml | 4 +++ jstests/core/index/geo/geo_polygon3.js | 29 +++++++++++++------ src/mongo/s/transaction_router.cpp | 9 ++++-- src/mongo/shell/collection.js | 4 +++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml index 54a09ff5bbf..9ddbf788211 100644 --- a/etc/backports_required_for_multiversion_tests.yml +++ b/etc/backports_required_for_multiversion_tests.yml @@ -512,6 +512,8 @@ last-continuous: ticket: SERVER-115594 - test_file: jstests/aggregation/variables/subpipeline_system_variables.js ticket: SERVER-114384 + - test_file: jstests/core/index/geo/geo_polygon3.js + ticket: SERVER-106239 suites: null last-lts: all: @@ -1081,4 +1083,6 @@ last-lts: ticket: SERVER-115594 - test_file: jstests/aggregation/variables/subpipeline_system_variables.js ticket: SERVER-114384 + - test_file: jstests/core/index/geo/geo_polygon3.js + ticket: SERVER-106239 suites: null diff --git a/jstests/core/index/geo/geo_polygon3.js b/jstests/core/index/geo/geo_polygon3.js index 15efd800ecc..3e716c1c7a4 100644 --- a/jstests/core/index/geo/geo_polygon3.js +++ b/jstests/core/index/geo/geo_polygon3.js @@ -25,19 +25,28 @@ bits.forEach((precision) => { const triangle = [[0, 0], [1, 1], [0, 2]]; // Look at only a small slice of the data within a triangle - assert.eq(1, t.countDocuments({loc: {"$within": {"$polygon": triangle}}}), "Triangle Test"); + const options = {allowDiskUse: true}; + assert.eq( + 1, t.countDocuments({loc: {"$within": {"$polygon": triangle}}}, options), "Triangle Test"); let boxBounds = [[0, 0], [0, 10], [10, 10], [10, 0]]; assert.eq(docs.length, - t.countDocuments({loc: {"$within": {"$polygon": boxBounds}}}), + t.countDocuments({loc: {"$within": {"$polygon": boxBounds}}}, options), "Bounding Box Test"); // Look in a box much bigger than the one we have data in - boxBounds = [[-100, -100], [-100, 100], [100, 100], [100, -100]]; - assert.eq(docs.length, - t.countDocuments({loc: {"$within": {"$polygon": boxBounds}}}), - "Big Bounding Box Test"); + boxBounds = [ + [-100, -100], + [-100, 100], + [100, 100], + [100, -100], + ]; + assert.eq( + docs.length, + t.countDocuments({loc: {"$within": {"$polygon": boxBounds}}}, options), + "Big Bounding Box Test", + ); t = db.getCollection(collNamePrefix + 'pacman_' + precision + '_bits'); t.drop(); @@ -58,7 +67,8 @@ bits.forEach((precision) => { assert.commandWorked(t.insert({_id: docId++, loc: [1, 3]})); // Add a point that's in - assert.eq(1, t.countDocuments({loc: {$within: {$polygon: pacman}}}), "Pacman single point"); + assert.eq( + 1, t.countDocuments({loc: {$within: {$polygon: pacman}}}, options), "Pacman single point"); docs = []; docs.push({_id: docId++, loc: [5, 3]}); // Add a point that's out right in the mouth opening @@ -66,5 +76,6 @@ bits.forEach((precision) => { docs.push({_id: docId++, loc: [3, -1]}); // Add a point above the center of the head assert.commandWorked(t.insert(docs)); - assert.eq(1, t.countDocuments({loc: {$within: {$polygon: pacman}}}), "Pacman double point"); -}); \ No newline at end of file + assert.eq( + 1, t.countDocuments({loc: {$within: {$polygon: pacman}}}, options), "Pacman double point"); +}); diff --git a/src/mongo/s/transaction_router.cpp b/src/mongo/s/transaction_router.cpp index a667f095fc5..9f4bea2ed5a 100644 --- a/src/mongo/s/transaction_router.cpp +++ b/src/mongo/s/transaction_router.cpp @@ -726,11 +726,16 @@ void TransactionRouter::Router::processParticipantResponse( return Participant::ReadOnly::kReadOnly; } + // Additional participants may not have the most up to date information, so we relax the + // assertion in this case. If a node is recruited to perform read-only work as part of a + // read operation on a shard it will always report that shard as read-only. If that + // shard then performs writes later that could cause this assertion to trigger without + // relaxing the constraint. uassert(51113, str::stream() << "Participant shard " << shardIdToUpdate << " claimed to be read-only for a transaction after previously " "claiming to have done a write for the transaction", - readOnlyCurrent == Participant::ReadOnly::kReadOnly); + readOnlyCurrent == Participant::ReadOnly::kReadOnly || isAdditionalParticipant); return boost::none; } @@ -750,7 +755,7 @@ void TransactionRouter::Router::processParticipantResponse( LOGV2_DEBUG(22881, 3, - "Marking shard has having done a write", + "Marking shard as having done a write", "sessionId"_attr = _sessionId(), "txnNumber"_attr = o().txnNumberAndRetryCounter.getTxnNumber(), "txnRetryCounter"_attr = o().txnNumberAndRetryCounter.getTxnRetryCounter(), diff --git a/src/mongo/shell/collection.js b/src/mongo/shell/collection.js index 2147a948f51..515a85a2d82 100644 --- a/src/mongo/shell/collection.js +++ b/src/mongo/shell/collection.js @@ -1568,6 +1568,10 @@ DBCollection.prototype.countDocuments = function(query, options) { aggregateOptions.rawData = options.rawData; } + if (options.allowDiskUse) { + aggregateOptions.allowDiskUse = options.allowDiskUse; + } + // Format cursor into an array. const res = this.aggregate(pipeline, aggregateOptions).toArray(); if (res.length) {