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_sharding_state.cpp22
-rw-r--r--src/mongo/db/s/collection_sharding_state.h9
-rw-r--r--src/mongo/db/s/collection_sharding_state_test.cpp11
-rw-r--r--src/mongo/db/s/metadata_manager.cpp58
-rw-r--r--src/mongo/db/s/metadata_manager.h11
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source.h2
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp3
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy.h2
8 files changed, 40 insertions, 78 deletions
diff --git a/src/mongo/db/s/collection_sharding_state.cpp b/src/mongo/db/s/collection_sharding_state.cpp
index b5a9217352f..4ad6a464009 100644
--- a/src/mongo/db/s/collection_sharding_state.cpp
+++ b/src/mongo/db/s/collection_sharding_state.cpp
@@ -267,17 +267,6 @@ boost::optional<KeyRange> CollectionShardingState::getNextOrphanRange(BSONObj co
return _metadataManager->getNextOrphanRange(from);
}
-bool CollectionShardingState::isDocumentInMigratingChunk(OperationContext* opCtx,
- const BSONObj& doc) {
- dassert(opCtx->lockState()->isCollectionLockedForMode(_nss.ns(), MODE_IX));
-
- if (_sourceMgr) {
- return _sourceMgr->getCloner()->isDocumentInMigratingChunk(opCtx, doc);
- }
-
- return false;
-}
-
void CollectionShardingState::onInsertOp(OperationContext* opCtx, const BSONObj& insertedDoc) {
dassert(opCtx->lockState()->isCollectionLockedForMode(_nss.ns(), MODE_IX));
@@ -330,11 +319,12 @@ void CollectionShardingState::onUpdateOp(OperationContext* opCtx,
}
}
-CollectionShardingState::DeleteState::DeleteState(OperationContext* opCtx,
- CollectionShardingState* css,
- BSONObj const& doc)
- : documentKey(css->_metadataManager->extractDocumentKey(doc).getOwned()),
- isMigrating(css->_sourceMgr && css->isDocumentInMigratingChunk(opCtx, doc)) {}
+auto CollectionShardingState::makeDeleteState(BSONObj const& doc) -> DeleteState {
+ BSONObj documentKey = getMetadata().extractDocumentKey(doc).getOwned();
+ invariant(documentKey.hasField("_id"_sd));
+ return {std::move(documentKey),
+ _sourceMgr && _sourceMgr->getCloner()->isDocumentInMigratingChunk(doc)};
+}
void CollectionShardingState::onDeleteOp(OperationContext* opCtx,
const CollectionShardingState::DeleteState& deleteState) {
diff --git a/src/mongo/db/s/collection_sharding_state.h b/src/mongo/db/s/collection_sharding_state.h
index 5d4393346e3..c94b64aeef3 100644
--- a/src/mongo/db/s/collection_sharding_state.h
+++ b/src/mongo/db/s/collection_sharding_state.h
@@ -71,12 +71,9 @@ public:
~CollectionShardingState();
/**
- * Holds information used for tracking document removals during chunk migration.
+ * Details of documents being removed from a sharded collection.
*/
struct DeleteState {
- DeleteState() = default;
- DeleteState(OperationContext*, CollectionShardingState*, BSONObj const& doc);
-
// Contains the fields of the document that are in the collection's shard key, and "_id".
BSONObj documentKey;
@@ -86,6 +83,8 @@ public:
bool isMigrating;
};
+ DeleteState makeDeleteState(BSONObj const& doc);
+
/**
* Obtains the sharding state for the specified collection. If it does not exist, it will be
* created and will remain active until the collection is dropped or unsharded.
@@ -224,7 +223,6 @@ public:
*
* The global exclusive lock is expected to be held by the caller of any of these functions.
*/
- bool isDocumentInMigratingChunk(OperationContext* opCtx, const BSONObj& doc);
void onInsertOp(OperationContext* opCtx, const BSONObj& insertedDoc);
void onUpdateOp(OperationContext* opCtx,
const BSONObj& query,
@@ -327,7 +325,6 @@ private:
int maxToDelete,
CollectionRangeDeleter*)
-> boost::optional<Date_t>;
- friend DeleteState;
};
} // namespace mongo
diff --git a/src/mongo/db/s/collection_sharding_state_test.cpp b/src/mongo/db/s/collection_sharding_state_test.cpp
index 3411becdf34..844727e72c4 100644
--- a/src/mongo/db/s/collection_sharding_state_test.cpp
+++ b/src/mongo/db/s/collection_sharding_state_test.cpp
@@ -196,7 +196,7 @@ TEST_F(CollShardingStateTest, MakeDeleteStateUnsharded) {
// First, check that an order for deletion from an unsharded collection (where css has not been
// "refreshed" with chunk metadata) extracts just the "_id" field:
- auto deleteState = CollectionShardingState::DeleteState(operationContext(), css, doc);
+ auto deleteState = css->makeDeleteState(doc);
ASSERT_BSONOBJ_EQ(deleteState.documentKey, BSON("_id" << "hello"));
ASSERT_FALSE(deleteState.isMigrating);
}
@@ -212,7 +212,7 @@ TEST_F(CollShardingStateTest, MakeDeleteStateShardedWithoutIdInShardKey) {
auto doc = BSON("key3" << "abc" << "key" << 100 << "_id" << "hello" << "key2" << true);
// Verify the shard key is extracted, in correct order, followed by the "_id" field.
- auto deleteState = CollectionShardingState::DeleteState(operationContext(), css, doc);
+ auto deleteState = css->makeDeleteState(doc);
ASSERT_BSONOBJ_EQ(
deleteState.documentKey, BSON("key" << 100 << "key3" << "abc" << "_id" << "hello"));
ASSERT_FALSE(deleteState.isMigrating);
@@ -230,7 +230,7 @@ TEST_F(CollShardingStateTest, MakeDeleteStateShardedWithIdInShardKey) {
auto doc = BSON("key2" << true << "key3" << "abc" << "_id" << "hello" << "key" << 100);
// Verify the shard key is extracted with "_id" in the right place.
- auto deleteState = CollectionShardingState::DeleteState(operationContext(), css, doc);
+ auto deleteState = css->makeDeleteState(doc);
ASSERT_BSONOBJ_EQ(
deleteState.documentKey, BSON("key" << 100 << "_id" << "hello" << "key2" << true));
ASSERT_FALSE(deleteState.isMigrating);
@@ -247,9 +247,8 @@ TEST_F(CollShardingStateTest, MakeDeleteStateShardedWithIdHashInShardKey) {
auto doc = BSON("key2" << true << "_id" << "hello" << "key" << 100);
// Verify the shard key is extracted with "_id" in the right place, not hashed.
- auto deleteState = CollectionShardingState::DeleteState(operationContext(), css, doc);
- ASSERT_BSONOBJ_EQ(
- deleteState.documentKey, BSON("_id" << "hello"));
+ auto deleteState = css->makeDeleteState(doc);
+ ASSERT_BSONOBJ_EQ(deleteState.documentKey, BSON("_id" << "hello"));
ASSERT_FALSE(deleteState.isMigrating);
}
} // unnamed namespace
diff --git a/src/mongo/db/s/metadata_manager.cpp b/src/mongo/db/s/metadata_manager.cpp
index 88450d4da96..d975a785e4e 100644
--- a/src/mongo/db/s/metadata_manager.cpp
+++ b/src/mongo/db/s/metadata_manager.cpp
@@ -35,6 +35,7 @@
#include "mongo/base/string_data.h"
#include "mongo/bson/simple_bsonobj_comparator.h"
#include "mongo/bson/util/builder.h"
+#include "mongo/db/bson/dotted_path_support.h"
#include "mongo/db/db_raii.h"
#include "mongo/db/query/internal_plans.h"
#include "mongo/db/range_arithmetic.h"
@@ -277,6 +278,22 @@ ScopedCollectionMetadata::ScopedCollectionMetadata(std::shared_ptr<MetadataManag
++_metadata->_tracker.usageCounter;
}
+BSONObj ScopedCollectionMetadata::extractDocumentKey(BSONObj const& doc) const {
+ BSONObj key;
+ if (*this) { // is sharded
+ auto const& pattern = _metadata->_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"_sd]) {
+ return key.isEmpty() ? id.wrap() : BSONObjBuilder(std::move(key)).append(id).obj();
+ }
+ return key;
+}
+
ScopedCollectionMetadata::~ScopedCollectionMetadata() {
_clear();
}
@@ -571,45 +588,4 @@ boost::optional<KeyRange> MetadataManager::getNextOrphanRange(BSONObj const& fro
return _metadata.back()->getNextOrphanRange(_receivingChunks, from);
}
-namespace {
-
-static BSONElement extractKeyElement(const BSONObj& doc, StringData pathStr) {
- ElementPath path(pathStr, false, false);
- BSONElementIterator elemIter(&path, doc);
- if (!elemIter.more()) {
- return {};
- }
- BSONElement matchEl = elemIter.next().element();
- // We shouldn't have more than one element - we don't expand arrays
- dassert(!elemIter.more());
- return matchEl;
-}
-
-} // namespace
-
-BSONObj MetadataManager::extractDocumentKey(BSONObj const& doc) {
- BSONObjBuilder keyBuilder;
- bool gotId = false;
- {
- stdx::lock_guard<stdx::mutex> scopedLock(_managerLock);
- if (!_metadata.empty()) {
- BSONObjIterator patternIt(_metadata.back()->_cm->getShardKeyPattern().toBSON());
- while (patternIt.more()) {
- BSONElement patternEl = patternIt.next();
- BSONElement matchEl = extractKeyElement(doc, patternEl.fieldNameStringData());
- if (matchEl.ok()) {
- if (patternEl.fieldNameStringData() == StringData("_id")) {
- gotId = true;
- }
- keyBuilder.appendAs(matchEl, patternEl.fieldName());
- }
- }
- }
- }
- if (!gotId && doc.hasField("_id")) {
- keyBuilder.append(doc["_id"]);
- }
- return keyBuilder.obj();
-}
-
} // namespace mongo
diff --git a/src/mongo/db/s/metadata_manager.h b/src/mongo/db/s/metadata_manager.h
index 7a15e47d709..48cd08df125 100644
--- a/src/mongo/db/s/metadata_manager.h
+++ b/src/mongo/db/s/metadata_manager.h
@@ -140,11 +140,6 @@ public:
boost::optional<KeyRange> getNextOrphanRange(BSONObj const& from);
- /**
- * Returns just the shard key fields, if collection is sharded, and the _id field, from `doc`.
- */
- BSONObj extractDocumentKey(BSONObj const& doc);
-
private:
// All of the following functions must be called while holding _managerLock.
@@ -266,6 +261,12 @@ public:
CollectionMetadata* getMetadata() const;
/**
+ * Returns just the shard key fields, if collection is sharded, and the _id field, from `doc`.
+ * Does not alter any field values (e.g. by hashing); values are copied verbatim.
+ */
+ BSONObj extractDocumentKey(BSONObj const& doc) const;
+
+ /**
* True if the ScopedCollectionMetadata stores a metadata (is not empty) and the collection is
* sharded.
*/
diff --git a/src/mongo/db/s/migration_chunk_cloner_source.h b/src/mongo/db/s/migration_chunk_cloner_source.h
index 50a31da4db6..750bcdcda80 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source.h
+++ b/src/mongo/db/s/migration_chunk_cloner_source.h
@@ -109,7 +109,7 @@ public:
*
* NOTE: Must be called with at least IS lock held on the collection.
*/
- virtual bool isDocumentInMigratingChunk(OperationContext* opCtx, const BSONObj& doc) = 0;
+ virtual bool isDocumentInMigratingChunk(const BSONObj& doc) = 0;
/**
* Notifies this cloner that an insert happened to the collection, which it owns. It is up to
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
index 2a60f3fbc8a..70a76e5e473 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy.cpp
@@ -339,8 +339,7 @@ void MigrationChunkClonerSourceLegacy::cancelClone(OperationContext* opCtx) {
}
}
-bool MigrationChunkClonerSourceLegacy::isDocumentInMigratingChunk(OperationContext* opCtx,
- const BSONObj& doc) {
+bool MigrationChunkClonerSourceLegacy::isDocumentInMigratingChunk(const BSONObj& doc) {
return isInRange(doc, _args.getMinKey(), _args.getMaxKey(), _shardKeyPattern);
}
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy.h b/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
index 28eca3989c5..c072718475a 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
@@ -70,7 +70,7 @@ public:
void cancelClone(OperationContext* opCtx) override;
- bool isDocumentInMigratingChunk(OperationContext* opCtx, const BSONObj& doc) override;
+ bool isDocumentInMigratingChunk(const BSONObj& doc) override;
void onInsertOp(OperationContext* opCtx, const BSONObj& insertedDoc) override;