diff options
author | Randolph Tan <randolph@10gen.com> | 2016-01-13 15:19:02 -0500 |
---|---|---|
committer | Randolph Tan <randolph@10gen.com> | 2016-01-15 17:07:14 -0500 |
commit | d74c7ae40f82bd5bf6334c8114c0cf4948f60002 (patch) | |
tree | 8cf4cd9579261875d579deb54a99b822107c0ff8 /src | |
parent | 927caf6e06d77adda6caa23120fc08b20059151b (diff) | |
download | mongo-d74c7ae40f82bd5bf6334c8114c0cf4948f60002.tar.gz |
SERVER-22114 Avoid doing unnecessary repeated calls to DBConfig::_load
(cherry picked from commit 0f85256eefa78b1b74b9e6ae0d1c646853f6f22f)
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/s/config.cpp | 18 | ||||
-rw-r--r-- | src/mongo/s/config.h | 32 |
2 files changed, 40 insertions, 10 deletions
diff --git a/src/mongo/s/config.cpp b/src/mongo/s/config.cpp index e051bfd5253..7716f012374 100644 --- a/src/mongo/s/config.cpp +++ b/src/mongo/s/config.cpp @@ -276,13 +276,15 @@ std::shared_ptr<ChunkManager> DBConfig::getChunkManager(OperationContext* txn, ChunkVersion oldVersion; ChunkManagerPtr oldManager; + const auto currentReloadIteration = _reloadCount.load(); + { stdx::lock_guard<stdx::mutex> lk(_lock); bool earlyReload = !_collections[ns].isSharded() && (shouldReload || forceReload); if (earlyReload) { // This is to catch cases where there this is a new sharded collection - _load(txn); + _loadIfNeeded(txn, currentReloadIteration); } CollectionInfo& ci = _collections[ns]; @@ -431,11 +433,16 @@ void DBConfig::setPrimary(OperationContext* txn, const ShardId& newPrimaryId) { } bool DBConfig::load(OperationContext* txn) { + const auto currentReloadIteration = _reloadCount.load(); stdx::lock_guard<stdx::mutex> lk(_lock); - return _load(txn); + return _loadIfNeeded(txn, currentReloadIteration); } -bool DBConfig::_load(OperationContext* txn) { +bool DBConfig::_loadIfNeeded(OperationContext* txn, Counter reloadIteration) { + if (reloadIteration != _reloadCount.load()) { + return true; + } + auto status = grid.catalogManager(txn)->getDatabase(txn, _name); if (status == ErrorCodes::NamespaceNotFound) { return false; @@ -483,6 +490,8 @@ bool DBConfig::_load(OperationContext* txn) { LOG(2) << "found " << numCollsSharded << " collections left and " << numCollsErased << " collections dropped for database " << _name; + _reloadCount.fetchAndAdd(1); + return true; } @@ -509,10 +518,11 @@ void DBConfig::_save(OperationContext* txn, bool db, bool coll) { bool DBConfig::reload(OperationContext* txn) { bool successful = false; + const auto currentReloadIteration = _reloadCount.load(); { stdx::lock_guard<stdx::mutex> lk(_lock); - successful = _load(txn); + successful = _loadIfNeeded(txn, currentReloadIteration); } // If we aren't successful loading the database entry, we don't want to keep the stale diff --git a/src/mongo/s/config.h b/src/mongo/s/config.h index ad179958c91..17a423db149 100644 --- a/src/mongo/s/config.h +++ b/src/mongo/s/config.h @@ -32,6 +32,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/repl/optime.h" +#include "mongo/platform/atomic_word.h" #include "mongo/s/client/shard.h" #include "mongo/util/concurrency/mutex.h" @@ -178,6 +179,7 @@ public: protected: typedef std::map<std::string, CollectionInfo> CollectionInfoMap; + typedef AtomicUInt64::WordType Counter; bool _dropShardedCollections(OperationContext* txn, int& num, @@ -187,30 +189,48 @@ protected: /** * Returns true if it is successful at loading the DBConfig, false if the database is not found, * and throws on all other errors. + * Also returns true without reloading if reloadIteration is not equal to the _reloadCount. + * This is to avoid multiple threads attempting to reload do duplicate work. */ - bool _load(OperationContext* txn); + bool _loadIfNeeded(OperationContext* txn, Counter reloadIteration); void _save(OperationContext* txn, bool db = true, bool coll = true); + // All member variables are labeled with one of the following codes indicating the + // synchronization rules for accessing them. + // + // (L) Must hold _lock for access. + // (I) Immutable, can access freely. + // (S) Self synchronizing, no explicit locking needed. + // + // Mutex lock order: + // _hitConfigServerLock -> _lock + // + // Name of the database which this entry caches - const std::string _name; + const std::string _name; // (I) // Primary shard id - ShardId _primaryId; + ShardId _primaryId; // (L) TODO: SERVER-22175 enforce this // Whether sharding has been enabled for this database - bool _shardingEnabled; + bool _shardingEnabled; // (L) TODO: SERVER-22175 enforce this // Set of collections and lock to protect access stdx::mutex _lock; - CollectionInfoMap _collections; + CollectionInfoMap _collections; // (L) // OpTime of config server when the database definition was loaded. - repl::OpTime _configOpTime; + repl::OpTime _configOpTime; // (L) // Ensures that only one thread at a time loads collection configuration data from // the config server stdx::mutex _hitConfigServerLock; + + // Increments every time this performs a full reload. Since a full reload can take a very + // long time for very large clusters, this can be used to minimize duplicate work when multiple + // threads tries to perform full reload at roughly the same time. + AtomicUInt64 _reloadCount; // (S) }; |