summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/s/resharding/resharding_data_copy_util.cpp6
-rw-r--r--src/mongo/db/s/resharding/resharding_data_copy_util.h9
-rw-r--r--src/mongo/db/s/resharding/resharding_oplog_applier.cpp10
-rw-r--r--src/mongo/db/s/resharding/resharding_oplog_applier.h3
-rw-r--r--src/mongo/db/s/resharding/resharding_recipient_service.cpp40
-rw-r--r--src/mongo/db/s/resharding/resharding_recipient_service.h6
-rw-r--r--src/mongo/db/s/resharding/resharding_recipient_service_test.cpp49
7 files changed, 104 insertions, 19 deletions
diff --git a/src/mongo/db/s/resharding/resharding_data_copy_util.cpp b/src/mongo/db/s/resharding/resharding_data_copy_util.cpp
index ad85a69d241..f870643e257 100644
--- a/src/mongo/db/s/resharding/resharding_data_copy_util.cpp
+++ b/src/mongo/db/s/resharding/resharding_data_copy_util.cpp
@@ -39,7 +39,9 @@
namespace mongo::resharding::data_copy {
-void ensureCollectionExists(OperationContext* opCtx, const NamespaceString& nss) {
+void ensureCollectionExists(OperationContext* opCtx,
+ const NamespaceString& nss,
+ const CollectionOptions& options) {
invariant(!opCtx->lockState()->isLocked());
invariant(!opCtx->lockState()->inAWriteUnitOfWork());
@@ -50,7 +52,7 @@ void ensureCollectionExists(OperationContext* opCtx, const NamespaceString& nss)
}
WriteUnitOfWork wuow(opCtx);
- coll.ensureDbExists()->createCollection(opCtx, nss);
+ coll.ensureDbExists()->createCollection(opCtx, nss, options);
wuow.commit();
});
}
diff --git a/src/mongo/db/s/resharding/resharding_data_copy_util.h b/src/mongo/db/s/resharding/resharding_data_copy_util.h
index 22b96a1b26a..3374b8c7228 100644
--- a/src/mongo/db/s/resharding/resharding_data_copy_util.h
+++ b/src/mongo/db/s/resharding/resharding_data_copy_util.h
@@ -40,7 +40,14 @@ class OperationContext;
namespace resharding::data_copy {
-void ensureCollectionExists(OperationContext* opCtx, const NamespaceString& nss);
+/**
+ * Creates the specified collection with the given options if the collection does not already exist.
+ * If the collection already exists, we do not compare the options because the resharding process
+ * will always use the same options for the same namespace.
+ */
+void ensureCollectionExists(OperationContext* opCtx,
+ const NamespaceString& nss,
+ const CollectionOptions& options);
/**
* Drops the specified collection or returns without error if the collection has already been
diff --git a/src/mongo/db/s/resharding/resharding_oplog_applier.cpp b/src/mongo/db/s/resharding/resharding_oplog_applier.cpp
index 263b8e05ec4..e2b4cc76667 100644
--- a/src/mongo/db/s/resharding/resharding_oplog_applier.cpp
+++ b/src/mongo/db/s/resharding/resharding_oplog_applier.cpp
@@ -496,14 +496,16 @@ Timestamp ReshardingOplogApplier::_clearAppliedOpsAndStoreProgress(OperationCont
return lastAppliedTs;
}
-NamespaceString ReshardingOplogApplier::ensureStashCollectionExists(OperationContext* opCtx,
- const UUID& existingUUID,
- const ShardId& donorShardId) {
+NamespaceString ReshardingOplogApplier::ensureStashCollectionExists(
+ OperationContext* opCtx,
+ const UUID& existingUUID,
+ const ShardId& donorShardId,
+ const CollectionOptions& options) {
auto nss = NamespaceString{NamespaceString::kConfigDb,
"localReshardingConflictStash.{}.{}"_format(
existingUUID.toString(), donorShardId.toString())};
- resharding::data_copy::ensureCollectionExists(opCtx, nss);
+ resharding::data_copy::ensureCollectionExists(opCtx, nss, options);
return nss;
}
diff --git a/src/mongo/db/s/resharding/resharding_oplog_applier.h b/src/mongo/db/s/resharding/resharding_oplog_applier.h
index 71462dbc9a0..e0b7b4df5da 100644
--- a/src/mongo/db/s/resharding/resharding_oplog_applier.h
+++ b/src/mongo/db/s/resharding/resharding_oplog_applier.h
@@ -86,7 +86,8 @@ public:
static NamespaceString ensureStashCollectionExists(OperationContext* opCtx,
const UUID& existingUUID,
- const ShardId& donorShardId);
+ const ShardId& donorShardId,
+ const CollectionOptions& options);
private:
using OplogBatch = std::vector<repl::OplogEntry>;
diff --git a/src/mongo/db/s/resharding/resharding_recipient_service.cpp b/src/mongo/db/s/resharding/resharding_recipient_service.cpp
index 548072bc3d4..cafff767d33 100644
--- a/src/mongo/db/s/resharding/resharding_recipient_service.cpp
+++ b/src/mongo/db/s/resharding/resharding_recipient_service.cpp
@@ -138,12 +138,35 @@ void createTemporaryReshardingCollectionLocally(OperationContext* opCtx,
// Set the temporary resharding collection's UUID to the resharding UUID. Note that
// BSONObj::addFields() replaces any fields that already exist.
collOptions = collOptions.addFields(BSON("uuid" << reshardingUUID));
-
CollectionOptionsAndIndexes optionsAndIndexes = {reshardingUUID, indexes, idIndex, collOptions};
MigrationDestinationManager::cloneCollectionIndexesAndOptions(
opCtx, reshardingNss, optionsAndIndexes);
}
+std::vector<NamespaceString> ensureStashCollectionsExist(
+ OperationContext* opCtx,
+ const ChunkManager& cm,
+ const UUID& existingUUID,
+ std::vector<DonorShardMirroringEntry> donorShards) {
+ // Use the same collation for the stash collections as the temporary resharding collection
+ auto collator = cm.getDefaultCollator();
+ BSONObj collationSpec = collator ? collator->getSpec().toBSON() : BSONObj();
+
+ std::vector<NamespaceString> stashCollections;
+ stashCollections.reserve(donorShards.size());
+
+ {
+ CollectionOptions options;
+ options.collation = std::move(collationSpec);
+ for (const auto& donor : donorShards) {
+ stashCollections.emplace_back(ReshardingOplogApplier::ensureStashCollectionExists(
+ opCtx, existingUUID, donor.getId(), options));
+ }
+ }
+
+ return stashCollections;
+}
+
} // namespace resharding
std::shared_ptr<repl::PrimaryOnlyService::Instance> ReshardingRecipientService::constructInstance(
@@ -420,16 +443,13 @@ ExecutorFuture<void> ReshardingRecipientService::RecipientStateMachine::
return catalogCache->getShardedCollectionRoutingInfo(opCtx.get(), _recipientDoc.getNss());
}();
- std::vector<NamespaceString> stashCollections;
- stashCollections.reserve(numDonors);
-
- {
+ auto stashCollections = [&] {
auto opCtx = cc().makeOperationContext();
- for (const auto& donor : _recipientDoc.getDonorShardsMirroring()) {
- stashCollections.emplace_back(ReshardingOplogApplier::ensureStashCollectionExists(
- opCtx.get(), _recipientDoc.getExistingUUID(), donor.getId()));
- }
- }
+ return resharding::ensureStashCollectionsExist(opCtx.get(),
+ sourceChunkMgr,
+ _recipientDoc.getExistingUUID(),
+ _recipientDoc.getDonorShardsMirroring());
+ }();
size_t i = 0;
auto futuresToWaitOn = std::move(_oplogFetcherFutures);
diff --git a/src/mongo/db/s/resharding/resharding_recipient_service.h b/src/mongo/db/s/resharding/resharding_recipient_service.h
index 045a55bc1a8..71939cdb06c 100644
--- a/src/mongo/db/s/resharding/resharding_recipient_service.h
+++ b/src/mongo/db/s/resharding/resharding_recipient_service.h
@@ -54,6 +54,12 @@ void createTemporaryReshardingCollectionLocally(OperationContext* opCtx,
const UUID& existingUUID,
Timestamp fetchTimestamp);
+std::vector<NamespaceString> ensureStashCollectionsExist(
+ OperationContext* opCtx,
+ const ChunkManager& cm,
+ const UUID& existingUUID,
+ std::vector<DonorShardMirroringEntry> donorShards);
+
} // namespace resharding
class ReshardingRecipientService final : public repl::PrimaryOnlyService {
diff --git a/src/mongo/db/s/resharding/resharding_recipient_service_test.cpp b/src/mongo/db/s/resharding/resharding_recipient_service_test.cpp
index f8380457895..8a03ed223c6 100644
--- a/src/mongo/db/s/resharding/resharding_recipient_service_test.cpp
+++ b/src/mongo/db/s/resharding/resharding_recipient_service_test.cpp
@@ -34,6 +34,8 @@
#include "mongo/bson/unordered_fields_bsonobj_comparator.h"
#include "mongo/db/catalog_raii.h"
#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/query/collation/collator_factory_interface.h"
+#include "mongo/db/query/collation/collator_interface_mock.h"
#include "mongo/db/repl/oplog.h"
#include "mongo/db/repl/replication_coordinator_mock.h"
#include "mongo/db/repl/storage_interface_impl.h"
@@ -133,13 +135,15 @@ public:
const NamespaceString& origNss,
const ShardKeyPattern& skey,
UUID uuid,
- OID epoch) {
+ OID epoch,
+ const BSONObj& collation = {}) {
auto future = scheduleRoutingInfoForcedRefresh(tempNss);
expectFindSendBSONObjVector(kConfigHostAndPort, [&]() {
CollectionType coll(tempNss, epoch, Date_t::now(), uuid);
coll.setKeyPattern(skey.getKeyPattern());
coll.setUnique(false);
+ coll.setDefaultCollation(collation);
TypeCollectionReshardingFields reshardingFields;
reshardingFields.setUuid(uuid);
@@ -539,5 +543,48 @@ TEST_F(ReshardingRecipientServiceTest,
verifyCollectionAndIndexes(kReshardingNss, kReshardingUUID, indexes);
}
+TEST_F(ReshardingRecipientServiceTest, StashCollectionsHaveSameCollationAsReshardingCollection) {
+ auto shards = setupNShards(2);
+
+ std::unique_ptr<CollatorInterfaceMock> collator =
+ std::make_unique<CollatorInterfaceMock>(CollatorInterfaceMock::MockType::kReverseString);
+ auto collationSpec = collator->getSpec().toBSON();
+ auto srcChunkMgr = makeChunkManager(kOrigNss,
+ ShardKeyPattern(BSON("_id" << 1)),
+ std::move(collator),
+ false /* unique */,
+ {} /* splitPoints */);
+
+ // Create stash collections for both donor shards
+ auto stashCollections = resharding::ensureStashCollectionsExist(
+ operationContext(),
+ srcChunkMgr,
+ kOrigUUID,
+ {DonorShardMirroringEntry(ShardId("shard0"), true),
+ DonorShardMirroringEntry(ShardId("shard1"), true)});
+
+ // Verify that each stash collation has the collation we passed in above
+ {
+ auto opCtx = operationContext();
+
+ DBDirectClient client(opCtx);
+ auto collInfos = client.getCollectionInfos("config");
+ StringMap<BSONObj> nsToOptions;
+ for (const auto& coll : collInfos) {
+ nsToOptions[coll["name"].str()] = coll["options"].Obj();
+ }
+
+ for (const auto& coll : stashCollections) {
+ auto it = nsToOptions.find(coll.coll());
+ ASSERT(it != nsToOptions.end());
+ auto options = it->second;
+
+ ASSERT(options.hasField("collation"));
+ auto collation = options["collation"].Obj();
+ ASSERT_BSONOBJ_EQ(collationSpec, collation);
+ }
+ }
+}
+
} // namespace
} // namespace mongo