Skip to content

Commit fa1233f

Browse files
committed
SERVER-14041 enhance secondaryThrottle parameter
1 parent a78c439 commit fa1233f

35 files changed

+845
-228
lines changed

jstests/noPassthroughWithMongod/balance_repl.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
var otherOptions = { rs: true , numReplicas: 2 , chunksize: 1 , nopreallocj: true };
22
var s = new ShardingTest({ shards: 2, verbose: 1, other: otherOptions });
33
s.config.settings.update({ _id: "balancer" },
4-
{ $set: { stopped: true, _secondaryThrottle: true }}, true );
4+
{ $set: { stopped: true }}, true );
55

66
db = s.getDB( "test" );
77
var bulk = db.foo.initializeUnorderedBulkOp();
@@ -29,8 +29,12 @@ for ( i=0; i<20; i++ ) {
2929
// Needs to waitForDelete because we'll be performing a slaveOk query,
3030
// and secondaries don't have a chunk manager so it doesn't know how to
3131
// filter out docs it doesn't own.
32-
s.adminCommand({ moveChunk: "test.foo", find: { _id: i * 100 }, to : other._id,
33-
_secondaryThrottle: true, _waitForDelete: true });
32+
s.adminCommand({ moveChunk: "test.foo",
33+
find: { _id: i * 100 },
34+
to : other._id,
35+
_secondaryThrottle: true,
36+
writeConcern: { w: 2 },
37+
_waitForDelete: true });
3438
assert.eq( 2100, coll.find().itcount() );
3539
}
3640

jstests/noPassthroughWithMongod/sharding_rs2.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ assert.commandWorked(s.getDB('admin').runCommand({ moveChunk: "test.foo",
130130
find: { x: 10 },
131131
to: other._id,
132132
_secondaryThrottle: true,
133+
writeConcern: { w: 2 },
133134
_waitForDelete: true }));
134135
assert.eq( 100 , t.count() , "C3" )
135136

jstests/sharding/cleanup_orphaned_cmd.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ assert.eq( 100, coll.find().itcount() );
8282
jsTest.log( "Cleaning up more orphaned data..." );
8383

8484
var shard0Admin = st.shard0.getDB( "admin" );
85-
var result = shard0Admin.runCommand({ cleanupOrphaned : coll + "" });
85+
var result = shard0Admin.runCommand({ cleanupOrphaned : coll + "",
86+
secondaryThrottle: true,
87+
writeConcern: { w: 1 }});
8688
while ( result.ok && result.stoppedAtKey ) {
8789
printjson( result );
8890
result = shard0Admin.runCommand({ cleanupOrphaned : coll + "",

src/mongo/base/error_codes.err

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ error_code("NotSecondary", 95)
9898
error_code("OperationFailed", 96)
9999
error_code("NoProjectionFound", 97)
100100
error_code("DBPathInUse", 98)
101+
error_code("WriteConcernNotDefined", 99)
102+
error_code("CannotSatisfyWriteConcern", 100)
101103

102104
# Non-sequential error codes (for compatibility only)
103105
error_code("NotMaster", 10107) #this comes from assert_util.h

src/mongo/db/commands/cleanup_orphaned_cmd.cpp

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,22 @@
4141
#include "mongo/db/jsobj.h"
4242
#include "mongo/db/namespace_string.h"
4343
#include "mongo/db/range_deleter_service.h"
44+
#include "mongo/db/repl/repl_coordinator_global.h"
4445
#include "mongo/s/collection_metadata.h"
4546
#include "mongo/s/d_logic.h"
4647
#include "mongo/s/range_arithmetic.h"
48+
#include "mongo/s/type_settings.h"
4749
#include "mongo/util/log.h"
4850

51+
namespace {
52+
using mongo::WriteConcernOptions;
53+
54+
const int kDefaultWTimeoutMs = 60 * 1000;
55+
const WriteConcernOptions DefaultWriteConcern("majority",
56+
WriteConcernOptions::NONE,
57+
kDefaultWTimeoutMs);
58+
}
59+
4960
namespace mongo {
5061

5162
MONGO_LOG_DEFAULT_COMPONENT_FILE(::mongo::logger::LogComponent::kCommands);
@@ -69,7 +80,7 @@ namespace mongo {
6980
CleanupResult cleanupOrphanedData( OperationContext* txn,
7081
const NamespaceString& ns,
7182
const BSONObj& startingFromKeyConst,
72-
bool secondaryThrottle,
83+
const WriteConcernOptions& secondaryThrottle,
7384
BSONObj* stoppedAtKey,
7485
string* errMsg ) {
7586

@@ -153,6 +164,17 @@ namespace mongo {
153164
* the balancer is off.
154165
*
155166
* Safe to call with the balancer on.
167+
*
168+
* Format:
169+
*
170+
* {
171+
* cleanupOrphaned: <ns>,
172+
* // optional parameters:
173+
* startingAtKey: { <shardKeyValue> }, // defaults to lowest value
174+
* secondaryThrottle: <bool>, // defaults to true
175+
* // defaults to { w: "majority", wtimeout: 60000 }. Applies to individual writes.
176+
* writeConcern: { <writeConcern options> }
177+
* }
156178
*/
157179
class CleanupOrphanedCommand : public Command {
158180
public:
@@ -179,7 +201,6 @@ namespace mongo {
179201
// Input
180202
static BSONField<string> nsField;
181203
static BSONField<BSONObj> startingFromKeyField;
182-
static BSONField<bool> secondaryThrottleField;
183204

184205
// Output
185206
static BSONField<BSONObj> stoppedAtKeyField;
@@ -210,12 +231,29 @@ namespace mongo {
210231
return false;
211232
}
212233

213-
bool secondaryThrottle = true;
214-
if ( !FieldParser::extract( cmdObj,
215-
secondaryThrottleField,
216-
&secondaryThrottle,
217-
&errmsg ) ) {
218-
return false;
234+
WriteConcernOptions writeConcern;
235+
Status status = writeConcern.parseSecondaryThrottle(cmdObj, NULL);
236+
237+
if (!status.isOK()){
238+
if (status.code() != ErrorCodes::WriteConcernNotDefined) {
239+
return appendCommandStatus(result, status);
240+
}
241+
242+
writeConcern = DefaultWriteConcern;
243+
}
244+
else {
245+
repl::ReplicationCoordinator* replCoordinator =
246+
repl::getGlobalReplicationCoordinator();
247+
Status status = replCoordinator->checkIfWriteConcernCanBeSatisfied(writeConcern);
248+
if (!status.isOK()) {
249+
return appendCommandStatus(result, status);
250+
}
251+
}
252+
253+
if (writeConcern.shouldWaitForOtherNodes() &&
254+
writeConcern.wTimeout == WriteConcernOptions::kNoTimeout) {
255+
// Don't allow no timeout.
256+
writeConcern.wTimeout = kDefaultWTimeoutMs;
219257
}
220258

221259
if (!shardingState.enabled()) {
@@ -225,7 +263,7 @@ namespace mongo {
225263
}
226264

227265
ChunkVersion shardVersion;
228-
Status status = shardingState.refreshMetadataNow( ns, &shardVersion );
266+
status = shardingState.refreshMetadataNow( ns, &shardVersion );
229267
if ( !status.isOK() ) {
230268
if ( status.code() == ErrorCodes::RemoteChangeDetected ) {
231269
warning() << "Shard version in transition detected while refreshing "
@@ -242,7 +280,7 @@ namespace mongo {
242280
CleanupResult cleanupResult = cleanupOrphanedData( txn,
243281
NamespaceString( ns ),
244282
startingFromKey,
245-
secondaryThrottle,
283+
writeConcern,
246284
&stoppedAtKey,
247285
&errmsg );
248286

@@ -263,7 +301,6 @@ namespace mongo {
263301

264302
BSONField<string> CleanupOrphanedCommand::nsField( "cleanupOrphaned" );
265303
BSONField<BSONObj> CleanupOrphanedCommand::startingFromKeyField( "startingFromKey" );
266-
BSONField<bool> CleanupOrphanedCommand::secondaryThrottleField( "secondaryThrottle" );
267304
BSONField<BSONObj> CleanupOrphanedCommand::stoppedAtKeyField( "stoppedAtKey" );
268305

269306
MONGO_INITIALIZER(RegisterCleanupOrphanedCommand)(InitializerContext* context) {

src/mongo/db/dbhelpers.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include "mongo/db/repl/oplog.h"
5353
#include "mongo/db/repl/repl_coordinator_global.h"
5454
#include "mongo/db/write_concern.h"
55+
#include "mongo/db/write_concern_options.h"
5556
#include "mongo/db/operation_context_impl.h"
5657
#include "mongo/db/storage_options.h"
5758
#include "mongo/db/catalog/collection.h"
@@ -305,7 +306,7 @@ namespace mongo {
305306
long long Helpers::removeRange( OperationContext* txn,
306307
const KeyRange& range,
307308
bool maxInclusive,
308-
bool secondaryThrottle,
309+
const WriteConcernOptions& writeConcern,
309310
RemoveSaver* callback,
310311
bool fromMigrate,
311312
bool onlyRemoveOrphanedDocs )
@@ -342,7 +343,7 @@ namespace mongo {
342343
Helpers::toKeyFormat( indexKeyPattern.extendRangeBound(range.maxKey,maxInclusive));
343344

344345
LOG(1) << "begin removal of " << min << " to " << max << " in " << ns
345-
<< (secondaryThrottle ? " (waiting for secondaries)" : "" ) << endl;
346+
<< " with write concern: " << writeConcern.toBSON() << endl;
346347

347348
Client& c = cc();
348349

@@ -435,10 +436,7 @@ namespace mongo {
435436
// TODO remove once the yielding below that references this timer has been removed
436437
Timer secondaryThrottleTime;
437438

438-
if ( secondaryThrottle && numDeleted > 0 ) {
439-
WriteConcernOptions writeConcern;
440-
writeConcern.wNumNodes = 2;
441-
writeConcern.wTimeout = 60 * 1000;
439+
if (writeConcern.shouldWaitForOtherNodes() && numDeleted > 0) {
442440
repl::ReplicationCoordinator::StatusAndDuration replStatus =
443441
repl::getGlobalReplicationCoordinator()->awaitReplication(txn,
444442
c.getLastOp(),
@@ -454,7 +452,7 @@ namespace mongo {
454452
}
455453
}
456454

457-
if ( secondaryThrottle )
455+
if (writeConcern.shouldWaitForOtherNodes())
458456
log() << "Helpers::removeRangeUnlocked time spent waiting for replication: "
459457
<< millisWaitingForReplication << "ms" << endl;
460458

src/mongo/db/dbhelpers.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace mongo {
4141
class Collection;
4242
class Cursor;
4343
class OperationContext;
44+
struct WriteConcernOptions;
4445

4546
/**
4647
* db helpers are helper functions and classes that let us easily manipulate the local
@@ -164,8 +165,8 @@ namespace mongo {
164165
*/
165166
static long long removeRange( OperationContext* txn,
166167
const KeyRange& range,
167-
bool maxInclusive = false,
168-
bool secondaryThrottle = false,
168+
bool maxInclusive,
169+
const WriteConcernOptions& secondaryThrottle,
169170
RemoveSaver* callback = NULL,
170171
bool fromMigrate = false,
171172
bool onlyRemoveOrphanedDocs = false );

src/mongo/db/field_parser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ namespace mongo {
111111
{
112112
if (elem.eoo()) {
113113
if (field.hasDefault()) {
114-
*out = field.getDefault();
114+
*out = field.getDefault().getOwned();
115115
return FIELD_DEFAULT;
116116
}
117117
else {

src/mongo/db/range_deleter.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ namespace mongo {
189189
const BSONObj& min,
190190
const BSONObj& max,
191191
const BSONObj& shardKeyPattern,
192-
bool secondaryThrottle,
192+
const WriteConcernOptions& writeConcern,
193193
Notification* notifyDone,
194194
std::string* errMsg) {
195195
string dummy;
@@ -199,7 +199,7 @@ namespace mongo {
199199
min.getOwned(),
200200
max.getOwned(),
201201
shardKeyPattern.getOwned(),
202-
secondaryThrottle));
202+
writeConcern));
203203
toDelete->notifyDone = notifyDone;
204204

205205
{
@@ -243,10 +243,13 @@ namespace mongo {
243243
}
244244

245245
namespace {
246-
bool _waitForReplication(OperationContext* txn, std::string* errMsg) {
247-
WriteConcernOptions writeConcern;
248-
writeConcern.wMode = "majority";
249-
writeConcern.wTimeout = 60 * 60 * 1000;
246+
const int kWTimeoutMillis = 60 * 60 * 1000;
247+
248+
bool _waitForMajority(OperationContext* txn, std::string* errMsg) {
249+
const WriteConcernOptions writeConcern("majority",
250+
WriteConcernOptions::NONE,
251+
kWTimeoutMillis);
252+
250253
repl::ReplicationCoordinator::StatusAndDuration replStatus =
251254
repl::getGlobalReplicationCoordinator()->awaitReplicationOfLastOp(txn,
252255
writeConcern);
@@ -279,7 +282,7 @@ namespace {
279282
const BSONObj& min,
280283
const BSONObj& max,
281284
const BSONObj& shardKeyPattern,
282-
bool secondaryThrottle,
285+
const WriteConcernOptions& writeConcern,
283286
string* errMsg) {
284287
if (stopRequested()) {
285288
*errMsg = "deleter is already stopped.";
@@ -314,7 +317,7 @@ namespace {
314317
<< " cursors in " << ns << " to finish" << endl;
315318
}
316319

317-
RangeDeleteEntry taskDetails(ns, min, max, shardKeyPattern, secondaryThrottle);
320+
RangeDeleteEntry taskDetails(ns, min, max, shardKeyPattern, writeConcern);
318321
taskDetails.stats.queueStartTS = jsTime();
319322

320323
Date_t timeSinceLastLog;
@@ -373,7 +376,7 @@ namespace {
373376

374377
if (result) {
375378
taskDetails.stats.waitForReplStartTS = jsTime();
376-
result = _waitForReplication(txn, errMsg);
379+
result = _waitForMajority(txn, errMsg);
377380
taskDetails.stats.waitForReplEndTS = jsTime();
378381
}
379382

@@ -555,7 +558,7 @@ namespace {
555558
if (delResult) {
556559
nextTask->stats.waitForReplStartTS = jsTime();
557560

558-
if (!_waitForReplication(txn.get(), &errMsg)) {
561+
if (!_waitForMajority(txn.get(), &errMsg)) {
559562
warning() << "Error encountered while waiting for replication: " << errMsg;
560563
}
561564

@@ -662,12 +665,12 @@ namespace {
662665
const BSONObj& min,
663666
const BSONObj& max,
664667
const BSONObj& shardKey,
665-
bool secondaryThrottle):
668+
const WriteConcernOptions& writeConcern):
666669
ns(ns),
667670
min(min),
668671
max(max),
669672
shardKeyPattern(shardKey),
670-
secondaryThrottle(secondaryThrottle),
673+
writeConcern(writeConcern),
671674
notifyDone(NULL) {
672675
}
673676

src/mongo/db/range_deleter.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "mongo/db/clientcursor.h"
4040
#include "mongo/db/jsobj.h"
4141
#include "mongo/db/operation_context.h"
42+
#include "mongo/db/write_concern_options.h"
4243
#include "mongo/util/concurrency/mutex.h"
4344
#include "mongo/util/concurrency/synchronization.h"
4445
#include "mongo/util/time_support.h"
@@ -138,7 +139,7 @@ namespace mongo {
138139
const BSONObj& min,
139140
const BSONObj& max,
140141
const BSONObj& shardKeyPattern,
141-
bool secondaryThrottle,
142+
const WriteConcernOptions& writeConcern,
142143
Notification* notifyDone,
143144
std::string* errMsg);
144145

@@ -154,7 +155,7 @@ namespace mongo {
154155
const BSONObj& min,
155156
const BSONObj& max,
156157
const BSONObj& shardKeyPattern,
157-
bool secondaryThrottle,
158+
const WriteConcernOptions& writeConcern,
158159
std::string* errMsg);
159160

160161
/**
@@ -309,7 +310,7 @@ namespace mongo {
309310
const BSONObj& min,
310311
const BSONObj& max,
311312
const BSONObj& shardKey,
312-
bool secondaryThrottle);
313+
const WriteConcernOptions& writeConcern);
313314

314315
const std::string ns;
315316

@@ -324,7 +325,7 @@ namespace mongo {
324325
// like hash indexes.
325326
const BSONObj shardKeyPattern;
326327

327-
const bool secondaryThrottle;
328+
const WriteConcernOptions writeConcern;
328329

329330
// Sets of cursors to wait to close until this can be ready
330331
// for deletion.

0 commit comments

Comments
 (0)