summaryrefslogtreecommitdiff
path: root/src/mongo/db/s
diff options
context:
space:
mode:
authorDaniel Gottlieb <daniel.gottlieb@mongodb.com>2021-03-31 17:02:12 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-03-31 21:45:49 +0000
commit9f857d7249b9dc5a8aa8032a2c55e533fc1e980a (patch)
tree1e25e84508d71ed494e4ea84c171e75bd9e17791 /src/mongo/db/s
parentbed9b4820e4421d63ff5457cd854671cf51bf4f6 (diff)
downloadmongo-9f857d7249b9dc5a8aa8032a2c55e533fc1e980a.tar.gz
SERVER-54486: Clear resharding filtering metadata on primary stepUp.
Diffstat (limited to 'src/mongo/db/s')
-rw-r--r--src/mongo/db/s/collection_metadata.cpp6
-rw-r--r--src/mongo/db/s/collection_metadata.h6
-rw-r--r--src/mongo/db/s/resharding/resharding_donor_recipient_common.cpp48
-rw-r--r--src/mongo/db/s/resharding/resharding_donor_recipient_common.h2
-rw-r--r--src/mongo/db/s/resharding/resharding_donor_recipient_common_test.cpp78
-rw-r--r--src/mongo/db/s/resharding/resharding_donor_recipient_common_test.h30
-rw-r--r--src/mongo/db/s/resharding_util.cpp2
7 files changed, 169 insertions, 3 deletions
diff --git a/src/mongo/db/s/collection_metadata.cpp b/src/mongo/db/s/collection_metadata.cpp
index 86744c1594f..518f5405085 100644
--- a/src/mongo/db/s/collection_metadata.cpp
+++ b/src/mongo/db/s/collection_metadata.cpp
@@ -184,6 +184,12 @@ void CollectionMetadata::toBSONBasic(BSONObjBuilder& bb) const {
}
}
+BSONObj CollectionMetadata::toBSON() const {
+ BSONObjBuilder builder;
+ toBSONBasic(builder);
+ return builder.obj();
+}
+
std::string CollectionMetadata::toStringBasic() const {
if (isSharded()) {
return str::stream() << "collection version: " << _cm->getVersion().toString()
diff --git a/src/mongo/db/s/collection_metadata.h b/src/mongo/db/s/collection_metadata.h
index 13fe79d78e0..a742b77726f 100644
--- a/src/mongo/db/s/collection_metadata.h
+++ b/src/mongo/db/s/collection_metadata.h
@@ -170,11 +170,17 @@ public:
*/
void toBSONBasic(BSONObjBuilder& bb) const;
+ BSONObj toBSON() const;
+
/**
* String output of the collection and shard versions.
*/
std::string toStringBasic() const;
+ std::string toString() const {
+ return toStringBasic();
+ }
+
//
// Methods used for orphan filtering and general introspection of the chunks owned by the shard
//
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 df03a16bddb..8c95024d108 100644
--- a/src/mongo/db/s/resharding/resharding_donor_recipient_common.cpp
+++ b/src/mongo/db/s/resharding/resharding_donor_recipient_common.cpp
@@ -32,14 +32,17 @@
#include "mongo/platform/basic.h"
#include "mongo/db/s/resharding/resharding_donor_recipient_common.h"
-#include "mongo/db/storage/duplicate_key_error_info.h"
#include <fmt/format.h>
+#include "mongo/db/persistent_task_store.h"
+#include "mongo/db/s/shard_filtering_metadata_refresh.h"
#include "mongo/db/s/sharding_state.h"
+#include "mongo/db/storage/duplicate_key_error_info.h"
#include "mongo/logv2/log.h"
#include "mongo/s/catalog/sharding_catalog_client.h"
#include "mongo/s/grid.h"
+#include "mongo/stdx/unordered_set.h"
namespace mongo {
namespace resharding {
@@ -376,6 +379,49 @@ void processReshardingFieldsForCollection(OperationContext* opCtx,
}
}
+void clearFilteringMetadata(OperationContext* opCtx, bool scheduleAsyncRefresh) {
+ stdx::unordered_set<NamespaceString> namespacesToRefresh;
+ for (const NamespaceString homeToReshardingDocs :
+ {NamespaceString::kDonorReshardingOperationsNamespace,
+ NamespaceString::kRecipientReshardingOperationsNamespace}) {
+ PersistentTaskStore<CommonReshardingMetadata> store(homeToReshardingDocs);
+
+ store.forEach(opCtx, Query(), [&](CommonReshardingMetadata reshardingDoc) -> bool {
+ namespacesToRefresh.insert(reshardingDoc.getSourceNss());
+ namespacesToRefresh.insert(reshardingDoc.getTempReshardingNss());
+
+ return true;
+ });
+ }
+
+ for (const auto& nss : namespacesToRefresh) {
+ AutoGetCollection autoColl(opCtx, nss, MODE_IX);
+ CollectionShardingRuntime::get(opCtx, nss)->clearFilteringMetadata(opCtx);
+
+ if (!scheduleAsyncRefresh) {
+ continue;
+ }
+
+ ExecutorFuture<void>(Grid::get(opCtx)->getExecutorPool()->getFixedExecutor())
+ .then([svcCtx = opCtx->getServiceContext(), nss] {
+ ThreadClient tc("TriggerReshardingRecovery", svcCtx);
+ {
+ stdx::lock_guard<Client> lk(*tc.get());
+ tc->setSystemOperationKillableByStepdown(lk);
+ }
+
+ auto opCtx = tc->makeOperationContext();
+ onShardVersionMismatch(opCtx.get(), nss, boost::none /* shardVersionReceived */);
+ })
+ .onError([](const Status& status) {
+ LOGV2_WARNING(5498101,
+ "Error on deferred shardVersion recovery execution",
+ "error"_attr = redact(status));
+ })
+ .getAsync([](auto) {});
+ }
+}
+
} // namespace resharding
} // namespace mongo
diff --git a/src/mongo/db/s/resharding/resharding_donor_recipient_common.h b/src/mongo/db/s/resharding/resharding_donor_recipient_common.h
index bf016473582..0a103ef3619 100644
--- a/src/mongo/db/s/resharding/resharding_donor_recipient_common.h
+++ b/src/mongo/db/s/resharding/resharding_donor_recipient_common.h
@@ -76,6 +76,8 @@ void processReshardingFieldsForCollection(OperationContext* opCtx,
const CollectionMetadata& metadata,
const ReshardingFields& reshardingFields);
+void clearFilteringMetadata(OperationContext* opCtx, bool scheduleAsyncRefresh);
+
} // namespace resharding
} // namespace mongo
diff --git a/src/mongo/db/s/resharding/resharding_donor_recipient_common_test.cpp b/src/mongo/db/s/resharding/resharding_donor_recipient_common_test.cpp
index 6bfdd45bbe8..9768b725524 100644
--- a/src/mongo/db/s/resharding/resharding_donor_recipient_common_test.cpp
+++ b/src/mongo/db/s/resharding/resharding_donor_recipient_common_test.cpp
@@ -31,12 +31,15 @@
#include "mongo/db/s/resharding/resharding_donor_recipient_common_test.h"
+#include "mongo/db/catalog/drop_database.h"
#include "mongo/db/catalog_raii.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/dbdirectclient.h"
+#include "mongo/db/persistent_task_store.h"
#include "mongo/db/repl/wait_for_majority_service.h"
#include "mongo/db/s/collection_sharding_runtime.h"
#include "mongo/db/s/operation_sharding_state.h"
+#include "mongo/db/s/resharding/donor_document_gen.h"
#include "mongo/db/s/resharding/resharding_donor_recipient_common.h"
#include "mongo/db/s/shard_server_test_fixture.h"
#include "mongo/unittest/death_test.h"
@@ -213,6 +216,81 @@ TEST_F(ReshardingDonorRecipientCommonTest, ProcessReshardingFieldsWithoutDonorOr
5274201);
}
+TEST_F(ReshardingDonorRecipientCommonTest, ClearReshardingFilteringMetaData) {
+ OperationContext* opCtx = operationContext();
+
+ const bool scheduleAsyncRefresh = false;
+ auto doSetupFunc = [&] {
+ // Clear out the resharding donor/recipient metadata collections.
+ for (auto const& nss : {NamespaceString::kDonorReshardingOperationsNamespace,
+ NamespaceString::kRecipientReshardingOperationsNamespace}) {
+ dropDatabase(opCtx, nss.db().toString()).ignore();
+ }
+
+ // Assert the prestate has no filtering metadata.
+ for (auto const& nss : {kOriginalNss, kTemporaryReshardingNss}) {
+ AutoGetCollection autoColl(opCtx, nss, LockMode::MODE_IS);
+ auto csr = CollectionShardingRuntime::get(opCtx, nss);
+ ASSERT(csr->getCurrentMetadataIfKnown() == boost::none);
+ }
+
+ // Add filtering metadata for the collection being resharded.
+ {
+ AutoGetCollection autoColl(opCtx, kOriginalNss, LockMode::MODE_IS);
+ auto csr = CollectionShardingRuntime::get(opCtx, kOriginalNss);
+ csr->setFilteringMetadata(opCtx,
+ makeShardedMetadataForOriginalCollection(opCtx, kThisShard));
+ ASSERT(csr->getCurrentMetadataIfKnown());
+ }
+
+ // Add filtering metadata for the temporary resharding namespace.
+ {
+ AutoGetCollection autoColl(opCtx, kTemporaryReshardingNss, LockMode::MODE_IS);
+ auto csr = CollectionShardingRuntime::get(opCtx, kTemporaryReshardingNss);
+ csr->setFilteringMetadata(
+ opCtx, makeShardedMetadataForTemporaryReshardingCollection(opCtx, kThisShard));
+ ASSERT(csr->getCurrentMetadataIfKnown());
+ }
+
+ // Prior to adding a resharding document, assert that attempting to clear filtering does
+ // nothing.
+ resharding::clearFilteringMetadata(opCtx, scheduleAsyncRefresh);
+
+ for (auto const& nss : {kOriginalNss, kTemporaryReshardingNss}) {
+ AutoGetCollection autoColl(opCtx, nss, LockMode::MODE_IS);
+ auto csr = CollectionShardingRuntime::get(opCtx, nss);
+ ASSERT(csr->getCurrentMetadataIfKnown());
+ }
+ };
+
+ doSetupFunc();
+ // Add a resharding donor document that targets the namespaces involved in resharding.
+ ReshardingDonorDocument donorDoc = makeDonorStateDoc();
+ ReshardingDonorService::DonorStateMachine::insertStateDocument(opCtx, donorDoc);
+
+ // Clear the filtering metadata (without scheduling a refresh) and assert the metadata is gone.
+ resharding::clearFilteringMetadata(opCtx, scheduleAsyncRefresh);
+
+ for (auto const& nss : {kOriginalNss, kTemporaryReshardingNss}) {
+ AutoGetCollection autoColl(opCtx, nss, LockMode::MODE_IS);
+ auto csr = CollectionShardingRuntime::get(opCtx, nss);
+ ASSERT(csr->getCurrentMetadataIfKnown() == boost::none);
+ }
+
+ doSetupFunc();
+ // Add a resharding recipient document that targets the namespaces involved in resharding.
+ ReshardingRecipientDocument recipDoc = makeRecipientStateDoc();
+ ReshardingRecipientService::RecipientStateMachine::insertStateDocument(opCtx, recipDoc);
+
+ // Clear the filtering metadata (without scheduling a refresh) and assert the metadata is gone.
+ resharding::clearFilteringMetadata(opCtx, scheduleAsyncRefresh);
+
+ for (auto const& nss : {kOriginalNss, kTemporaryReshardingNss}) {
+ AutoGetCollection autoColl(opCtx, nss, LockMode::MODE_IS);
+ auto csr = CollectionShardingRuntime::get(opCtx, nss);
+ ASSERT(csr->getCurrentMetadataIfKnown() == boost::none);
+ }
+}
} // namespace
} // namespace mongo
diff --git a/src/mongo/db/s/resharding/resharding_donor_recipient_common_test.h b/src/mongo/db/s/resharding/resharding_donor_recipient_common_test.h
index b707a975444..f2f4ee7001f 100644
--- a/src/mongo/db/s/resharding/resharding_donor_recipient_common_test.h
+++ b/src/mongo/db/s/resharding/resharding_donor_recipient_common_test.h
@@ -126,6 +126,36 @@ protected:
return CollectionMetadata(std::move(cm), kThisShard);
}
+ ReshardingDonorDocument makeDonorStateDoc() {
+ DonorShardContext donorCtx;
+ donorCtx.setState(DonorStateEnum::kPreparingToDonate);
+
+ ReshardingDonorDocument doc(std::move(donorCtx), {kThisShard, kOtherShard});
+
+ NamespaceString sourceNss = kOriginalNss;
+ auto sourceUUID = UUID::gen();
+ auto commonMetadata = CommonReshardingMetadata(
+ UUID::gen(), sourceNss, sourceUUID, kTemporaryReshardingNss, kReshardingKeyPattern);
+
+ doc.setCommonReshardingMetadata(std::move(commonMetadata));
+ return doc;
+ }
+
+ ReshardingRecipientDocument makeRecipientStateDoc() {
+ RecipientShardContext recipCtx;
+ recipCtx.setState(RecipientStateEnum::kCloning);
+
+ ReshardingRecipientDocument doc(std::move(recipCtx), {kThisShard, kOtherShard}, 1000);
+
+ NamespaceString sourceNss = kOriginalNss;
+ auto sourceUUID = UUID::gen();
+ auto commonMetadata = CommonReshardingMetadata(
+ UUID::gen(), sourceNss, sourceUUID, kTemporaryReshardingNss, kReshardingKeyPattern);
+
+ doc.setCommonReshardingMetadata(std::move(commonMetadata));
+ return doc;
+ }
+
ReshardingFields createCommonReshardingFields(const UUID& reshardingUUID,
CoordinatorStateEnum state) {
auto fields = ReshardingFields(reshardingUUID);
diff --git a/src/mongo/db/s/resharding_util.cpp b/src/mongo/db/s/resharding_util.cpp
index 10bb3fcc583..b96711fd30b 100644
--- a/src/mongo/db/s/resharding_util.cpp
+++ b/src/mongo/db/s/resharding_util.cpp
@@ -177,7 +177,6 @@ void validateReshardedChunks(const std::vector<mongo::BSONObj>& chunks,
Grid::get(opCtx)->shardRegistry()->getShard(opCtx, chunk.getRecipientShardId()));
validChunks.push_back(chunk);
}
-
checkForHolesAndOverlapsInChunks(validChunks, keyPattern);
}
@@ -527,5 +526,4 @@ NamespaceString getLocalConflictStashNamespace(UUID existingUUID, ShardId donorS
"localReshardingConflictStash.{}.{}"_format(existingUUID.toString(),
donorShardId.toString())};
}
-
} // namespace mongo