summaryrefslogtreecommitdiff
path: root/src/mongo/s
diff options
context:
space:
mode:
authorRandolph Tan <randolph@10gen.com>2014-10-10 14:11:52 -0400
committerRandolph Tan <randolph@10gen.com>2014-10-15 11:55:42 -0400
commit658f0bce4379fc0334a53c4381d57b8b7c7d53b7 (patch)
tree57b9bf3f7d1aa4be39856b0214599c6e0a967bfb /src/mongo/s
parent3d7564c44a2117c72b9c6830c5a14ab467f8ffa3 (diff)
downloadmongo-658f0bce4379fc0334a53c4381d57b8b7c7d53b7.tar.gz
SERVER-15591 enforce secondaryThrottle during moveChunk commit
Diffstat (limited to 'src/mongo/s')
-rw-r--r--src/mongo/s/d_migrate.cpp75
1 files changed, 58 insertions, 17 deletions
diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp
index 70224df5ec4..eae740f2c79 100644
--- a/src/mongo/s/d_migrate.cpp
+++ b/src/mongo/s/d_migrate.cpp
@@ -105,11 +105,15 @@ namespace {
WriteConcernOptions getDefaultWriteConcern() {
ReplicationCoordinator* replCoordinator =
mongo::repl::getGlobalReplicationCoordinator();
- mongo::Status status =
+
+ if (replCoordinator->getReplicationMode() ==
+ mongo::repl::ReplicationCoordinator::modeReplSet) {
+ mongo::Status status =
replCoordinator->checkIfWriteConcernCanBeSatisfied(DefaultWriteConcern);
- if (status.isOK()) {
- return DefaultWriteConcern;
+ if (status.isOK()) {
+ return DefaultWriteConcern;
+ }
}
return WriteConcernOptions(1, WriteConcernOptions::NONE, 0);
@@ -879,6 +883,15 @@ namespace mongo {
else {
repl::ReplicationCoordinator* replCoordinator =
repl::getGlobalReplicationCoordinator();
+
+ if (replCoordinator->getReplicationMode() ==
+ repl::ReplicationCoordinator::modeMasterSlave &&
+ writeConcern.shouldWaitForOtherNodes()) {
+ warning() << "moveChunk cannot check if secondary throttle setting "
+ << writeConcern.toBSON()
+ << " can be enforced in a master slave configuration";
+ }
+
Status status = replCoordinator->checkIfWriteConcernCanBeSatisfied(writeConcern);
if (!status.isOK() && status != ErrorCodes::NoReplicationEnabled) {
warning() << status.toString() << endl;
@@ -1962,7 +1975,7 @@ namespace mongo {
return;
}
- if (opReplicatedEnough(txn, lastOpApplied))
+ if (opReplicatedEnough(txn, lastOpApplied, writeConcern))
break;
if ( i > 100 ) {
@@ -2000,7 +2013,7 @@ namespace mongo {
log() << "Waiting for replication to catch up before entering critical section"
<< endl;
- if ( flushPendingWrites(txn, lastOpApplied ) )
+ if (flushPendingWrites(txn, lastOpApplied, writeConcern))
break;
sleepsecs(1);
}
@@ -2047,7 +2060,7 @@ namespace mongo {
// 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 ( getState() == COMMIT_START && transferAfterCommit == true ) {
- if ( flushPendingWrites(txn, lastOpApplied ) )
+ if (flushPendingWrites(txn, lastOpApplied, writeConcern))
break;
}
@@ -2190,19 +2203,38 @@ namespace mongo {
return false;
}
- bool opReplicatedEnough(const OperationContext* txn, const ReplTime& lastOpApplied) {
- // if replication is on, try to force enough secondaries to catch up
- // TODO opReplicatedEnough should eventually honor priorities and geo-awareness
- // for now, we try to replicate to a sensible number of secondaries
- WriteConcernOptions writeConcern;
- writeConcern.wTimeout = -1;
- writeConcern.wMode = "majority";
- return repl::getGlobalReplicationCoordinator()->awaitReplication(txn, lastOpApplied,
- writeConcern).status.isOK();
+ /**
+ * Returns true if the majority of the nodes and the nodes corresponding to the given
+ * writeConcern (if not empty) have applied till the specified lastOp.
+ */
+ bool opReplicatedEnough(const OperationContext* txn,
+ const ReplTime& lastOpApplied,
+ const WriteConcernOptions& writeConcern) {
+ WriteConcernOptions majorityWriteConcern;
+ majorityWriteConcern.wTimeout = -1;
+ majorityWriteConcern.wMode = "majority";
+ Status majorityStatus = repl::getGlobalReplicationCoordinator()->awaitReplication(
+ txn, lastOpApplied, majorityWriteConcern).status;
+
+ if (!writeConcern.shouldWaitForOtherNodes()) {
+ return majorityStatus.isOK();
+ }
+
+ // Also enforce the user specified write concern after "majority" so it covers
+ // the union of the 2 write concerns.
+
+ WriteConcernOptions userWriteConcern(writeConcern);
+ userWriteConcern.wTimeout = -1;
+ Status userStatus = repl::getGlobalReplicationCoordinator()->awaitReplication(
+ txn, lastOpApplied, userWriteConcern).status;
+
+ return majorityStatus.isOK() && userStatus.isOK();
}
- bool flushPendingWrites(OperationContext* txn, const ReplTime& lastOpApplied ) {
- if (!opReplicatedEnough(txn, lastOpApplied)) {
+ bool flushPendingWrites(OperationContext* txn,
+ const ReplTime& lastOpApplied,
+ const WriteConcernOptions& writeConcern) {
+ if (!opReplicatedEnough(txn, lastOpApplied, writeConcern)) {
OpTime op( lastOpApplied );
OCCASIONALLY warning() << "migrate commit waiting for a majority of slaves for '"
<< ns << "' " << min << " -> " << max
@@ -2438,6 +2470,15 @@ namespace mongo {
else {
repl::ReplicationCoordinator* replCoordinator =
repl::getGlobalReplicationCoordinator();
+
+ if (replCoordinator->getReplicationMode() ==
+ repl::ReplicationCoordinator::modeMasterSlave &&
+ writeConcern.shouldWaitForOtherNodes()) {
+ warning() << "recvChunk cannot check if secondary throttle setting "
+ << writeConcern.toBSON()
+ << " can be enforced in a master slave configuration";
+ }
+
Status status = replCoordinator->checkIfWriteConcernCanBeSatisfied(writeConcern);
if (!status.isOK() && status != ErrorCodes::NoReplicationEnabled) {
warning() << status.toString() << endl;