diff options
author | Abdul Qadeer <abdul.qadeer@mongodb.com> | 2022-08-09 11:53:22 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-09 15:39:36 +0000 |
commit | 0d3499eef76a29bc28015113dd4cc7cb412abf27 (patch) | |
tree | 1a1216716ef2d96ac6314c407565a756b79533a3 | |
parent | abdedd367e2f331816354563f8ae95f6bb35c51d (diff) | |
download | mongo-0d3499eef76a29bc28015113dd4cc7cb412abf27.tar.gz |
SERVER-67492 Skip updating txn table for op=n when o2 is empty
4 files changed, 63 insertions, 2 deletions
diff --git a/etc/backports_required_for_multiversion_tests.yml b/etc/backports_required_for_multiversion_tests.yml index 2938a496e67..63951991640 100644 --- a/etc/backports_required_for_multiversion_tests.yml +++ b/etc/backports_required_for_multiversion_tests.yml @@ -100,6 +100,8 @@ last-continuous: test_file: jstests/replsets/optime.js - ticket: SERVER-66072 test_file: jstests/aggregation/match_no_swap_rand.js + - ticket: SERVER-67492 + test_file: jstests/sharding/move_chunk_interrupt_postimage.js # Tests that should only be excluded from particular suites should be listed under that suite. suites: @@ -360,6 +362,8 @@ last-lts: test_file: jstests/replsets/optime.js - ticket: SERVER-66072 test_file: jstests/aggregation/match_no_swap_rand.js + - ticket: SERVER-67492 + test_file: jstests/sharding/move_chunk_interrupt_postimage.js # Tests that should only be excluded from particular suites should be listed under that suite. suites: diff --git a/jstests/sharding/move_chunk_interrupt_postimage.js b/jstests/sharding/move_chunk_interrupt_postimage.js new file mode 100644 index 00000000000..58beced5927 --- /dev/null +++ b/jstests/sharding/move_chunk_interrupt_postimage.js @@ -0,0 +1,43 @@ +/** + * Tests that chunk migration interruption before processing post/pre image oplog entry leads + * to consistent config.transactions data across primary and secondaries (SERVER-67492) + */ + +(function() { +"use strict"; + +load("jstests/sharding/libs/create_sharded_collection_util.js"); +load("jstests/libs/fail_point_util.js"); +load('jstests/libs/parallel_shell_helpers.js'); + +const st = new ShardingTest({mongos: 1, config: 1, shards: 2, rs: {nodes: 2}}); +const interruptBeforeProcessingPrePostImageOriginatingOpFP = + configureFailPoint(st.rs1.getPrimary(), "interruptBeforeProcessingPrePostImageOriginatingOp"); + +const collection = st.s.getCollection("test.mycoll"); +CreateShardedCollectionUtil.shardCollectionWithChunks(collection, {x: 1}, [ + {min: {x: MinKey}, max: {x: 0}, shard: st.shard0.shardName}, + {min: {x: 0}, max: {x: 100}, shard: st.shard0.shardName}, + {min: {x: 100}, max: {x: MaxKey}, shard: st.shard1.shardName}, +]); + +assert.commandWorked(collection.insert({_id: 0, x: 10})); +assert.commandWorked(collection.runCommand("findAndModify", { + query: {x: 10}, + update: {$set: {y: 2}}, + new: true, + txnNumber: NumberLong(1), + lsid: {id: UUID()} +})); + +const res = st.s.adminCommand({ + moveChunk: collection.getFullName(), + find: {x: 10}, + to: st.shard1.shardName, +}); +assert.commandFailedWithCode(res, ErrorCodes.CommandFailed); +interruptBeforeProcessingPrePostImageOriginatingOpFP.wait(); + +interruptBeforeProcessingPrePostImageOriginatingOpFP.off(); +st.stop(); +})(); diff --git a/src/mongo/db/repl/session_update_tracker.cpp b/src/mongo/db/repl/session_update_tracker.cpp index 2d0ef6fc603..ec1575ea4c0 100644 --- a/src/mongo/db/repl/session_update_tracker.cpp +++ b/src/mongo/db/repl/session_update_tracker.cpp @@ -204,7 +204,7 @@ boost::optional<std::vector<OplogEntry>> SessionUpdateTracker::_updateSessionInf return {}; } - if (!entry.getObject2()) { + if (!entry.getObject2() || entry.getObject2()->isEmpty()) { return {}; } } diff --git a/src/mongo/db/s/session_catalog_migration_destination.cpp b/src/mongo/db/s/session_catalog_migration_destination.cpp index 36e37b27c84..7af9176b23d 100644 --- a/src/mongo/db/s/session_catalog_migration_destination.cpp +++ b/src/mongo/db/s/session_catalog_migration_destination.cpp @@ -55,6 +55,8 @@ namespace mongo { namespace { +MONGO_FAIL_POINT_DEFINE(interruptBeforeProcessingPrePostImageOriginatingOp); + const auto kOplogField = "oplog"; const WriteConcernOptions kMajorityWC(WriteConcernOptions::kMajority, WriteConcernOptions::SyncMode::UNSET, @@ -465,9 +467,21 @@ void SessionCatalogMigrationDestination::_retrieveSessionStateFromSource(Service lastOpTimeWaited = lastResult.oplogTime; } } + for (BSONArrayIteratorSorted oplogIter(oplogArray); oplogIter.more();) { + auto oplogEntry = oplogIter.next().Obj(); + interruptBeforeProcessingPrePostImageOriginatingOp.executeIf( + [&](const auto&) { + uasserted(6749200, + "Intentionally failing session migration before processing post/pre " + "image originating update oplog entry"); + }, + [&](const auto&) { + return !oplogEntry["preImageOpTime"].eoo() || + !oplogEntry["postImageOpTime"].eoo(); + }); try { - lastResult = processSessionOplog(oplogIter.next().Obj(), lastResult); + lastResult = processSessionOplog(oplogEntry, lastResult); } catch (const ExceptionFor<ErrorCodes::TransactionTooOld>&) { // This means that the server has a newer txnNumber than the oplog being // migrated, so just skip it |