summaryrefslogtreecommitdiff
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 16:05:32 -0500
commitaaa56a5d37ee1ad78326a2e22e097bdf91bedeed (patch)
tree2e6fe3152ee1724317080778127cfd0beddc4ff7
parent56eae69cf882d92e502340c9ce5dcc4a7058db9a (diff)
downloadmongo-aaa56a5d37ee1ad78326a2e22e097bdf91bedeed.tar.gz
SERVER-22114 Avoid doing unnecessary repeated calls to DBConfig::_load
(cherry picked from commit 0f85256eefa78b1b74b9e6ae0d1c646853f6f22f) Conflicts: src/mongo/s/config.cpp src/mongo/s/config.h
-rw-r--r--src/mongo/s/config.cpp25
-rw-r--r--src/mongo/s/config.h19
2 files changed, 31 insertions, 13 deletions
diff --git a/src/mongo/s/config.cpp b/src/mongo/s/config.cpp
index f6d0e01c151..3f7586e70bb 100644
--- a/src/mongo/s/config.cpp
+++ b/src/mongo/s/config.cpp
@@ -367,13 +367,15 @@ ChunkManagerPtr DBConfig::getChunkManager(const string& ns, bool shouldReload, b
ChunkVersion oldVersion;
ChunkManagerPtr oldManager;
+ const auto currentReloadIteration = _reloadCount.load();
+
{
scoped_lock lk(_lock);
bool earlyReload = !_collections[ns].isSharded() && (shouldReload || forceReload);
if (earlyReload) {
- // this is to catch cases where there this is a new sharded collection
- _reload();
+ // This is to catch cases where there this is a new sharded collection
+ _loadIfNeeded(currentReloadIteration);
}
CollectionInfo& ci = _collections[ns];
@@ -530,11 +532,16 @@ void DBConfig::unserialize(const BSONObj& from) {
}
bool DBConfig::load() {
+ const auto currentReloadIteration = _reloadCount.load();
scoped_lock lk(_lock);
- return _load();
+ return _loadIfNeeded(currentReloadIteration);
}
-bool DBConfig::_load() {
+bool DBConfig::_loadIfNeeded(Counter reloadIteration) {
+ if (reloadIteration != _reloadCount.load()) {
+ return true;
+ }
+
ScopedDbConnection conn(configServer.modelServer(), 30.0);
BSONObj dbObj = conn->findOne(DatabaseType::ConfigNS, BSON(DatabaseType::name(_name)));
@@ -580,6 +587,8 @@ bool DBConfig::_load() {
conn.done();
+ _reloadCount.fetchAndAdd(1);
+
return true;
}
@@ -617,10 +626,11 @@ void DBConfig::_save(bool db, bool coll) {
bool DBConfig::reload() {
bool successful = false;
+ const auto currentReloadIteration = _reloadCount.load();
{
scoped_lock lk(_lock);
- successful = _reload();
+ successful = _loadIfNeeded(currentReloadIteration);
}
//
@@ -634,11 +644,6 @@ bool DBConfig::reload() {
return successful;
}
-bool DBConfig::_reload() {
- // TODO: i don't think is 100% correct
- return _load();
-}
-
bool DBConfig::dropDatabase(string& errmsg) {
/**
* 1) make sure everything is up
diff --git a/src/mongo/s/config.h b/src/mongo/s/config.h
index d638a3a483b..a187320f55d 100644
--- a/src/mongo/s/config.h
+++ b/src/mongo/s/config.h
@@ -38,6 +38,7 @@
#include <boost/shared_ptr.hpp>
#include "mongo/client/dbclient_rs.h"
+#include "mongo/platform/atomic_word.h"
#include "mongo/s/chunk.h"
#include "mongo/s/shard.h"
#include "mongo/s/shard_key_pattern.h"
@@ -198,8 +199,9 @@ public:
void getAllShards(std::set<Shard>& shards) const;
void getAllShardedCollections(std::set<std::string>& namespaces) const;
-
protected:
+ typedef AtomicUInt64::WordType Counter;
+
/**
lockless
*/
@@ -207,8 +209,14 @@ protected:
bool _dropShardedCollections(int& num, std::set<Shard>& allServers, std::string& errmsg);
- bool _load();
- bool _reload();
+ /**
+ * 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 _loadIfNeeded(Counter reloadIteration);
+
void _save(bool db = true, bool coll = true);
std::string _name; // e.g. "alleyinsider"
@@ -224,6 +232,11 @@ protected:
mutable mongo::mutex _lock; // TODO: change to r/w lock ??
mutable mongo::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)
};
class ConfigServer : public DBConfig {