summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRandolph Tan <randolph@10gen.com>2016-01-13 15:19:02 -0500
committerRandolph Tan <randolph@10gen.com>2016-01-15 17:07:14 -0500
commitd74c7ae40f82bd5bf6334c8114c0cf4948f60002 (patch)
tree8cf4cd9579261875d579deb54a99b822107c0ff8 /src
parent927caf6e06d77adda6caa23120fc08b20059151b (diff)
downloadmongo-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.cpp18
-rw-r--r--src/mongo/s/config.h32
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)
};