diff options
author | Spencer T Brody <spencer@mongodb.com> | 2017-10-05 18:57:19 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2017-10-16 18:05:08 -0400 |
commit | ae9262c5c48b378216f276ca150204dff63f04b4 (patch) | |
tree | 5ed77d9babd0ab4be195db05013c232012178f9c /src/mongo/db/repl | |
parent | d8279111b61afac242ddbb9f6d9697bbd14ed9d4 (diff) | |
download | mongo-ae9262c5c48b378216f276ca150204dff63f04b4.tar.gz |
SERVER-31431 Ensure that all state transitions in or out of SECONDARY occur with the global X lock held
Diffstat (limited to 'src/mongo/db/repl')
-rw-r--r-- | src/mongo/db/repl/bgsync.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/repl/resync.cpp | 39 | ||||
-rw-r--r-- | src/mongo/db/repl/sync_tail.cpp | 4 |
3 files changed, 28 insertions, 19 deletions
diff --git a/src/mongo/db/repl/bgsync.cpp b/src/mongo/db/repl/bgsync.cpp index 1ae84415b4a..f2c369ea0bd 100644 --- a/src/mongo/db/repl/bgsync.cpp +++ b/src/mongo/db/repl/bgsync.cpp @@ -364,6 +364,10 @@ void BackgroundSync::_produce() { // Mark yourself as too stale. _tooStale = true; + // Need to take global X lock to transition out of SECONDARY. + auto opCtx = cc().makeOperationContext(); + Lock::GlobalWrite globalWriteLock(opCtx.get()); + error() << "too stale to catch up -- entering maintenance mode"; log() << "Our newest OpTime : " << lastOpTimeFetched; log() << "Earliest OpTime available is " << syncSourceResp.earliestOpTimeSeen; diff --git a/src/mongo/db/repl/resync.cpp b/src/mongo/db/repl/resync.cpp index c18c26bfd46..a1e60050652 100644 --- a/src/mongo/db/repl/resync.cpp +++ b/src/mongo/db/repl/resync.cpp @@ -90,23 +90,28 @@ public: "Replica sets do not support the resync command")); } - const MemberState memberState = replCoord->getMemberState(); - if (memberState.startup()) { - return appendCommandStatus( - result, Status(ErrorCodes::NotYetInitialized, "no replication yet active")); - } - if (memberState.primary()) { - return appendCommandStatus( - result, Status(ErrorCodes::NotSecondary, "primaries cannot resync")); - } - auto status = replCoord->setFollowerMode(MemberState::RS_STARTUP2); - if (!status.isOK()) { - return appendCommandStatus( - result, - Status(status.code(), - str::stream() - << "Failed to transition to STARTUP2 state to perform resync: " - << status.reason())); + { + // Need global write lock to transition out of SECONDARY + Lock::GlobalWrite globalWriteLock(opCtx); + + const MemberState memberState = replCoord->getMemberState(); + if (memberState.startup()) { + return appendCommandStatus( + result, Status(ErrorCodes::NotYetInitialized, "no replication yet active")); + } + if (memberState.primary()) { + return appendCommandStatus( + result, Status(ErrorCodes::NotSecondary, "primaries cannot resync")); + } + auto status = replCoord->setFollowerMode(MemberState::RS_STARTUP2); + if (!status.isOK()) { + return appendCommandStatus( + result, + Status(status.code(), + str::stream() + << "Failed to transition to STARTUP2 state to perform resync: " + << status.reason())); + } } uassertStatusOKWithLocation(replCoord->resyncData(opCtx, waitForResync), "resync", 0); return true; diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp index 15e6fabb856..15185abaf73 100644 --- a/src/mongo/db/repl/sync_tail.cpp +++ b/src/mongo/db/repl/sync_tail.cpp @@ -691,8 +691,8 @@ void tryToGoLiveAsASecondary(OperationContext* opCtx, ReplicationCoordinator* re // This needs to happen after the attempt so readers can be sure we've already tried. ON_BLOCK_EXIT([] { attemptsToBecomeSecondary.increment(); }); - // TODO(SERVER-27892): Change to GlobalWrite - Lock::GlobalRead readLock(opCtx); + // Need global X lock to transition to SECONDARY + Lock::GlobalWrite readLock(opCtx); if (replCoord->getMaintenanceMode()) { LOG(1) << "Can't go live (tryToGoLiveAsASecondary) as maintenance mode is active."; |