summaryrefslogtreecommitdiff
path: root/src/mongo/db/s
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/s')
-rw-r--r--src/mongo/db/s/collection_metadata.cpp110
-rw-r--r--src/mongo/db/s/collection_metadata.h110
-rw-r--r--src/mongo/db/s/collection_metadata_filtering_test.cpp6
-rw-r--r--src/mongo/db/s/collection_sharding_state.cpp27
-rw-r--r--src/mongo/db/s/collection_sharding_state.h26
-rw-r--r--src/mongo/db/s/get_shard_version_command.cpp2
-rw-r--r--src/mongo/db/s/op_observer_sharding_impl.cpp1
-rw-r--r--src/mongo/db/s/shard_server_op_observer.cpp4
8 files changed, 134 insertions, 152 deletions
diff --git a/src/mongo/db/s/collection_metadata.cpp b/src/mongo/db/s/collection_metadata.cpp
index 108395683d8..19c7b60a759 100644
--- a/src/mongo/db/s/collection_metadata.cpp
+++ b/src/mongo/db/s/collection_metadata.cpp
@@ -47,46 +47,6 @@ namespace mongo {
CollectionMetadata::CollectionMetadata(std::shared_ptr<ChunkManager> cm, const ShardId& thisShardId)
: _cm(std::move(cm)), _thisShardId(thisShardId) {}
-BSONObj CollectionMetadata::extractDocumentKey(const BSONObj& doc) const {
- BSONObj key;
-
- if (isSharded()) {
- auto const& pattern = _cm->getShardKeyPattern();
- key = dotted_path_support::extractElementsBasedOnTemplate(doc, pattern.toBSON());
- if (pattern.hasId()) {
- return key;
- }
- // else, try to append an _id field from the document.
- }
-
- if (auto id = doc["_id"]) {
- return key.isEmpty() ? id.wrap() : BSONObjBuilder(std::move(key)).append(id).obj();
- }
-
- // For legacy documents that lack an _id, use the document itself as its key.
- return doc;
-}
-
-void CollectionMetadata::toBSONBasic(BSONObjBuilder& bb) const {
- if (isSharded()) {
- _cm->getVersion().appendLegacyWithField(&bb, "collVersion");
- getShardVersion().appendLegacyWithField(&bb, "shardVersion");
- bb.append("keyPattern", _cm->getShardKeyPattern().toBSON());
- } else {
- ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "collVersion");
- ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "shardVersion");
- }
-}
-
-std::string CollectionMetadata::toStringBasic() const {
- if (isSharded()) {
- return str::stream() << "collection version: " << _cm->getVersion().toString()
- << ", shard version: " << getShardVersion().toString();
- } else {
- return "collection version: <unsharded>";
- }
-}
-
RangeMap CollectionMetadata::getChunks() const {
invariant(isSharded());
@@ -153,8 +113,62 @@ Status CollectionMetadata::checkChunkIsValid(const ChunkType& chunk) const {
return Status::OK();
}
+BSONObj CollectionMetadata::extractDocumentKey(BSONObj const& doc) const {
+ BSONObj key;
+
+ if (isSharded()) {
+ auto const& pattern = getChunkManager()->getShardKeyPattern();
+ key = dotted_path_support::extractElementsBasedOnTemplate(doc, pattern.toBSON());
+ if (pattern.hasId()) {
+ return key;
+ }
+ // else, try to append an _id field from the document.
+ }
+
+ if (auto id = doc["_id"]) {
+ return key.isEmpty() ? id.wrap() : BSONObjBuilder(std::move(key)).append(id).obj();
+ }
+
+ // For legacy documents that lack an _id, use the document itself as its key.
+ return doc;
+}
+
+void CollectionMetadata::toBSONBasic(BSONObjBuilder& bb) const {
+ if (isSharded()) {
+ _cm->getVersion().appendLegacyWithField(&bb, "collVersion");
+ getShardVersion().appendLegacyWithField(&bb, "shardVersion");
+ bb.append("keyPattern", _cm->getShardKeyPattern().toBSON());
+ } else {
+ ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "collVersion");
+ ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "shardVersion");
+ }
+}
+
+void CollectionMetadata::toBSONChunks(BSONArrayBuilder& bb) const {
+ if (!isSharded())
+ return;
+
+ for (const auto& chunk : _cm->chunks()) {
+ if (chunk.getShardId() == _thisShardId) {
+ BSONArrayBuilder chunkBB(bb.subarrayStart());
+ chunkBB.append(chunk.getMin());
+ chunkBB.append(chunk.getMax());
+ chunkBB.done();
+ }
+ }
+}
+
+std::string CollectionMetadata::toStringBasic() const {
+ if (isSharded()) {
+ return str::stream() << "collection version: " << _cm->getVersion().toString()
+ << ", shard version: " << getShardVersion().toString();
+ } else {
+ return "collection version: <unsharded>";
+ }
+}
+
boost::optional<ChunkRange> CollectionMetadata::getNextOrphanRange(
- const RangeMap& receivingChunks, const BSONObj& origLookupKey) const {
+ RangeMap const& receivingChunks, BSONObj const& origLookupKey) const {
invariant(isSharded());
const BSONObj maxKey = getMaxKey();
@@ -222,18 +236,4 @@ boost::optional<ChunkRange> CollectionMetadata::getNextOrphanRange(
return boost::none;
}
-void CollectionMetadata::toBSONChunks(BSONArrayBuilder* builder) const {
- if (!isSharded())
- return;
-
- for (const auto& chunk : _cm->chunks()) {
- if (chunk.getShardId() == _thisShardId) {
- BSONArrayBuilder chunkBB(builder->subarrayStart());
- chunkBB.append(chunk.getMin());
- chunkBB.append(chunk.getMax());
- chunkBB.done();
- }
- }
-}
-
} // namespace mongo
diff --git a/src/mongo/db/s/collection_metadata.h b/src/mongo/db/s/collection_metadata.h
index f123af36e26..ae72682ca49 100644
--- a/src/mongo/db/s/collection_metadata.h
+++ b/src/mongo/db/s/collection_metadata.h
@@ -64,7 +64,8 @@ public:
CollectionMetadata(std::shared_ptr<ChunkManager> cm, const ShardId& thisShardId);
/**
- * Returns whether this metadata object represents a sharded or unsharded collection.
+ * Returns whether this metadata object represents a sharded collection which requires
+ * filtering.
*/
bool isSharded() const {
return bool(_cm);
@@ -85,47 +86,6 @@ public:
}
/**
- * Obtains the shard id with which this collection metadata is configured.
- */
- const ShardId& shardId() const {
- invariant(isSharded());
- return _thisShardId;
- }
-
- /**
- * Returns true if 'key' contains exactly the same fields as the shard key pattern.
- */
- bool isValidKey(const BSONObj& key) const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().isShardKey(key);
- }
-
- const BSONObj& getKeyPattern() const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().toBSON();
- }
-
- const std::vector<std::unique_ptr<FieldRef>>& getKeyPatternFields() const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().getKeyPatternFields();
- }
-
- BSONObj getMinKey() const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().getKeyPattern().globalMin();
- }
-
- BSONObj getMaxKey() const {
- invariant(isSharded());
- return _cm->getShardKeyPattern().getKeyPattern().globalMax();
- }
-
- bool uuidMatches(UUID uuid) const {
- invariant(isSharded());
- return _cm->uuidMatches(uuid);
- }
-
- /**
* Returns just the shard key fields, if the collection is sharded, and the _id field, from
* `doc`. Does not alter any field values (e.g. by hashing); values are copied verbatim.
*/
@@ -137,17 +97,29 @@ public:
void toBSONBasic(BSONObjBuilder& bb) const;
/**
+ * BSON output of the chunks metadata into a BSONArray
+ */
+ void toBSONChunks(BSONArrayBuilder& bb) const;
+
+ /**
* String output of the collection and shard versions.
*/
std::string toStringBasic() const;
- //
- // Methods used for orphan filtering and general introspection of the chunks owned by the shard
- //
+ /**
+ * Obtains the shard id with which this collection metadata is configured.
+ */
+ const ShardId& shardId() const {
+ invariant(isSharded());
+ return _thisShardId;
+ }
- ChunkManager* getChunkManager() const {
+ /**
+ * Returns true if 'key' contains exactly the same fields as the shard key pattern.
+ */
+ bool isValidKey(const BSONObj& key) const {
invariant(isSharded());
- return _cm.get();
+ return _cm->getShardKeyPattern().isShardKey(key);
}
/**
@@ -180,7 +152,7 @@ public:
/**
* Returns true if the argument range overlaps any chunk.
*/
- bool rangeOverlapsChunk(const ChunkRange& range) const {
+ bool rangeOverlapsChunk(ChunkRange const& range) const {
invariant(isSharded());
return _cm->rangeOverlapsShard(range, _thisShardId);
}
@@ -203,25 +175,49 @@ public:
*
* @return orphanRange the output range. Note that the NS is not set.
*/
- boost::optional<ChunkRange> getNextOrphanRange(const RangeMap& receiveMap,
- const BSONObj& lookupKey) const;
+ boost::optional<ChunkRange> getNextOrphanRange(RangeMap const& receiveMap,
+ BSONObj const& lookupKey) const;
/**
* Returns all the chunks which are contained on this shard.
*/
RangeMap getChunks() const;
- /**
- * BSON output of the chunks metadata into a BSONArray
- */
- void toBSONChunks(BSONArrayBuilder* builder) const;
+ const BSONObj& getKeyPattern() const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().toBSON();
+ }
+
+ const std::vector<std::unique_ptr<FieldRef>>& getKeyPatternFields() const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().getKeyPatternFields();
+ }
+
+ BSONObj getMinKey() const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().getKeyPattern().globalMin();
+ }
+
+ BSONObj getMaxKey() const {
+ invariant(isSharded());
+ return _cm->getShardKeyPattern().getKeyPattern().globalMax();
+ }
+
+ std::shared_ptr<ChunkManager> getChunkManager() const {
+ invariant(isSharded());
+ return _cm;
+ }
+
+ bool uuidMatches(UUID uuid) const {
+ invariant(isSharded());
+ return _cm->uuidMatches(uuid);
+ }
private:
- // The full routing table for the collection or nullptr if the collection is not sharded
+ // The full routing table for the collection.
std::shared_ptr<ChunkManager> _cm;
- // The identity of this shard, for the purpose of answering "key belongs to me" queries. If the
- // collection is not sharded (_cm is nullptr), then this value will be empty.
+ // The identity of this shard, for the purpose of answering "key belongs to me" queries.
ShardId _thisShardId;
};
diff --git a/src/mongo/db/s/collection_metadata_filtering_test.cpp b/src/mongo/db/s/collection_metadata_filtering_test.cpp
index 00c19583b17..46db156c36a 100644
--- a/src/mongo/db/s/collection_metadata_filtering_test.cpp
+++ b/src/mongo/db/s/collection_metadata_filtering_test.cpp
@@ -141,7 +141,7 @@ TEST_F(CollectionMetadataFilteringTest, FilterDocumentsInTheFuture) {
AutoGetCollection autoColl(operationContext(), kNss, MODE_IS);
auto* const css = CollectionShardingState::get(operationContext(), kNss);
- testFn(css->getOrphansFilter(operationContext()));
+ testFn(css->getMetadataForOperation(operationContext()));
}
{
@@ -172,7 +172,7 @@ TEST_F(CollectionMetadataFilteringTest, FilterDocumentsInThePast) {
AutoGetCollection autoColl(operationContext(), kNss, MODE_IS);
auto* const css = CollectionShardingState::get(operationContext(), kNss);
- testFn(css->getOrphansFilter(operationContext()));
+ testFn(css->getMetadataForOperation(operationContext()));
}
{
@@ -211,7 +211,7 @@ TEST_F(CollectionMetadataFilteringTest, FilterDocumentsTooFarInThePastThrowsStal
AutoGetCollection autoColl(operationContext(), kNss, MODE_IS);
auto* const css = CollectionShardingState::get(operationContext(), kNss);
- testFn(css->getOrphansFilter(operationContext()));
+ testFn(css->getMetadataForOperation(operationContext()));
}
{
diff --git a/src/mongo/db/s/collection_sharding_state.cpp b/src/mongo/db/s/collection_sharding_state.cpp
index 8a3e0304146..f65f262a029 100644
--- a/src/mongo/db/s/collection_sharding_state.cpp
+++ b/src/mongo/db/s/collection_sharding_state.cpp
@@ -111,8 +111,7 @@ private:
const auto kUnshardedCollection = std::make_shared<UnshardedCollection>();
-boost::optional<ChunkVersion> getOperationReceivedVersion(OperationContext* opCtx,
- const NamespaceString& nss) {
+ChunkVersion getOperationReceivedVersion(OperationContext* opCtx, const NamespaceString& nss) {
auto& oss = OperationShardingState::get(opCtx);
// If there is a version attached to the OperationContext, use it as the received version,
@@ -126,12 +125,12 @@ boost::optional<ChunkVersion> getOperationReceivedVersion(OperationContext* opCt
// in a single call, the lack of version for a namespace on the collection must be treated
// as UNSHARDED
return connectionShardVersion.value_or(ChunkVersion::UNSHARDED());
+ } else {
+ // There is no shard version information on either 'opCtx' or 'client'. This means that the
+ // operation represented by 'opCtx' is unversioned, and the shard version is always OK for
+ // unversioned operations.
+ return ChunkVersion::IGNORED();
}
-
- // There is no shard version information on either 'opCtx' or 'client'. This means that the
- // operation represented by 'opCtx' is unversioned, and the shard version is always OK for
- // unversioned operations
- return boost::none;
}
} // namespace
@@ -152,10 +151,12 @@ void CollectionShardingState::report(OperationContext* opCtx, BSONObjBuilder* bu
collectionsMap->report(opCtx, builder);
}
-ScopedCollectionMetadata CollectionShardingState::getOrphansFilter(OperationContext* opCtx) {
+ScopedCollectionMetadata CollectionShardingState::getMetadataForOperation(OperationContext* opCtx) {
const auto receivedShardVersion = getOperationReceivedVersion(opCtx, _nss);
- if (!receivedShardVersion)
+
+ if (ChunkVersion::isIgnoredVersion(receivedShardVersion)) {
return {kUnshardedCollection};
+ }
const auto atClusterTime = repl::ReadConcernArgs::get(opCtx).getArgsAtClusterTime();
auto optMetadata = _getMetadata(atClusterTime);
@@ -192,12 +193,8 @@ boost::optional<ChunkVersion> CollectionShardingState::getCurrentShardVersionIfK
}
void CollectionShardingState::checkShardVersionOrThrow(OperationContext* opCtx) {
- const auto optReceivedShardVersion = getOperationReceivedVersion(opCtx, _nss);
-
- if (!optReceivedShardVersion)
- return;
+ const auto receivedShardVersion = getOperationReceivedVersion(opCtx, _nss);
- const auto& receivedShardVersion = *optReceivedShardVersion;
if (ChunkVersion::isIgnoredVersion(receivedShardVersion)) {
return;
}
@@ -206,7 +203,7 @@ void CollectionShardingState::checkShardVersionOrThrow(OperationContext* opCtx)
invariant(repl::ReadConcernArgs::get(opCtx).getLevel() !=
repl::ReadConcernLevel::kAvailableReadConcern);
- const auto metadata = getCurrentMetadata();
+ const auto metadata = getMetadataForOperation(opCtx);
const auto wantedShardVersion =
metadata->isSharded() ? metadata->getShardVersion() : ChunkVersion::UNSHARDED();
diff --git a/src/mongo/db/s/collection_sharding_state.h b/src/mongo/db/s/collection_sharding_state.h
index cbd7f9d563f..e964dbced12 100644
--- a/src/mongo/db/s/collection_sharding_state.h
+++ b/src/mongo/db/s/collection_sharding_state.h
@@ -73,26 +73,16 @@ public:
static void report(OperationContext* opCtx, BSONObjBuilder* builder);
/**
- * Returns the orphan chunk filtering metadata that the current operation should be using for
- * the collection.
+ * Returns the chunk filtering metadata that the current operation should be using for that
+ * collection or otherwise throws if it has not been loaded yet. If the operation does not
+ * require a specific shard version, returns an UNSHARDED metadata. The returned object is safe
+ * to access outside of collection lock.
*
- * If the operation context contains an 'atClusterTime', the returned filtering metadata will be
- * tied to a specific point in time. Otherwise, it will reference the latest time available. If
- * the operation is not associated with a shard version (refer to
- * OperationShardingState::isOperationVersioned for more info on that), returns an UNSHARDED
- * metadata object.
- *
- * The intended users of this method are callers which need to perform orphan filtering. Use
- * 'getCurrentMetadata' for all other cases, where just sharding-related properties of the
- * collection are necessary (e.g., isSharded or the shard key).
- *
- * The returned object is safe to access even after the collection lock has been dropped.
- */
- ScopedCollectionMetadata getOrphansFilter(OperationContext* opCtx);
-
- /**
- * See the comments for 'getOrphansFilter' above for more information on this method.
+ * If the operation context contains an 'atClusterTime' property, the returned filtering
+ * metadata will be tied to a specific point in time. Otherwise it will reference the latest
+ * time available.
*/
+ ScopedCollectionMetadata getMetadataForOperation(OperationContext* opCtx);
ScopedCollectionMetadata getCurrentMetadata();
/**
diff --git a/src/mongo/db/s/get_shard_version_command.cpp b/src/mongo/db/s/get_shard_version_command.cpp
index b986ffecb82..a51ce749549 100644
--- a/src/mongo/db/s/get_shard_version_command.cpp
+++ b/src/mongo/db/s/get_shard_version_command.cpp
@@ -133,7 +133,7 @@ public:
metadata->toBSONBasic(metadataBuilder);
BSONArrayBuilder chunksArr(metadataBuilder.subarrayStart("chunks"));
- metadata->toBSONChunks(&chunksArr);
+ metadata->toBSONChunks(chunksArr);
chunksArr.doneFast();
BSONArrayBuilder pendingArr(metadataBuilder.subarrayStart("pending"));
diff --git a/src/mongo/db/s/op_observer_sharding_impl.cpp b/src/mongo/db/s/op_observer_sharding_impl.cpp
index 70b090881de..0f6aaba48c4 100644
--- a/src/mongo/db/s/op_observer_sharding_impl.cpp
+++ b/src/mongo/db/s/op_observer_sharding_impl.cpp
@@ -63,7 +63,6 @@
namespace mongo {
namespace {
-
const auto getIsMigrating = OperationContext::declareDecoration<bool>();
}
diff --git a/src/mongo/db/s/shard_server_op_observer.cpp b/src/mongo/db/s/shard_server_op_observer.cpp
index 5733763902c..3078fd59396 100644
--- a/src/mongo/db/s/shard_server_op_observer.cpp
+++ b/src/mongo/db/s/shard_server_op_observer.cpp
@@ -207,7 +207,7 @@ void ShardServerOpObserver::onInserts(OperationContext* opCtx,
std::vector<InsertStatement>::const_iterator end,
bool fromMigrate) {
auto* const css = CollectionShardingState::get(opCtx, nss);
- const auto metadata = css->getCurrentMetadata();
+ const auto metadata = css->getMetadataForOperation(opCtx);
for (auto it = begin; it != end; ++it) {
const auto& insertedDoc = it->doc;
@@ -233,7 +233,7 @@ void ShardServerOpObserver::onInserts(OperationContext* opCtx,
void ShardServerOpObserver::onUpdate(OperationContext* opCtx, const OplogUpdateEntryArgs& args) {
auto* const css = CollectionShardingState::get(opCtx, args.nss);
- const auto metadata = css->getCurrentMetadata();
+ const auto metadata = css->getMetadataForOperation(opCtx);
if (args.nss == NamespaceString::kShardConfigCollectionsNamespace) {
// Notification of routing table changes are only needed on secondaries