diff options
author | matt dannenberg <matt.dannenberg@10gen.com> | 2013-10-21 13:27:03 -0400 |
---|---|---|
committer | matt dannenberg <matt.dannenberg@10gen.com> | 2013-10-28 14:16:06 -0400 |
commit | 38b665b22722ab442a9c022b54558e3cd7a9b84f (patch) | |
tree | 7592e04b21d6c42b01e2e65db240fc49c70c3dc9 /src/mongo/db/repl/resync.cpp | |
parent | ba1c7d57ea1a5e82e5af93e41344cf068cdc675b (diff) | |
download | mongo-38b665b22722ab442a9c022b54558e3cd7a9b84f.tar.gz |
SERVER-6552 implement resync command for replicaset members
Diffstat (limited to 'src/mongo/db/repl/resync.cpp')
-rw-r--r-- | src/mongo/db/repl/resync.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/mongo/db/repl/resync.cpp b/src/mongo/db/repl/resync.cpp new file mode 100644 index 00000000000..8bdcca2594b --- /dev/null +++ b/src/mongo/db/repl/resync.cpp @@ -0,0 +1,112 @@ +/** +* 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/commands.h" +#include "mongo/db/repl/master_slave.h" // replSettings +#include "mongo/db/repl/replication_server_status.h" // replSettings +#include "mongo/db/repl/rs.h" // replLocalAuth() + +namespace mongo { + + // operator requested resynchronization of replication (on a slave or secondary). {resync: 1} + class CmdResync : public Command { + public: + virtual bool slaveOk() const { + return true; + } + virtual bool adminOnly() const { + return true; + } + virtual bool logTheOp() { return false; } + virtual bool lockGlobally() const { return true; } + virtual LockType locktype() const { return WRITE; } + virtual void addRequiredPrivileges(const std::string& dbname, + const BSONObj& cmdObj, + std::vector<Privilege>* out) { + ActionSet actions; + actions.addAction(ActionType::resync); + out->push_back(Privilege(ResourcePattern::forClusterResource(), actions)); + } + + void help(stringstream& h) const { + h << "resync (from scratch) a stale slave or replica set secondary node.\n"; + } + + CmdResync() : Command("resync") { } + virtual bool run(const string&, + BSONObj& cmdObj, + int, + string& errmsg, + BSONObjBuilder& result, + bool fromRepl) { + if (replSettings.usingReplSets()) { + if (theReplSet->isPrimary()) { + errmsg = "primaries cannot resync"; + return false; + } + return theReplSet->resync(errmsg); + } + + // below this comment pertains only to master/slave replication + if ( cmdObj.getBoolField( "force" ) ) { + if ( !waitForSyncToFinish( errmsg ) ) + return false; + replAllDead = "resync forced"; + } + if ( !replAllDead ) { + errmsg = "not dead, no need to resync"; + return false; + } + if ( !waitForSyncToFinish( errmsg ) ) + return false; + + ReplSource::forceResyncDead( "client" ); + result.append( "info", "triggered resync for all sources" ); + return true; + } + bool waitForSyncToFinish( string &errmsg ) const { + // Wait for slave thread to finish syncing, so sources will be be + // reloaded with new saved state on next pass. + Timer t; + while ( 1 ) { + if ( syncing == 0 || t.millis() > 30000 ) + break; + { + Lock::TempRelease t; + relinquishSyncingSome = 1; + sleepmillis(1); + } + } + if ( syncing ) { + errmsg = "timeout waiting for sync() to finish"; + return false; + } + return true; + } + } cmdResync; +} |