summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Fuschetto <antonio.fuschetto@mongodb.com>2021-04-23 15:26:49 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-04-27 08:18:17 +0000
commitbd5d5c0a03a557c25282075b93bf606a4435aa4a (patch)
tree43a3bc3cf5ec22bbdecd2195aec7ab7ddd3bcd44
parent0c7ff5fc51ce3cdfd103798e38525a99590430b8 (diff)
downloadmongo-bd5d5c0a03a557c25282075b93bf606a4435aa4a.tar.gz
SERVER-55867 commitMovePrimary concurrent with setFCV may write incorrect metadata
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager.cpp23
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager.h10
-rw-r--r--src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp3
3 files changed, 27 insertions, 9 deletions
diff --git a/src/mongo/db/s/config/sharding_catalog_manager.cpp b/src/mongo/db/s/config/sharding_catalog_manager.cpp
index 0d96ec927f4..ce8ce68368b 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager.cpp
+++ b/src/mongo/db/s/config/sharding_catalog_manager.cpp
@@ -314,7 +314,8 @@ ShardingCatalogManager::ShardingCatalogManager(
_executorForAddShard(std::move(addShardExecutor)),
_kShardMembershipLock("shardMembershipLock"),
_kChunkOpLock("chunkOpLock"),
- _kZoneOpLock("zoneOpLock") {
+ _kZoneOpLock("zoneOpLock"),
+ _kDatabaseOpLock("databaseOpLock") {
startup();
}
@@ -657,6 +658,7 @@ void ShardingCatalogManager::_upgradeDatabasesEntriesTo50(OperationContext* opCt
auto now = VectorClock::get(opCtx)->getTime();
auto clusterTime = now.clusterTime().asTimestamp();
+ Lock::ExclusiveLock lock(opCtx->lockState(), _kDatabaseOpLock);
updateConfigDocumentDBDirect(
opCtx,
DatabaseType::ConfigNS,
@@ -690,14 +692,17 @@ void ShardingCatalogManager::_upgradeDatabasesEntriesTo50(OperationContext* opCt
void ShardingCatalogManager::_downgradeDatabasesEntriesToPre50(OperationContext* opCtx) {
LOGV2(5258806, "Starting downgrade of config.databases");
- updateConfigDocumentDBDirect(
- opCtx,
- DatabaseType::ConfigNS,
- {} /* query */,
- BSON("$unset" << BSON(DatabaseType::version() + "." + DatabaseVersion::kTimestampFieldName
- << "")),
- false /* upsert */,
- true /* multi */);
+ {
+ Lock::ExclusiveLock lock(opCtx->lockState(), _kDatabaseOpLock);
+ updateConfigDocumentDBDirect(
+ opCtx,
+ DatabaseType::ConfigNS,
+ {} /* query */,
+ BSON("$unset" << BSON(
+ DatabaseType::version() + "." + DatabaseVersion::kTimestampFieldName << "")),
+ false /* upsert */,
+ true /* multi */);
+ }
auto const catalogCache = Grid::get(opCtx)->catalogCache();
auto const configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard();
diff --git a/src/mongo/db/s/config/sharding_catalog_manager.h b/src/mongo/db/s/config/sharding_catalog_manager.h
index 5a72d95d78a..e8a7da2b356 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager.h
+++ b/src/mongo/db/s/config/sharding_catalog_manager.h
@@ -671,6 +671,16 @@ private:
* taking this.
*/
Lock::ResourceMutex _kZoneOpLock;
+
+ /**
+ * Lock for local database operations. This should be acquired when executing
+ * 'commitMovePrimary' and 'setFeatureCompatibilityVersion' commands which affect the
+ * config.databases collection. No other locks should be held when locking this. If an operation
+ * needs to take database locks (for example to write to a local collection) those locks should
+ * be taken after taking this.
+ * TODO (SERVER-53283): Remove once version 5.0 has been released.
+ */
+ Lock::ResourceMutex _kDatabaseOpLock;
};
} // namespace mongo
diff --git a/src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp b/src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp
index 00d36d441d7..0f9450cf712 100644
--- a/src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp
+++ b/src/mongo/db/s/config/sharding_catalog_manager_database_operations.cpp
@@ -266,6 +266,9 @@ Status ShardingCatalogManager::commitMovePrimary(OperationContext* opCtx,
auto const configShard = Grid::get(opCtx)->shardRegistry()->getConfigShard();
+ // TODO (SERVER-53283): Remove once version 5.0 has been released.
+ Lock::SharedLock lock(opCtx->lockState(), _kDatabaseOpLock);
+
// Must use local read concern because we will perform subsequent writes.
auto findResponse = uassertStatusOK(
configShard->exhaustiveFindOnConfig(opCtx,