summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatt dannenberg <matt.dannenberg@10gen.com>2015-06-08 10:36:10 -0400
committermatt dannenberg <matt.dannenberg@10gen.com>2015-06-08 12:17:04 -0400
commit43f94f503d7be84aab9417a81fd5abef537bdcb4 (patch)
treeeb95cad42b0c544856342c861584f6036828454d
parent6cff58bea0dd2bda391d84a8d7bc1f604d4a4607 (diff)
downloadmongo-43f94f503d7be84aab9417a81fd5abef537bdcb4.tar.gz
SERVER-18511 report replication progress upstream after initial sync completes
-rw-r--r--jstests/replsets/initial_sync_report_progress.js39
-rw-r--r--src/mongo/db/repl/rs_initialsync.cpp37
2 files changed, 76 insertions, 0 deletions
diff --git a/jstests/replsets/initial_sync_report_progress.js b/jstests/replsets/initial_sync_report_progress.js
new file mode 100644
index 00000000000..de7ce96039c
--- /dev/null
+++ b/jstests/replsets/initial_sync_report_progress.js
@@ -0,0 +1,39 @@
+// Ensure replication progress is sent upstream when initial sync completes
+load("jstests/replsets/rslib.js");
+(function() {
+ "use strict";
+ // start 1 node set
+ var name = "initialSyncReportProgress";
+ var ports = allocatePorts(2);
+ var hostname = getHostName();
+
+ var replSet = new ReplSetTest({name: name, nodes: 1});
+ replSet.startSet();
+
+ replSet.initiate({
+ _id: name,
+ members: [
+ {_id: 0, host: hostname + ":" + ports[0]},
+ ]});
+
+ var primary = replSet.getPrimary();
+
+ // do a single insert
+ assert.writeOK(primary.getDB(name).foo.insert({x: 13}));
+ var optime = primary.getDB(name).getLastErrorObj(1)["lastOp"];
+
+ // start a new node and add it to the replset
+ var secondary = startMongodTest(ports[1], name, false, {replSet: name, oplogSize: 25});
+ var config = replSet.getReplSetConfig();
+ config.version = 2;
+ config.members.push({_id: 1, host: hostname + ":" + ports[1]});
+ reconfig(replSet, config);
+ reconnect(secondary);
+
+ // confirm that the primary becomes aware of the new node's progress
+ assert.commandWorked(primary.getDB(name).runCommand({getLastError: 1,
+ w: 2,
+ wOpTime: optime,
+ wTimeout: 30*1000}));
+ replSet.stopSet();
+})();
diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp
index 86265d0e601..f95a28d9a15 100644
--- a/src/mongo/db/repl/rs_initialsync.cpp
+++ b/src/mongo/db/repl/rs_initialsync.cpp
@@ -492,6 +492,43 @@ namespace {
bgsync->notify(&txn);
log() << "initial sync done";
+ std::vector<BSONObj> handshakeObjs;
+ replCoord->prepareReplSetUpdatePositionCommandHandshakes(&handshakeObjs);
+ for (std::vector<BSONObj>::iterator it = handshakeObjs.begin();
+ it != handshakeObjs.end();
+ ++it) {
+ BSONObj res;
+ try {
+ if (!r.conn()->runCommand("admin", *it, res)) {
+ warning() << "InitialSync error reporting sync progress during handshake";
+ return Status::OK();
+ }
+ }
+ catch (const DBException& e) {
+ warning() << "InitialSync error reporting sync progress during handshake: "
+ << e.what();
+ return Status::OK();
+ }
+ }
+
+ BSONObjBuilder updateCmd;
+ BSONObj res;
+ if (!replCoord->prepareReplSetUpdatePositionCommand(&updateCmd)) {
+ warning() << "InitialSync couldn't generate updatePosition command";
+ return Status::OK();
+ }
+ try {
+ if (!r.conn()->runCommand("admin", updateCmd.obj(), res)) {
+ warning() << "InitialSync error reporting sync progress during updatePosition";
+ return Status::OK();
+ }
+ }
+ catch (const DBException& e) {
+ warning() << "InitialSync error reporting sync progress during updatePosition: "
+ << e.what();
+ return Status::OK();
+ }
+
return Status::OK();
}
} // namespace