summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan Myers <nathan.myers@10gen.com>2017-10-17 14:07:38 -0400
committerNathan Myers <nathan.myers@10gen.com>2017-10-17 14:07:38 -0400
commitaeabbf96ff3c2990f553ba0a5e6e1d18ebddab2f (patch)
treecfb67393fadfd03d0c40d5082711da5dfa44edc4 /src
parentbd0c03a8816985f74f7bd24245aa81f9cb5b37f7 (diff)
downloadmongo-aeabbf96ff3c2990f553ba0a5e6e1d18ebddab2f.tar.gz
SERVER-31191 Plumb Collection UUIDs through catalog cache
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/s/catalog_cache_loader_mock.cpp5
-rw-r--r--src/mongo/db/s/collection_metadata.h4
-rw-r--r--src/mongo/db/s/collection_metadata_test.cpp3
-rw-r--r--src/mongo/db/s/collection_range_deleter_test.cpp1
-rw-r--r--src/mongo/db/s/collection_sharding_state.cpp4
-rw-r--r--src/mongo/db/s/collection_sharding_state_test.cpp2
-rw-r--r--src/mongo/db/s/metadata_manager_test.cpp1
-rw-r--r--src/mongo/db/s/shard_metadata_util.cpp12
-rw-r--r--src/mongo/db/s/shard_metadata_util_test.cpp82
-rw-r--r--src/mongo/db/s/shard_server_catalog_cache_loader.cpp7
-rw-r--r--src/mongo/s/catalog/type_shard_collection.cpp61
-rw-r--r--src/mongo/s/catalog/type_shard_collection.h45
-rw-r--r--src/mongo/s/catalog/type_shard_collection_test.cpp54
-rw-r--r--src/mongo/s/catalog_cache.cpp1
-rw-r--r--src/mongo/s/catalog_cache_loader.cpp4
-rw-r--r--src/mongo/s/catalog_cache_loader.h5
-rw-r--r--src/mongo/s/chunk_manager.cpp5
-rw-r--r--src/mongo/s/chunk_manager.h9
-rw-r--r--src/mongo/s/config_server_catalog_cache_loader.cpp11
-rw-r--r--src/mongo/util/uuid.h2
20 files changed, 177 insertions, 141 deletions
diff --git a/src/mongo/db/s/catalog_cache_loader_mock.cpp b/src/mongo/db/s/catalog_cache_loader_mock.cpp
index 4dc0f775fab..7b3a3b03c2d 100644
--- a/src/mongo/db/s/catalog_cache_loader_mock.cpp
+++ b/src/mongo/db/s/catalog_cache_loader_mock.cpp
@@ -105,12 +105,13 @@ std::shared_ptr<Notification<void>> CatalogCacheLoaderMock::getChunksSince(
uassertStatusOK(_swCollectionReturnValue);
uassertStatusOK(_swChunksReturnValue);
- return CollectionAndChangedChunks{
+ return CollectionAndChangedChunks(
+ _swCollectionReturnValue.getValue().getUUID(),
_swCollectionReturnValue.getValue().getEpoch(),
_swCollectionReturnValue.getValue().getKeyPattern().toBSON(),
_swCollectionReturnValue.getValue().getDefaultCollation(),
_swCollectionReturnValue.getValue().getUnique(),
- _swChunksReturnValue.getValue()};
+ _swChunksReturnValue.getValue());
} catch (const DBException& ex) {
return ex.toStatus();
}
diff --git a/src/mongo/db/s/collection_metadata.h b/src/mongo/db/s/collection_metadata.h
index ae301d90212..dbec901f2e0 100644
--- a/src/mongo/db/s/collection_metadata.h
+++ b/src/mongo/db/s/collection_metadata.h
@@ -172,6 +172,10 @@ public:
return _cm;
}
+ bool uuidMatches(UUID uuid) const {
+ return _cm->uuidMatches(uuid);
+ }
+
private:
struct Tracker {
uint32_t usageCounter{0};
diff --git a/src/mongo/db/s/collection_metadata_test.cpp b/src/mongo/db/s/collection_metadata_test.cpp
index cf5bea78a00..13b4d540de2 100644
--- a/src/mongo/db/s/collection_metadata_test.cpp
+++ b/src/mongo/db/s/collection_metadata_test.cpp
@@ -70,7 +70,8 @@ std::unique_ptr<CollectionMetadata> makeCollectionMetadataImpl(
kNss, ChunkRange{nextMinKey, shardKeyPattern.globalMax()}, version, kOtherShard);
}
- auto cm = ChunkManager::makeNew(kNss, shardKeyPattern, nullptr, false, epoch, allChunks);
+ UUID uuid(UUID::gen());
+ auto cm = ChunkManager::makeNew(kNss, uuid, shardKeyPattern, nullptr, false, epoch, allChunks);
return stdx::make_unique<CollectionMetadata>(cm, kThisShard);
}
diff --git a/src/mongo/db/s/collection_range_deleter_test.cpp b/src/mongo/db/s/collection_range_deleter_test.cpp
index 1763301fbb4..30135befdbc 100644
--- a/src/mongo/db/s/collection_range_deleter_test.cpp
+++ b/src/mongo/db/s/collection_range_deleter_test.cpp
@@ -110,6 +110,7 @@ void CollectionRangeDeleterTest::setUp() {
const KeyPattern skPattern(kKeyPattern);
auto cm = ChunkManager::makeNew(
kNss,
+ UUID::gen(),
kKeyPattern,
nullptr,
false,
diff --git a/src/mongo/db/s/collection_sharding_state.cpp b/src/mongo/db/s/collection_sharding_state.cpp
index 0c4e6a1b70d..25f2727ff55 100644
--- a/src/mongo/db/s/collection_sharding_state.cpp
+++ b/src/mongo/db/s/collection_sharding_state.cpp
@@ -418,7 +418,7 @@ void CollectionShardingState::_onConfigRefreshCompleteInvalidateCachedMetadataAn
// Extract which collection entry is being updated
std::string refreshCollection;
fassertStatusOK(
- 40477, bsonExtractStringField(query, ShardCollectionType::uuid.name(), &refreshCollection));
+ 40477, bsonExtractStringField(query, ShardCollectionType::ns.name(), &refreshCollection));
// Parse the '$set' update, which will contain the 'lastRefreshedCollectionVersion' if it is
// present.
@@ -443,7 +443,7 @@ void CollectionShardingState::_onConfigDeleteInvalidateCachedMetadataAndNotify(
// Extract which collection entry is being deleted from the _id field.
std::string deletedCollection;
fassertStatusOK(
- 40479, bsonExtractStringField(query, ShardCollectionType::uuid.name(), &deletedCollection));
+ 40479, bsonExtractStringField(query, ShardCollectionType::ns.name(), &deletedCollection));
opCtx->recoveryUnit()->registerChange(
new CollectionVersionLogOpHandler(opCtx, NamespaceString(deletedCollection)));
diff --git a/src/mongo/db/s/collection_sharding_state_test.cpp b/src/mongo/db/s/collection_sharding_state_test.cpp
index 9ac9f4a9702..f9fcbc69420 100644
--- a/src/mongo/db/s/collection_sharding_state_test.cpp
+++ b/src/mongo/db/s/collection_sharding_state_test.cpp
@@ -180,7 +180,7 @@ auto makeAMetadata(BSONObj const& keyPattern) -> std::unique_ptr<CollectionMetad
auto range = ChunkRange(BSON("key" << MINKEY), BSON("key" << MAXKEY));
auto chunk = ChunkType(testNss, std::move(range), ChunkVersion(1, 0, epoch), ShardId("other"));
auto cm = ChunkManager::makeNew(
- testNss, KeyPattern(keyPattern), nullptr, false, epoch, {std::move(chunk)});
+ testNss, UUID::gen(), KeyPattern(keyPattern), nullptr, false, epoch, {std::move(chunk)});
return stdx::make_unique<CollectionMetadata>(std::move(cm), ShardId("this"));
}
diff --git a/src/mongo/db/s/metadata_manager_test.cpp b/src/mongo/db/s/metadata_manager_test.cpp
index 16cb8a5e122..50f2aed8274 100644
--- a/src/mongo/db/s/metadata_manager_test.cpp
+++ b/src/mongo/db/s/metadata_manager_test.cpp
@@ -92,6 +92,7 @@ protected:
auto cm = ChunkManager::makeNew(
kNss,
+ UUID::gen(),
kShardKeyPattern,
nullptr,
false,
diff --git a/src/mongo/db/s/shard_metadata_util.cpp b/src/mongo/db/s/shard_metadata_util.cpp
index 9e076435a4c..533d955d575 100644
--- a/src/mongo/db/s/shard_metadata_util.cpp
+++ b/src/mongo/db/s/shard_metadata_util.cpp
@@ -91,7 +91,7 @@ Status setPersistedRefreshFlags(OperationContext* opCtx, const NamespaceString&
// Set 'refreshing' to true.
BSONObj update = BSON(ShardCollectionType::refreshing() << true);
return updateShardCollectionsEntry(
- opCtx, BSON(ShardCollectionType::uuid() << nss.ns()), update, false /*upsert*/);
+ opCtx, BSON(ShardCollectionType::ns() << nss.ns()), update, false /*upsert*/);
}
Status unsetPersistedRefreshFlags(OperationContext* opCtx,
@@ -103,10 +103,8 @@ Status unsetPersistedRefreshFlags(OperationContext* opCtx,
updateBuilder.appendTimestamp(ShardCollectionType::lastRefreshedCollectionVersion(),
refreshedVersion.toLong());
- return updateShardCollectionsEntry(opCtx,
- BSON(ShardCollectionType::uuid() << nss.ns()),
- updateBuilder.obj(),
- false /*upsert*/);
+ return updateShardCollectionsEntry(
+ opCtx, BSON(ShardCollectionType::ns() << nss.ns()), updateBuilder.obj(), false /*upsert*/);
}
StatusWith<RefreshState> getPersistedRefreshFlags(OperationContext* opCtx,
@@ -142,7 +140,7 @@ StatusWith<RefreshState> getPersistedRefreshFlags(OperationContext* opCtx,
StatusWith<ShardCollectionType> readShardCollectionsEntry(OperationContext* opCtx,
const NamespaceString& nss) {
- Query fullQuery(BSON(ShardCollectionType::uuid() << nss.ns()));
+ Query fullQuery(BSON(ShardCollectionType::ns() << nss.ns()));
try {
DBDirectClient client(opCtx);
@@ -335,7 +333,7 @@ Status dropChunksAndDeleteCollectionsEntry(OperationContext* opCtx, const Namesp
NamespaceString{NamespaceString::kShardConfigCollectionsCollectionName});
deleteOp.setDeletes({[&] {
write_ops::DeleteOpEntry entry;
- entry.setQ(BSON(ShardCollectionType::uuid << nss.ns()));
+ entry.setQ(BSON(ShardCollectionType::ns << nss.ns()));
entry.setMulti(true);
return entry;
}()});
diff --git a/src/mongo/db/s/shard_metadata_util_test.cpp b/src/mongo/db/s/shard_metadata_util_test.cpp
index fa30bda71af..31564329893 100644
--- a/src/mongo/db/s/shard_metadata_util_test.cpp
+++ b/src/mongo/db/s/shard_metadata_util_test.cpp
@@ -55,24 +55,23 @@ const NamespaceString kChunkMetadataNss = NamespaceString("config.chunks.test.fo
const ShardId kShardId = ShardId("shard0");
const bool kUnique = false;
-class ShardMetadataUtilTest : public ShardServerTestFixture {
-protected:
+struct ShardMetadataUtilTest : public ShardServerTestFixture {
/**
* Inserts a collections collection entry for 'kNss'.
*/
ShardCollectionType setUpCollection() {
BSONObjBuilder builder;
- builder.append(ShardCollectionType::uuid(), kNss.ns());
builder.append(ShardCollectionType::ns(), kNss.ns());
- builder.append(ShardCollectionType::epoch(), _maxCollVersion.epoch());
- builder.append(ShardCollectionType::keyPattern(), _keyPattern.toBSON());
- builder.append(ShardCollectionType::defaultCollation(), _defaultCollation);
+ uuid.appendToBuilder(&builder, ShardCollectionType::uuid());
+ builder.append(ShardCollectionType::epoch(), maxCollVersion.epoch());
+ builder.append(ShardCollectionType::keyPattern(), keyPattern.toBSON());
+ builder.append(ShardCollectionType::defaultCollation(), defaultCollation);
builder.append(ShardCollectionType::unique(), kUnique);
ShardCollectionType shardCollectionType =
assertGet(ShardCollectionType::fromBSON(builder.obj()));
ASSERT_OK(updateShardCollectionsEntry(operationContext(),
- BSON(ShardCollectionType::uuid(kNss.ns())),
+ BSON(ShardCollectionType::ns(kNss.ns())),
shardCollectionType.toBSON(),
true /*upsert*/));
return shardCollectionType;
@@ -84,7 +83,7 @@ protected:
void setUpChunks(const NamespaceString& nss, const std::vector<ChunkType> chunks) {
NamespaceString chunkMetadataNss(ChunkType::ShardNSPrefix + nss.ns());
- ASSERT_OK(updateShardChunks(operationContext(), kNss, chunks, _maxCollVersion.epoch()));
+ ASSERT_OK(updateShardChunks(operationContext(), kNss, chunks, maxCollVersion.epoch()));
}
/**
@@ -96,15 +95,15 @@ protected:
BSONObj maxs[] = {BSON("a" << 10), BSON("a" << 50), BSON("a" << 100), BSON("a" << MAXKEY)};
for (int i = 0; i < 4; ++i) {
- _maxCollVersion.incMajor();
+ maxCollVersion.incMajor();
BSONObj shardChunk =
BSON(ChunkType::minShardID(mins[i])
<< ChunkType::max(maxs[i])
<< ChunkType::shard(kShardId.toString())
- << ChunkType::lastmod(Date_t::fromMillisSinceEpoch(_maxCollVersion.toLong())));
+ << ChunkType::lastmod(Date_t::fromMillisSinceEpoch(maxCollVersion.toLong())));
chunks.push_back(
- assertGet(ChunkType::fromShardBSON(shardChunk, _maxCollVersion.epoch())));
+ assertGet(ChunkType::fromShardBSON(shardChunk, maxCollVersion.epoch())));
}
return chunks;
@@ -162,23 +161,11 @@ protected:
}
}
- const ChunkVersion& getCollectionVersion() const {
- return _maxCollVersion;
- }
-
- const BSONObj& getKeyPattern() const {
- return _keyPattern.toBSON();
- }
-
- const BSONObj& getDefaultCollation() const {
- return _defaultCollation;
- }
-
-private:
- ChunkVersion _maxCollVersion{0, 0, OID::gen()};
- const KeyPattern _keyPattern{BSON("a" << 1)};
- const BSONObj _defaultCollation{BSON("locale"
- << "fr_CA")};
+ ChunkVersion maxCollVersion{0, 0, OID::gen()};
+ const KeyPattern keyPattern{BSON("a" << 1)};
+ const BSONObj defaultCollation{BSON("locale"
+ << "fr_CA")};
+ const UUID uuid = UUID::gen();
};
TEST_F(ShardMetadataUtilTest, UpdateAndReadCollectionsEntry) {
@@ -186,7 +173,8 @@ TEST_F(ShardMetadataUtilTest, UpdateAndReadCollectionsEntry) {
ShardCollectionType readShardCollectionType =
assertGet(readShardCollectionsEntry(operationContext(), kNss));
- ASSERT_EQUALS(updateShardCollectionType.getUUID(), readShardCollectionType.getUUID());
+ ASSERT_TRUE(readShardCollectionType.getUUID());
+ ASSERT_EQUALS(*updateShardCollectionType.getUUID(), *readShardCollectionType.getUUID());
ASSERT_EQUALS(updateShardCollectionType.getNss(), readShardCollectionType.getNss());
ASSERT_EQUALS(updateShardCollectionType.getEpoch(), readShardCollectionType.getEpoch());
ASSERT_BSONOBJ_EQ(updateShardCollectionType.getKeyPattern().toBSON(),
@@ -211,11 +199,11 @@ TEST_F(ShardMetadataUtilTest, PersistedRefreshSignalStartAndFinish) {
ShardCollectionType shardCollectionsEntry =
assertGet(readShardCollectionsEntry(operationContext(), kNss));
- ASSERT_EQUALS(shardCollectionsEntry.getUUID(), kNss);
- ASSERT_EQUALS(shardCollectionsEntry.getNss(), kNss);
- ASSERT_EQUALS(shardCollectionsEntry.getEpoch(), getCollectionVersion().epoch());
- ASSERT_BSONOBJ_EQ(shardCollectionsEntry.getKeyPattern().toBSON(), getKeyPattern());
- ASSERT_BSONOBJ_EQ(shardCollectionsEntry.getDefaultCollation(), getDefaultCollation());
+ ASSERT_EQUALS(*shardCollectionsEntry.getUUID(), uuid);
+ ASSERT_EQUALS(shardCollectionsEntry.getNss(), kNss.ns());
+ ASSERT_EQUALS(shardCollectionsEntry.getEpoch(), maxCollVersion.epoch());
+ ASSERT_BSONOBJ_EQ(shardCollectionsEntry.getKeyPattern().toBSON(), keyPattern.toBSON());
+ ASSERT_BSONOBJ_EQ(shardCollectionsEntry.getDefaultCollation(), defaultCollation);
ASSERT_EQUALS(shardCollectionsEntry.getUnique(), kUnique);
ASSERT_EQUALS(shardCollectionsEntry.getRefreshing(), true);
ASSERT(!shardCollectionsEntry.hasLastRefreshedCollectionVersion());
@@ -225,35 +213,34 @@ TEST_F(ShardMetadataUtilTest, PersistedRefreshSignalStartAndFinish) {
RefreshState state = assertGet(getPersistedRefreshFlags(operationContext(), kNss));
- ASSERT_EQUALS(state.epoch, getCollectionVersion().epoch());
+ ASSERT_EQUALS(state.epoch, maxCollVersion.epoch());
ASSERT_EQUALS(state.refreshing, true);
- ASSERT_EQUALS(state.lastRefreshedCollectionVersion,
- ChunkVersion(0, 0, getCollectionVersion().epoch()));
+ ASSERT_EQUALS(state.lastRefreshedCollectionVersion, ChunkVersion(0, 0, maxCollVersion.epoch()));
// Signal refresh finish
- ASSERT_OK(unsetPersistedRefreshFlags(operationContext(), kNss, getCollectionVersion()));
+ ASSERT_OK(unsetPersistedRefreshFlags(operationContext(), kNss, maxCollVersion));
state = assertGet(getPersistedRefreshFlags(operationContext(), kNss));
- ASSERT_EQUALS(state.epoch, getCollectionVersion().epoch());
+ ASSERT_EQUALS(state.epoch, maxCollVersion.epoch());
ASSERT_EQUALS(state.refreshing, false);
- ASSERT_EQUALS(state.lastRefreshedCollectionVersion, getCollectionVersion());
+ ASSERT_EQUALS(state.lastRefreshedCollectionVersion, maxCollVersion);
}
TEST_F(ShardMetadataUtilTest, WriteAndReadChunks) {
std::vector<ChunkType> chunks = makeFourChunks();
- ASSERT_OK(updateShardChunks(operationContext(), kNss, chunks, getCollectionVersion().epoch()));
+ ASSERT_OK(updateShardChunks(operationContext(), kNss, chunks, maxCollVersion.epoch()));
checkChunks(kChunkMetadataNss, chunks);
// read all the chunks
QueryAndSort allChunkDiff =
- createShardChunkDiffQuery(ChunkVersion(0, 0, getCollectionVersion().epoch()));
+ createShardChunkDiffQuery(ChunkVersion(0, 0, maxCollVersion.epoch()));
std::vector<ChunkType> readChunks = assertGet(readShardChunks(operationContext(),
kNss,
allChunkDiff.query,
allChunkDiff.sort,
boost::none,
- getCollectionVersion().epoch()));
+ maxCollVersion.epoch()));
for (auto chunkIt = chunks.begin(), readChunkIt = readChunks.begin();
chunkIt != chunks.end() && readChunkIt != readChunks.end();
++chunkIt, ++readChunkIt) {
@@ -261,13 +248,13 @@ TEST_F(ShardMetadataUtilTest, WriteAndReadChunks) {
}
// read only the highest version chunk
- QueryAndSort oneChunkDiff = createShardChunkDiffQuery(getCollectionVersion());
+ QueryAndSort oneChunkDiff = createShardChunkDiffQuery(maxCollVersion);
readChunks = assertGet(readShardChunks(operationContext(),
kNss,
oneChunkDiff.query,
oneChunkDiff.sort,
boost::none,
- getCollectionVersion().epoch()));
+ maxCollVersion.epoch()));
ASSERT_TRUE(readChunks.size() == 1);
ASSERT_BSONOBJ_EQ(chunks.back().toShardBSON(), readChunks.front().toShardBSON());
@@ -277,7 +264,7 @@ TEST_F(ShardMetadataUtilTest, UpdateWithWriteNewChunks) {
// Load some chunk metadata.
std::vector<ChunkType> chunks = makeFourChunks();
- ASSERT_OK(updateShardChunks(operationContext(), kNss, chunks, getCollectionVersion().epoch()));
+ ASSERT_OK(updateShardChunks(operationContext(), kNss, chunks, maxCollVersion.epoch()));
checkChunks(kChunkMetadataNss, chunks);
// Load some changes and make sure it's applied correctly.
@@ -286,7 +273,7 @@ TEST_F(ShardMetadataUtilTest, UpdateWithWriteNewChunks) {
std::vector<ChunkType> newChunks;
ChunkType lastChunk = chunks.back();
chunks.pop_back();
- ChunkVersion collVersion = getCollectionVersion();
+ ChunkVersion collVersion = maxCollVersion;
collVersion.incMinor(); // chunk only split
BSONObjBuilder splitChunkOneBuilder;
@@ -302,6 +289,7 @@ TEST_F(ShardMetadataUtilTest, UpdateWithWriteNewChunks) {
newChunks.push_back(splitChunkOne);
collVersion.incMajor(); // chunk split and moved
+
BSONObjBuilder splitChunkTwoMovedBuilder;
{
BSONObjBuilder subMin(splitChunkTwoMovedBuilder.subobjStart(ChunkType::minShardID()));
diff --git a/src/mongo/db/s/shard_server_catalog_cache_loader.cpp b/src/mongo/db/s/shard_server_catalog_cache_loader.cpp
index 683e5d0317b..70d1a50968c 100644
--- a/src/mongo/db/s/shard_server_catalog_cache_loader.cpp
+++ b/src/mongo/db/s/shard_server_catalog_cache_loader.cpp
@@ -83,13 +83,13 @@ Status persistCollectionAndChangedChunks(OperationContext* opCtx,
const CollectionAndChangedChunks& collAndChunks) {
// Update the collections collection entry for 'nss' in case there are any new updates.
ShardCollectionType update = ShardCollectionType(nss,
- nss,
+ collAndChunks.uuid,
collAndChunks.epoch,
collAndChunks.shardKeyPattern,
collAndChunks.defaultCollation,
collAndChunks.shardKeyIsUnique);
Status status = updateShardCollectionsEntry(
- opCtx, BSON(ShardCollectionType::uuid() << nss.ns()), update.toBSON(), true /*upsert*/);
+ opCtx, BSON(ShardCollectionType::ns() << nss.ns()), update.toBSON(), true /*upsert*/);
if (!status.isOK()) {
return status;
}
@@ -189,7 +189,8 @@ CollectionAndChangedChunks getPersistedMetadataSinceVersion(OperationContext* op
auto changedChunks = uassertStatusOK(
readShardChunks(opCtx, nss, diff.query, diff.sort, boost::none, startingVersion.epoch()));
- return CollectionAndChangedChunks{shardCollectionEntry.getEpoch(),
+ return CollectionAndChangedChunks{shardCollectionEntry.getUUID(),
+ shardCollectionEntry.getEpoch(),
shardCollectionEntry.getKeyPattern().toBSON(),
shardCollectionEntry.getDefaultCollation(),
shardCollectionEntry.getUnique(),
diff --git a/src/mongo/s/catalog/type_shard_collection.cpp b/src/mongo/s/catalog/type_shard_collection.cpp
index 186b35fbb44..3a98a15f7ba 100644
--- a/src/mongo/s/catalog/type_shard_collection.cpp
+++ b/src/mongo/s/catalog/type_shard_collection.cpp
@@ -42,8 +42,8 @@ namespace mongo {
const std::string ShardCollectionType::ConfigNS =
NamespaceString::kShardConfigCollectionsCollectionName.toString();
-const BSONField<std::string> ShardCollectionType::uuid("_id");
-const BSONField<std::string> ShardCollectionType::ns("ns");
+const BSONField<std::string> ShardCollectionType::ns("_id");
+const BSONField<UUID> ShardCollectionType::uuid("uuid");
const BSONField<OID> ShardCollectionType::epoch("epoch");
const BSONField<BSONObj> ShardCollectionType::keyPattern("key");
const BSONField<BSONObj> ShardCollectionType::defaultCollation("defaultCollation");
@@ -52,28 +52,20 @@ const BSONField<bool> ShardCollectionType::refreshing("refreshing");
const BSONField<Date_t> ShardCollectionType::lastRefreshedCollectionVersion(
"lastRefreshedCollectionVersion");
-ShardCollectionType::ShardCollectionType(const NamespaceString& uuid,
- const NamespaceString& nss,
- const OID& epoch,
+ShardCollectionType::ShardCollectionType(NamespaceString nss,
+ boost::optional<UUID> uuid,
+ OID epoch,
const KeyPattern& keyPattern,
const BSONObj& defaultCollation,
- const bool& unique)
- : _uuid(uuid),
- _nss(nss),
- _epoch(epoch),
+ bool unique)
+ : _nss(std::move(nss)),
+ _uuid(uuid),
+ _epoch(std::move(epoch)),
_keyPattern(keyPattern.toBSON()),
_defaultCollation(defaultCollation.getOwned()),
_unique(unique) {}
StatusWith<ShardCollectionType> ShardCollectionType::fromBSON(const BSONObj& source) {
- NamespaceString uuid;
- {
- std::string ns;
- Status status = bsonExtractStringField(source, ShardCollectionType::uuid.name(), &ns);
- if (!status.isOK())
- return status;
- uuid = NamespaceString{ns};
- }
NamespaceString nss;
{
@@ -85,6 +77,23 @@ StatusWith<ShardCollectionType> ShardCollectionType::fromBSON(const BSONObj& sou
nss = NamespaceString{ns};
}
+ boost::optional<UUID> uuid;
+ {
+ BSONElement uuidElem;
+ Status status = bsonExtractTypedField(
+ source, ShardCollectionType::uuid.name(), BSONType::BinData, &uuidElem);
+ if (status.isOK()) {
+ auto uuidWith = UUID::parse(uuidElem);
+ if (!uuidWith.isOK())
+ return uuidWith.getStatus();
+ uuid = uuidWith.getValue();
+ } else if (status == ErrorCodes::NoSuchKey) {
+ // The field is not set, which is okay.
+ } else {
+ return status;
+ }
+ }
+
OID epoch;
{
BSONElement oidElem;
@@ -134,7 +143,8 @@ StatusWith<ShardCollectionType> ShardCollectionType::fromBSON(const BSONObj& sou
}
}
- ShardCollectionType shardCollectionType(uuid, nss, epoch, pattern, collation, unique);
+ ShardCollectionType shardCollectionType(
+ std::move(nss), uuid, std::move(epoch), pattern, collation, unique);
// Below are optional fields.
@@ -170,8 +180,10 @@ StatusWith<ShardCollectionType> ShardCollectionType::fromBSON(const BSONObj& sou
BSONObj ShardCollectionType::toBSON() const {
BSONObjBuilder builder;
- builder.append(uuid.name(), _uuid.ns());
builder.append(ns.name(), _nss.ns());
+ if (_uuid) {
+ _uuid->appendToBuilder(&builder, uuid.name());
+ }
builder.append(epoch.name(), _epoch);
builder.append(keyPattern.name(), _keyPattern.toBSON());
@@ -196,19 +208,18 @@ std::string ShardCollectionType::toString() const {
return toBSON().toString();
}
-void ShardCollectionType::setUUID(const NamespaceString& uuid) {
- invariant(uuid.isValid());
+void ShardCollectionType::setUUID(UUID uuid) {
_uuid = uuid;
}
-void ShardCollectionType::setNss(const NamespaceString& nss) {
+void ShardCollectionType::setNss(NamespaceString nss) {
invariant(nss.isValid());
- _nss = nss;
+ _nss = std::move(nss);
}
-void ShardCollectionType::setEpoch(const OID& epoch) {
+void ShardCollectionType::setEpoch(OID epoch) {
invariant(epoch.isSet());
- _epoch = epoch;
+ _epoch = std::move(epoch);
}
void ShardCollectionType::setKeyPattern(const KeyPattern& keyPattern) {
diff --git a/src/mongo/s/catalog/type_shard_collection.h b/src/mongo/s/catalog/type_shard_collection.h
index aa17812e980..8129943ade0 100644
--- a/src/mongo/s/catalog/type_shard_collection.h
+++ b/src/mongo/s/catalog/type_shard_collection.h
@@ -35,6 +35,7 @@
#include "mongo/db/keypattern.h"
#include "mongo/db/namespace_string.h"
#include "mongo/s/chunk_version.h"
+#include "mongo/util/uuid.h"
namespace mongo {
@@ -50,8 +51,8 @@ class StatusWith;
*
* Expected shard server config.collections collection format:
* {
- * "_id" : "foo.bar", // will become UUID when available
- * "ns" : "foo.bar",
+ * "_id" : "foo.bar",
+ * "uuid" : UUID, // optional in 3.6
* "epoch" : ObjectId("58b6fd76132358839e409e47"), // will remove when UUID becomes available
* "key" : {
* "_id" : 1
@@ -60,8 +61,8 @@ class StatusWith;
* "locale" : "fr_CA"
* },
* "unique" : false,
- * "refreshing" : true,
- * "lastRefreshedCollectionVersion" : Timestamp(1, 0)
+ * "refreshing" : true, // optional
+ * "lastRefreshedCollectionVersion" : Timestamp(1, 0) // optional
* }
*
*/
@@ -70,8 +71,8 @@ public:
// Name of the collections collection on the shard server.
static const std::string ConfigNS;
- static const BSONField<std::string> uuid;
- static const BSONField<std::string> ns;
+ static const BSONField<std::string> ns; // "_id"
+ static const BSONField<UUID> uuid;
static const BSONField<OID> epoch;
static const BSONField<BSONObj> keyPattern;
static const BSONField<BSONObj> defaultCollation;
@@ -79,12 +80,12 @@ public:
static const BSONField<bool> refreshing;
static const BSONField<Date_t> lastRefreshedCollectionVersion;
- explicit ShardCollectionType(const NamespaceString& uuid,
- const NamespaceString& nss,
- const OID& epoch,
- const KeyPattern& keyPattern,
- const BSONObj& defaultCollation,
- const bool& unique);
+ ShardCollectionType(NamespaceString nss,
+ boost::optional<UUID> uuid,
+ OID epoch,
+ const KeyPattern& keyPattern,
+ const BSONObj& defaultCollation,
+ bool unique);
/**
* Constructs a new ShardCollectionType object from BSON. Also does validation of the contents.
@@ -101,20 +102,20 @@ public:
*/
std::string toString() const;
- const NamespaceString& getUUID() const {
- return _uuid;
- }
- void setUUID(const NamespaceString& uuid);
-
const NamespaceString& getNss() const {
return _nss;
}
- void setNss(const NamespaceString& nss);
+ void setNss(NamespaceString nss);
+
+ const boost::optional<UUID> getUUID() const {
+ return _uuid;
+ }
+ void setUUID(UUID uuid);
const OID& getEpoch() const {
return _epoch;
}
- void setEpoch(const OID& epoch);
+ void setEpoch(OID epoch);
const KeyPattern& getKeyPattern() const {
return _keyPattern;
@@ -152,12 +153,12 @@ public:
}
private:
- // Will become the UUID when available. Currently a duplicate of '_nss'.
- NamespaceString _uuid;
-
// The full namespace (with the database prefix).
NamespaceString _nss;
+ // The UUID of the collection, if known.
+ boost::optional<UUID> _uuid;
+
// Uniquely identifies this instance of the collection, in case of drop/create.
OID _epoch;
diff --git a/src/mongo/s/catalog/type_shard_collection_test.cpp b/src/mongo/s/catalog/type_shard_collection_test.cpp
index 51a8b6758ca..5d31d5940ad 100644
--- a/src/mongo/s/catalog/type_shard_collection_test.cpp
+++ b/src/mongo/s/catalog/type_shard_collection_test.cpp
@@ -48,11 +48,12 @@ const BSONObj kDefaultCollation = BSON("locale"
TEST(ShardCollectionType, ToFromBSON) {
const OID epoch = OID::gen();
+ const UUID uuid = UUID::gen();
const ChunkVersion lastRefreshedCollectionVersion(2, 0, epoch);
BSONObjBuilder builder;
- builder.append(ShardCollectionType::uuid.name(), kNss.ns());
builder.append(ShardCollectionType::ns.name(), kNss.ns());
+ uuid.appendToBuilder(&builder, ShardCollectionType::uuid.name());
builder.append(ShardCollectionType::epoch(), epoch);
builder.append(ShardCollectionType::keyPattern.name(), kKeyPattern);
builder.append(ShardCollectionType::defaultCollation(), kDefaultCollation);
@@ -64,8 +65,9 @@ TEST(ShardCollectionType, ToFromBSON) {
ShardCollectionType shardCollectionType = assertGet(ShardCollectionType::fromBSON(obj));
- ASSERT_EQUALS(shardCollectionType.getUUID(), kNss);
ASSERT_EQUALS(shardCollectionType.getNss(), kNss);
+ ASSERT(shardCollectionType.getUUID());
+ ASSERT_EQUALS(*shardCollectionType.getUUID(), uuid);
ASSERT_EQUALS(shardCollectionType.getEpoch(), epoch);
ASSERT_BSONOBJ_EQ(shardCollectionType.getKeyPattern().toBSON(), kKeyPattern);
ASSERT_BSONOBJ_EQ(shardCollectionType.getDefaultCollation(), kDefaultCollation);
@@ -81,7 +83,6 @@ TEST(ShardCollectionType, ToFromShardBSONWithoutOptionals) {
const OID epoch = OID::gen();
BSONObjBuilder builder;
- builder.append(ShardCollectionType::uuid.name(), kNss.ns());
builder.append(ShardCollectionType::ns.name(), kNss.ns());
builder.append(ShardCollectionType::epoch(), epoch);
builder.append(ShardCollectionType::keyPattern.name(), kKeyPattern);
@@ -91,12 +92,13 @@ TEST(ShardCollectionType, ToFromShardBSONWithoutOptionals) {
ShardCollectionType shardCollectionType = assertGet(ShardCollectionType::fromBSON(obj));
- ASSERT_EQUALS(shardCollectionType.getUUID(), kNss);
ASSERT_EQUALS(shardCollectionType.getNss(), kNss);
ASSERT_EQUALS(shardCollectionType.getEpoch(), epoch);
ASSERT_BSONOBJ_EQ(shardCollectionType.getKeyPattern().toBSON(), kKeyPattern);
ASSERT_BSONOBJ_EQ(shardCollectionType.getDefaultCollation(), kDefaultCollation);
ASSERT_EQUALS(shardCollectionType.getUnique(), true);
+ ASSERT_FALSE(shardCollectionType.hasRefreshing());
+ ASSERT_FALSE(shardCollectionType.hasLastRefreshedCollectionVersion());
ASSERT_BSONOBJ_EQ(obj, shardCollectionType.toBSON());
}
@@ -106,38 +108,45 @@ TEST(ShardCollectionType, FromEmptyBSON) {
ASSERT_FALSE(status.isOK());
}
-TEST(ShardCollectionType, FromBSONNoUUIDFails) {
- BSONObj obj =
- BSON(ShardCollectionType::ns(kNss.ns()) << ShardCollectionType::keyPattern(kKeyPattern));
-
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(obj);
- ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
- ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::uuid());
+TEST(ShardCollectionType, FromBSONNoUUIDIsOK) {
+ BSONObjBuilder builder;
+ builder.append(ShardCollectionType::ns.name(), kNss.ns());
+ builder.append(ShardCollectionType::epoch(), OID::gen());
+ builder.append(ShardCollectionType::keyPattern(), kKeyPattern);
+ builder.append(ShardCollectionType::unique(), true);
+ StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
+ ASSERT_OK(status.getStatus());
+ ASSERT_FALSE(status.getValue().getUUID());
}
TEST(ShardCollectionType, FromBSONNoNSFails) {
- BSONObj obj =
- BSON(ShardCollectionType::uuid(kNss.ns()) << ShardCollectionType::keyPattern(kKeyPattern));
-
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(obj);
+ BSONObjBuilder builder;
+ UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
+ builder.append(ShardCollectionType::epoch(), OID::gen());
+ builder.append(ShardCollectionType::keyPattern(), kKeyPattern);
+ builder.append(ShardCollectionType::unique(), true);
+ StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::ns());
}
TEST(ShardCollectionType, FromBSONNoEpochFails) {
- BSONObj obj = BSON(ShardCollectionType::uuid(kNss.ns()) << ShardCollectionType::ns(kNss.ns()));
-
- StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(obj);
+ BSONObjBuilder builder;
+ builder.append(ShardCollectionType::ns.name(), kNss.ns());
+ UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
+ builder.append(ShardCollectionType::keyPattern(), kKeyPattern);
+ builder.append(ShardCollectionType::unique(), true);
+ StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::epoch());
}
TEST(ShardCollectionType, FromBSONNoShardKeyFails) {
BSONObjBuilder builder;
- builder.append(ShardCollectionType::uuid.name(), kNss.ns());
builder.append(ShardCollectionType::ns.name(), kNss.ns());
+ UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
builder.append(ShardCollectionType::epoch(), OID::gen());
-
+ builder.append(ShardCollectionType::unique(), true);
StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::keyPattern());
@@ -145,12 +154,11 @@ TEST(ShardCollectionType, FromBSONNoShardKeyFails) {
TEST(ShardCollectionType, FromBSONNoUniqueFails) {
BSONObjBuilder builder;
- builder.append(ShardCollectionType::uuid.name(), kNss.ns());
builder.append(ShardCollectionType::ns.name(), kNss.ns());
+ UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
builder.append(ShardCollectionType::epoch(), OID::gen());
builder.append(ShardCollectionType::keyPattern.name(), kKeyPattern);
builder.append(ShardCollectionType::defaultCollation(), kDefaultCollation);
-
StatusWith<ShardCollectionType> status = ShardCollectionType::fromBSON(builder.obj());
ASSERT_EQUALS(status.getStatus().code(), ErrorCodes::NoSuchKey);
ASSERT_STRING_CONTAINS(status.getStatus().reason(), ShardCollectionType::unique());
@@ -158,8 +166,8 @@ TEST(ShardCollectionType, FromBSONNoUniqueFails) {
TEST(ShardCollectionType, FromBSONNoDefaultCollationIsOK) {
BSONObjBuilder builder;
- builder.append(ShardCollectionType::uuid.name(), kNss.ns());
builder.append(ShardCollectionType::ns.name(), kNss.ns());
+ UUID::gen().appendToBuilder(&builder, ShardCollectionType::uuid.name());
builder.append(ShardCollectionType::epoch(), OID::gen());
builder.append(ShardCollectionType::keyPattern.name(), kKeyPattern);
builder.append(ShardCollectionType::unique(), true);
diff --git a/src/mongo/s/catalog_cache.cpp b/src/mongo/s/catalog_cache.cpp
index 5681d0afa05..2ca85400c86 100644
--- a/src/mongo/s/catalog_cache.cpp
+++ b/src/mongo/s/catalog_cache.cpp
@@ -95,6 +95,7 @@ std::shared_ptr<ChunkManager> refreshCollectionRoutingInfo(
return nullptr;
}();
return ChunkManager::makeNew(nss,
+ collectionAndChunks.uuid,
KeyPattern(collectionAndChunks.shardKeyPattern),
std::move(defaultCollator),
collectionAndChunks.shardKeyIsUnique,
diff --git a/src/mongo/s/catalog_cache_loader.cpp b/src/mongo/s/catalog_cache_loader.cpp
index ba81c0fe771..faa433d4d1c 100644
--- a/src/mongo/s/catalog_cache_loader.cpp
+++ b/src/mongo/s/catalog_cache_loader.cpp
@@ -41,12 +41,14 @@ const auto catalogCacheLoaderDecoration =
CatalogCacheLoader::CollectionAndChangedChunks::CollectionAndChangedChunks() = default;
CatalogCacheLoader::CollectionAndChangedChunks::CollectionAndChangedChunks(
+ boost::optional<UUID> collUuid,
const OID& collEpoch,
const BSONObj& collShardKeyPattern,
const BSONObj& collDefaultCollation,
bool collShardKeyIsUnique,
std::vector<ChunkType> chunks)
- : epoch(collEpoch),
+ : uuid(collUuid),
+ epoch(collEpoch),
shardKeyPattern(collShardKeyPattern),
defaultCollation(collDefaultCollation),
shardKeyIsUnique(collShardKeyIsUnique),
diff --git a/src/mongo/s/catalog_cache_loader.h b/src/mongo/s/catalog_cache_loader.h
index ed16cb0f178..ebafdff76fd 100644
--- a/src/mongo/s/catalog_cache_loader.h
+++ b/src/mongo/s/catalog_cache_loader.h
@@ -38,6 +38,7 @@
#include "mongo/s/chunk_version.h"
#include "mongo/stdx/memory.h"
#include "mongo/util/concurrency/notification.h"
+#include "mongo/util/uuid.h"
namespace mongo {
@@ -67,13 +68,15 @@ public:
*/
struct CollectionAndChangedChunks {
CollectionAndChangedChunks();
- CollectionAndChangedChunks(const OID& collEpoch,
+ CollectionAndChangedChunks(boost::optional<UUID> uuid,
+ const OID& collEpoch,
const BSONObj& collShardKeyPattern,
const BSONObj& collDefaultCollation,
bool collShardKeyIsUnique,
std::vector<ChunkType> chunks);
// Information about the entire collection
+ boost::optional<UUID> uuid;
OID epoch;
BSONObj shardKeyPattern;
BSONObj defaultCollation;
diff --git a/src/mongo/s/chunk_manager.cpp b/src/mongo/s/chunk_manager.cpp
index a7bc21d39df..a54e311b61b 100644
--- a/src/mongo/s/chunk_manager.cpp
+++ b/src/mongo/s/chunk_manager.cpp
@@ -60,6 +60,7 @@ void checkAllElementsAreOfType(BSONType type, const BSONObj& o) {
} // namespace
ChunkManager::ChunkManager(NamespaceString nss,
+ boost::optional<UUID> uuid,
KeyPattern shardKeyPattern,
std::unique_ptr<CollatorInterface> defaultCollator,
bool unique,
@@ -67,6 +68,7 @@ ChunkManager::ChunkManager(NamespaceString nss,
ChunkVersion collectionVersion)
: _sequenceNumber(nextCMSequenceNumber.addAndFetch(1)),
_nss(std::move(nss)),
+ _uuid(uuid),
_shardKeyPattern(shardKeyPattern),
_defaultCollator(std::move(defaultCollator)),
_unique(unique),
@@ -426,6 +428,7 @@ ChunkManager::ChunkMapViews ChunkManager::_constructChunkMapViews(const OID& epo
std::shared_ptr<ChunkManager> ChunkManager::makeNew(
NamespaceString nss,
+ boost::optional<UUID> uuid,
KeyPattern shardKeyPattern,
std::unique_ptr<CollatorInterface> defaultCollator,
bool unique,
@@ -434,6 +437,7 @@ std::shared_ptr<ChunkManager> ChunkManager::makeNew(
return ChunkManager(
std::move(nss),
+ uuid,
std::move(shardKeyPattern),
std::move(defaultCollator),
std::move(unique),
@@ -489,6 +493,7 @@ std::shared_ptr<ChunkManager> ChunkManager::makeUpdated(
return std::shared_ptr<ChunkManager>(
new ChunkManager(_nss,
+ _uuid,
KeyPattern(getShardKeyPattern().getKeyPattern()),
CollatorInterface::cloneCollator(getDefaultCollator()),
isUnique(),
diff --git a/src/mongo/s/chunk_manager.h b/src/mongo/s/chunk_manager.h
index bb2580f8b4a..51bc9df1e5c 100644
--- a/src/mongo/s/chunk_manager.h
+++ b/src/mongo/s/chunk_manager.h
@@ -115,6 +115,7 @@ public:
* chunk version, and adhere to the requirements of the routing table update algorithm.
*/
static std::shared_ptr<ChunkManager> makeNew(NamespaceString nss,
+ boost::optional<UUID>,
KeyPattern shardKeyPattern,
std::unique_ptr<CollatorInterface> defaultCollator,
bool unique,
@@ -235,6 +236,10 @@ public:
std::string toString() const;
+ bool uuidMatches(UUID uuid) const {
+ return _uuid && *_uuid == uuid;
+ }
+
private:
/**
* Represents a range of chunk keys [getMin(), getMax()) and the id of the shard on which they
@@ -275,6 +280,7 @@ private:
static ChunkMapViews _constructChunkMapViews(const OID& epoch, const ChunkMap& chunkMap);
ChunkManager(NamespaceString nss,
+ boost::optional<UUID>,
KeyPattern shardKeyPattern,
std::unique_ptr<CollatorInterface> defaultCollator,
bool unique,
@@ -288,6 +294,9 @@ private:
// Namespace to which this routing information corresponds
const NamespaceString _nss;
+ // The invariant UUID of the collection. This is optional in 3.6, except in change streams.
+ const boost::optional<UUID> _uuid;
+
// The key pattern used to shard the collection
const ShardKeyPattern _shardKeyPattern;
diff --git a/src/mongo/s/config_server_catalog_cache_loader.cpp b/src/mongo/s/config_server_catalog_cache_loader.cpp
index 5f5f10e316f..bd6d8964fcf 100644
--- a/src/mongo/s/config_server_catalog_cache_loader.cpp
+++ b/src/mongo/s/config_server_catalog_cache_loader.cpp
@@ -122,11 +122,12 @@ CollectionAndChangedChunks getChangedChunks(OperationContext* opCtx,
"No chunks were found for the collection",
!changedChunks.empty());
- return {coll.getEpoch(),
- coll.getKeyPattern().toBSON(),
- coll.getDefaultCollation(),
- coll.getUnique(),
- std::move(changedChunks)};
+ return CollectionAndChangedChunks(coll.getUUID(),
+ coll.getEpoch(),
+ coll.getKeyPattern().toBSON(),
+ coll.getDefaultCollation(),
+ coll.getUnique(),
+ std::move(changedChunks));
}
} // namespace
diff --git a/src/mongo/util/uuid.h b/src/mongo/util/uuid.h
index 87939e91e96..d5c3f7c71b3 100644
--- a/src/mongo/util/uuid.h
+++ b/src/mongo/util/uuid.h
@@ -180,7 +180,7 @@ public:
private:
UUID(const UUIDStorage& uuid) : _uuid(uuid) {}
- UUIDStorage _uuid; // UUID in network byte order
+ UUIDStorage _uuid{}; // UUID in network byte order
};
inline std::ostream& operator<<(std::ostream& s, const UUID& uuid) {