diff options
author | Kristina <kristina@10gen.com> | 2012-10-01 10:45:29 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2012-10-04 10:52:08 -0400 |
commit | 011f6072f5d900c25a364a127c24118c1bc3988f (patch) | |
tree | 3a45ae726755bcc891c6d9385e673e81711b3ed8 | |
parent | d4619ef38fdd8548a2cc25e0633a9147648819a4 (diff) | |
download | mongo-011f6072f5d900c25a364a127c24118c1bc3988f.tar.gz |
SERVER-7199 Don't reclone docs on 2nd and 3rd oplog applications
-rw-r--r-- | src/mongo/db/repl/rs.h | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_initialsync.cpp | 22 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_sync.cpp | 34 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_sync.h | 3 |
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); |