summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristina <kristina@10gen.com>2012-10-01 10:45:29 -0400
committerEric Milkie <milkie@10gen.com>2012-10-04 10:52:08 -0400
commit011f6072f5d900c25a364a127c24118c1bc3988f (patch)
tree3a45ae726755bcc891c6d9385e673e81711b3ed8
parentd4619ef38fdd8548a2cc25e0633a9147648819a4 (diff)
downloadmongo-011f6072f5d900c25a364a127c24118c1bc3988f.tar.gz
SERVER-7199 Don't reclone docs on 2nd and 3rd oplog applications
-rw-r--r--src/mongo/db/repl/rs.h4
-rw-r--r--src/mongo/db/repl/rs_initialsync.cpp22
-rw-r--r--src/mongo/db/repl/rs_sync.cpp34
-rw-r--r--src/mongo/db/repl/rs_sync.h3
4 files changed, 43 insertions, 20 deletions
diff --git a/src/mongo/db/repl/rs.h b/src/mongo/db/repl/rs.h
index ac189e05ffc..2feef015c60 100644
--- a/src/mongo/db/repl/rs.h
+++ b/src/mongo/db/repl/rs.h
@@ -498,8 +498,8 @@ namespace mongo {
private:
bool _syncDoInitialSync_clone( const char *master, const list<string>& dbs , bool dataPass );
- bool _syncDoInitialSync_applyToHead( replset::InitialSync& init, OplogReader* r ,
- const Member* source, const BSONObj& lastOp,
+ bool _syncDoInitialSync_applyToHead( replset::SyncTail& syncer, OplogReader* r ,
+ const Member* source, const BSONObj& lastOp,
BSONObj& minValidOut);
void _syncDoInitialSync();
void syncDoInitialSync();
diff --git a/src/mongo/db/repl/rs_initialsync.cpp b/src/mongo/db/repl/rs_initialsync.cpp
index ad5c9faa0e4..93265edf7a9 100644
--- a/src/mongo/db/repl/rs_initialsync.cpp
+++ b/src/mongo/db/repl/rs_initialsync.cpp
@@ -248,8 +248,19 @@ namespace mongo {
_veto[host] = time(0)+secs;
}
- bool ReplSetImpl::_syncDoInitialSync_applyToHead( replset::InitialSync& init, OplogReader* r,
- const Member* source, const BSONObj& lastOp ,
+ /**
+ * Replays the sync target's oplog from lastOp to the latest op on the sync target.
+ *
+ * @param syncer either initial sync (can reclone missing docs) or "normal" sync (no recloning)
+ * @param r the oplog reader
+ * @param source the sync target
+ * @param lastOp the op to start syncing at (inclusive)
+ * @param minValid populated by this function. The most recent op on the sync target's oplog,
+ * this function syncs to this value (inclusive)
+ * @return if applying the oplog succeeded
+ */
+ bool ReplSetImpl::_syncDoInitialSync_applyToHead( replset::SyncTail& syncer, OplogReader* r,
+ const Member* source, const BSONObj& lastOp ,
BSONObj& minValid ) {
/* our cloned copy will be strange until we apply oplog events that occurred
through the process. we note that time point here. */
@@ -282,7 +293,7 @@ namespace mongo {
// apply startingTS..mvoptime portion of the oplog
{
try {
- init.oplogApplication(lastOp, minValid);
+ syncer.oplogApplication(lastOp, minValid);
}
catch (const DBException&) {
log() << "replSet initial sync failed during oplog application phase" << rsLog;
@@ -329,6 +340,7 @@ namespace mongo {
*/
void ReplSetImpl::_syncDoInitialSync() {
replset::InitialSync init(replset::BackgroundSync::get());
+ replset::SyncTail tail(replset::BackgroundSync::get());
sethbmsg("initial sync pending",0);
// if this is the first node, it may have already become primary
@@ -395,7 +407,7 @@ namespace mongo {
// that were "from the future" compared with minValid. During this second application,
// nothing should need to be recloned.
log() << "oplog sync 2 of 3" << endl;
- if (!_syncDoInitialSync_applyToHead(init, &r , source , lastOp , minValid)) {
+ if (!_syncDoInitialSync_applyToHead(tail, &r , source , lastOp , minValid)) {
return;
}
// data should now be consistent
@@ -430,7 +442,7 @@ namespace mongo {
BSONObj minValid;
log() << "oplog sync 3 of 3" << endl;
- if ( ! _syncDoInitialSync_applyToHead( init, &r, source, lastOp, minValid ) ) {
+ if (!_syncDoInitialSync_applyToHead(tail, &r, source, lastOp, minValid)) {
return;
}
diff --git a/src/mongo/db/repl/rs_sync.cpp b/src/mongo/db/repl/rs_sync.cpp
index 92b21c7ad85..3e45738bc52 100644
--- a/src/mongo/db/repl/rs_sync.cpp
+++ b/src/mongo/db/repl/rs_sync.cpp
@@ -240,19 +240,11 @@ namespace replset {
InitialSync::~InitialSync() {}
-
- /* initial oplog application, during initial sync, after cloning.
- */
- void InitialSync::oplogApplication(const BSONObj& applyGTEObj, const BSONObj& minValidObj) {
+ void SyncTail::oplogApplySegment(const BSONObj& applyGTEObj, const BSONObj& minValidObj,
+ MultiSyncApplyFunc func) {
OpTime applyGTE = applyGTEObj["ts"]._opTime();
OpTime minValid = minValidObj["ts"]._opTime();
- if (replSetForceInitialSyncFailure > 0) {
- log() << "replSet test code invoked, forced InitialSync failure: " << replSetForceInitialSyncFailure << rsLog;
- replSetForceInitialSyncFailure--;
- throw DBException("forced error",0);
- }
-
syncApply(applyGTEObj);
_logOpObjRS(applyGTEObj);
@@ -266,7 +258,7 @@ namespace replset {
OpTime ts;
time_t start = time(0);
unsigned long long n = 0, lastN = 0;
-
+
while( ts < minValid ) {
OpQueue ops;
@@ -276,8 +268,8 @@ namespace replset {
}
}
-
- multiApply(ops.getDeque(), multiInitialSyncApply);
+
+ multiApply(ops.getDeque(), func);
n += ops.getDeque().size();
@@ -301,6 +293,22 @@ namespace replset {
}
}
+ /* initial oplog application, during initial sync, after cloning.
+ */
+ void InitialSync::oplogApplication(const BSONObj& applyGTEObj, const BSONObj& minValidObj) {
+ if (replSetForceInitialSyncFailure > 0) {
+ log() << "replSet test code invoked, forced InitialSync failure: " << replSetForceInitialSyncFailure << rsLog;
+ replSetForceInitialSyncFailure--;
+ throw DBException("forced error",0);
+ }
+
+ oplogApplySegment(applyGTEObj, minValidObj, multiInitialSyncApply);
+ }
+
+ void SyncTail::oplogApplication(const BSONObj& applyGTEObj, const BSONObj& minValidObj) {
+ oplogApplySegment(applyGTEObj, minValidObj, multiSyncApply);
+ }
+
/* tail an oplog. ok to return, will be re-called. */
void SyncTail::oplogApplication() {
while( 1 ) {
diff --git a/src/mongo/db/repl/rs_sync.h b/src/mongo/db/repl/rs_sync.h
index b02fe7eaf6c..aa3a5c9a2cb 100644
--- a/src/mongo/db/repl/rs_sync.h
+++ b/src/mongo/db/repl/rs_sync.h
@@ -39,6 +39,9 @@ namespace replset {
SyncTail(BackgroundSyncInterface *q);
virtual ~SyncTail();
virtual bool syncApply(const BSONObj &o, bool convertUpdateToUpsert = false);
+ void oplogApplySegment(const BSONObj& applyGTEObj, const BSONObj& minValidObj,
+ MultiSyncApplyFunc func);
+ virtual void oplogApplication(const BSONObj& applyGTEObj, const BSONObj& minValidObj);
void oplogApplication();
bool peek(BSONObj* obj);