summaryrefslogtreecommitdiff
path: root/src/mongo/db/repl/resync.cpp
diff options
context:
space:
mode:
authormatt dannenberg <matt.dannenberg@10gen.com>2013-10-21 13:27:03 -0400
committermatt dannenberg <matt.dannenberg@10gen.com>2013-10-28 14:16:06 -0400
commit38b665b22722ab442a9c022b54558e3cd7a9b84f (patch)
tree7592e04b21d6c42b01e2e65db240fc49c70c3dc9 /src/mongo/db/repl/resync.cpp
parentba1c7d57ea1a5e82e5af93e41344cf068cdc675b (diff)
downloadmongo-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.cpp112
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;
+}