summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBlake Oler <blake.oler@mongodb.com>2020-04-06 11:09:36 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-04-06 23:27:50 +0000
commit6c88549226e8f68f06b19d9e9a1e0b5f756494b0 (patch)
tree84b0a86115190bb40bff1b7d51406a81945173f9 /src
parent1467c9ba4781aea4ba1663b469576cfb9a74d57b (diff)
downloadmongo-6c88549226e8f68f06b19d9e9a1e0b5f756494b0.tar.gz
SERVER-46845 Allow logging operations to bypass ShardInvalidatedForTargeting exception when accessing shard versions
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/s/collection_metadata.cpp4
-rw-r--r--src/mongo/db/s/collection_metadata.h14
-rw-r--r--src/mongo/s/chunk_manager.cpp13
-rw-r--r--src/mongo/s/chunk_manager.h17
4 files changed, 44 insertions, 4 deletions
diff --git a/src/mongo/db/s/collection_metadata.cpp b/src/mongo/db/s/collection_metadata.cpp
index 0738c4e1cee..4ac6cfbda2d 100644
--- a/src/mongo/db/s/collection_metadata.cpp
+++ b/src/mongo/db/s/collection_metadata.cpp
@@ -69,7 +69,7 @@ BSONObj CollectionMetadata::extractDocumentKey(const BSONObj& doc) const {
void CollectionMetadata::toBSONBasic(BSONObjBuilder& bb) const {
if (isSharded()) {
_cm->getVersion().appendLegacyWithField(&bb, "collVersion");
- getShardVersion().appendLegacyWithField(&bb, "shardVersion");
+ getShardVersionForLogging().appendLegacyWithField(&bb, "shardVersion");
bb.append("keyPattern", _cm->getShardKeyPattern().toBSON());
} else {
ChunkVersion::UNSHARDED().appendLegacyWithField(&bb, "collVersion");
@@ -80,7 +80,7 @@ void CollectionMetadata::toBSONBasic(BSONObjBuilder& bb) const {
std::string CollectionMetadata::toStringBasic() const {
if (isSharded()) {
return str::stream() << "collection version: " << _cm->getVersion().toString()
- << ", shard version: " << getShardVersion().toString();
+ << ", shard version: " << getShardVersionForLogging().toString();
} else {
return "collection version: <unsharded>";
}
diff --git a/src/mongo/db/s/collection_metadata.h b/src/mongo/db/s/collection_metadata.h
index 824787506f4..be575a983ed 100644
--- a/src/mongo/db/s/collection_metadata.h
+++ b/src/mongo/db/s/collection_metadata.h
@@ -71,12 +71,26 @@ public:
/**
* Returns the current shard version for the collection or UNSHARDED if it is not sharded.
+ *
+ * Will throw ShardInvalidatedForTargeting if _thisShardId is marked as stale by
+ * the CollectionMetadata's current chunk manager.
*/
ChunkVersion getShardVersion() const {
return (isSharded() ? _cm->getVersion(_thisShardId) : ChunkVersion::UNSHARDED());
}
/**
+ * Returns the current shard version for the collection or UNSHARDED if it is not sharded.
+ *
+ * Will not throw an exception if _thisShardId is marked as stale by the CollectionMetadata's
+ * current chunk manager. Only use this function when logging the returned ChunkVersion. If the
+ * caller must execute logic based on the returned ChunkVersion, use getShardVersion() instead.
+ */
+ ChunkVersion getShardVersionForLogging() const {
+ return (isSharded() ? _cm->getVersionForLogging(_thisShardId) : ChunkVersion::UNSHARDED());
+ }
+
+ /**
* Returns the current collection version or UNSHARDED if it is not sharded.
*/
ChunkVersion getCollVersion() const {
diff --git a/src/mongo/s/chunk_manager.cpp b/src/mongo/s/chunk_manager.cpp
index aa0eb056623..9e1d8a1ae5e 100644
--- a/src/mongo/s/chunk_manager.cpp
+++ b/src/mongo/s/chunk_manager.cpp
@@ -431,7 +431,8 @@ bool RoutingTableHistory::compatibleWith(const RoutingTableHistory& other,
return other.getVersion(shardName) == getVersion(shardName);
}
-ChunkVersion RoutingTableHistory::getVersion(const ShardId& shardName) const {
+ChunkVersion RoutingTableHistory::_getVersion(const ShardId& shardName,
+ bool throwOnStaleShard) const {
auto it = _shardVersions.find(shardName);
if (it == _shardVersions.end()) {
// Shards without explicitly tracked shard versions (meaning they have no chunks) always
@@ -439,7 +440,7 @@ ChunkVersion RoutingTableHistory::getVersion(const ShardId& shardName) const {
return ChunkVersion(0, 0, _collectionVersion.epoch());
}
- if (gEnableFinerGrainedCatalogCacheRefresh) {
+ if (throwOnStaleShard && gEnableFinerGrainedCatalogCacheRefresh) {
uassert(ShardInvalidatedForTargetingInfo(_nss),
"shard has been marked stale",
!it->second.isStale.load());
@@ -448,6 +449,14 @@ ChunkVersion RoutingTableHistory::getVersion(const ShardId& shardName) const {
return it->second.shardVersion;
}
+ChunkVersion RoutingTableHistory::getVersion(const ShardId& shardName) const {
+ return _getVersion(shardName, true);
+}
+
+ChunkVersion RoutingTableHistory::getVersionForLogging(const ShardId& shardName) const {
+ return _getVersion(shardName, false);
+}
+
std::string RoutingTableHistory::toString() const {
StringBuilder sb;
sb << "RoutingTableHistory: " << _nss.ns() << " key: " << _shardKeyPattern.toString() << '\n';
diff --git a/src/mongo/s/chunk_manager.h b/src/mongo/s/chunk_manager.h
index d3a67ff1631..6b4f97766ca 100644
--- a/src/mongo/s/chunk_manager.h
+++ b/src/mongo/s/chunk_manager.h
@@ -144,8 +144,19 @@ public:
return _collectionVersion;
}
+ /**
+ * Retrieves the shard version for the given shard. Will throw a ShardInvalidatedForTargeting
+ * exception if the shard is marked as stale.
+ */
ChunkVersion getVersion(const ShardId& shardId) const;
+ /**
+ * Retrieves the shard version for the given shard. Will not throw if the shard is marked as
+ * stale. Only use when logging the given chunk version -- if the caller must execute logic
+ * based on the returned version, use getVersion() instead.
+ */
+ ChunkVersion getVersionForLogging(const ShardId& shardId) const;
+
const ChunkInfoMap& getChunkMap() const {
return _chunkMap;
}
@@ -193,6 +204,8 @@ private:
*/
ShardVersionMap _constructShardVersionMap() const;
+ ChunkVersion _getVersion(const ShardId& shardName, bool throwOnStaleShard) const;
+
std::string _extractKeyString(const BSONObj& shardKeyValue) const;
// The shard versioning mechanism hinges on keeping track of the number of times we reload
@@ -317,6 +330,10 @@ public:
return _rt->getVersion(shardId);
}
+ ChunkVersion getVersionForLogging(const ShardId& shardId) const {
+ return _rt->getVersionForLogging(shardId);
+ }
+
ConstRangeOfChunks chunks() const {
return {ConstChunkIterator{_rt->getChunkMap().cbegin(), _clusterTime},
ConstChunkIterator{_rt->getChunkMap().cend(), _clusterTime}};