Skip to content

Commit 30f39cc

Browse files
alextaskovevergreen
authored andcommitted
SERVER-42473 Create concurrency workload to validate current cleanupOrphaned command and range deleter
1 parent 7277c7c commit 30f39cc

9 files changed

+147
-1
lines changed

buildscripts/resmokeconfig/suites/concurrency_sharded_causal_consistency.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ selector:
110110

111111
exclude_with_any_tags:
112112
- does_not_support_causal_consistency
113+
- assumes_balancer_on
113114
# This suite uses secondary read preference, which isn't currently compatible with transactions.
114115
- uses_transactions
115116
- requires_replication

buildscripts/resmokeconfig/suites/concurrency_sharded_local_read_write_multi_stmt_txn.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ selector:
154154
exclude_with_any_tags:
155155
- does_not_support_causal_consistency
156156
- requires_replication
157+
- assumes_balancer_on
157158
# The touch command does not exist on mongos, which is enforced before session information is
158159
# parsed, causing state functions in these workloads to fail before starting a transaction despite
159160
# sending a command with startTransaction=true, leading to an infinite loop in the auto

buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ selector:
154154
exclude_with_any_tags:
155155
- does_not_support_causal_consistency
156156
- requires_replication
157+
- assumes_balancer_on
157158
# The touch command does not exist on mongos, which is enforced before session information is
158159
# parsed, causing state functions in these workloads to fail before starting a transaction despite
159160
# sending a command with startTransaction=true, leading to an infinite loop in the auto

buildscripts/resmokeconfig/suites/concurrency_sharded_multi_stmt_txn_with_stepdowns.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ selector:
219219
exclude_with_any_tags:
220220
- does_not_support_causal_consistency
221221
- requires_replication
222+
- assumes_balancer_on
222223
# The touch command does not exist on mongos, which is enforced before session information is
223224
# parsed, causing state functions in these workloads to fail before starting a transaction despite
224225
# sending a command with startTransaction=true, leading to an infinite loop in the auto

buildscripts/resmokeconfig/suites/concurrency_sharded_replication.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ selector:
118118

119119
exclude_with_any_tags:
120120
- requires_replication
121+
- assumes_balancer_on
121122

122123
executor:
123124
archive:

buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ selector:
183183
exclude_with_any_tags:
184184
- requires_replication
185185
- requires_non_retryable_writes
186+
- assumes_balancer_on
186187
# Curop requires readConcern local.
187188
- uses_curop_agg_stage
188189

jstests/concurrency/fsm_libs/cluster.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,22 @@ var Cluster = function(options) {
231231
replSets.push(rs);
232232
}
233233

234+
if (options.sharded.enableBalancer === true) {
235+
st._configServers.forEach((conn) => {
236+
const configDb = conn.getDB('admin');
237+
238+
configDb.adminCommand({
239+
configureFailPoint: 'balancerShouldReturnRandomMigrations',
240+
mode: 'alwaysOn'
241+
});
242+
configDb.adminCommand({
243+
configureFailPoint: 'overrideBalanceRoundInterval',
244+
mode: 'alwaysOn',
245+
data: {intervalMs: 100}
246+
});
247+
});
248+
}
249+
234250
} else if (options.replication.enabled) {
235251
rst = new ReplSetTest(db.getMongo().host);
236252

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
'use strict';
2+
3+
/**
4+
* Performs range deletions while chunks are being moved.
5+
*
6+
* @tags: [requires_sharding, assumes_balancer_on]
7+
*/
8+
9+
load('jstests/concurrency/fsm_libs/extend_workload.js');
10+
load('jstests/concurrency/fsm_workloads/sharded_base_partitioned.js');
11+
12+
var $config = extendWorkload($config, function($config, $super) {
13+
$config.threadCount = 5;
14+
$config.iterations = 50;
15+
16+
$config.data.shardKey = {skey: 1};
17+
$config.data.shardKeyField = 'skey';
18+
19+
const numChunks = 50;
20+
const numDocs = 100;
21+
22+
// Total count of documents when initialized.
23+
$config.data.initialCount = numChunks * numDocs;
24+
25+
function executeCommandWithRetries(fn, sleepInterval, retries, name) {
26+
let result = null;
27+
let done = false;
28+
29+
while (retries > 0 && !done) {
30+
result = fn();
31+
32+
if (result.ok) {
33+
print("command succeeded: " + name);
34+
done = true;
35+
} else {
36+
print("command failed: " + name);
37+
printjson(result);
38+
sleep(sleepInterval);
39+
}
40+
}
41+
42+
return result;
43+
}
44+
45+
// Run cleanupOrphaned on a random shard's primary node.
46+
$config.states.cleanupOrphans = function(db, collName, connCache) {
47+
const ns = db[collName].getFullName();
48+
49+
// Get index of random shard.
50+
const shardNames = Object.keys(connCache.shards);
51+
const randomIndex = Math.floor(Math.random() * shardNames.length);
52+
53+
const shard = connCache.shards[shardNames[randomIndex]];
54+
const shardPrimary = ChunkHelper.getPrimary(shard);
55+
56+
let nextKey = {};
57+
let result = null;
58+
59+
let iteration = 0;
60+
while (nextKey != null) {
61+
result = executeCommandWithRetries(() => {
62+
return shardPrimary.adminCommand(
63+
{cleanupOrphaned: ns, startingFromKey: nextKey, secondaryThrottle: true});
64+
}, 100, 1000, "cleanupOrphaned");
65+
66+
nextKey = result.stoppedAtKey;
67+
iteration++;
68+
}
69+
70+
assert(result.ok);
71+
};
72+
73+
// Verify that counts are stable.
74+
$config.states.validate = function(db, collName, connCache) {
75+
const ns = db[collName].getFullName();
76+
77+
// Get total count from mongos. Need to specify batch count that is larger than the total
78+
// number of records to prevent getmore command from being issued since stepdown suites
79+
// ban it.
80+
const mongos = ChunkHelper.getRandomMongos(connCache.mongos);
81+
const coll = mongos.getCollection(ns);
82+
const totalCount = coll.find({}).batchSize($config.data.initialCount + numDocs).itcount();
83+
84+
// Verify that sum equals original total.
85+
assert(this.initialCount === totalCount,
86+
"Document count doesn't match initial count: " + this.initialCount +
87+
" != " + totalCount);
88+
};
89+
90+
$config.states.init = function init(db, collName, connCache) {};
91+
92+
$config.setup = function setup(db, collName, cluster) {
93+
const ns = db[collName].getFullName();
94+
95+
for (let chunkIndex = 0; chunkIndex < numChunks; chunkIndex++) {
96+
let bulk = db[collName].initializeUnorderedBulkOp();
97+
98+
const splitKey = chunkIndex * numDocs;
99+
print("splitting at: " + splitKey);
100+
101+
for (let docIndex = splitKey - numDocs; docIndex < splitKey; docIndex++) {
102+
bulk.insert({_id: docIndex, skey: docIndex});
103+
}
104+
105+
assertAlways.commandWorked(bulk.execute());
106+
107+
if (chunkIndex > 0) {
108+
// Need to retry split command to avoid conflicting with moveChunks issued by the
109+
// balancer.
110+
let result = executeCommandWithRetries(() => {
111+
return db.adminCommand({split: ns, middle: {skey: splitKey}});
112+
}, 100, 10, "split");
113+
assertAlways.commandWorked(result);
114+
}
115+
}
116+
};
117+
118+
$config.transitions = {
119+
init: {cleanupOrphans: 1},
120+
cleanupOrphans: {cleanupOrphans: 0.5, validate: 0.5},
121+
validate: {cleanupOrphans: 1}
122+
};
123+
124+
return $config;
125+
});

jstests/libs/override_methods/network_error_and_txn_override.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ const kNonRetryableCommands = new Set([
8585
"appendOplogNote",
8686
"applyOps",
8787
"captrunc",
88-
"cleanupOrphaned",
8988
"clone",
9089
"cloneCollectionAsCapped",
9190
"collMod",

0 commit comments

Comments
 (0)