diff options
36 files changed, 297 insertions, 201 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript index 76c0037ea1e..2f628b8c017 100644 --- a/src/mongo/SConscript +++ b/src/mongo/SConscript @@ -949,7 +949,6 @@ serveronlyLibdeps = ["coreshard", "db/repl/replication_executor", "db/repl/repl_coordinator_impl", "db/repl/repl_coordinator_global", - "db/repl/repl_settings", "db/repl/replication_executor", 'db/storage/mmap_v1/extent', 'db/storage/heap1/storage_heap1', diff --git a/src/mongo/db/commands/count.h b/src/mongo/db/commands/count.h index f95c7c27846..ce54b0b5b26 100644 --- a/src/mongo/db/commands/count.h +++ b/src/mongo/db/commands/count.h @@ -31,7 +31,7 @@ #include "mongo/db/catalog/collection.h" #include "mongo/db/commands.h" #include "mongo/db/jsobj.h" -#include "mongo/db/repl/repl_settings.h" +#include "mongo/db/repl/repl_coordinator_global.h" namespace mongo { @@ -58,7 +58,7 @@ namespace mongo { CmdCount() : Command("count") { } virtual bool slaveOk() const { // ok on --slave setups - return repl::replSettings.slave == repl::SimpleSlave; + return repl::getGlobalReplicationCoordinator()->getSettings().slave == repl::SimpleSlave; } virtual bool slaveOverrideOk() const { return true; } virtual bool maintenanceOk() const { return false; } diff --git a/src/mongo/db/commands/oplog_note.cpp b/src/mongo/db/commands/oplog_note.cpp index 5cf4006908e..da81ebd1a25 100644 --- a/src/mongo/db/commands/oplog_note.cpp +++ b/src/mongo/db/commands/oplog_note.cpp @@ -35,7 +35,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/commands.h" #include "mongo/db/repl/oplog.h" -#include "mongo/db/repl/repl_settings.h" +#include "mongo/db/repl/repl_coordinator_global.h" namespace mongo { class AppendOplogNoteCmd : public Command { @@ -62,7 +62,7 @@ namespace mongo { string& errmsg, BSONObjBuilder& result, bool fromRepl) { - if (!repl::replSettings.master) { + if (!repl::getGlobalReplicationCoordinator()->isReplEnabled()) { return appendCommandStatus(result, Status( ErrorCodes::NoReplicationEnabled, "Must have replication set up to run \"appendOplogNote\"")); diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 612c1c28d3d..50657a2ebf5 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -342,7 +342,7 @@ namespace mongo { Client::Context ctx(&txn, dbName ); - if (repl::replSettings.usingReplSets()) { + if (repl::getGlobalReplicationCoordinator()->getSettings().usingReplSets()) { // we only care about the _id index if we are in a replset checkForIdIndexes(&txn, ctx.db()); } @@ -429,7 +429,7 @@ namespace mongo { // This is helpful for the query below to work as you can't open files when readlocked Lock::GlobalWrite lk(txn.lockState()); - if (!repl::replSettings.usingReplSets()) { + if (!repl::getGlobalReplicationCoordinator()->getSettings().usingReplSets()) { DBDirectClient c(&txn); return c.count("local.system.replset"); } @@ -600,14 +600,16 @@ namespace mongo { bool is32bit = sizeof(int*) == 4; + const repl::ReplSettings& replSettings = + repl::getGlobalReplicationCoordinator()->getSettings(); { ProcessId pid = ProcessId::getCurrent(); LogstreamBuilder l = log(); l << "MongoDB starting : pid=" << pid << " port=" << serverGlobalParams.port << " dbpath=" << storageGlobalParams.dbpath; - if( repl::replSettings.master ) l << " master=" << repl::replSettings.master; - if( repl::replSettings.slave ) l << " slave=" << (int) repl::replSettings.slave; + if( replSettings.master ) l << " master=" << replSettings.master; + if( replSettings.slave ) l << " slave=" << (int) replSettings.slave; l << ( is32bit ? " 32" : " 64" ) << "-bit host=" << getHostNameCached() << endl; } DEV log() << "_DEBUG build (which is slower)" << endl; @@ -678,8 +680,8 @@ namespace mongo { // promotion to primary. On pure slaves, they are only cleared when the oplog tells them to. // The local DB is special because it is not replicated. See SERVER-10927 for more details. const bool shouldClearNonLocalTmpCollections =!(missingRepl - || repl::replSettings.usingReplSets() - || repl::replSettings.slave == repl::SimpleSlave); + || replSettings.usingReplSets() + || replSettings.slave == repl::SimpleSlave); repairDatabasesAndCheckVersion(shouldClearNonLocalTmpCollections); if (mongodGlobalParams.upgrade) { @@ -900,11 +902,23 @@ namespace { MONGO_EXPORT_STARTUP_SERVER_PARAMETER(useNewReplCoordinator, bool, false); } // namespace -MONGO_INITIALIZER(CreateReplicationManager)(InitializerContext* context) { +namespace { + repl::ReplSettings replSettings; +} // namespace + +namespace mongo { + void setGlobalReplSettings(const repl::ReplSettings& settings) { + replSettings = settings; + } +} // namespace mongo + +MONGO_INITIALIZER(CreateReplicationCoordinator)(InitializerContext* context) { if (useNewReplCoordinator) { - repl::setGlobalReplicationCoordinator(new repl::ReplicationCoordinatorImpl()); + repl::setGlobalReplicationCoordinator( + new repl::ReplicationCoordinatorImpl(replSettings)); } else { - repl::setGlobalReplicationCoordinator(new repl::LegacyReplicationCoordinator()); + repl::setGlobalReplicationCoordinator( + new repl::LegacyReplicationCoordinator(replSettings)); } return Status::OK(); } diff --git a/src/mongo/db/db.h b/src/mongo/db/db.h index c0a20aec069..006f5a35c85 100644 --- a/src/mongo/db/db.h +++ b/src/mongo/db/db.h @@ -37,6 +37,12 @@ namespace mongo { +namespace repl { + class ReplSettings; +} // namespace repl + extern void (*snmpInit)(); + void setGlobalReplSettings(const repl::ReplSettings& settings); + } // namespace mongo diff --git a/src/mongo/db/mongod_options.cpp b/src/mongo/db/mongod_options.cpp index 5ec74934cbe..bbfe400dfa4 100644 --- a/src/mongo/db/mongod_options.cpp +++ b/src/mongo/db/mongod_options.cpp @@ -36,6 +36,7 @@ #include "mongo/bson/util/builder.h" #include "mongo/db/auth/authorization_manager.h" #include "mongo/db/auth/authorization_manager_global.h" +#include "mongo/db/db.h" #include "mongo/db/instance.h" #include "mongo/db/repl/repl_settings.h" #include "mongo/db/server_options.h" @@ -998,37 +999,39 @@ namespace mongo { if (params.count("notablescan")) { storageGlobalParams.noTableScan = params["notablescan"].as<bool>(); } + + repl::ReplSettings replSettings; if (params.count("master")) { - repl::replSettings.master = params["master"].as<bool>(); + replSettings.master = params["master"].as<bool>(); } if (params.count("slave") && params["slave"].as<bool>() == true) { - repl::replSettings.slave = repl::SimpleSlave; + replSettings.slave = repl::SimpleSlave; } if (params.count("slavedelay")) { - repl::replSettings.slavedelay = params["slavedelay"].as<int>(); + replSettings.slavedelay = params["slavedelay"].as<int>(); } if (params.count("fastsync")) { - repl::replSettings.fastsync = params["fastsync"].as<bool>(); + replSettings.fastsync = params["fastsync"].as<bool>(); } if (params.count("autoresync")) { - repl::replSettings.autoresync = params["autoresync"].as<bool>(); + replSettings.autoresync = params["autoresync"].as<bool>(); } if (params.count("source")) { /* specifies what the source in local.sources should be */ - repl::replSettings.source = params["source"].as<string>().c_str(); + replSettings.source = params["source"].as<string>().c_str(); } if( params.count("pretouch") ) { - repl::replSettings.pretouch = params["pretouch"].as<int>(); + replSettings.pretouch = params["pretouch"].as<int>(); } if (params.count("replication.replSetName")) { - repl::replSettings.replSet = params["replication.replSetName"].as<string>().c_str(); + replSettings.replSet = params["replication.replSetName"].as<string>().c_str(); } if (params.count("replication.replSet")) { /* seed list of hosts for the repl set */ - repl::replSettings.replSet = params["replication.replSet"].as<string>().c_str(); + replSettings.replSet = params["replication.replSet"].as<string>().c_str(); } if (params.count("replication.secondaryIndexPrefetch")) { - repl::replSettings.rsIndexPrefetch = + replSettings.rsIndexPrefetch = params["replication.secondaryIndexPrefetch"].as<std::string>(); } @@ -1037,7 +1040,7 @@ namespace mongo { } if (params.count("only")) { - repl::replSettings.only = params["only"].as<string>().c_str(); + replSettings.only = params["only"].as<string>().c_str(); } if( params.count("storage.nsSize") ) { int x = params["storage.nsSize"].as<int>(); @@ -1050,7 +1053,9 @@ namespace mongo { if (params.count("replication.oplogSizeMB")) { long long x = params["replication.oplogSizeMB"].as<int>(); if (x <= 0) { - return Status(ErrorCodes::BadValue, "bad --oplogSize arg"); + return Status(ErrorCodes::BadValue, + str::stream() << "bad --oplogSize, arg must be greater than 0," + "found: " << x); } // note a small size such as x==1 is ok for an arbiter. if( x > 1000 && sizeof(void*) == 4 ) { @@ -1059,8 +1064,8 @@ namespace mongo { << "MB is too big for 32 bit version. Use 64 bit build instead."; return Status(ErrorCodes::BadValue, sb.str()); } - repl::replSettings.oplogSize = x * 1024 * 1024; - verify(repl::replSettings.oplogSize > 0); + replSettings.oplogSize = x * 1024 * 1024; + invariant(replSettings.oplogSize > 0); } if (params.count("cacheSize")) { long x = params["cacheSize"].as<long>(); @@ -1095,9 +1100,9 @@ namespace mongo { params["sharding.clusterRole"].as<std::string>() == "configsvr") { serverGlobalParams.configsvr = true; storageGlobalParams.smallfiles = true; // config server implies small files - if (repl::replSettings.usingReplSets() - || repl::replSettings.master - || repl::replSettings.slave) { + if (replSettings.usingReplSets() + || replSettings.master + || replSettings.slave) { return Status(ErrorCodes::BadValue, "replication should not be enabled on a config server"); } @@ -1110,9 +1115,9 @@ namespace mongo { if (!params.count("storage.dbPath")) storageGlobalParams.dbpath = "/data/configdb"; - repl::replSettings.master = true; + replSettings.master = true; if (!params.count("replication.oplogSizeMB")) - repl::replSettings.oplogSize = 5 * 1024 * 1024; + replSettings.oplogSize = 5 * 1024 * 1024; } if (params.count("sharding.archiveMovedChunks")) { @@ -1147,8 +1152,8 @@ namespace mongo { storageGlobalParams.repairpath = storageGlobalParams.dbpath; } - if (repl::replSettings.pretouch) - log() << "--pretouch " << repl::replSettings.pretouch; + if (replSettings.pretouch) + log() << "--pretouch " << replSettings.pretouch; // Check if we are 32 bit and have not explicitly specified any journaling options if (sizeof(void*) == 4 && !params.count("storage.journal.enabled")) { @@ -1159,6 +1164,7 @@ namespace mongo { log() << endl; } + setGlobalReplSettings(replSettings); return Status::OK(); } diff --git a/src/mongo/db/mongod_options.h b/src/mongo/db/mongod_options.h index 61112f54f3d..f8ed7d86dcb 100644 --- a/src/mongo/db/mongod_options.h +++ b/src/mongo/db/mongod_options.h @@ -29,6 +29,7 @@ #pragma once #include "mongo/base/status.h" +#include "mongo/db/repl/repl_settings.h" #include "mongo/db/server_options.h" #include "mongo/db/storage_options.h" #include "mongo/util/options_parser/environment.h" @@ -84,5 +85,8 @@ namespace mongo { */ Status canonicalizeMongodOptions(moe::Environment* params); + // Must be called after "storeMongodOptions" + StatusWith<repl::ReplSettings> parseMongodReplicationOptions(const moe::Environment& params); + Status storeMongodOptions(const moe::Environment& params, const std::vector<std::string>& args); } diff --git a/src/mongo/db/range_deleter_test.cpp b/src/mongo/db/range_deleter_test.cpp index 80fbe9f066b..05ce3918320 100644 --- a/src/mongo/db/range_deleter_test.cpp +++ b/src/mongo/db/range_deleter_test.cpp @@ -34,6 +34,7 @@ #include "mongo/db/range_deleter_mock_env.h" #include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/repl_coordinator_mock.h" +#include "mongo/db/repl/repl_settings.h" #include "mongo/stdx/functional.h" #include "mongo/unittest/unittest.h" @@ -55,9 +56,12 @@ namespace { // Capped sleep interval is 640 mSec, Nyquist frequency is 1280 mSec => round up to 2 sec. const int MAX_IMMEDIATE_DELETE_WAIT_SECS = 2; + const mongo::repl::ReplSettings replSettings; + // Should not be able to queue deletes if deleter workers were not started. TEST(QueueDelete, CantAfterStop) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); @@ -79,7 +83,8 @@ namespace { // Should not start delete if the set of cursors that were open when the // delete was queued is still open. TEST(QueuedDelete, ShouldWaitCursor) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); const string ns("test.user"); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); @@ -114,7 +119,8 @@ namespace { // Should terminate when stop is requested. TEST(QueuedDelete, StopWhileWaitingCursor) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); const string ns("test.user"); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); @@ -147,7 +153,8 @@ namespace { // Should not start delete if the set of cursors that were open when the // deleteNow method is called is still open. TEST(ImmediateDelete, ShouldWaitCursor) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); const string ns("test.user"); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); @@ -195,7 +202,8 @@ namespace { // Should terminate when stop is requested. TEST(ImmediateDelete, StopWhileWaitingCursor) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); const string ns("test.user"); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); @@ -237,7 +245,8 @@ namespace { // other one is waiting for an open cursor. The test then makes sure that the // deletes are performed in the right order. TEST(MixedDeletes, MultipleDeletes) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); const string blockedNS("foo.bar"); const string ns("test.user"); @@ -336,7 +345,8 @@ namespace { // Should not be able to delete ranges that overlaps with a black listed range. TEST(BlackList, CantDeleteBlackListed) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); deleter.startWorkers(); @@ -365,7 +375,8 @@ namespace { // Should not be able to black list a range that overlaps with a range that is // already blacklisted. TEST(BlackList, CantDoubleBlackList) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); const string ns("test.user"); @@ -388,7 +399,8 @@ namespace { // Should not be able to black list a range that overlaps with a range that is already // queued for deletion. TEST(BlackList, CantBlackListQueued) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); const string ns("test.user"); @@ -419,7 +431,8 @@ namespace { // Should not be able to black list a range that overlaps the range of an // immediate delete that is currently in progress. TEST(BlackList, CantBlackListImmediateInProgress) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); const string ns("test.user"); @@ -459,7 +472,8 @@ namespace { // Undo black list should only work if the range given exactly match with an // existing black listed range. TEST(BlackList, UndoShouldBeExact) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); const string ns("test.user"); @@ -478,7 +492,8 @@ namespace { // Should be able to delete the range again once the black list has been undone. TEST(BlackList, UndoBlackList) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); const string ns("test.user"); @@ -504,7 +519,8 @@ namespace { // Black listing should only affect the specified namespace. TEST(BlackList, NSIsolation) { - mongo::repl::setGlobalReplicationCoordinator(new mongo::repl::ReplicationCoordinatorMock()); + mongo::repl::setGlobalReplicationCoordinator( + new mongo::repl::ReplicationCoordinatorMock(replSettings)); RangeDeleterMockEnv* env = new RangeDeleterMockEnv(); RangeDeleter deleter(env); diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript index 39e6261d7fe..71c00c8bb4c 100644 --- a/src/mongo/db/repl/SConscript +++ b/src/mongo/db/repl/SConscript @@ -10,10 +10,6 @@ env.Library( '$BUILD_DIR/mongo/clientdriver' ]) -env.Library('repl_settings', - 'repl_settings.cpp', - LIBDEPS=['$BUILD_DIR/mongo/foundation']) - env.Library('replication_executor', 'replication_executor.cpp', LIBDEPS=['$BUILD_DIR/mongo/foundation']) @@ -28,8 +24,7 @@ env.Library('repl_coordinator_impl', LIBDEPS=['$BUILD_DIR/mongo/db/common', '$BUILD_DIR/mongo/foundation', '$BUILD_DIR/mongo/server_options_core', - 'replication_executor', - 'repl_settings']) + 'replication_executor']) env.CppUnitTest('repl_coordinator_impl_test', 'repl_coordinator_impl_test.cpp', diff --git a/src/mongo/db/repl/heartbeat.cpp b/src/mongo/db/repl/heartbeat.cpp index 48e6cf97e2f..05ca44afb85 100644 --- a/src/mongo/db/repl/heartbeat.cpp +++ b/src/mongo/db/repl/heartbeat.cpp @@ -37,7 +37,6 @@ #include "mongo/db/repl/heartbeat_info.h" #include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/repl_set_health_poll_task.h" -#include "mongo/db/repl/repl_settings.h" // replSettings #include "mongo/db/repl/replset_commands.h" #include "mongo/db/repl/rs.h" #include "mongo/db/repl/server.h" @@ -75,7 +74,7 @@ namespace repl { /* we don't call ReplSetCommand::check() here because heartbeat checks many things that are pre-initialization. */ - if (!replSettings.usingReplSets()) { + if (!getGlobalReplicationCoordinator()->getSettings().usingReplSets()) { errmsg = "not running with --replSet"; return false; } diff --git a/src/mongo/db/repl/master_slave.cpp b/src/mongo/db/repl/master_slave.cpp index 00c7e40d86f..973c78d22b6 100644 --- a/src/mongo/db/repl/master_slave.cpp +++ b/src/mongo/db/repl/master_slave.cpp @@ -53,7 +53,7 @@ #include "mongo/db/ops/update.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/repl/oplog.h" -#include "mongo/db/repl/repl_settings.h" // replSettings +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/rs.h" // replLocalAuth() #include "mongo/db/server_parameters.h" #include "mongo/db/operation_context_impl.h" @@ -246,6 +246,7 @@ namespace repl { SourceVector old = v; v.clear(); + const ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); if (!replSettings.source.empty()) { // --source <host> specified. // check that no items are in sources other than that @@ -588,6 +589,7 @@ namespace repl { if ( !only.empty() && only != clientName ) return; + const ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); if (replSettings.pretouch && !alreadyLocked/*doesn't make sense if in write lock already*/) { if (replSettings.pretouch > 1) { @@ -723,6 +725,7 @@ namespace repl { "replApplyBatchSize has to be >= 1 and < 1024" ); } + const ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); if ( replSettings.slavedelay != 0 && b > 1 ) { return Status( ErrorCodes::BadValue, "can't use a batch size > 1 with slavedelay" ); @@ -959,6 +962,8 @@ namespace repl { replInfo = replAllDead = "sync error last >= nextOpTime"; uassert( 10123 , "replication error last applied optime at slave >= nextOpTime from master", false); } + const ReplSettings& replSettings = + getGlobalReplicationCoordinator()->getSettings(); if ( replSettings.slavedelay && ( unsigned( time( 0 ) ) < nextOpTime.getSecs() + replSettings.slavedelay ) ) { verify( justOne ); oplogReader.putBack( op ); @@ -1048,7 +1053,8 @@ namespace repl { Lock::GlobalWrite lk(txn.lockState()); ReplSource::loadAll(&txn, sources); - replSettings.fastsync = false; // only need this param for initial reset + // only need this param for initial reset + getGlobalReplicationCoordinator()->getSettings().fastsync = false; } if ( sources.empty() ) { @@ -1119,7 +1125,8 @@ namespace repl { Lock::GlobalWrite lk(txn.lockState()); if ( replAllDead ) { // throttledForceResyncDead can throw - if ( !replSettings.autoresync || !ReplSource::throttledForceResyncDead( &txn, "auto" ) ) { + if ( !getGlobalReplicationCoordinator()->getSettings().autoresync || + !ReplSource::throttledForceResyncDead( &txn, "auto" ) ) { log() << "all sources dead: " << replAllDead << ", sleeping for 5 seconds" << endl; break; } @@ -1239,6 +1246,7 @@ namespace repl { oldRepl(); + ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); if( !replSettings.slave && !replSettings.master ) return; diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index f8414766eea..37c3057ec15 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -51,7 +51,7 @@ #include "mongo/db/ops/update_lifecycle_impl.h" #include "mongo/db/ops/delete.h" #include "mongo/db/repl/bgsync.h" -#include "mongo/db/repl/repl_settings.h" +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/rs.h" #include "mongo/db/repl/write_concern.h" #include "mongo/db/stats/counters.h" @@ -397,11 +397,13 @@ namespace repl { bool *bb, bool fromMigrate ) = _logOpOld; void newReplUp() { - replSettings.master = true; + getGlobalReplicationCoordinator()->getSettings().master = true; _logOp = _logOpRS; } void newRepl() { - replSettings.master = true; // TODO(spencer): is this necessary even when a replset? + // TODO(spencer): We shouldn't be changing the ReplicationCoordinator's settings after + // startup + getGlobalReplicationCoordinator()->getSettings().master = true; _logOp = _logOpUninitialized; } void oldRepl() { _logOp = _logOpOld; } @@ -431,7 +433,7 @@ namespace repl { bool* b, bool fromMigrate) { try { - if ( replSettings.master ) { + if ( getGlobalReplicationCoordinator()->getSettings().master ) { _logOp(txn, opstr, ns, 0, obj, patt, b, fromMigrate); } @@ -463,6 +465,7 @@ namespace repl { const char * ns = "local.oplog.$main"; + const ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); bool rs = !replSettings.replSet.empty(); if( rs ) ns = rsoplog; diff --git a/src/mongo/db/repl/repl_coordinator.h b/src/mongo/db/repl/repl_coordinator.h index 5c9b9a7d130..cf9b20630e6 100644 --- a/src/mongo/db/repl/repl_coordinator.h +++ b/src/mongo/db/repl/repl_coordinator.h @@ -35,6 +35,7 @@ #include "mongo/db/jsobj.h" #include "mongo/db/repl/member_state.h" #include "mongo/db/repl/replication_executor.h" +#include "mongo/db/repl/repl_settings.h" #include "mongo/util/net/hostandport.h" namespace mongo { @@ -97,6 +98,13 @@ namespace repl { */ virtual bool isShutdownOkay() const = 0; + /** + * Returns a reference to the parsed command line arguments that are related to replication. + * TODO(spencer): Change this to a const ref once we are no longer using it for mutable + * global state. + */ + virtual ReplSettings& getSettings() = 0; + enum Mode { modeNone = 0, modeReplSet, diff --git a/src/mongo/db/repl/repl_coordinator_impl.cpp b/src/mongo/db/repl/repl_coordinator_impl.cpp index 6dab4ac4957..9949b10a673 100644 --- a/src/mongo/db/repl/repl_coordinator_impl.cpp +++ b/src/mongo/db/repl/repl_coordinator_impl.cpp @@ -73,7 +73,8 @@ namespace repl { boost::condition_variable* condVar; }; - ReplicationCoordinatorImpl::ReplicationCoordinatorImpl() : _inShutdown(false) {} + ReplicationCoordinatorImpl::ReplicationCoordinatorImpl(const ReplSettings& settings) : + _inShutdown(false), _settings(settings) {} ReplicationCoordinatorImpl::~ReplicationCoordinatorImpl() {} @@ -129,11 +130,14 @@ namespace repl { return false; } + ReplSettings& ReplicationCoordinatorImpl::getSettings() { + return _settings; + } + ReplicationCoordinator::Mode ReplicationCoordinatorImpl::getReplicationMode() const { - // TODO(spencer): Don't rely on global replSettings object - if (replSettings.usingReplSets()) { + if (_settings.usingReplSets()) { return modeReplSet; - } else if (replSettings.slave || replSettings.master) { + } else if (_settings.slave || _settings.master) { return modeMasterSlave; } return modeNone; diff --git a/src/mongo/db/repl/repl_coordinator_impl.h b/src/mongo/db/repl/repl_coordinator_impl.h index 7dbc53218bd..095c3897a70 100644 --- a/src/mongo/db/repl/repl_coordinator_impl.h +++ b/src/mongo/db/repl/repl_coordinator_impl.h @@ -50,7 +50,7 @@ namespace repl { public: - ReplicationCoordinatorImpl(); + ReplicationCoordinatorImpl(const ReplSettings& settings); virtual ~ReplicationCoordinatorImpl(); // ================== Members of public ReplicationCoordinator API =================== @@ -62,6 +62,8 @@ namespace repl { virtual bool isShutdownOkay() const; + virtual ReplSettings& getSettings(); + virtual Mode getReplicationMode() const; virtual MemberState getCurrentMemberState() const; @@ -171,6 +173,9 @@ namespace repl { // Set to true when we are in the process of shutting down replication bool _inShutdown; + // Parsed command line arguments related to replication + ReplSettings _settings; + // Pointer to the TopologyCoordinator owned by this ReplicationCoordinator boost::scoped_ptr<TopologyCoordinator> _topCoord; diff --git a/src/mongo/db/repl/repl_coordinator_impl_test.cpp b/src/mongo/db/repl/repl_coordinator_impl_test.cpp index a7109982678..9a39426d504 100644 --- a/src/mongo/db/repl/repl_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/repl_coordinator_impl_test.cpp @@ -46,13 +46,17 @@ namespace repl { namespace { TEST(ReplicationCoordinator, StartupShutdown) { - ReplicationCoordinatorImpl coordinator; + ReplSettings settings; + // Make sure we think we're a replSet + settings.replSet = "mySet/node1:12345,node2:54321"; + ReplicationCoordinatorImpl coordinator(settings); coordinator.startReplication(new TopologyCoordinatorMock, new NetworkInterfaceMock); coordinator.shutdown(); } TEST(ReplicationCoordinator, AwaitReplicationNumberBaseCases) { - ReplicationCoordinatorImpl coordinator; + ReplSettings settings; + ReplicationCoordinatorImpl coordinator(settings); OperationContextNoop txn; OpTime time(1, 1); @@ -60,14 +64,14 @@ namespace { writeConcern.wTimeout = WriteConcernOptions::kNoWaiting; writeConcern.wNumNodes = 2; - // Because we didn't set replSettings.replSet, it will think we're a standalone so + // Because we didn't set ReplSettings.replSet, it will think we're a standalone so // awaitReplication will always work. ReplicationCoordinator::StatusAndDuration statusAndDur = coordinator.awaitReplication( &txn, time, writeConcern); ASSERT_OK(statusAndDur.status); // Now make us a master in master/slave - replSettings.master = true; + coordinator.getSettings().master = true; writeConcern.wNumNodes = 0; writeConcern.wMode = "majority"; @@ -76,7 +80,7 @@ namespace { ASSERT_OK(statusAndDur.status); // Now make us a replica set - replSettings.replSet = "mySet/node1:12345,node2:54321"; + coordinator.getSettings().replSet = "mySet/node1:12345,node2:54321"; // Waiting for 1 nodes always works writeConcern.wNumNodes = 1; @@ -86,10 +90,11 @@ namespace { } TEST(ReplicationCoordinator, AwaitReplicationNumberOfNodesNonBlocking) { - ReplicationCoordinatorImpl coordinator; - OperationContextNoop txn; + ReplSettings settings; // Make sure we think we're a replSet - replSettings.replSet = "mySet/node1:12345,node2:54321"; + settings.replSet = "mySet/node1:12345,node2:54321"; + ReplicationCoordinatorImpl coordinator(settings); + OperationContextNoop txn; OID client1 = OID::gen(); OID client2 = OID::gen(); @@ -192,11 +197,12 @@ namespace { }; TEST(ReplicationCoordinator, AwaitReplicationNumberOfNodesBlocking) { - ReplicationCoordinatorImpl coordinator; + ReplSettings settings; + // Make sure we think we're a replSet + settings.replSet = "mySet/node1:12345,node2:54321"; + ReplicationCoordinatorImpl coordinator(settings); OperationContextNoop txn; ReplicationAwaiter awaiter(&coordinator, &txn); - // Make sure we think we're a replSet - replSettings.replSet = "mySet/node1:12345,node2:54321"; OID client1 = OID::gen(); OID client2 = OID::gen(); @@ -238,11 +244,12 @@ namespace { } TEST(ReplicationCoordinator, AwaitReplicationTimeout) { - ReplicationCoordinatorImpl coordinator; + ReplSettings settings; + // Make sure we think we're a replSet + settings.replSet = "mySet/node1:12345,node2:54321"; + ReplicationCoordinatorImpl coordinator(settings); OperationContextNoop txn; ReplicationAwaiter awaiter(&coordinator, &txn); - // Make sure we think we're a replSet - replSettings.replSet = "mySet/node1:12345,node2:54321"; OID client1 = OID::gen(); OID client2 = OID::gen(); @@ -265,12 +272,13 @@ namespace { } TEST(ReplicationCoordinator, AwaitReplicationShutdown) { - ReplicationCoordinatorImpl coordinator; + ReplSettings settings; + // Make sure we think we're a replSet + settings.replSet = "mySet/node1:12345,node2:54321"; + ReplicationCoordinatorImpl coordinator(settings); coordinator.startReplication(new TopologyCoordinatorMock, new NetworkInterfaceMock); OperationContextNoop txn; ReplicationAwaiter awaiter(&coordinator, &txn); - // Make sure we think we're a replSet - replSettings.replSet = "mySet/node1:12345,node2:54321"; OID client1 = OID::gen(); OID client2 = OID::gen(); diff --git a/src/mongo/db/repl/repl_coordinator_legacy.cpp b/src/mongo/db/repl/repl_coordinator_legacy.cpp index 0d84e97b873..97419e74d2e 100644 --- a/src/mongo/db/repl/repl_coordinator_legacy.cpp +++ b/src/mongo/db/repl/repl_coordinator_legacy.cpp @@ -58,7 +58,8 @@ namespace mongo { namespace repl { - LegacyReplicationCoordinator::LegacyReplicationCoordinator() { + LegacyReplicationCoordinator::LegacyReplicationCoordinator(const ReplSettings& settings) : + _settings(settings) { // this is ok but micros or combo with some rand() and/or 64 bits might be better -- // imagine a restart and a clock correction simultaneously (very unlikely but possible...) _rbid = (int) curTimeMillis64(); @@ -68,15 +69,15 @@ namespace repl { void LegacyReplicationCoordinator::startReplication(TopologyCoordinator*, ReplicationExecutor::NetworkInterface*) { // if we are going to be a replica set, we aren't doing other forms of replication. - if (!replSettings.replSet.empty()) { - if (replSettings.slave || replSettings.master) { + if (!_settings.replSet.empty()) { + if (_settings.slave || _settings.master) { log() << "***" << endl; log() << "ERROR: can't use --slave or --master replication options with --replSet"; log() << "***" << endl; } newRepl(); - ReplSetSeedList *replSetSeedList = new ReplSetSeedList(replSettings.replSet); + ReplSetSeedList *replSetSeedList = new ReplSetSeedList(_settings.replSet); boost::thread t(stdx::bind(&startReplSets, replSetSeedList)); } else { startMasterSlave(); @@ -94,10 +95,14 @@ namespace repl { return false; } + ReplSettings& LegacyReplicationCoordinator::getSettings() { + return _settings; + } + ReplicationCoordinator::Mode LegacyReplicationCoordinator::getReplicationMode() const { if (theReplSet) { return modeReplSet; - } else if (replSettings.slave || replSettings.master) { + } else if (_settings.slave || _settings.master) { return modeMasterSlave; } return modeNone; @@ -265,21 +270,21 @@ namespace { bool LegacyReplicationCoordinator::isMasterForReportingPurposes() { // we must check replSet since because getReplicationMode() isn't aware of modeReplSet // until theReplSet is initialized - if (replSettings.usingReplSets()) { + if (_settings.usingReplSets()) { if (theReplSet && getCurrentMemberState().primary()) { return true; } return false; } - if (!replSettings.slave) + if (!_settings.slave) return true; if (replAllDead) { return false; } - if (replSettings.master) { + if (_settings.master) { // if running with --master --slave, allow. return true; } @@ -290,21 +295,21 @@ namespace { bool LegacyReplicationCoordinator::canAcceptWritesForDatabase(const StringData& dbName) { // we must check replSet since because getReplicationMode() isn't aware of modeReplSet // until theReplSet is initialized - if (replSettings.usingReplSets()) { + if (_settings.usingReplSets()) { if (theReplSet && getCurrentMemberState().primary()) { return true; } return dbName == "local"; } - if (!replSettings.slave) + if (!_settings.slave) return true; if (replAllDead) { return dbName == "local"; } - if (replSettings.master) { + if (_settings.master) { // if running with --master --slave, allow. return true; } @@ -324,7 +329,7 @@ namespace { if (canAcceptWritesForDatabase(ns.db())) { return Status::OK(); } - if (getReplicationMode() == modeMasterSlave && replSettings.slave == SimpleSlave) { + if (getReplicationMode() == modeMasterSlave && _settings.slave == SimpleSlave) { return Status::OK(); } if (slaveOk) { @@ -415,8 +420,8 @@ namespace { { string s = string(cmdObj.getStringField("replSetHeartbeat")); - if (replSettings.ourSetName() != s) { - log() << "replSet set names do not match, our cmdline: " << replSettings.replSet + if (_settings.ourSetName() != s) { + log() << "replSet set names do not match, our cmdline: " << _settings.replSet << rsLog; log() << "replSet s: " << s << rsLog; resultObj->append("mismatch", true); @@ -428,8 +433,8 @@ namespace { if( (theReplSet == 0) || (theReplSet->startupStatus == ReplSetImpl::LOADINGCONFIG) ) { string from( cmdObj.getStringField("from") ); if( !from.empty() ) { - scoped_lock lck( replSettings.discoveredSeeds_mx ); - replSettings.discoveredSeeds.insert(from); + scoped_lock lck( _settings.discoveredSeeds_mx ); + _settings.discoveredSeeds.insert(from); } resultObj->append("hbmsg", "still initializing"); return Status::OK(); @@ -487,9 +492,8 @@ namespace { return Status::OK(); } -namespace { - Status _checkReplEnabledForCommand(BSONObjBuilder* result) { - if (!replSettings.usingReplSets()) { + Status LegacyReplicationCoordinator::_checkReplEnabledForCommand(BSONObjBuilder* result) { + if (!_settings.usingReplSets()) { if (serverGlobalParams.configsvr) { result->append("info", "configsvr"); // for shell prompt } @@ -506,14 +510,13 @@ namespace { return Status::OK(); } -} // namespace Status LegacyReplicationCoordinator::processReplSetReconfig(OperationContext* txn, const ReplSetReconfigArgs& args, BSONObjBuilder* resultObj) { if( args.force && !theReplSet ) { - replSettings.reconfig = args.newConfigObj.getOwned(); + _settings.reconfig = args.newConfigObj.getOwned(); resultObj->append("msg", "will try this config momentarily, try running rs.conf() again in a " "few seconds"); @@ -579,7 +582,7 @@ namespace { log() << "replSet replSetInitiate admin command received from client" << rsLog; - if (!replSettings.usingReplSets()) { + if (!_settings.usingReplSets()) { return Status(ErrorCodes::NoReplicationEnabled, "server is not running with --replSet"); } @@ -620,7 +623,7 @@ namespace { } if( ReplSet::startupStatus != ReplSet::EMPTYCONFIG ) { resultObj->append("startupStatus", ReplSet::startupStatus); - resultObj->append("info", replSettings.replSet); + resultObj->append("info", _settings.replSet); return Status(ErrorCodes::InvalidReplicaSetConfig, "all members and seeds must be reachable to initiate set"); } @@ -636,7 +639,7 @@ namespace { string name; vector<HostAndPort> seeds; set<HostAndPort> seedSet; - parseReplSetSeedList(replSettings.replSet, name, seeds, seedSet); // may throw... + parseReplSetSeedList(_settings.replSet, name, seeds, seedSet); // may throw... BSONObjBuilder b; b.append("_id", name); diff --git a/src/mongo/db/repl/repl_coordinator_legacy.h b/src/mongo/db/repl/repl_coordinator_legacy.h index a2092ddb440..a9095f80a09 100644 --- a/src/mongo/db/repl/repl_coordinator_legacy.h +++ b/src/mongo/db/repl/repl_coordinator_legacy.h @@ -42,7 +42,7 @@ namespace repl { public: - LegacyReplicationCoordinator(); + LegacyReplicationCoordinator(const ReplSettings& settings); virtual ~LegacyReplicationCoordinator(); virtual void startReplication(TopologyCoordinator*, @@ -52,6 +52,8 @@ namespace repl { virtual bool isShutdownOkay() const; + virtual ReplSettings& getSettings(); + virtual Mode getReplicationMode() const; virtual MemberState getCurrentMemberState() const; @@ -136,6 +138,8 @@ namespace repl { const Milliseconds& stepdownTime, const Milliseconds& postStepdownWaitTime); + Status _checkReplEnabledForCommand(BSONObjBuilder* result); + // Mutex that protects the _ridConfigMap boost::mutex _ridConfigMapMutex; @@ -145,6 +149,8 @@ namespace repl { // Rollback id. used to check if a rollback happened during some interval of time // TODO: ideally this should only change on rollbacks NOT on mongod restarts also. int _rbid; + + ReplSettings _settings; }; } // namespace repl diff --git a/src/mongo/db/repl/repl_coordinator_mock.cpp b/src/mongo/db/repl/repl_coordinator_mock.cpp index 5c79a962654..b7b712bd0d4 100644 --- a/src/mongo/db/repl/repl_coordinator_mock.cpp +++ b/src/mongo/db/repl/repl_coordinator_mock.cpp @@ -36,7 +36,8 @@ namespace mongo { namespace repl { - ReplicationCoordinatorMock::ReplicationCoordinatorMock() {} + ReplicationCoordinatorMock::ReplicationCoordinatorMock(const ReplSettings& settings) : + _settings(settings) {} ReplicationCoordinatorMock::~ReplicationCoordinatorMock() {} void ReplicationCoordinatorMock::startReplication( @@ -54,6 +55,10 @@ namespace repl { return false; } + ReplSettings& ReplicationCoordinatorMock::getSettings() { + return _settings; + } + bool ReplicationCoordinatorMock::isReplEnabled() const { return false; } diff --git a/src/mongo/db/repl/repl_coordinator_mock.h b/src/mongo/db/repl/repl_coordinator_mock.h index 607e0452b6d..260ed685705 100644 --- a/src/mongo/db/repl/repl_coordinator_mock.h +++ b/src/mongo/db/repl/repl_coordinator_mock.h @@ -43,7 +43,7 @@ namespace repl { public: - ReplicationCoordinatorMock(); + ReplicationCoordinatorMock(const ReplSettings& settings); virtual ~ReplicationCoordinatorMock(); virtual void startReplication(TopologyCoordinator* topCoord, @@ -53,6 +53,8 @@ namespace repl { virtual bool isShutdownOkay() const; + virtual ReplSettings& getSettings(); + virtual bool isReplEnabled() const; virtual Mode getReplicationMode() const; @@ -134,6 +136,9 @@ namespace repl { virtual std::vector<BSONObj> getHostsWrittenTo(const OpTime& op); + private: + + ReplSettings _settings; }; } // namespace repl diff --git a/src/mongo/db/repl/repl_info.cpp b/src/mongo/db/repl/repl_info.cpp index 5222bb5453b..c05de79df5d 100644 --- a/src/mongo/db/repl/repl_info.cpp +++ b/src/mongo/db/repl/repl_info.cpp @@ -37,7 +37,6 @@ #include "mongo/db/repl/master_slave.h" #include "mongo/db/repl/oplogreader.h" #include "mongo/db/repl/repl_coordinator_global.h" -#include "mongo/db/repl/repl_settings.h" #include "mongo/db/repl/rs.h" #include "mongo/db/operation_context_impl.h" #include "mongo/db/storage_options.h" @@ -48,8 +47,8 @@ namespace mongo { namespace repl { void appendReplicationInfo(OperationContext* txn, BSONObjBuilder& result, int level) { - if (replSettings.usingReplSets()) { - ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator(); + ReplicationCoordinator* replCoord = getGlobalReplicationCoordinator(); + if (replCoord->getSettings().usingReplSets()) { if (replCoord->getReplicationMode() != ReplicationCoordinator::modeReplSet || replCoord->getCurrentMemberState().shunned()) { result.append("ismaster", false); @@ -73,7 +72,7 @@ namespace repl { getGlobalReplicationCoordinator()->isMasterForReportingPurposes()); } - if (level && replSettings.usingReplSets()) { + if (level && replCoord->getSettings().usingReplSets()) { result.append( "info" , "is replica set" ); } else if ( level ) { diff --git a/src/mongo/db/repl/repl_set_impl.cpp b/src/mongo/db/repl/repl_set_impl.cpp index 9450d5c58bb..000d4065ed0 100644 --- a/src/mongo/db/repl/repl_set_impl.cpp +++ b/src/mongo/db/repl/repl_set_impl.cpp @@ -41,7 +41,7 @@ #include "mongo/db/repl/isself.h" #include "mongo/db/repl/oplog.h" #include "mongo/db/repl/repl_set_seed_list.h" -#include "mongo/db/repl/repl_settings.h" // replSettings +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/storage/storage_engine.h" #include "mongo/s/d_logic.h" #include "mongo/util/background.h" @@ -418,7 +418,7 @@ namespace { } // Figure out indexPrefetch setting - std::string& prefetch = replSettings.rsIndexPrefetch; + std::string& prefetch = getGlobalReplicationCoordinator()->getSettings().rsIndexPrefetch; if (!prefetch.empty()) { IndexPrefetchConfig prefetchConfig = PREFETCH_ALL; if (prefetch == "none") @@ -771,6 +771,7 @@ namespace { << " : " << e.toString() << rsLog; } } + ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); { scoped_lock lck(replSettings.discoveredSeeds_mx); if (replSettings.discoveredSeeds.size() > 0) { diff --git a/src/mongo/db/repl/repl_settings.cpp b/src/mongo/db/repl/repl_settings.cpp deleted file mode 100644 index 5927f47d576..00000000000 --- a/src/mongo/db/repl/repl_settings.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/** -* Copyright (C) 2008 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. -*/ - -#include "mongo/db/repl/repl_settings.h" - -namespace mongo { -namespace repl { - - // our config from command line etc. - ReplSettings replSettings; - -} // namespace repl -} // namespace mongo diff --git a/src/mongo/db/repl/repl_settings.h b/src/mongo/db/repl/repl_settings.h index 253d7d9a2d3..1cd26081bb3 100644 --- a/src/mongo/db/repl/repl_settings.h +++ b/src/mongo/db/repl/repl_settings.h @@ -94,8 +94,44 @@ namespace repl { discoveredSeeds_mx("ReplSettings::discoveredSeeds") { } + // TODO(spencer): Remove explicit copy constructor after we no longer have mutable state + // in ReplSettings. + ReplSettings(const ReplSettings& other) : + slave(other.slave), + master(other.master), + fastsync(other.fastsync), + autoresync(other.autoresync), + slavedelay(other.slavedelay), + oplogSize(other.oplogSize), + source(other.source), + only(other.only), + pretouch(other.pretouch), + replSet(other.replSet), + rsIndexPrefetch(other.rsIndexPrefetch), + discoveredSeeds(other.discoveredSeeds), + discoveredSeeds_mx("ReplSettings::discoveredSeeds"), + reconfig(other.reconfig.getOwned()) {} + + ReplSettings& operator=(const ReplSettings& other) { + if (this == &other) return *this; + + slave = other.slave; + master = other.master; + fastsync = other.fastsync; + autoresync = other.autoresync; + slavedelay = other.slavedelay; + oplogSize = other.oplogSize; + source = other.source; + only = other.only; + pretouch = other.pretouch; + replSet = other.replSet; + rsIndexPrefetch = other.rsIndexPrefetch; + discoveredSeeds = other.discoveredSeeds; + reconfig = other.reconfig.getOwned(); + return *this; + } + }; - extern ReplSettings replSettings; } // namespace repl } // namespace mongo diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp index 2cec334217d..36cfd2a0e31 100644 --- a/src/mongo/db/repl/replset_commands.cpp +++ b/src/mongo/db/repl/replset_commands.cpp @@ -36,7 +36,6 @@ #include "mongo/db/commands.h" #include "mongo/db/repl/oplog.h" #include "mongo/db/repl/repl_coordinator_global.h" -#include "mongo/db/repl/repl_settings.h" // replSettings #include "mongo/db/repl/replset_commands.h" #include "mongo/db/repl/rs_config.h" #include "mongo/db/repl/write_concern.h" @@ -51,6 +50,28 @@ namespace repl { replSetInitiate - rs_mod.cpp */ + bool ReplSetCommand::check(string& errmsg, BSONObjBuilder& result) { + if (!getGlobalReplicationCoordinator()->getSettings().usingReplSets()) { + errmsg = "not running with --replSet"; + if (serverGlobalParams.configsvr) { + result.append("info", "configsvr"); // for shell prompt + } + return false; + } + + if( theReplSet == 0 ) { + result.append("startupStatus", ReplSet::startupStatus); + string s; + errmsg = ReplSet::startupStatusMsg.empty() ? + "replset unknown error 2" : ReplSet::startupStatusMsg.get(); + if( ReplSet::startupStatus == 3 ) + result.append("info", "run rs.initiate(...) if not yet done for the set"); + return false; + } + + return true; + } + bool replSetBlind = false; unsigned replSetForceInitialSyncFailure = 0; diff --git a/src/mongo/db/repl/replset_commands.h b/src/mongo/db/repl/replset_commands.h index fd34d2346e7..9dc8adddaf1 100644 --- a/src/mongo/db/repl/replset_commands.h +++ b/src/mongo/db/repl/replset_commands.h @@ -32,7 +32,6 @@ #include "mongo/bson/bsonobjbuilder.h" #include "mongo/db/commands.h" -#include "mongo/db/repl/repl_settings.h" #include "mongo/db/repl/rs.h" namespace mongo { @@ -54,27 +53,7 @@ namespace repl { virtual void help( stringstream &help ) const { help << "internal"; } // TODO(spencer): Remove this once all command processing happens in the repl coordinator - bool check(string& errmsg, BSONObjBuilder& result) { - if (!replSettings.usingReplSets()) { - errmsg = "not running with --replSet"; - if (serverGlobalParams.configsvr) { - result.append("info", "configsvr"); // for shell prompt - } - return false; - } - - if( theReplSet == 0 ) { - result.append("startupStatus", ReplSet::startupStatus); - string s; - errmsg = ReplSet::startupStatusMsg.empty() ? - "replset unknown error 2" : ReplSet::startupStatusMsg.get(); - if( ReplSet::startupStatus == 3 ) - result.append("info", "run rs.initiate(...) if not yet done for the set"); - return false; - } - - return true; - } + bool check(string& errmsg, BSONObjBuilder& result); }; } // namespace repl diff --git a/src/mongo/db/repl/replset_web_handler.cpp b/src/mongo/db/repl/replset_web_handler.cpp index 3480014607d..175883e967e 100644 --- a/src/mongo/db/repl/replset_web_handler.cpp +++ b/src/mongo/db/repl/replset_web_handler.cpp @@ -30,7 +30,7 @@ #include "mongo/db/dbwebserver.h" #include "mongo/db/jsobj.h" -#include "mongo/db/repl/repl_settings.h" // replSettings +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/rs.h" #include "mongo/util/mongoutils/html.h" #include "mongo/util/mongoutils/str.h" @@ -75,7 +75,7 @@ namespace repl { s << p(t); if( theReplSet == 0 ) { - if (replSettings.replSet.empty()) + if (getGlobalReplicationCoordinator()->getSettings().replSet.empty()) s << p("Not using --replSet"); else { s << p("Still starting up, or else set is not yet " + a("http://dochub.mongodb.org/core/replicasetconfiguration#ReplicaSetConfiguration-InitialSetup", "", "initiated") @@ -106,7 +106,7 @@ namespace repl { ); if( theReplSet == 0 ) { - if (replSettings.replSet.empty()) + if (getGlobalReplicationCoordinator()->getSettings().replSet.empty()) s << p("Not using --replSet"); else { s << p("Still starting up, or else set is not yet " + a("http://dochub.mongodb.org/core/replicasetconfiguration#ReplicaSetConfiguration-InitialSetup", "", "initiated") diff --git a/src/mongo/db/repl/resync.cpp b/src/mongo/db/repl/resync.cpp index 5267532e17e..431050b3551 100644 --- a/src/mongo/db/repl/resync.cpp +++ b/src/mongo/db/repl/resync.cpp @@ -28,7 +28,7 @@ #include "mongo/db/commands.h" #include "mongo/db/repl/master_slave.h" // replSettings -#include "mongo/db/repl/repl_settings.h" // replSettings +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/rs.h" // replLocalAuth() #include "mongo/db/operation_context_impl.h" @@ -70,7 +70,7 @@ namespace repl { Lock::GlobalWrite globalWriteLock(txn->lockState()); WriteUnitOfWork wunit(txn->recoveryUnit()); Client::Context ctx(txn, ns); - if (replSettings.usingReplSets()) { + if (getGlobalReplicationCoordinator()->getSettings().usingReplSets()) { if (!theReplSet) { errmsg = "no replication yet active"; return false; diff --git a/src/mongo/db/repl/rs_config.cpp b/src/mongo/db/repl/rs_config.cpp index 925125034f6..45db18f0066 100644 --- a/src/mongo/db/repl/rs_config.cpp +++ b/src/mongo/db/repl/rs_config.cpp @@ -38,7 +38,7 @@ #include "mongo/db/repl/heartbeat.h" #include "mongo/db/repl/isself.h" #include "mongo/db/repl/oplog.h" -#include "mongo/db/repl/repl_settings.h" // replSettings +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/rs.h" #include "mongo/db/operation_context_impl.h" #include "mongo/util/log.h" @@ -334,6 +334,7 @@ namespace { } void ReplSetConfig::checkRsConfig() const { + const ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); uassert(13132, str::stream() << "nonmatching repl set name in _id field: " << _id << " vs. " << replSettings.ourSetName(), @@ -670,7 +671,7 @@ namespace { } else { /* first, make sure other node is configured to be a replset. just to be safe. */ - string setname = replSettings.ourSetName(); + string setname = getGlobalReplicationCoordinator()->getSettings().ourSetName(); BSONObj cmd = BSON( "replSetHeartbeat" << setname ); int theirVersion; BSONObj info; diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp index e41a22f6064..72094a53308 100644 --- a/src/mongo/db/repl/rs_initialsync.cpp +++ b/src/mongo/db/repl/rs_initialsync.cpp @@ -44,7 +44,7 @@ #include "mongo/db/repl/member.h" #include "mongo/db/repl/oplog.h" #include "mongo/db/repl/oplogreader.h" -#include "mongo/db/repl/repl_settings.h" // replSettings +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" @@ -400,7 +400,7 @@ namespace repl { // written by applyToHead calls BSONObj minValid; - if (replSettings.fastsync) { + if (getGlobalReplicationCoordinator()->getSettings().fastsync) { log() << "fastsync: skipping database clone" << rsLog; // prime oplog diff --git a/src/mongo/db/repl/topology_coordinator_impl.cpp b/src/mongo/db/repl/topology_coordinator_impl.cpp index 126461ca1ad..0b7aba77ded 100644 --- a/src/mongo/db/repl/topology_coordinator_impl.cpp +++ b/src/mongo/db/repl/topology_coordinator_impl.cpp @@ -33,7 +33,7 @@ #include "mongo/db/operation_context.h" #include "mongo/db/repl/isself.h" #include "mongo/db/repl/member.h" -#include "mongo/db/repl/repl_settings.h" +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/replication_executor.h" #include "mongo/db/repl/rs_sync.h" // maxSyncSourceLagSecs #include "mongo/util/log.h" @@ -273,6 +273,7 @@ namespace repl { // Verify that replica set names match std::string rshb = std::string(cmdObj.getStringField("replSetHeartbeat")); + const ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); if (replSettings.ourSetName() != rshb) { *result = Status(ErrorCodes::BadValue, "repl set names do not match"); log() << "replSet set names do not match, our cmdline: " << replSettings.replSet diff --git a/src/mongo/db/restapi.cpp b/src/mongo/db/restapi.cpp index 4b3975491b6..cd6619d2d06 100644 --- a/src/mongo/db/restapi.cpp +++ b/src/mongo/db/restapi.cpp @@ -42,7 +42,6 @@ #include "mongo/db/dbwebserver.h" #include "mongo/db/instance.h" #include "mongo/db/repl/master_slave.h" -#include "mongo/db/repl/repl_settings.h" #include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/util/md5.hpp" #include "mongo/util/mongoutils/html.h" @@ -277,6 +276,8 @@ namespace mongo { virtual void init() {} void _gotLock( int millis , stringstream& ss ) { + const repl::ReplSettings& replSettings = + repl::getGlobalReplicationCoordinator()->getSettings(); ss << "<pre>\n"; ss << "time to get readlock: " << millis << "ms\n"; ss << "# Cursors: " << ClientCursor::totalOpen() << '\n'; @@ -286,13 +287,13 @@ namespace mongo { if (repl::getGlobalReplicationCoordinator()->getReplicationMode() == repl::ReplicationCoordinator::modeReplSet) { ss << a("", "see replSetGetStatus link top of page") << "--replSet </a>" - << repl::replSettings.replSet; + << replSettings.replSet; } if (repl::replAllDead) ss << "\n<b>replication replAllDead=" << repl::replAllDead << "</b>\n"; else { - ss << "\nmaster: " << repl::replSettings.master << '\n'; - ss << "slave: " << repl::replSettings.slave << '\n'; + ss << "\nmaster: " << replSettings.master << '\n'; + ss << "slave: " << replSettings.slave << '\n'; ss << '\n'; } diff --git a/src/mongo/dbtests/dbtests.cpp b/src/mongo/dbtests/dbtests.cpp index 7e056fb924b..e040301bde3 100644 --- a/src/mongo/dbtests/dbtests.cpp +++ b/src/mongo/dbtests/dbtests.cpp @@ -58,7 +58,9 @@ int dbtestsMain( int argc, char** argv, char** envp ) { setWindowsUnhandledExceptionFilter(); setGlobalAuthorizationManager(new AuthorizationManager(new AuthzManagerExternalStateMock())); setGlobalEnvironment(new GlobalEnvironmentMongoD()); - repl::setGlobalReplicationCoordinator(new repl::ReplicationCoordinatorMock()); + repl::ReplSettings replSettings; + replSettings.oplogSize = 10 * 1024 * 1024; + repl::setGlobalReplicationCoordinator(new repl::ReplicationCoordinatorMock(replSettings)); Command::testCommandsEnabled = 1; mongo::runGlobalInitializersOrDie(argc, argv, envp); StartupTest::runTests(); diff --git a/src/mongo/dbtests/framework_options.cpp b/src/mongo/dbtests/framework_options.cpp index 4a9a97a4914..4e482589331 100644 --- a/src/mongo/dbtests/framework_options.cpp +++ b/src/mongo/dbtests/framework_options.cpp @@ -33,7 +33,6 @@ #include "mongo/base/status.h" #include "mongo/bson/util/builder.h" #include "mongo/db/query/new_find.h" -#include "mongo/db/repl/repl_settings.h" // replSettings #include "mongo/db/storage_options.h" #include "mongo/dbtests/dbtests.h" #include "mongo/unittest/unittest.h" @@ -191,8 +190,6 @@ namespace mongo { storageGlobalParams.dur = true; } - repl::replSettings.oplogSize = 10 * 1024 * 1024; - DEV log() << "_DEBUG build" << endl; if( sizeof(void*)==4 ) log() << "32bit" << endl; diff --git a/src/mongo/dbtests/repltests.cpp b/src/mongo/dbtests/repltests.cpp index 4580b5682d2..d7ed5f5477c 100644 --- a/src/mongo/dbtests/repltests.cpp +++ b/src/mongo/dbtests/repltests.cpp @@ -38,7 +38,7 @@ #include "mongo/db/json.h" #include "mongo/db/repl/master_slave.h" #include "mongo/db/repl/oplog.h" -#include "mongo/db/repl/repl_settings.h" +#include "mongo/db/repl/repl_coordinator_global.h" #include "mongo/db/repl/rs.h" #include "mongo/db/ops/update.h" #include "mongo/db/catalog/collection.h" @@ -70,6 +70,7 @@ namespace ReplTests { _context(&_txn, ns()) { oldRepl(); + ReplSettings& replSettings = getGlobalReplicationCoordinator()->getSettings(); replSettings.replSet = ""; replSettings.oplogSize = 5 * 1024 * 1024; replSettings.master = true; @@ -84,7 +85,7 @@ namespace ReplTests { } ~Base() { try { - replSettings.master = false; + getGlobalReplicationCoordinator()->getSettings().master = false; deleteAll( ns() ); deleteAll( cllNS() ); _wunit.commit(); diff --git a/src/mongo/tools/tool.cpp b/src/mongo/tools/tool.cpp index 92daecb1860..ac009f39552 100644 --- a/src/mongo/tools/tool.cpp +++ b/src/mongo/tools/tool.cpp @@ -77,7 +77,8 @@ namespace mongo { MONGO_INITIALIZER(ToolMocks)(InitializerContext*) { setGlobalAuthorizationManager(new AuthorizationManager( new AuthzManagerExternalStateMock())); - repl::setGlobalReplicationCoordinator(new repl::ReplicationCoordinatorMock()); + repl::ReplSettings replSettings; + repl::setGlobalReplicationCoordinator(new repl::ReplicationCoordinatorMock(replSettings)); setGlobalEnvironment(new GlobalEnvironmentNoop()); return Status::OK(); } |