summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2015-02-23 11:37:20 -0500
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2015-03-03 10:53:07 -0500
commit41986e669a4ef32b38c433a2cfd0b70e872e6899 (patch)
tree675ec225c7e9fad5902a78e71efc2e6c9d167325 /src/mongo
parentacea28520290e793c1ff9e6ed4117ff543c59a98 (diff)
downloadmongo-41986e669a4ef32b38c433a2cfd0b70e872e6899.tar.gz
SERVER-17151 ConfigCoordinator should not call fsync
This is expensive to do, especially with WiredTiger and is not a deterministic check. This change replaces it with something cheaper, but has the same outcome - validates that previous writes were successfully journaled, which is an approximate predictor that subsequent writes have high chance of succeeding.
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/SConscript15
-rw-r--r--src/mongo/bson/bsonmisc.h4
-rw-r--r--src/mongo/client/syncclusterconnection.cpp20
-rw-r--r--src/mongo/client/syncclusterconnection.h5
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_s.cpp5
-rw-r--r--src/mongo/db/write_concern_options.cpp1
-rw-r--r--src/mongo/db/write_concern_options.h1
-rw-r--r--src/mongo/s/SConscript83
-rw-r--r--src/mongo/s/balance.cpp8
-rw-r--r--src/mongo/s/balancing_window_test.cpp94
-rw-r--r--src/mongo/s/chunk.cpp3
-rw-r--r--src/mongo/s/chunk.h32
-rw-r--r--src/mongo/s/chunk_manager_targeter.cpp22
-rw-r--r--src/mongo/s/chunk_manager_targeter.h38
-rw-r--r--src/mongo/s/cluster_client_internal.cpp1
-rw-r--r--src/mongo/s/cluster_write.cpp51
-rw-r--r--src/mongo/s/cluster_write.h27
-rw-r--r--src/mongo/s/commands/cluster_explain_cmd.cpp153
-rw-r--r--src/mongo/s/commands/cluster_explain_cmd.h86
-rw-r--r--src/mongo/s/commands/cluster_find_cmd.cpp156
-rw-r--r--src/mongo/s/commands/cluster_find_cmd.h82
-rw-r--r--src/mongo/s/commands_admin.cpp11
-rw-r--r--src/mongo/s/config.cpp14
-rw-r--r--src/mongo/s/config.h8
-rw-r--r--src/mongo/s/config_upgrade_helpers.cpp3
-rw-r--r--src/mongo/s/config_upgrade_v0_to_v6.cpp1
-rw-r--r--src/mongo/s/config_upgrade_v5_to_v6.cpp1
-rw-r--r--src/mongo/s/grid.cpp68
-rw-r--r--src/mongo/s/grid.h3
-rw-r--r--src/mongo/s/strategy.cpp8
-rw-r--r--src/mongo/s/write_ops/config_coordinator.cpp254
-rw-r--r--src/mongo/s/write_ops/config_coordinator.h4
32 files changed, 409 insertions, 853 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index 683c959e7af..809c8c2d58f 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -827,23 +827,20 @@ env.Library('mongoscore',
's/upgrade',
])
-env.CppUnitTest("shard_key_pattern_test", [ "s/shard_key_pattern_test.cpp" ],
+env.CppUnitTest("mongoscore_test",
+ ["s/shard_key_pattern_test.cpp",
+ "s/balancing_window_test.cpp",
+ "s/balancer_policy_tests.cpp",
+ ],
LIBDEPS=["mongoscore",
"coreshard",
"mongocommon",
"coreserver",
"coredb"])
-env.CppUnitTest( "balancer_policy_test" , [ "s/balancer_policy_tests.cpp" ] ,
- LIBDEPS=["mongoscore",
- "coreshard",
- "mongocommon",
- "coreserver",
- "coredb",
- "message_server_port"])
-
env.CppUnitTest("dbclient_rs_test", [ "client/dbclient_rs_test.cpp" ],
LIBDEPS=['clientdriver', 'mocklib'])
+
env.CppUnitTest("scoped_db_conn_test", [ "client/scoped_db_conn_test.cpp" ],
LIBDEPS=[
"coredb",
diff --git a/src/mongo/bson/bsonmisc.h b/src/mongo/bson/bsonmisc.h
index 21cbc135b8c..483528d80e0 100644
--- a/src/mongo/bson/bsonmisc.h
+++ b/src/mongo/bson/bsonmisc.h
@@ -29,10 +29,8 @@
#pragma once
-#include <boost/noncopyable.hpp>
-#include <memory>
-
#include "mongo/bson/bsonelement.h"
+#include "mongo/bson/bsonobj.h"
namespace mongo {
diff --git a/src/mongo/client/syncclusterconnection.cpp b/src/mongo/client/syncclusterconnection.cpp
index 285c0baba26..762a2d69ea0 100644
--- a/src/mongo/client/syncclusterconnection.cpp
+++ b/src/mongo/client/syncclusterconnection.cpp
@@ -96,33 +96,29 @@ namespace mongo {
_conns.clear();
}
- bool SyncClusterConnection::prepare( string& errmsg ) {
+ bool SyncClusterConnection::prepare(string& errmsg) {
_lastErrors.clear();
- return fsync( errmsg );
- }
- bool SyncClusterConnection::fsync( string& errmsg ) {
bool ok = true;
errmsg = "";
- for ( size_t i=0; i<_conns.size(); i++ ) {
+
+ for (size_t i = 0; i < _conns.size(); i++) {
string singleErr;
try {
- // this is fsync=true
- // which with journalling on is a journal commit
- // without journalling, is a full fsync
- _conns[i]->simpleCommand( "admin", NULL, "resetError" );
- singleErr = _conns[i]->getLastError( true );
+ _conns[i]->simpleCommand("admin", NULL, "resetError");
+ singleErr = _conns[i]->getLastError(true);
- if ( singleErr.size() == 0 )
+ if (singleErr.size() == 0)
continue;
}
- catch ( DBException& e ) {
+ catch (DBException& e) {
singleErr = e.toString();
}
ok = false;
errmsg += " " + _conns[i]->toString() + ":" + singleErr;
}
+
return ok;
}
diff --git a/src/mongo/client/syncclusterconnection.h b/src/mongo/client/syncclusterconnection.h
index d9f5ab3f2c8..6a99f59a364 100644
--- a/src/mongo/client/syncclusterconnection.h
+++ b/src/mongo/client/syncclusterconnection.h
@@ -78,11 +78,6 @@ namespace mongo {
*/
bool prepare( std::string& errmsg );
- /**
- * runs fsync on all servers
- */
- bool fsync( std::string& errmsg );
-
// --- from DBClientInterface
virtual BSONObj findOne(const std::string &ns, const Query& query, const BSONObj *fieldsToReturn, int queryOptions);
diff --git a/src/mongo/db/auth/authz_manager_external_state_s.cpp b/src/mongo/db/auth/authz_manager_external_state_s.cpp
index 20e47afaed1..5d70845324f 100644
--- a/src/mongo/db/auth/authz_manager_external_state_s.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_s.cpp
@@ -245,7 +245,7 @@ namespace mongo {
const NamespaceString& collectionName,
const BSONObj& document,
const BSONObj& writeConcern) {
- return clusterInsert(collectionName, document, writeConcern, NULL);
+ return clusterInsert(collectionName, document, NULL);
}
Status AuthzManagerExternalStateMongos::update(OperationContext* txn,
@@ -262,7 +262,6 @@ namespace mongo {
updatePattern,
upsert,
multi,
- writeConcern,
&response);
if (res.isOK()) {
@@ -279,7 +278,7 @@ namespace mongo {
const BSONObj& writeConcern,
int* numRemoved) {
BatchedCommandResponse response;
- Status res = clusterDelete(collectionName, query, 0 /* limit */, writeConcern, &response);
+ Status res = clusterDelete(collectionName, query, 0 /* limit */, &response);
if (res.isOK()) {
*numRemoved = response.getN();
diff --git a/src/mongo/db/write_concern_options.cpp b/src/mongo/db/write_concern_options.cpp
index dd8b14cdb05..5c0102ebc4a 100644
--- a/src/mongo/db/write_concern_options.cpp
+++ b/src/mongo/db/write_concern_options.cpp
@@ -37,7 +37,6 @@ namespace mongo {
const BSONObj WriteConcernOptions::Default = BSONObj();
const BSONObj WriteConcernOptions::Acknowledged(BSON("w" << W_NORMAL));
- const BSONObj WriteConcernOptions::AllConfigs = BSONObj();
const BSONObj WriteConcernOptions::Unacknowledged(BSON("w" << W_NONE));
static const BSONField<bool> mongosSecondaryThrottleField("_secondaryThrottle", true);
diff --git a/src/mongo/db/write_concern_options.h b/src/mongo/db/write_concern_options.h
index 31b0f556c30..445b6fab1db 100644
--- a/src/mongo/db/write_concern_options.h
+++ b/src/mongo/db/write_concern_options.h
@@ -44,7 +44,6 @@ namespace mongo {
static const BSONObj Default;
static const BSONObj Acknowledged;
- static const BSONObj AllConfigs;
static const BSONObj Unacknowledged;
WriteConcernOptions() { reset(); }
diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript
index ced76ef6768..8ff9e09e754 100644
--- a/src/mongo/s/SConscript
+++ b/src/mongo/s/SConscript
@@ -153,52 +153,12 @@ env.Library(
)
env.CppUnitTest(
- target='batched_command_response_test',
+ target='batch_write_types_test',
source=[
'write_ops/batched_command_response_test.cpp',
- ],
- LIBDEPS=[
- 'batch_write_types',
- '$BUILD_DIR/mongo/db/common',
- ]
-)
-
-env.CppUnitTest(
- target='batched_delete_request_test',
- source=[
'write_ops/batched_delete_request_test.cpp',
- ],
- LIBDEPS=[
- 'batch_write_types',
- '$BUILD_DIR/mongo/db/common',
- ]
-)
-
-env.CppUnitTest(
- target='batched_insert_request_test',
- source=[
'write_ops/batched_insert_request_test.cpp',
- ],
- LIBDEPS=[
- 'batch_write_types',
- '$BUILD_DIR/mongo/db/common',
- ]
-)
-
-env.CppUnitTest(
- target='batched_request_metadata_test',
- source=[
'write_ops/batched_request_metadata_test.cpp',
- ],
- LIBDEPS=[
- 'batch_write_types',
- '$BUILD_DIR/mongo/db/common',
- ]
-)
-
-env.CppUnitTest(
- target='batched_update_request_test',
- source=[
'write_ops/batched_update_request_test.cpp',
],
LIBDEPS=[
@@ -231,32 +191,10 @@ env.Library(
)
env.CppUnitTest(
- target='write_op_test',
+ target='cluster_ops_test',
source=[
'write_ops/write_op_test.cpp',
- ],
- LIBDEPS=[
- 'base',
- 'cluster_ops',
- '$BUILD_DIR/mongo/db/common',
- ]
-)
-
-env.CppUnitTest(
- target='batch_write_op_test',
- source=[
'write_ops/batch_write_op_test.cpp',
- ],
- LIBDEPS=[
- 'base',
- 'cluster_ops',
- '$BUILD_DIR/mongo/db/common',
- ]
-)
-
-env.CppUnitTest(
- target='batch_write_exec_test',
- source=[
'write_ops/batch_write_exec_test.cpp',
],
LIBDEPS=[
@@ -264,7 +202,7 @@ env.CppUnitTest(
'cluster_ops',
'$BUILD_DIR/mongo/db/common',
'$BUILD_DIR/mongo/clientdriver',
- ],
+ ]
)
env.CppUnitTest(
@@ -308,22 +246,9 @@ env.Library(
)
env.CppUnitTest(
- target='batch_upconvert_test',
+ target='cluster_write_op_conversion_test',
source=[
'write_ops/batch_upconvert_test.cpp',
- ],
- LIBDEPS=[
- 'cluster_ops',
- 'cluster_write_op_conversion',
- '$BUILD_DIR/mongo/db/common',
- '$BUILD_DIR/mongo/server_options', # DbMessage needs server options
- "$BUILD_DIR/mongo/clientdriver",
- ]
-)
-
-env.CppUnitTest(
- target='batch_downconvert_test',
- source=[
'write_ops/batch_downconvert_test.cpp',
],
LIBDEPS=[
diff --git a/src/mongo/s/balance.cpp b/src/mongo/s/balance.cpp
index e380a136191..418f63a7197 100644
--- a/src/mongo/s/balance.cpp
+++ b/src/mongo/s/balance.cpp
@@ -188,7 +188,6 @@ namespace mongo {
MongosType::mongoVersion(versionString) )),
true, // upsert
false, // multi
- WriteConcernOptions::Unacknowledged,
NULL );
}
@@ -262,11 +261,7 @@ namespace mongo {
createActionlog = true;
}
- Status result = clusterInsert( ActionLogType::ConfigNS,
- actionLog.toBSON(),
- WriteConcernOptions::AllConfigs,
- NULL );
-
+ Status result = clusterInsert(ActionLogType::ConfigNS, actionLog.toBSON(), NULL);
if ( !result.isOK() ) {
log() << "Error encountered while logging action from balancer "
<< result.reason();
@@ -446,7 +441,6 @@ namespace mongo {
DistributionStatus status(shardInfo, shardToChunksMap.map());
- // load tags
cursor = conn.query(TagsType::ConfigNS,
QUERY(TagsType::ns(ns)).sort(TagsType::min()));
diff --git a/src/mongo/s/balancing_window_test.cpp b/src/mongo/s/balancing_window_test.cpp
new file mode 100644
index 00000000000..c24fe283318
--- /dev/null
+++ b/src/mongo/s/balancing_window_test.cpp
@@ -0,0 +1,94 @@
+/* Copyright 2012 10gen Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects
+ * for all of the code used other than as permitted herein. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you do not
+ * wish to do so, delete this exception statement from your version. If you
+ * delete this exception statement from all source files in the program,
+ * then also delete it in the license file.
+ */
+
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
+
+#include "mongo/s/grid.h"
+#include "mongo/s/type_settings.h"
+#include "mongo/unittest/unittest.h"
+#include "mongo/util/log.h"
+
+namespace mongo {
+
+ using std::string;
+
+namespace {
+
+ TEST(BalancingWindow, Test) {
+ // T0 < T1 < now < T2 < T3 and Error
+ const string T0 = "9:00";
+ const string T1 = "11:00";
+ boost::posix_time::ptime now(currentDate(),
+ boost::posix_time::hours(13) +
+ boost::posix_time::minutes(48));
+ const string T2 = "17:00";
+ const string T3 = "21:30";
+ const string E = "28:35";
+
+ // closed in the past
+ BSONObj w1 = BSON(SettingsType::balancerActiveWindow(BSON("start" << T0 << "stop" << T1)));
+
+ // not opened until the future
+ BSONObj w2 = BSON(SettingsType::balancerActiveWindow(BSON("start" << T2 << "stop" << T3)));
+
+ // open now
+ BSONObj w3 = BSON(SettingsType::balancerActiveWindow(BSON("start" << T1 << "stop" << T2)));
+
+ // open since last day
+ BSONObj w4 = BSON(SettingsType::balancerActiveWindow(BSON("start" << T3 << "stop" << T2)));
+
+ ASSERT(!Grid::_inBalancingWindow(w1, now));
+ ASSERT(!Grid::_inBalancingWindow(w2, now));
+ ASSERT(Grid::_inBalancingWindow(w3, now));
+ ASSERT(Grid::_inBalancingWindow(w4, now));
+
+ // bad input should not stop the balancer
+
+ // empty window
+ BSONObj w5;
+
+ // missing stop
+ BSONObj w6 = BSON(SettingsType::balancerActiveWindow(BSON("start" << 1)));
+
+ // missing start
+ BSONObj w7 = BSON(SettingsType::balancerActiveWindow(BSON("stop" << 1)));
+
+ // active window marker missing
+ BSONObj w8 = BSON("wrongMarker" << 1 << "start" << 1 << "stop" << 1);
+
+ // garbage in window
+ BSONObj w9 = BSON(SettingsType::balancerActiveWindow(BSON("start" << T3 << "stop" << E)));
+
+ ASSERT(Grid::_inBalancingWindow(w5, now));
+ ASSERT(Grid::_inBalancingWindow(w6, now));
+ ASSERT(Grid::_inBalancingWindow(w7, now));
+ ASSERT(Grid::_inBalancingWindow(w8, now));
+ ASSERT(Grid::_inBalancingWindow(w9, now));
+ }
+
+} // namespace
+} // namespace mongo
diff --git a/src/mongo/s/chunk.cpp b/src/mongo/s/chunk.cpp
index 9814f97f6a3..6df0afcdbb2 100644
--- a/src/mongo/s/chunk.cpp
+++ b/src/mongo/s/chunk.cpp
@@ -745,7 +745,6 @@ namespace mongo {
BSON("$set" << BSON(ChunkType::jumbo(true))),
false, // upsert
false, // multi
- WriteConcernOptions::AllConfigs,
NULL );
if ( !result.isOK() ) {
@@ -1158,7 +1157,6 @@ namespace mongo {
chunkObj,
true, // upsert
false, // multi
- WriteConcernOptions::AllConfigs,
NULL );
version.incMinor();
@@ -1447,7 +1445,6 @@ namespace mongo {
Status result = clusterDelete( ChunkType::ConfigNS,
BSON(ChunkType::ns(_ns)),
0 /* limit */,
- WriteConcernOptions::AllConfigs,
NULL );
// Make sure we're dropped on the config
diff --git a/src/mongo/s/chunk.h b/src/mongo/s/chunk.h
index 24d9689488e..46ab7bcf6c2 100644
--- a/src/mongo/s/chunk.h
+++ b/src/mongo/s/chunk.h
@@ -565,38 +565,6 @@ namespace mongo {
friend class TestableChunkManager;
};
- // like BSONObjCmp. for use as an STL comparison functor
- // key-order in "order" argument must match key-order in shardkey
- class ChunkCmp {
- public:
- ChunkCmp( const BSONObj &order = BSONObj() ) : _cmp( order ) {}
- bool operator()( const Chunk &l, const Chunk &r ) const {
- return _cmp(l.getMin(), r.getMin());
- }
- bool operator()( const ptr<Chunk> l, const ptr<Chunk> r ) const {
- return operator()(*l, *r);
- }
-
- // Also support ChunkRanges
- bool operator()( const ChunkRange &l, const ChunkRange &r ) const {
- return _cmp(l.getMin(), r.getMin());
- }
- bool operator()( const boost::shared_ptr<ChunkRange> l, const boost::shared_ptr<ChunkRange> r ) const {
- return operator()(*l, *r);
- }
- private:
- BSONObjCmp _cmp;
- };
-
- /*
- struct chunk_lock {
- chunk_lock( const Chunk* c ){
-
- }
-
- Chunk _c;
- };
- */
inline std::string Chunk::genID() const { return genID(_manager->getns(), _min); }
bool setShardVersion( DBClientBase & conn,
diff --git a/src/mongo/s/chunk_manager_targeter.cpp b/src/mongo/s/chunk_manager_targeter.cpp
index 83ca4cfe07c..1981d9dfb6c 100644
--- a/src/mongo/s/chunk_manager_targeter.cpp
+++ b/src/mongo/s/chunk_manager_targeter.cpp
@@ -60,18 +60,13 @@ namespace mongo {
return config.get();
}
- ChunkManagerTargeter::ChunkManagerTargeter() :
- _needsTargetingRefresh( false ), _stats( new TargeterStats ) {
- }
-
- Status ChunkManagerTargeter::init( const NamespaceString& nss ) {
+ ChunkManagerTargeter::ChunkManagerTargeter(const NamespaceString& nss)
+ : _nss(nss),
+ _needsTargetingRefresh(false) {
- _nss = nss;
-
- //
- // Get the latest metadata information from the cache
- //
+ }
+ Status ChunkManagerTargeter::init() {
DBConfigPtr config;
string errMsg;
@@ -399,8 +394,9 @@ namespace mongo {
// Track autosplit stats for sharded collections
// Note: this is only best effort accounting and is not accurate.
- if (estDataSize > 0)
- _stats->chunkSizeDelta[chunk->getMin()] += estDataSize;
+ if (estDataSize > 0) {
+ _stats.chunkSizeDelta[chunk->getMin()] += estDataSize;
+ }
Shard shard = chunk->getShard();
*endpoint = new ShardEndpoint(shard.getName(),
@@ -646,7 +642,7 @@ namespace mongo {
}
const TargeterStats* ChunkManagerTargeter::getStats() const {
- return _stats.get();
+ return &_stats;
}
Status ChunkManagerTargeter::refreshIfNeeded( bool *wasChanged ) {
diff --git a/src/mongo/s/chunk_manager_targeter.h b/src/mongo/s/chunk_manager_targeter.h
index b082ad62eec..aaa115b044b 100644
--- a/src/mongo/s/chunk_manager_targeter.h
+++ b/src/mongo/s/chunk_manager_targeter.h
@@ -40,7 +40,13 @@
namespace mongo {
- struct TargeterStats;
+ class Grid;
+
+ struct TargeterStats {
+ // Map of chunk shard minKey -> approximate delta. This is used for deciding
+ // whether a chunk might need splitting or not.
+ std::map<BSONObj, int> chunkSizeDelta;
+ };
/**
* NSTargeter based on a ChunkManager implementation. Wraps all exception codepaths and
@@ -51,7 +57,7 @@ namespace mongo {
class ChunkManagerTargeter : public NSTargeter {
public:
- ChunkManagerTargeter();
+ ChunkManagerTargeter(const NamespaceString& nss);
/**
* Initializes the ChunkManagerTargeter with the latest targeting information for the
@@ -59,7 +65,7 @@ namespace mongo {
*
* Returns !OK if the information could not be initialized.
*/
- Status init( const NamespaceString& nss );
+ Status init();
const NamespaceString& getNS() const;
@@ -101,7 +107,6 @@ namespace mongo {
private:
// Different ways we can refresh metadata
- // TODO: Improve these ways.
enum RefreshType {
// No refresh is needed
RefreshType_None,
@@ -111,6 +116,9 @@ namespace mongo {
RefreshType_ReloadDatabase
};
+ typedef std::map<std::string, ChunkVersion> ShardVersionMap;
+
+
/**
* Performs an actual refresh from the config server.
*/
@@ -140,7 +148,14 @@ namespace mongo {
long long estDataSize,
ShardEndpoint** endpoint) const;
- NamespaceString _nss;
+ // Full namespace of the collection for this targeter
+ const NamespaceString _nss;
+
+ // Stores whether we need to check the remote server on refresh
+ bool _needsTargetingRefresh;
+
+ // Represents only the view and not really part of the targeter state.
+ mutable TargeterStats _stats;
// Zero or one of these are filled at all times
// If sharded, _manager, if unsharded, _primary, on error, neither
@@ -148,20 +163,7 @@ namespace mongo {
ShardPtr _primary;
// Map of shard->remote shard version reported from stale errors
- typedef std::map<std::string, ChunkVersion> ShardVersionMap;
ShardVersionMap _remoteShardVersions;
-
- // Stores whether we need to check the remote server on refresh
- bool _needsTargetingRefresh;
-
- // Represents only the view and not really part of the targeter state.
- mutable boost::scoped_ptr<TargeterStats> _stats;
- };
-
- struct TargeterStats {
- // Map of chunk shard minKey -> approximate delta. This is used for deciding
- // whether a chunk might need splitting or not.
- std::map<BSONObj, int> chunkSizeDelta;
};
} // namespace mongo
diff --git a/src/mongo/s/cluster_client_internal.cpp b/src/mongo/s/cluster_client_internal.cpp
index b0b4fc53f81..42e285bbc65 100644
--- a/src/mongo/s/cluster_client_internal.cpp
+++ b/src/mongo/s/cluster_client_internal.cpp
@@ -394,7 +394,6 @@ namespace mongo {
Status result = clusterInsert( ChangelogType::ConfigNS,
changelog.toBSON(),
- WriteConcernOptions::AllConfigs,
NULL );
if ( !result.isOK() ) {
diff --git a/src/mongo/s/cluster_write.cpp b/src/mongo/s/cluster_write.cpp
index ec66e80b790..c34189df99a 100644
--- a/src/mongo/s/cluster_write.cpp
+++ b/src/mongo/s/cluster_write.cpp
@@ -37,6 +37,7 @@
#include "mongo/base/init.h"
#include "mongo/base/status.h"
+#include "mongo/db/write_concern_options.h"
#include "mongo/s/chunk_manager_targeter.h"
#include "mongo/s/config.h"
#include "mongo/s/dbclient_multi_command.h"
@@ -100,6 +101,14 @@ namespace mongo {
return indexDoc.obj();
}
+
+ void clusterWrite(const BatchedCommandRequest& request,
+ BatchedCommandResponse* response,
+ bool autoSplit) {
+
+ ClusterWriter writer(autoSplit, 0);
+ writer.write(request, response);
+ }
}
/**
@@ -195,16 +204,13 @@ namespace mongo {
Status clusterInsert( const string& ns,
const BSONObj& doc,
- const BSONObj& writeConcern,
BatchedCommandResponse* response ) {
auto_ptr<BatchedInsertRequest> insert( new BatchedInsertRequest() );
insert->addToDocuments( doc );
BatchedCommandRequest request( insert.release() );
request.setNS( ns );
- if ( !writeConcern.isEmpty() ) {
- request.setWriteConcern( writeConcern );
- }
+ request.setWriteConcern(WriteConcernOptions::Acknowledged);
BatchedCommandResponse dummyResponse;
@@ -221,7 +227,6 @@ namespace mongo {
const BSONObj& update,
bool upsert,
bool multi,
- const BSONObj& writeConcern,
BatchedCommandResponse* response ) {
auto_ptr<BatchedUpdateDocument> updateDoc( new BatchedUpdateDocument() );
updateDoc->setQuery( query );
@@ -231,10 +236,7 @@ namespace mongo {
auto_ptr<BatchedUpdateRequest> updateRequest( new BatchedUpdateRequest() );
updateRequest->addToUpdates( updateDoc.release() );
-
- if ( !writeConcern.isEmpty() ) {
- updateRequest->setWriteConcern( writeConcern );
- }
+ updateRequest->setWriteConcern(WriteConcernOptions::Acknowledged);
BatchedCommandRequest request( updateRequest.release() );
request.setNS( ns );
@@ -252,7 +254,6 @@ namespace mongo {
Status clusterDelete( const string& ns,
const BSONObj& query,
int limit,
- const BSONObj& writeConcern,
BatchedCommandResponse* response ) {
auto_ptr<BatchedDeleteDocument> deleteDoc( new BatchedDeleteDocument );
deleteDoc->setQuery( query );
@@ -260,10 +261,7 @@ namespace mongo {
auto_ptr<BatchedDeleteRequest> deleteRequest( new BatchedDeleteRequest() );
deleteRequest->addToDeletes( deleteDoc.release() );
-
- if ( !writeConcern.isEmpty() ) {
- deleteRequest->setWriteConcern( writeConcern );
- }
+ deleteRequest->setWriteConcern(WriteConcernOptions::Acknowledged);
BatchedCommandRequest request( deleteRequest.release() );
request.setNS( ns );
@@ -281,21 +279,12 @@ namespace mongo {
Status clusterCreateIndex( const string& ns,
BSONObj keys,
bool unique,
- const BSONObj& writeConcern,
BatchedCommandResponse* response ) {
return clusterInsert( NamespaceString( ns ).getSystemIndexesCollection(),
createIndexDoc( ns, keys, unique ),
- writeConcern,
response );
}
- void clusterWrite( const BatchedCommandRequest& request,
- BatchedCommandResponse* response,
- bool autoSplit ) {
- ClusterWriter writer( autoSplit, 0 );
- writer.write( request, response );
- }
-
bool validConfigWC( const BSONObj& writeConcern ) {
BSONElement elem(writeConcern["w"]);
@@ -368,9 +357,6 @@ namespace mongo {
// Config writes and shard writes are done differently
string dbName = nss.db().toString();
if ( dbName == "config" || dbName == "admin" ) {
-
- bool verboseWC = request.isVerboseWC();
-
// We only support batch sizes of one for config writes
if ( request.sizeWriteOps() != 1 ) {
toBatchError( Status( ErrorCodes::InvalidOptions,
@@ -393,7 +379,7 @@ namespace mongo {
// We need to support "best-effort" writes for pings to the config server.
// {w:0} (!verbose) writes are interpreted as best-effort in this case - they may still
// error, but do not do the initial fsync check.
- configWrite( request, response, verboseWC );
+ configWrite(request, response);
}
else {
shardWrite( request, response );
@@ -411,8 +397,8 @@ namespace mongo {
void ClusterWriter::shardWrite( const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
- ChunkManagerTargeter targeter;
- Status targetInitStatus = targeter.init( request.getTargetingNSS() );
+ ChunkManagerTargeter targeter(request.getTargetingNSS());
+ Status targetInitStatus = targeter.init();
if ( !targetInitStatus.isOK() ) {
@@ -434,9 +420,8 @@ namespace mongo {
_stats->setShardStats( exec.releaseStats() );
}
- void ClusterWriter::configWrite( const BatchedCommandRequest& request,
- BatchedCommandResponse* response,
- bool fsyncCheck ) {
+ void ClusterWriter::configWrite(const BatchedCommandRequest& request,
+ BatchedCommandResponse* response) {
DBClientMultiCommand dispatcher;
vector<ConnectionString> configHosts = getConfigHosts();
@@ -454,7 +439,7 @@ namespace mongo {
}
ConfigCoordinator exec( &dispatcher, configHosts );
- exec.executeBatch( request, response, fsyncCheck );
+ exec.executeBatch(request, response);
}
void ClusterWriterStats::setShardStats( BatchWriteExecStats* shardStats ) {
diff --git a/src/mongo/s/cluster_write.h b/src/mongo/s/cluster_write.h
index a4144fff252..8f64009773a 100644
--- a/src/mongo/s/cluster_write.h
+++ b/src/mongo/s/cluster_write.h
@@ -50,12 +50,8 @@ namespace mongo {
private:
- void configWrite( const BatchedCommandRequest& request,
- BatchedCommandResponse* response,
- bool fsyncCheck );
-
- void shardWrite( const BatchedCommandRequest& request,
- BatchedCommandResponse* response );
+ void configWrite(const BatchedCommandRequest& request, BatchedCommandResponse* response);
+ void shardWrite(const BatchedCommandRequest& request, BatchedCommandResponse* response);
bool _autoSplit;
int _timeoutMillis;
@@ -81,21 +77,17 @@ namespace mongo {
};
/**
- * Note: response can NEVER be NULL.
- */
- void clusterWrite( const BatchedCommandRequest& request,
- BatchedCommandResponse* response,
- bool autoSplit );
-
- /**
+ * Used only for writes to the config server, config and admin databases.
+ *
* Note: response can be NULL if you don't care about the write statistics.
*/
Status clusterInsert( const std::string& ns,
const BSONObj& doc,
- const BSONObj& writeConcern,
BatchedCommandResponse* response );
/**
+ * Used only for writes to the config server, config and admin databases.
+ *
* Note: response can be NULL if you don't care about the write statistics.
*/
Status clusterUpdate( const std::string& ns,
@@ -103,25 +95,26 @@ namespace mongo {
const BSONObj& update,
bool upsert,
bool multi,
- const BSONObj& writeConcern,
BatchedCommandResponse* response );
/**
+ * Used only for writes to the config server, config and admin databases.
+ *
* Note: response can be NULL if you don't care about the write statistics.
*/
Status clusterDelete( const std::string& ns,
const BSONObj& query,
int limit,
- const BSONObj& writeConcern,
BatchedCommandResponse* response );
/**
+ * Used only for writes to the config server, config and admin databases.
+ *
* Note: response can be NULL if you don't care about the write statistics.
*/
Status clusterCreateIndex( const std::string& ns,
BSONObj keys,
bool unique,
- const BSONObj& writeConcern,
BatchedCommandResponse* response );
} // namespace mongo
diff --git a/src/mongo/s/commands/cluster_explain_cmd.cpp b/src/mongo/s/commands/cluster_explain_cmd.cpp
index ea80aa75d3b..e2289e048e7 100644
--- a/src/mongo/s/commands/cluster_explain_cmd.cpp
+++ b/src/mongo/s/commands/cluster_explain_cmd.cpp
@@ -28,73 +28,110 @@
#include "mongo/platform/basic.h"
-#include "mongo/s/commands/cluster_explain_cmd.h"
-
+#include "mongo/db/commands.h"
#include "mongo/db/query/explain.h"
namespace mongo {
- using std::string;
-
- static ClusterExplainCmd cmdExplainCluster;
-
- Status ClusterExplainCmd::checkAuthForCommand(ClientBasic* client,
- const std::string& dbname,
- const BSONObj& cmdObj) {
- if (Object != cmdObj.firstElement().type()) {
- return Status(ErrorCodes::BadValue, "explain command requires a nested object");
- }
-
- BSONObj explainObj = cmdObj.firstElement().Obj();
-
- Command* commToExplain = Command::findCommand(explainObj.firstElementFieldName());
- if (NULL == commToExplain) {
- mongoutils::str::stream ss;
- ss << "unknown command: " << explainObj.firstElementFieldName();
- return Status(ErrorCodes::CommandNotFound, ss);
+ /**
+ * Implements the explain command on mongos.
+ *
+ * "Old-style" explains (i.e. queries which have the $explain flag set), do not run
+ * through this path. Such explains will be supported for backwards compatibility,
+ * and must succeed in multiversion clusters.
+ *
+ * "New-style" explains use the explain command. When the explain command is routed
+ * through mongos, it is forwarded to all relevant shards. If *any* shard does not
+ * support a new-style explain, then the entire explain will fail (i.e. new-style
+ * explains cannot be used in multiversion clusters).
+ */
+ class ClusterExplainCmd : public Command {
+ MONGO_DISALLOW_COPYING(ClusterExplainCmd);
+ public:
+ ClusterExplainCmd() : Command("explain") { }
+
+ virtual bool isWriteCommandForConfigServer() const { return false; }
+
+ /**
+ * Running an explain on a secondary requires explicitly setting slaveOk.
+ */
+ virtual bool slaveOk() const { return false; }
+ virtual bool slaveOverrideOk() const { return true; }
+
+ virtual bool maintenanceOk() const { return false; }
+
+ virtual bool adminOnly() const { return false; }
+
+ virtual void help(std::stringstream& help) const {
+ help << "explain database reads and writes";
}
- return commToExplain->checkAuthForCommand(client, dbname, explainObj);
- }
-
- bool ClusterExplainCmd::run(OperationContext* txn, const string& dbName,
- BSONObj& cmdObj,
- int options,
- string& errmsg,
- BSONObjBuilder& result,
- bool fromRepl) {
- // Should never get explain commands issued from replication.
- if (fromRepl) {
- Status commandStat(ErrorCodes::IllegalOperation,
- "explain command should not be from repl");
- return appendCommandStatus(result, commandStat);
- }
-
- ExplainCommon::Verbosity verbosity;
- Status parseStatus = ExplainCommon::parseCmdBSON(cmdObj, &verbosity);
- if (!parseStatus.isOK()) {
- return appendCommandStatus(result, parseStatus);
- }
-
- // This is the nested command which we are explaining.
- BSONObj explainObj = cmdObj.firstElement().Obj();
-
- const std::string cmdName = explainObj.firstElementFieldName();
- Command* commToExplain = Command::findCommand(cmdName);
- if (NULL == commToExplain) {
- mongoutils::str::stream ss;
- ss << "Explain failed due to unknown command: " << cmdName;
- Status explainStatus(ErrorCodes::CommandNotFound, ss);
- return appendCommandStatus(result, explainStatus);
+ /**
+ * You are authorized to run an explain if you are authorized to run
+ * the command that you are explaining. The auth check is performed recursively
+ * on the nested command.
+ */
+ virtual Status checkAuthForCommand(ClientBasic* client,
+ const std::string& dbname,
+ const BSONObj& cmdObj) {
+
+ if (Object != cmdObj.firstElement().type()) {
+ return Status(ErrorCodes::BadValue, "explain command requires a nested object");
+ }
+
+ BSONObj explainObj = cmdObj.firstElement().Obj();
+
+ Command* commToExplain = Command::findCommand(explainObj.firstElementFieldName());
+ if (NULL == commToExplain) {
+ mongoutils::str::stream ss;
+ ss << "unknown command: " << explainObj.firstElementFieldName();
+ return Status(ErrorCodes::CommandNotFound, ss);
+ }
+
+ return commToExplain->checkAuthForCommand(client, dbname, explainObj);
}
- // Actually call the nested command's explain(...) method.
- Status explainStatus = commToExplain->explain(txn, dbName, explainObj, verbosity, &result);
- if (!explainStatus.isOK()) {
- return appendCommandStatus(result, explainStatus);
+ virtual bool run(OperationContext* txn, const std::string& dbName,
+ BSONObj& cmdObj,
+ int options,
+ std::string& errmsg,
+ BSONObjBuilder& result,
+ bool fromRepl) {
+
+ // Should never get explain commands issued from replication.
+ if (fromRepl) {
+ Status commandStat(ErrorCodes::IllegalOperation,
+ "explain command should not be from repl");
+ return appendCommandStatus(result, commandStat);
+ }
+
+ ExplainCommon::Verbosity verbosity;
+ Status parseStatus = ExplainCommon::parseCmdBSON(cmdObj, &verbosity);
+ if (!parseStatus.isOK()) {
+ return appendCommandStatus(result, parseStatus);
+ }
+
+ // This is the nested command which we are explaining.
+ BSONObj explainObj = cmdObj.firstElement().Obj();
+
+ const std::string cmdName = explainObj.firstElementFieldName();
+ Command* commToExplain = Command::findCommand(cmdName);
+ if (NULL == commToExplain) {
+ mongoutils::str::stream ss;
+ ss << "Explain failed due to unknown command: " << cmdName;
+ Status explainStatus(ErrorCodes::CommandNotFound, ss);
+ return appendCommandStatus(result, explainStatus);
+ }
+
+ // Actually call the nested command's explain(...) method.
+ Status explainStatus = commToExplain->explain(txn, dbName, explainObj, verbosity, &result);
+ if (!explainStatus.isOK()) {
+ return appendCommandStatus(result, explainStatus);
+ }
+
+ return true;
}
- return true;
- }
+ } cmdExplainCluster;
} // namespace mongo
diff --git a/src/mongo/s/commands/cluster_explain_cmd.h b/src/mongo/s/commands/cluster_explain_cmd.h
deleted file mode 100644
index f7388cd1188..00000000000
--- a/src/mongo/s/commands/cluster_explain_cmd.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Copyright (C) 2014 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#pragma once
-
-#include "mongo/db/commands.h"
-
-namespace mongo {
-
- /**
- * Implements the explain command on mongos.
- *
- * "Old-style" explains (i.e. queries which have the $explain flag set), do not run
- * through this path. Such explains will be supported for backwards compatibility,
- * and must succeed in multiversion clusters.
- *
- * "New-style" explains use the explain command. When the explain command is routed
- * through mongos, it is forwarded to all relevant shards. If *any* shard does not
- * support a new-style explain, then the entire explain will fail (i.e. new-style
- * explains cannot be used in multiversion clusters).
- */
- class ClusterExplainCmd : public Command {
- MONGO_DISALLOW_COPYING(ClusterExplainCmd);
- public:
- ClusterExplainCmd() : Command("explain") { }
-
- virtual bool isWriteCommandForConfigServer() const { return false; }
-
- /**
- * Running an explain on a secondary requires explicitly setting slaveOk.
- */
- virtual bool slaveOk() const { return false; }
- virtual bool slaveOverrideOk() const { return true; }
-
- virtual bool maintenanceOk() const { return false; }
-
- virtual bool adminOnly() const { return false; }
-
- virtual void help( std::stringstream& help ) const {
- help << "explain database reads and writes";
- }
-
- /**
- * You are authorized to run an explain if you are authorized to run
- * the command that you are explaining. The auth check is performed recursively
- * on the nested command.
- */
- virtual Status checkAuthForCommand(ClientBasic* client,
- const std::string& dbname,
- const BSONObj& cmdObj);
-
- virtual bool run(OperationContext* txn, const std::string& dbName,
- BSONObj& cmdObj,
- int options,
- std::string& errmsg,
- BSONObjBuilder& result,
- bool fromRepl);
-
- };
-
-} // namespace mongo
diff --git a/src/mongo/s/commands/cluster_find_cmd.cpp b/src/mongo/s/commands/cluster_find_cmd.cpp
index 4d819207f43..e9b2901deab 100644
--- a/src/mongo/s/commands/cluster_find_cmd.cpp
+++ b/src/mongo/s/commands/cluster_find_cmd.cpp
@@ -28,9 +28,8 @@
#include "mongo/platform/basic.h"
-#include "mongo/s/commands/cluster_find_cmd.h"
-
#include "mongo/db/auth/authorization_session.h"
+#include "mongo/db/commands.h"
#include "mongo/s/cluster_explain.h"
#include "mongo/s/strategy.h"
#include "mongo/util/timer.h"
@@ -41,71 +40,102 @@ namespace mongo {
using std::string;
using std::vector;
- static ClusterFindCmd cmdFindCluster;
+ /**
+ * Implements the find command on mongos.
+ *
+ * TODO: this is just a placeholder. It needs to be implemented for real under SERVER-15176.
+ */
+ class ClusterFindCmd : public Command {
+ MONGO_DISALLOW_COPYING(ClusterFindCmd);
+ public:
+ ClusterFindCmd() : Command("find") { }
+
+ virtual bool isWriteCommandForConfigServer() const { return false; }
+
+ virtual bool slaveOk() const { return false; }
+
+ virtual bool slaveOverrideOk() const { return true; }
- Status ClusterFindCmd::checkAuthForCommand(ClientBasic* client,
- const std::string& dbname,
- const BSONObj& cmdObj) {
- AuthorizationSession* authzSession = client->getAuthorizationSession();
- ResourcePattern pattern = parseResourcePattern(dbname, cmdObj);
+ virtual bool maintenanceOk() const { return false; }
- if (authzSession->isAuthorizedForActionsOnResource(pattern, ActionType::find)) {
- return Status::OK();
+ virtual bool adminOnly() const { return false; }
+
+ virtual void help(std::stringstream& help) const {
+ help << "query for documents";
}
- return Status(ErrorCodes::Unauthorized, "unauthorized");
- }
-
- Status ClusterFindCmd::explain(OperationContext* txn,
- const std::string& dbname,
- const BSONObj& cmdObj,
- ExplainCommon::Verbosity verbosity,
- BSONObjBuilder* out) const {
- const string fullns = parseNs(dbname, cmdObj);
-
- // Parse the command BSON to a LiteParsedQuery.
- LiteParsedQuery* rawLpq;
- bool isExplain = true;
- Status lpqStatus = LiteParsedQuery::make(fullns, cmdObj, isExplain, &rawLpq);
- if (!lpqStatus.isOK()) {
- return lpqStatus;
+ /**
+ * In order to run the find command, you must be authorized for the "find" action
+ * type on the collection.
+ */
+ virtual Status checkAuthForCommand(ClientBasic* client,
+ const std::string& dbname,
+ const BSONObj& cmdObj) {
+
+ AuthorizationSession* authzSession = client->getAuthorizationSession();
+ ResourcePattern pattern = parseResourcePattern(dbname, cmdObj);
+
+ if (authzSession->isAuthorizedForActionsOnResource(pattern, ActionType::find)) {
+ return Status::OK();
+ }
+
+ return Status(ErrorCodes::Unauthorized, "unauthorized");
+ }
+
+ virtual Status explain(OperationContext* txn,
+ const std::string& dbname,
+ const BSONObj& cmdObj,
+ ExplainCommon::Verbosity verbosity,
+ BSONObjBuilder* out) const {
+
+ const string fullns = parseNs(dbname, cmdObj);
+
+ // Parse the command BSON to a LiteParsedQuery.
+ LiteParsedQuery* rawLpq;
+ bool isExplain = true;
+ Status lpqStatus = LiteParsedQuery::make(fullns, cmdObj, isExplain, &rawLpq);
+ if (!lpqStatus.isOK()) {
+ return lpqStatus;
+ }
+ auto_ptr<LiteParsedQuery> lpq(rawLpq);
+
+ BSONObjBuilder explainCmdBob;
+ ClusterExplain::wrapAsExplain(cmdObj, verbosity, &explainCmdBob);
+
+ // We will time how long it takes to run the commands on the shards.
+ Timer timer;
+
+ vector<Strategy::CommandResult> shardResults;
+ STRATEGY->commandOp(dbname,
+ explainCmdBob.obj(),
+ lpq->getOptions().toInt(),
+ fullns,
+ lpq->getFilter(),
+ &shardResults);
+
+ long long millisElapsed = timer.millis();
+
+ const char* mongosStageName = ClusterExplain::getStageNameForReadOp(shardResults, cmdObj);
+
+ return ClusterExplain::buildExplainResult(shardResults,
+ mongosStageName,
+ millisElapsed,
+ out);
}
- auto_ptr<LiteParsedQuery> lpq(rawLpq);
-
- BSONObjBuilder explainCmdBob;
- ClusterExplain::wrapAsExplain(cmdObj, verbosity, &explainCmdBob);
-
- // We will time how long it takes to run the commands on the shards.
- Timer timer;
-
- vector<Strategy::CommandResult> shardResults;
- STRATEGY->commandOp(dbname,
- explainCmdBob.obj(),
- lpq->getOptions().toInt(),
- fullns,
- lpq->getFilter(),
- &shardResults);
-
- long long millisElapsed = timer.millis();
-
- const char* mongosStageName = ClusterExplain::getStageNameForReadOp(shardResults, cmdObj);
-
- return ClusterExplain::buildExplainResult(shardResults,
- mongosStageName,
- millisElapsed,
- out);
- }
-
- bool ClusterFindCmd::run(OperationContext* txn, const string& dbName,
- BSONObj& cmdObj,
- int options,
- string& errmsg,
- BSONObjBuilder& result,
- bool fromRepl) {
- // Currently only explains of finds run through the find command. Queries that are not
- // explained use the legacy OP_QUERY path.
- errmsg = "find command not yet implemented";
- return false;
- }
+
+ virtual bool run(OperationContext* txn,
+ const std::string& dbname,
+ BSONObj& cmdObj, int options,
+ std::string& errmsg,
+ BSONObjBuilder& result,
+ bool fromRepl) {
+
+ // Currently only explains of finds run through the find command. Queries that are not
+ // explained use the legacy OP_QUERY path.
+ errmsg = "find command not yet implemented";
+ return false;
+ }
+
+ } cmdFindCluster;
} // namespace mongo
diff --git a/src/mongo/s/commands/cluster_find_cmd.h b/src/mongo/s/commands/cluster_find_cmd.h
deleted file mode 100644
index c62dd402907..00000000000
--- a/src/mongo/s/commands/cluster_find_cmd.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright (C) 2014 MongoDB Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License, version 3,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the GNU Affero General Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#pragma once
-
-#include "mongo/db/commands.h"
-
-namespace mongo {
-
- /**
- * Implements the find command on mongos.
- *
- * TODO: this is just a placeholder. It needs to be implemented for real under SERVER-15176.
- */
- class ClusterFindCmd : public Command {
- MONGO_DISALLOW_COPYING(ClusterFindCmd);
- public:
- ClusterFindCmd() : Command("find") { }
-
- virtual bool isWriteCommandForConfigServer() const { return false; }
-
- virtual bool slaveOk() const { return false; }
-
- virtual bool slaveOverrideOk() const { return true; }
-
- virtual bool maintenanceOk() const { return false; }
-
- virtual bool adminOnly() const { return false; }
-
- virtual void help(std::stringstream& help) const {
- help << "query for documents";
- }
-
- /**
- * In order to run the find command, you must be authorized for the "find" action
- * type on the collection.
- */
- virtual Status checkAuthForCommand(ClientBasic* client,
- const std::string& dbname,
- const BSONObj& cmdObj);
-
- virtual Status explain(OperationContext* txn,
- const std::string& dbname,
- const BSONObj& cmdObj,
- ExplainCommon::Verbosity verbosity,
- BSONObjBuilder* out) const;
-
- virtual bool run(OperationContext* txn,
- const std::string& dbname,
- BSONObj& cmdObj, int options,
- std::string& errmsg,
- BSONObjBuilder& result,
- bool fromRepl);
-
- };
-
-} // namespace mongo
diff --git a/src/mongo/s/commands_admin.cpp b/src/mongo/s/commands_admin.cpp
index 01d760ce407..5f0831d598f 100644
--- a/src/mongo/s/commands_admin.cpp
+++ b/src/mongo/s/commands_admin.cpp
@@ -688,13 +688,7 @@ namespace mongo {
// Only need to call ensureIndex on primary shard, since indexes get copied to
// receiving shard whenever a migrate occurs.
else {
- // call ensureIndex with cache=false, see SERVER-1691
- Status result = clusterCreateIndex( ns,
- proposedKey,
- careAboutUnique,
- WriteConcernOptions::Default,
- NULL );
-
+ Status result = clusterCreateIndex(ns, proposedKey, careAboutUnique, NULL);
if ( !result.isOK() ) {
errmsg = str::stream() << "ensureIndex failed to create index on "
<< "primary shard: " << result.reason();
@@ -1443,7 +1437,6 @@ namespace mongo {
newStatus,
false /* do no upsert */,
false /* multi */,
- WriteConcernOptions::AllConfigs,
NULL );
if ( !status.isOK() ) {
@@ -1461,7 +1454,6 @@ namespace mongo {
Status status = clusterDelete( DatabaseType::ConfigNS,
BSON(DatabaseType::name("local")),
0 /* limit */,
- WriteConcernOptions::AllConfigs,
NULL );
if ( !status.isOK() ) {
@@ -1498,7 +1490,6 @@ namespace mongo {
Status status = clusterDelete( ShardType::ConfigNS,
searchDoc,
0, // limit
- WriteConcernOptions::AllConfigs,
NULL );
if ( !status.isOK() ) {
diff --git a/src/mongo/s/config.cpp b/src/mongo/s/config.cpp
index c5ac31d36cb..4d95f66ff74 100644
--- a/src/mongo/s/config.cpp
+++ b/src/mongo/s/config.cpp
@@ -138,7 +138,6 @@ namespace mongo {
val.obj(),
true /* upsert */,
false /* multi */,
- WriteConcernOptions::AllConfigs,
NULL);
if ( !result.isOK() ) {
@@ -602,7 +601,6 @@ namespace mongo {
n,
true, // upsert
false, // multi
- WriteConcernOptions::AllConfigs,
&response );
if ( !result.isOK() ) {
@@ -668,7 +666,6 @@ namespace mongo {
Status result = clusterDelete( DatabaseType::ConfigNS,
BSON( DatabaseType::name( _name )),
0 /* limit */,
- WriteConcernOptions::AllConfigs,
NULL );
if ( !result.isOK() ) {
@@ -1113,7 +1110,6 @@ namespace mongo {
Status result = clusterInsert( SettingsType::ConfigNS,
BSON( SettingsType::key("chunksize") <<
SettingsType::chunksize(chunkSize)),
- WriteConcernOptions::AllConfigs,
NULL );
if (!result.isOK()) {
warning() << "couldn't set chunkSize on config db" << causedBy(result);
@@ -1124,7 +1120,6 @@ namespace mongo {
Status result = clusterCreateIndex( ChunkType::ConfigNS,
BSON( ChunkType::ns() << 1 << ChunkType::min() << 1 ),
true, // unique
- WriteConcernOptions::AllConfigs,
NULL );
if (!result.isOK()) {
@@ -1136,7 +1131,6 @@ namespace mongo {
ChunkType::shard() << 1 <<
ChunkType::min() << 1 ),
true, // unique
- WriteConcernOptions::AllConfigs,
NULL );
if (!result.isOK()) {
@@ -1148,7 +1142,6 @@ namespace mongo {
BSON( ChunkType::ns() << 1 <<
ChunkType::DEPRECATED_lastmod() << 1 ),
true, // unique
- WriteConcernOptions::AllConfigs,
NULL );
if (!result.isOK()) {
@@ -1158,7 +1151,6 @@ namespace mongo {
result = clusterCreateIndex( ShardType::ConfigNS,
BSON( ShardType::host() << 1 ),
true, // unique
- WriteConcernOptions::AllConfigs,
NULL );
if (!result.isOK()) {
@@ -1168,7 +1160,6 @@ namespace mongo {
result = clusterCreateIndex(LocksType::ConfigNS,
BSON(LocksType::lockID() << 1),
false, // unique
- WriteConcernOptions::AllConfigs,
NULL);
if (!result.isOK()) {
@@ -1179,7 +1170,6 @@ namespace mongo {
BSON( LocksType::state() << 1 <<
LocksType::process() << 1 ),
false, // unique
- WriteConcernOptions::AllConfigs,
NULL );
if (!result.isOK()) {
@@ -1190,7 +1180,6 @@ namespace mongo {
result = clusterCreateIndex( LockpingsType::ConfigNS,
BSON( LockpingsType::ping() << 1 ),
false, // unique
- WriteConcernOptions::AllConfigs,
NULL );
if (!result.isOK()) {
@@ -1201,7 +1190,6 @@ namespace mongo {
result = clusterCreateIndex(TagsType::ConfigNS,
BSON(TagsType::ns() << 1 << TagsType::min() << 1),
true, // unique
- WriteConcernOptions::AllConfigs,
NULL);
if (!result.isOK()) {
@@ -1266,7 +1254,6 @@ namespace mongo {
Status result = clusterInsert( ChangelogType::ConfigNS,
msg,
- WriteConcernOptions::AllConfigs,
NULL );
if ( !result.isOK() ) {
@@ -1296,7 +1283,6 @@ namespace mongo {
BSON("$set" << BSON(ShardType::host(newConnectionString))),
false, // upsert
false, // multi
- WriteConcernOptions::AllConfigs,
NULL);
if ( !result.isOK() ) {
diff --git a/src/mongo/s/config.h b/src/mongo/s/config.h
index 4284ecf463e..d3626baada5 100644
--- a/src/mongo/s/config.h
+++ b/src/mongo/s/config.h
@@ -138,8 +138,8 @@ namespace mongo {
ChunkManagerPtr shardCollection(const std::string& ns,
const ShardKeyPattern& fieldsAndOrder,
bool unique,
- std::vector<BSONObj>* initPoints = 0,
- std::vector<Shard>* initShards = 0);
+ std::vector<BSONObj>* initPoints,
+ std::vector<Shard>* initShards = NULL);
/**
@return true if there was sharding info to remove
@@ -214,15 +214,15 @@ namespace mongo {
mutable mongo::mutex _hitConfigServerLock;
};
+
class ConfigServer : public DBConfig {
public:
-
ConfigServer();
~ConfigServer();
bool ok( bool checkConsistency = false );
- virtual std::string modelServer() {
+ std::string modelServer() {
uassert( 10190 , "ConfigServer not setup" , _primary.ok() );
return _primary.getConnString();
}
diff --git a/src/mongo/s/config_upgrade_helpers.cpp b/src/mongo/s/config_upgrade_helpers.cpp
index bb60f91a7be..cff2c04e054 100644
--- a/src/mongo/s/config_upgrade_helpers.cpp
+++ b/src/mongo/s/config_upgrade_helpers.cpp
@@ -298,7 +298,6 @@ namespace mongo {
BSON("$set" << setUpgradeIdObj.done()),
false, // upsert
false, // multi
- WriteConcernOptions::AllConfigs,
NULL);
if ( !result.isOK() ) {
@@ -318,7 +317,6 @@ namespace mongo {
BSON("$set" << setUpgradeStateObj.done()),
false, // upsert
false, // multi
- WriteConcernOptions::AllConfigs,
NULL);
log() << "entered critical section for config upgrade" << endl;
@@ -359,7 +357,6 @@ namespace mongo {
BSON("$set" << setObj.done() << "$unset" << unsetObj.done()),
false, // upsert
false, // multi,
- WriteConcernOptions::AllConfigs,
NULL);
if ( !result.isOK() ) {
diff --git a/src/mongo/s/config_upgrade_v0_to_v6.cpp b/src/mongo/s/config_upgrade_v0_to_v6.cpp
index e27b85eebc8..f9011b41cea 100644
--- a/src/mongo/s/config_upgrade_v0_to_v6.cpp
+++ b/src/mongo/s/config_upgrade_v0_to_v6.cpp
@@ -85,7 +85,6 @@ namespace mongo {
versionInfo.toBSON(),
true /* upsert */,
false /* multi */,
- WriteConcernOptions::AllConfigs,
NULL);
if ( !result.isOK() ) {
diff --git a/src/mongo/s/config_upgrade_v5_to_v6.cpp b/src/mongo/s/config_upgrade_v5_to_v6.cpp
index 11afb8e65fb..52ec6e43f5b 100644
--- a/src/mongo/s/config_upgrade_v5_to_v6.cpp
+++ b/src/mongo/s/config_upgrade_v5_to_v6.cpp
@@ -175,7 +175,6 @@ namespace mongo {
result = clusterCreateIndex(LocksType::ConfigNS,
BSON(LocksType::lockID() << 1),
false, // unique
- WriteConcernOptions::AllConfigs,
NULL);
if (!result.isOK()) {
diff --git a/src/mongo/s/grid.cpp b/src/mongo/s/grid.cpp
index f70431ffc6c..2e44fec54f4 100644
--- a/src/mongo/s/grid.cpp
+++ b/src/mongo/s/grid.cpp
@@ -43,7 +43,6 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/write_concern.h"
#include "mongo/s/cluster_write.h"
-#include "mongo/s/grid.h"
#include "mongo/s/mongos_options.h"
#include "mongo/s/shard.h"
#include "mongo/s/type_collection.h"
@@ -52,7 +51,6 @@
#include "mongo/s/type_shard.h"
#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
-#include "mongo/util/startup_test.h"
#include "mongo/util/stringutils.h"
namespace mongo {
@@ -442,7 +440,6 @@ namespace mongo {
Status result = clusterInsert( ShardType::ConfigNS,
shardDoc,
- WriteConcernOptions::AllConfigs,
NULL );
if ( !result.isOK() ) {
@@ -648,69 +645,4 @@ namespace mongo {
}
Grid grid;
-
-
- // unit tests
-
- class BalancingWindowUnitTest : public StartupTest {
- public:
- void run() {
-
- if (!isMongos())
- return;
-
- // T0 < T1 < now < T2 < T3 and Error
- const string T0 = "9:00";
- const string T1 = "11:00";
- boost::posix_time::ptime now( currentDate(), boost::posix_time::hours( 13 ) + boost::posix_time::minutes( 48 ) );
- const string T2 = "17:00";
- const string T3 = "21:30";
- const string E = "28:35";
-
- // closed in the past
- BSONObj w1 = BSON( SettingsType::balancerActiveWindow( BSON( "start" << T0 <<
- "stop" << T1 ) ) );
- // not opened until the future
- BSONObj w2 = BSON( SettingsType::balancerActiveWindow( BSON( "start" << T2 <<
- "stop" << T3 ) ) );
- // open now
- BSONObj w3 = BSON( SettingsType::balancerActiveWindow( BSON( "start" << T1 <<
- "stop" << T2 ) ) );
- // open since last day
- BSONObj w4 = BSON( SettingsType::balancerActiveWindow( BSON( "start" << T3 <<
- "stop" << T2 ) ) );
-
- verify( ! Grid::_inBalancingWindow( w1 , now ) );
- verify( ! Grid::_inBalancingWindow( w2 , now ) );
- verify( Grid::_inBalancingWindow( w3 , now ) );
- verify( Grid::_inBalancingWindow( w4 , now ) );
-
- // bad input should not stop the balancer
-
- // empty window
- BSONObj w5;
-
- // missing stop
- BSONObj w6 = BSON( SettingsType::balancerActiveWindow( BSON( "start" << 1 ) ) );
-
- // missing start
- BSONObj w7 = BSON( SettingsType::balancerActiveWindow( BSON( "stop" << 1 ) ) );
-
- // active window marker missing
- BSONObj w8 = BSON( "wrongMarker" << 1 << "start" << 1 << "stop" << 1 );
-
- // garbage in window
- BSONObj w9 = BSON( SettingsType::balancerActiveWindow( BSON( "start" << T3 <<
- "stop" << E ) ) );
-
- verify( Grid::_inBalancingWindow( w5 , now ) );
- verify( Grid::_inBalancingWindow( w6 , now ) );
- verify( Grid::_inBalancingWindow( w7 , now ) );
- verify( Grid::_inBalancingWindow( w8 , now ) );
- verify( Grid::_inBalancingWindow( w9 , now ) );
-
- LOG(1) << "BalancingWidowObjTest passed" << endl;
- }
- } BalancingWindowObjTest;
-
}
diff --git a/src/mongo/s/grid.h b/src/mongo/s/grid.h
index e7a3f1221d5..a63d0e970d9 100644
--- a/src/mongo/s/grid.h
+++ b/src/mongo/s/grid.h
@@ -36,10 +36,11 @@
#include "mongo/util/concurrency/mutex.h"
#include "mongo/s/config.h" // DBConfigPtr
-#include "mongo/s/type_settings.h"
namespace mongo {
+ class SettingsType;
+
/**
* stores meta-information about the grid
* TODO: used shard_ptr for DBConfig pointers
diff --git a/src/mongo/s/strategy.cpp b/src/mongo/s/strategy.cpp
index 90c29a897d0..19cbc5d11d0 100644
--- a/src/mongo/s/strategy.cpp
+++ b/src/mongo/s/strategy.cpp
@@ -26,8 +26,6 @@
* then also delete it in the license file.
*/
-// strategy_sharded.cpp
-
#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding
#include "mongo/platform/basic.h"
@@ -472,9 +470,9 @@ namespace mongo {
// Note that this implementation will not handle targeting retries and does not completely
// emulate write behavior
- ChunkManagerTargeter targeter;
- Status status =
- targeter.init(NamespaceString(targetingBatchItem.getRequest()->getTargetingNS()));
+ ChunkManagerTargeter targeter(NamespaceString(
+ targetingBatchItem.getRequest()->getTargetingNS()));
+ Status status = targeter.init();
if (!status.isOK())
return status;
diff --git a/src/mongo/s/write_ops/config_coordinator.cpp b/src/mongo/s/write_ops/config_coordinator.cpp
index 66b1d6723c2..6d8e0c25241 100644
--- a/src/mongo/s/write_ops/config_coordinator.cpp
+++ b/src/mongo/s/write_ops/config_coordinator.cpp
@@ -26,17 +26,19 @@
* it in the license file.
*/
+#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding
+
#include "mongo/s/write_ops/config_coordinator.h"
#include "mongo/base/owned_pointer_vector.h"
+#include "mongo/db/field_parser.h"
#include "mongo/db/lasterror.h"
#include "mongo/db/namespace_string.h"
#include "mongo/s/write_ops/batched_command_request.h"
#include "mongo/s/write_ops/batched_command_response.h"
+#include "mongo/util/log.h"
#include "mongo/util/net/message.h"
-#include "mongo/db/field_parser.h"
-
namespace mongo {
using std::string;
@@ -49,162 +51,6 @@ namespace mongo {
namespace {
- //
- // Types to handle the reachability fsync checks
- //
-
- /**
- * A BSON serializable object representing an fsync command request
- */
- class FsyncRequest : public BSONSerializable {
- MONGO_DISALLOW_COPYING(FsyncRequest);
- public:
-
- FsyncRequest() {
- }
-
- bool isValid( std::string* errMsg ) const {
- return true;
- }
-
- /** Returns the BSON representation of the entry. */
- BSONObj toBSON() const {
- return BSON( "fsync" << true );
- }
-
- bool parseBSON( const BSONObj& source, std::string* errMsg ) {
- // Not implemented
- dassert( false );
- return false;
- }
-
- void clear() {
- // Not implemented
- dassert( false );
- }
-
- string toString() const {
- return toBSON().toString();
- }
- };
-
- /**
- * A BSON serializable object representing an fsync command response
- */
- class FsyncResponse : public BSONSerializable {
- MONGO_DISALLOW_COPYING(FsyncResponse);
- public:
-
- static const BSONField<int> ok;
- static const BSONField<int> errCode;
- static const BSONField<string> errMessage;
-
- FsyncResponse() {
- clear();
- }
-
- bool isValid( std::string* errMsg ) const {
- return _isOkSet;
- }
-
- BSONObj toBSON() const {
- BSONObjBuilder builder;
-
- if ( _isOkSet ) builder << ok( _ok );
- if ( _isErrCodeSet ) builder << errCode( _errCode );
- if ( _isErrMessageSet ) builder << errMessage( _errMessage );
-
- return builder.obj();
- }
-
- bool parseBSON( const BSONObj& source, std::string* errMsg ) {
-
- FieldParser::FieldState result;
-
- result = FieldParser::extractNumber( source, ok, &_ok, errMsg );
- if ( result == FieldParser::FIELD_INVALID )
- return false;
- _isOkSet = result != FieldParser::FIELD_NONE;
-
- result = FieldParser::extract( source, errCode, &_errCode, errMsg );
- if ( result == FieldParser::FIELD_INVALID )
- return false;
- _isErrCodeSet = result != FieldParser::FIELD_NONE;
-
- result = FieldParser::extract( source, errMessage, &_errMessage, errMsg );
- if ( result == FieldParser::FIELD_INVALID )
- return false;
- _isErrMessageSet = result != FieldParser::FIELD_NONE;
-
- return true;
- }
-
- void clear() {
- _ok = false;
- _isOkSet = false;
-
- _errCode = 0;
- _isErrCodeSet = false;
-
- _errMessage = "";
- _isErrMessageSet = false;
- }
-
- string toString() const {
- return toBSON().toString();
- }
-
- int getOk() {
- dassert( _isOkSet );
- return _ok;
- }
-
- void setOk( int ok ) {
- _ok = ok;
- _isOkSet = true;
- }
-
- int getErrCode() {
- if ( _isErrCodeSet ) {
- return _errCode;
- }
- else {
- return errCode.getDefault();
- }
- }
-
- void setErrCode( int errCode ) {
- _errCode = errCode;
- _isErrCodeSet = true;
- }
-
- const string& getErrMessage() {
- dassert( _isErrMessageSet );
- return _errMessage;
- }
-
- void setErrMessage( StringData errMsg ) {
- _errMessage = errMsg.toString();
- _isErrMessageSet = true;
- }
-
- private:
-
- int _ok;
- bool _isOkSet;
-
- int _errCode;
- bool _isErrCodeSet;
-
- string _errMessage;
- bool _isErrMessageSet;
-
- };
-
- const BSONField<int> FsyncResponse::ok( "ok" );
- const BSONField<int> FsyncResponse::errCode( "code" );
- const BSONField<string> FsyncResponse::errMessage( "errmsg" );
-
/**
* A BSON serializable object representing a setShardVersion command request.
*/
@@ -380,10 +226,6 @@ namespace mongo {
BatchedCommandResponse response;
};
- struct ConfigFsyncResponse {
- ConnectionString configHost;
- FsyncResponse response;
- };
}
//
@@ -398,12 +240,6 @@ namespace mongo {
dassert( response->isValid( NULL ) );
}
- static void buildFsyncErrorFrom( const Status& status, FsyncResponse* response ) {
- response->setOk( false );
- response->setErrCode( static_cast<int>( status.code() ) );
- response->setErrMessage( status.reason() );
- }
-
static bool areResponsesEqual( const BatchedCommandResponse& responseA,
const BatchedCommandResponse& responseB ) {
@@ -469,14 +305,6 @@ namespace mongo {
"config responses: " + builder.obj().toString() );
}
- static void combineFsyncErrors( const vector<ConfigFsyncResponse*>& responses,
- BatchedCommandResponse* clientResponse ) {
-
- clientResponse->setOk( false );
- clientResponse->setErrCode( ErrorCodes::RemoteValidationError );
- clientResponse->setErrMessage( "could not verify config servers were "
- "active and reachable before write" );
- }
bool ConfigCoordinator::_checkConfigString(BatchedCommandResponse* clientResponse) {
//
@@ -549,65 +377,57 @@ namespace mongo {
* is probably the next step.
*/
void ConfigCoordinator::executeBatch( const BatchedCommandRequest& clientRequest,
- BatchedCommandResponse* clientResponse,
- bool fsyncCheck ) {
+ BatchedCommandResponse* clientResponse) {
NamespaceString nss( clientRequest.getNS() );
dassert( nss.db() == "config" || nss.db() == "admin" );
- dassert( clientRequest.sizeWriteOps() == 1u );
-
- if ( fsyncCheck ) {
-
- //
- // Sanity check that all configs are still reachable using fsync, preserving legacy
- // behavior
- //
-
- OwnedPointerVector<ConfigFsyncResponse> fsyncResponsesOwned;
- vector<ConfigFsyncResponse*>& fsyncResponses = fsyncResponsesOwned.mutableVector();
+ dassert(clientRequest.sizeWriteOps() == 1u);
- //
- // Send side
- //
+ // This is an opportunistic check that all config servers look healthy by calling
+ // getLastError on each one of them. If there was some form of write/journaling error, get
+ // last error would fail.
+ {
+ for (vector<ConnectionString>::iterator it = _configHosts.begin();
+ it != _configHosts.end();
+ ++it) {
- for ( vector<ConnectionString>::iterator it = _configHosts.begin();
- it != _configHosts.end(); ++it ) {
- ConnectionString& configHost = *it;
- FsyncRequest fsyncRequest;
- _dispatcher->addCommand( configHost, "admin", fsyncRequest );
+ _dispatcher->addCommand(*it,
+ "admin",
+ RawBSONSerializable(BSON("getLastError" << true <<
+ "fsync" << true)));
}
_dispatcher->sendAll();
- //
- // Recv side
- //
+ bool error = false;
+ while (_dispatcher->numPending()) {
+ ConnectionString host;
+ RawBSONSerializable response;
- bool fsyncError = false;
- while ( _dispatcher->numPending() > 0 ) {
+ Status status = _dispatcher->recvAny(&host, &response);
+ if (status.isOK()) {
+ BSONObj obj = response.toBSON();
- fsyncResponses.push_back( new ConfigFsyncResponse() );
- ConfigFsyncResponse& fsyncResponse = *fsyncResponses.back();
- Status dispatchStatus = _dispatcher->recvAny( &fsyncResponse.configHost,
- &fsyncResponse.response );
+ LOG(3) << "Response " << obj.toString();
- // We've got to recv everything, no matter what
- if ( !dispatchStatus.isOK() ) {
- fsyncError = true;
- buildFsyncErrorFrom( dispatchStatus, &fsyncResponse.response );
+ // If the ok field is anything other than 1, count it as error
+ if (!obj["ok"].trueValue()) {
+ error = true;
+ }
}
- else if ( !fsyncResponse.response.getOk() ) {
- fsyncError = true;
+ else {
+ error = true;
}
}
- if ( fsyncError ) {
- combineFsyncErrors( fsyncResponses, clientResponse );
+ // All responses should have been gathered by this point
+ if (error) {
+ clientResponse->setOk(false);
+ clientResponse->setErrCode(ErrorCodes::RemoteValidationError);
+ clientResponse->setErrMessage("Could not verify that config servers were active"
+ " and reachable before write");
return;
}
- else {
- fsyncResponsesOwned.clear();
- }
}
if (!_checkConfigString(clientResponse)) {
diff --git a/src/mongo/s/write_ops/config_coordinator.h b/src/mongo/s/write_ops/config_coordinator.h
index f90c5b83dc4..90fd24f694e 100644
--- a/src/mongo/s/write_ops/config_coordinator.h
+++ b/src/mongo/s/write_ops/config_coordinator.h
@@ -43,9 +43,7 @@ namespace mongo {
ConfigCoordinator( MultiCommandDispatch* dispatcher,
const std::vector<ConnectionString>& configHosts );
- void executeBatch( const BatchedCommandRequest& request,
- BatchedCommandResponse* response,
- bool fsyncCheck );
+ void executeBatch(const BatchedCommandRequest& request, BatchedCommandResponse* response);
private: