diff --git a/db/instance.cpp b/db/instance.cpp index f1022f0d606..42086adf212 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -443,7 +443,6 @@ namespace mongo { DbMessage d(m); const char *ns = d.getns(); assert(*ns); - uassert( 10054 , "not master", isMasterNs( ns ) ); op.debug().str << ns << ' '; int flags = d.pullInt(); BSONObj query = d.nextJsObj(); @@ -469,6 +468,9 @@ namespace mongo { writelock lk; + // writelock is used to synchronize stepdowns w/ writes + uassert( 10054 , "not master", isMasterNs( ns ) ); + // if this ever moves to outside of lock, need to adjust check Client::Context::_finishInit if ( ! broadcast && handlePossibleShardedMessage( m , 0 ) ) return; @@ -483,7 +485,6 @@ namespace mongo { DbMessage d(m); const char *ns = d.getns(); assert(*ns); - uassert( 10056 , "not master", isMasterNs( ns ) ); op.debug().str << ns << ' '; int flags = d.pullInt(); bool justOne = flags & RemoveOption_JustOne; @@ -497,6 +498,10 @@ namespace mongo { } writelock lk(ns); + + // writelock is used to synchronize stepdowns w/ writes + uassert( 10056 , "not master", isMasterNs( ns ) ); + // if this ever moves to outside of lock, need to adjust check Client::Context::_finishInit if ( ! broadcast & handlePossibleShardedMessage( m , 0 ) ) return; @@ -580,11 +585,13 @@ namespace mongo { DbMessage d(m); const char *ns = d.getns(); assert(*ns); - uassert( 10058 , "not master", isMasterNs( ns ) ); op.debug().str << ns; writelock lk(ns); + // writelock is used to synchronize stepdowns w/ writes + uassert( 10058 , "not master", isMasterNs( ns ) ); + if ( handlePossibleShardedMessage( m , 0 ) ) return; diff --git a/db/repl/rs.cpp b/db/repl/rs.cpp index a73e1207dd5..dafed9225d9 100644 --- a/db/repl/rs.cpp +++ b/db/repl/rs.cpp @@ -93,9 +93,13 @@ namespace mongo { void ReplSetImpl::relinquish() { if( box.getState().primary() ) { - log() << "replSet relinquishing primary state" << rsLog; - changeState(MemberState::RS_SECONDARY); - + { + writelock lk("admin."); // so we are synchronized with _logOp() + + log() << "replSet relinquishing primary state" << rsLog; + changeState(MemberState::RS_SECONDARY); + } + if( closeOnRelinquish ) { /* close sockets that were talking to us so they don't blithly send many writes that will fail with "not master" (of course client could check result code, but in case they are not)