summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/sharding/libs/resharding_test_fixture.js11
-rw-r--r--jstests/sharding/resharding_verify_primary_catalog_consistency.js40
-rw-r--r--src/mongo/db/s/resharding/resharding_coordinator_service.cpp4
-rw-r--r--src/mongo/db/s/resharding/resharding_donor_recipient_common.cpp6
4 files changed, 57 insertions, 4 deletions
diff --git a/jstests/sharding/libs/resharding_test_fixture.js b/jstests/sharding/libs/resharding_test_fixture.js
index 580eb1bf4bb..f536f25435b 100644
--- a/jstests/sharding/libs/resharding_test_fixture.js
+++ b/jstests/sharding/libs/resharding_test_fixture.js
@@ -58,6 +58,8 @@ var ReshardingTest = class {
this._sourceCollectionUUID = undefined;
/** @private */
this._tempNs = undefined;
+ /** @private */
+ this._primaryShardName = undefined;
// Properties set by startReshardingInBackground() and withReshardingInBackground().
/** @private */
@@ -149,7 +151,8 @@ var ReshardingTest = class {
* {min: <shardKeyValue0>, max: <shardKeyValue1>, shard: <shardName>} objects. The chunks must
* form a partition of the {shardKey: MinKey} --> {shardKey: MaxKey} space.
*/
- createShardedCollection({ns, shardKeyPattern, chunks}) {
+ createShardedCollection(
+ {ns, shardKeyPattern, chunks, primaryShardName = this.donorShardNames[0]}) {
this._ns = ns;
this._currentShardKey = Object.assign({}, shardKeyPattern);
@@ -169,7 +172,8 @@ var ReshardingTest = class {
// collection is unsharded. We configure one of the recipient shards to be the primary shard
// for the database so mongos still ends up routing operations to a shard which owns the
// temporary resharding collection.
- this._st.ensurePrimaryShard(sourceDB.getName(), this.recipientShardNames[0]);
+ this._st.ensurePrimaryShard(sourceDB.getName(), primaryShardName);
+ this._primaryShardName = primaryShardName;
return sourceCollection;
}
@@ -627,7 +631,8 @@ var ReshardingTest = class {
/** @private */
_checkDonorPostState(donor, expectedErrorCode) {
const collInfo = donor.getCollection(this._ns).exists();
- const isAlsoRecipient = this._recipientShards().includes(donor);
+ const isAlsoRecipient =
+ this._recipientShards().includes(donor) || donor.shardName === this._primaryShardName;
if (expectedErrorCode === ErrorCodes.OK && !isAlsoRecipient) {
assert.eq(
null,
diff --git a/jstests/sharding/resharding_verify_primary_catalog_consistency.js b/jstests/sharding/resharding_verify_primary_catalog_consistency.js
new file mode 100644
index 00000000000..63db7e158d3
--- /dev/null
+++ b/jstests/sharding/resharding_verify_primary_catalog_consistency.js
@@ -0,0 +1,40 @@
+/**
+ * Tests that the collection catalog entry is updated correctly and is consistent after a resharding
+ * operation has completed.
+ *
+ * @tags: [
+ * requires_fcv_49,
+ * uses_atclustertime,
+ * ]
+ */
+(function() {
+"use strict";
+
+load("jstests/sharding/libs/resharding_test_fixture.js");
+
+const reshardingTest = new ReshardingTest({numDonors: 2, reshardInPlace: false});
+reshardingTest.setup();
+
+const donorShardNames = reshardingTest.donorShardNames;
+const sourceCollection = reshardingTest.createShardedCollection({
+ ns: "reshardingDb.coll",
+ shardKeyPattern: {oldKey: 1},
+ chunks: [{min: {oldKey: MinKey}, max: {oldKey: MaxKey}, shard: donorShardNames[1]}],
+ primaryShardName: donorShardNames[0],
+});
+
+const originalCollInfo = sourceCollection.exists();
+assert.neq(originalCollInfo, null, "failed to find sharded collection before resharding");
+
+const recipientShardNames = reshardingTest.recipientShardNames;
+reshardingTest.withReshardingInBackground({
+ newShardKeyPattern: {newKey: 1},
+ newChunks: [{min: {newKey: MinKey}, max: {newKey: MaxKey}, shard: recipientShardNames[0]}],
+});
+
+const newCollInfo = sourceCollection.exists();
+assert.neq(newCollInfo, null, "failed to find sharded collection after resharding");
+assert.neq(newCollInfo.info.uuid, originalCollInfo.info.uuid, {newCollInfo, originalCollInfo});
+
+reshardingTest.teardown();
+})();
diff --git a/src/mongo/db/s/resharding/resharding_coordinator_service.cpp b/src/mongo/db/s/resharding/resharding_coordinator_service.cpp
index 0fbd503d233..3ef29568df1 100644
--- a/src/mongo/db/s/resharding/resharding_coordinator_service.cpp
+++ b/src/mongo/db/s/resharding/resharding_coordinator_service.cpp
@@ -629,6 +629,10 @@ ParticipantShardsAndChunks calculateParticipantShardsAndChunks(
std::set<ShardId> recipientShardIds;
std::vector<ChunkType> initialChunks;
+ // The database primary must always be a recipient to ensure it ends up with consistent
+ // collection metadata.
+ recipientShardIds.emplace(cm.dbPrimary());
+
if (const auto& chunks = coordinatorDoc.getPresetReshardedChunks()) {
auto version = calculateChunkVersionForInitialChunks(opCtx);
diff --git a/src/mongo/db/s/resharding/resharding_donor_recipient_common.cpp b/src/mongo/db/s/resharding/resharding_donor_recipient_common.cpp
index 9b577a4f59f..df03a16bddb 100644
--- a/src/mongo/db/s/resharding/resharding_donor_recipient_common.cpp
+++ b/src/mongo/db/s/resharding/resharding_donor_recipient_common.cpp
@@ -208,6 +208,10 @@ void processReshardingFieldsForDonorCollection(OperationContext* opCtx,
ReshardingDonorDocument>(opCtx, donorDoc);
}
+bool isCurrentShardPrimary(OperationContext* opCtx, const CollectionMetadata& metadata) {
+ return metadata.getChunkManager()->dbPrimary() == ShardingState::get(opCtx)->shardId();
+}
+
/*
* Either constructs a new ReshardingRecipientStateMachine with 'reshardingFields' or passes
* 'reshardingFields' to an already-existing ReshardingRecipientStateMachine.
@@ -243,7 +247,7 @@ void processReshardingFieldsForRecipientCollection(OperationContext* opCtx,
// This could be a shard not indicated as a recipient that's trying to refresh the temporary
// collection. In this case, we don't want to create a recipient machine.
- if (!metadata.currentShardHasAnyChunks()) {
+ if (!isCurrentShardPrimary(opCtx, metadata) && !metadata.currentShardHasAnyChunks()) {
return;
}