diff options
author | Greg Studer <greg@10gen.com> | 2013-05-14 13:49:03 -0400 |
---|---|---|
committer | Dan Pasette <dan@10gen.com> | 2013-05-19 09:07:08 -0700 |
commit | 90bca9c3ad719d3070fe1c94dc3a716aff63bb3c (patch) | |
tree | d5fd257a4e76d74f4d6caf7660a786acd6dc3beb | |
parent | ae626614e5ee0de1724fbeaf07c862d6e566d745 (diff) | |
download | mongo-90bca9c3ad719d3070fe1c94dc3a716aff63bb3c.tar.gz |
SERVER-8741 make sure we contact from-shard at least once after commit
-rw-r--r-- | src/mongo/s/d_migrate.cpp | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp index c633eceaa36..84a7f3961b3 100644 --- a/src/mongo/s/d_migrate.cpp +++ b/src/mongo/s/d_migrate.cpp @@ -1627,7 +1627,15 @@ namespace mongo { // 5. wait for commit state = STEADY; + bool transferAfterCommit = false; while ( state == STEADY || state == COMMIT_START ) { + + // Make sure we do at least one transfer after recv'ing the commit message + // If we aren't sure that at least one transfer happens *after* our state + // changes to COMMIT_START, there could be mods still on the FROM shard that + // got logged *after* our _transferMods but *before* the critical section. + if ( state == COMMIT_START ) transferAfterCommit = true; + BSONObj res; if ( ! conn->runCommand( "admin" , BSON( "_transferMods" << 1 ) , res ) ) { log() << "_transferMods failed in STEADY state: " << res << migrateLog; @@ -1645,12 +1653,16 @@ namespace mongo { return; } - if ( state == COMMIT_START ) { + // We know we're finished when: + // 1) The from side has told us that it has locked writes (COMMIT_START) + // 2) We've checked at least one more time for un-transmitted mods + if ( state == COMMIT_START && transferAfterCommit == true ) { if ( flushPendingWrites( lastOpApplied ) ) break; } - sleepmillis( 10 ); + // Only sleep if we aren't committing + if ( state == STEADY ) sleepmillis( 10 ); } if ( state == FAIL ) { |