diff options
author | Sergi Mateo Bellido <sergi.mateo-bellido@mongodb.com> | 2021-10-04 09:34:11 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-10-04 09:58:38 +0000 |
commit | 3008af2319af2098f4691612f31a431c52ccc52c (patch) | |
tree | d13b3e94078fb3028ef4e998a318d639c0b9fdfc /src | |
parent | 0ae7d4aa4916c5783a523280fe2d4ec3c2897002 (diff) | |
download | mongo-3008af2319af2098f4691612f31a431c52ccc52c.tar.gz |
SERVER-60268 Reintroduce disambiguationg sequence number
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/s/catalog_cache.cpp | 17 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache.h | 16 | ||||
-rw-r--r-- | src/mongo/s/catalog_cache_test.cpp | 28 | ||||
-rw-r--r-- | src/mongo/s/comparable_database_version_test.cpp | 16 |
4 files changed, 65 insertions, 12 deletions
diff --git a/src/mongo/s/catalog_cache.cpp b/src/mongo/s/catalog_cache.cpp index d786da676f9..ed6283dacf7 100644 --- a/src/mongo/s/catalog_cache.cpp +++ b/src/mongo/s/catalog_cache.cpp @@ -73,6 +73,7 @@ const OperationContext::Decoration<bool> operationBlockedBehindCatalogCacheRefre } // namespace +AtomicWord<uint64_t> ComparableDatabaseVersion::_disambiguatingSequenceNumSource{1ULL}; AtomicWord<uint64_t> ComparableDatabaseVersion::_forcedRefreshSequenceNumSource{1ULL}; CachedDatabaseInfo::CachedDatabaseInfo(DatabaseTypeValueHandle&& dbt) : _dbt(std::move(dbt)){}; @@ -95,12 +96,15 @@ DatabaseVersion CachedDatabaseInfo::databaseVersion() const { ComparableDatabaseVersion ComparableDatabaseVersion::makeComparableDatabaseVersion( const boost::optional<DatabaseVersion>& version) { - return ComparableDatabaseVersion(version, _forcedRefreshSequenceNumSource.load()); + return ComparableDatabaseVersion(version, + _disambiguatingSequenceNumSource.fetchAndAdd(1), + _forcedRefreshSequenceNumSource.load()); } ComparableDatabaseVersion ComparableDatabaseVersion::makeComparableDatabaseVersionForForcedRefresh() { return ComparableDatabaseVersion(boost::none /* version */, + _disambiguatingSequenceNumSource.fetchAndAdd(1), _forcedRefreshSequenceNumSource.addAndFetch(2) - 1); } @@ -115,6 +119,9 @@ BSONObj ComparableDatabaseVersion::toBSONForLogging() const { else builder.append("dbVersion"_sd, "None"); + builder.append("disambiguatingSequenceNum"_sd, + static_cast<int64_t>(_disambiguatingSequenceNum)); + builder.append("forcedRefreshSequenceNum"_sd, static_cast<int64_t>(_forcedRefreshSequenceNum)); return builder.obj(); @@ -142,7 +149,13 @@ bool ComparableDatabaseVersion::operator<(const ComparableDatabaseVersion& other if (_forcedRefreshSequenceNum == 0) return false; // Only default constructed values have _forcedRefreshSequenceNum == 0 and // they are always equal - return _dbVersion < other._dbVersion; + + // If both versions are valid we rely on the underlying DatabaseVersion comparison + if (_dbVersion && other._dbVersion) + return _dbVersion < other._dbVersion; + + // Finally, we do a disambiguating sequence number comparison + return _disambiguatingSequenceNum < other._disambiguatingSequenceNum; } CatalogCache::CatalogCache(ServiceContext* const service, CatalogCacheLoader& cacheLoader) diff --git a/src/mongo/s/catalog_cache.h b/src/mongo/s/catalog_cache.h index 9dd31c65fa7..a50f010984e 100644 --- a/src/mongo/s/catalog_cache.h +++ b/src/mongo/s/catalog_cache.h @@ -71,8 +71,9 @@ private: }; /** - * This class wrap a DatabaseVersion object augmenting it with a sequence number to allow for forced - * catalog cache refreshes. + * This class wrap a DatabaseVersion object augmenting it with: + * - a sequence number to allow for forced catalog cache refreshes + * - a sequence number to disambiguate scenarios in which the DatabaseVersion isn't valid */ class ComparableDatabaseVersion { public: @@ -80,8 +81,8 @@ public: * Creates a ComparableDatabaseVersion that wraps the given DatabaseVersion. * * If version is boost::none it creates a ComparableDatabaseVersion that doesn't have a valid - * DatabaseVersion. This is useful in some scenarios in which the DatabaseVersion is provided - * later through ComparableDatabaseVersion::setVersion. + * version. This is useful in some scenarios in which the DatabaseVersion is provided later + * through ComparableDatabaseVersion::setVersion or to represent that a Database doesn't exist */ static ComparableDatabaseVersion makeComparableDatabaseVersion( const boost::optional<DatabaseVersion>& version); @@ -128,16 +129,21 @@ public: private: friend class CatalogCache; + static AtomicWord<uint64_t> _disambiguatingSequenceNumSource; static AtomicWord<uint64_t> _forcedRefreshSequenceNumSource; ComparableDatabaseVersion(boost::optional<DatabaseVersion> version, + uint64_t disambiguatingSequenceNum, uint64_t forcedRefreshSequenceNum) - : _dbVersion(std::move(version)), _forcedRefreshSequenceNum(forcedRefreshSequenceNum) {} + : _dbVersion(std::move(version)), + _disambiguatingSequenceNum(disambiguatingSequenceNum), + _forcedRefreshSequenceNum(forcedRefreshSequenceNum) {} void setDatabaseVersion(const DatabaseVersion& version); boost::optional<DatabaseVersion> _dbVersion; + uint64_t _disambiguatingSequenceNum{0}; uint64_t _forcedRefreshSequenceNum{0}; }; diff --git a/src/mongo/s/catalog_cache_test.cpp b/src/mongo/s/catalog_cache_test.cpp index 0106cf4b393..818cf2d38b0 100644 --- a/src/mongo/s/catalog_cache_test.cpp +++ b/src/mongo/s/catalog_cache_test.cpp @@ -211,6 +211,34 @@ TEST_F(CatalogCacheTest, GetCachedDatabase) { ASSERT_EQ(cachedDb.databaseVersion().getLastMod(), dbVersion.getLastMod()); } +TEST_F(CatalogCacheTest, GetDatabaseDrop) { + const auto dbName = "testDB"; + const auto dbVersion = DatabaseVersion(UUID::gen(), Timestamp()); + + _catalogCacheLoader->setDatabaseRefreshReturnValue( + DatabaseType(dbName, kShards[0], true, dbVersion)); + + // The CatalogCache doesn't have any valid info about this DB and finds a new DatabaseType + auto swDatabase = _catalogCache->getDatabase(operationContext(), dbName); + ASSERT_OK(swDatabase.getStatus()); + const auto cachedDb = swDatabase.getValue(); + ASSERT_TRUE(cachedDb.shardingEnabled()); + ASSERT_EQ(cachedDb.databaseVersion().getUuid(), dbVersion.getUuid()); + ASSERT_EQ(cachedDb.databaseVersion().getLastMod(), dbVersion.getLastMod()); + + // Advancing the timeInStore, e.g. because of a movePrimary + _catalogCache->onStaleDatabaseVersion(dbName, dbVersion.makeUpdated()); + + // However, when this CatalogCache asks to the loader for the new info associated to dbName it + // didn't find any (i.e. the database was dropped) + _catalogCacheLoader->setDatabaseRefreshReturnValue( + Status(ErrorCodes::NamespaceNotFound, "dummy errmsg")); + + // Finally, the CatalogCache shouldn't find the Database + swDatabase = _catalogCache->getDatabase(operationContext(), dbName); + ASSERT_EQUALS(ErrorCodes::NamespaceNotFound, swDatabase.getStatus()); +} + TEST_F(CatalogCacheTest, InvalidateSingleDbOnShardRemoval) { const auto dbName = "testDB"; const auto dbVersion = DatabaseVersion(UUID::gen(), Timestamp()); diff --git a/src/mongo/s/comparable_database_version_test.cpp b/src/mongo/s/comparable_database_version_test.cpp index d1a499b26f6..ff073db5042 100644 --- a/src/mongo/s/comparable_database_version_test.cpp +++ b/src/mongo/s/comparable_database_version_test.cpp @@ -131,11 +131,17 @@ TEST(ComparableDatabaseVersionTest, CompareTwoForcedRefreshVersions) { ASSERT_FALSE(forcedRefreshVersion1 > forcedRefreshVersion2); } -TEST(ComparableDatabaseVersionTest, CompareTwoComparableChunkVersionsWithBoostNone) { - const auto version1 = ComparableDatabaseVersion::makeComparableDatabaseVersion(boost::none); - const auto version2 = ComparableDatabaseVersion::makeComparableDatabaseVersion(boost::none); - - ASSERT_TRUE(version1 == version2); +TEST(ComparableDatabaseVersionTest, CompareVersionsAgainstBoostNone) { + auto checkGreatherThan = [](const boost::optional<DatabaseVersion>& v1, + const boost::optional<DatabaseVersion>& v2) { + const auto version1 = ComparableDatabaseVersion::makeComparableDatabaseVersion(v1); + const auto version2 = ComparableDatabaseVersion::makeComparableDatabaseVersion(v2); + ASSERT_TRUE(version1 < version2); + }; + const DatabaseVersion v(UUID::gen(), Timestamp(42)); + checkGreatherThan(boost::none, v); + checkGreatherThan(v, boost::none); + checkGreatherThan(boost::none, boost::none); } } // namespace |