summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Studer <greg@10gen.com>2013-05-14 13:49:03 -0400
committerDan Pasette <dan@10gen.com>2013-05-19 09:07:08 -0700
commit90bca9c3ad719d3070fe1c94dc3a716aff63bb3c (patch)
treed5fd257a4e76d74f4d6caf7660a786acd6dc3beb
parentae626614e5ee0de1724fbeaf07c862d6e566d745 (diff)
downloadmongo-90bca9c3ad719d3070fe1c94dc3a716aff63bb3c.tar.gz
SERVER-8741 make sure we contact from-shard at least once after commit
-rw-r--r--src/mongo/s/d_migrate.cpp16
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 ) {