diff options
author | Eric Milkie <milkie@10gen.com> | 2016-04-05 11:46:05 -0400 |
---|---|---|
committer | Eric Milkie <milkie@10gen.com> | 2016-04-05 15:43:20 -0400 |
commit | 389d3a6d07507af85ea6af58247f472eb00c085c (patch) | |
tree | ac2c84bb5493661d55140fb7cf727e60cd599c00 | |
parent | 059ce80468b460c9b79d93a5d289f317675c0cba (diff) | |
download | mongo-389d3a6d07507af85ea6af58247f472eb00c085c.tar.gz |
SERVER-23351 ensure applier aquires new minvalid value after rollback
(cherry picked from commit 42cfa52297f1fc6d9fae8bb3bdf236389c800225)
-rw-r--r-- | src/mongo/db/repl/bgsync.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/repl/rs_rollback.cpp | 16 |
2 files changed, 12 insertions, 15 deletions
diff --git a/src/mongo/db/repl/bgsync.cpp b/src/mongo/db/repl/bgsync.cpp index 6c69a0a3269..e34c4f73335 100644 --- a/src/mongo/db/repl/bgsync.cpp +++ b/src/mongo/db/repl/bgsync.cpp @@ -698,7 +698,7 @@ void BackgroundSync::_rollback(OperationContext* txn, if (status.isOK()) { // When the syncTail thread sees there is no new data by adding something to the buffer. _signalNoNewDataForApplier(); - // Wait until the buffer is emtpy. + // Wait until the buffer is empty. // This is an indication that syncTail has removed the sentinal marker from the buffer // and reset its local lastAppliedOpTime via the replCoord. while (!_buffer.empty()) { @@ -707,6 +707,15 @@ void BackgroundSync::_rollback(OperationContext* txn, return; } } + + // It is now safe to clear the ROLLBACK state, which may result in the applier thread + // transitioning to SECONDARY. This is safe because the applier thread has now reloaded + // the new rollback minValid from the database. + if (!_replCoord->setFollowerMode(MemberState::RS_RECOVERING)) { + warning() << "Failed to transition into " << MemberState(MemberState::RS_RECOVERING) + << "; expected to be in state " << MemberState(MemberState::RS_ROLLBACK) + << " but found self in " << _replCoord->getMemberState(); + } return; } if (ErrorCodes::UnrecoverableRollbackError == status.code()) { diff --git a/src/mongo/db/repl/rs_rollback.cpp b/src/mongo/db/repl/rs_rollback.cpp index 076507b4106..d52032cb6a4 100644 --- a/src/mongo/db/repl/rs_rollback.cpp +++ b/src/mongo/db/repl/rs_rollback.cpp @@ -879,24 +879,12 @@ Status _syncRollback(OperationContext* txn, } catch (...) { replCoord->incrementRollbackID(); - if (!replCoord->setFollowerMode(MemberState::RS_RECOVERING)) { - warning() << "Failed to transition into " << MemberState(MemberState::RS_RECOVERING) - << "; expected to be in state " << MemberState(MemberState::RS_ROLLBACK) - << " but found self in " << replCoord->getMemberState(); - } - throw; } replCoord->incrementRollbackID(); - // success - leave "ROLLBACK" state - // can go to SECONDARY once minvalid is achieved - if (!replCoord->setFollowerMode(MemberState::RS_RECOVERING)) { - warning() << "Failed to transition into " << MemberState(MemberState::RS_RECOVERING) - << "; expected to be in state " << MemberState(MemberState::RS_ROLLBACK) - << " but found self in " << replCoord->getMemberState(); - } - + // Success; leave "ROLLBACK" state intact until applier thread has reloaded the new minValid. + // Otherwise, the applier could transition the node to SECONDARY with an out-of-date minValid. return Status::OK(); } |