mirror of https://github.com/mongodb/mongo
161 lines
6.5 KiB
JavaScript
161 lines
6.5 KiB
JavaScript
/**
|
|
* Tests readConcern level snapshot outside of transactions.
|
|
*
|
|
* @tags: [
|
|
* requires_majority_read_concern,
|
|
* requires_persistence,
|
|
* ]
|
|
*/
|
|
|
|
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
|
|
import {SnapshotReadsTest} from "jstests/libs/global_snapshot_reads_util.js";
|
|
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
|
import {findChunksUtil} from "jstests/sharding/libs/find_chunks_util.js";
|
|
import {flushRoutersAndRefreshShardMetadata} from "jstests/sharding/libs/sharded_transactions_helpers.js";
|
|
|
|
const nodeOptions = {
|
|
// Set a large snapshot window of 10 minutes for the test.
|
|
setParameter: {minSnapshotHistoryWindowInSeconds: 600},
|
|
};
|
|
|
|
const dbName = "test";
|
|
const shardedCollName = "shardedColl";
|
|
const unshardedCollName = "unshardedColl";
|
|
|
|
function setUpAllScenarios(st) {
|
|
assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
|
|
assert.commandWorked(st.s.adminCommand({shardCollection: st.s.getDB(dbName)[shardedCollName] + "", key: {_id: 1}}));
|
|
}
|
|
|
|
let shardingScenarios = {
|
|
singleShard: {
|
|
compatibleCollections: [shardedCollName, unshardedCollName],
|
|
setUp: function () {
|
|
const st = new ShardingTest({
|
|
mongos: 1,
|
|
config: TestData.configShard ? undefined : 1,
|
|
shards: {rs0: {nodes: 2}},
|
|
other: {configOptions: nodeOptions, rsOptions: nodeOptions},
|
|
});
|
|
setUpAllScenarios(st);
|
|
return st;
|
|
},
|
|
},
|
|
multiShardAllShardReads: {
|
|
compatibleCollections: [shardedCollName],
|
|
setUp: function () {
|
|
let st = new ShardingTest({
|
|
shards: {
|
|
rs0: {nodes: 2},
|
|
rs1: {nodes: 2},
|
|
rs2: {nodes: 2},
|
|
},
|
|
mongos: 1,
|
|
config: TestData.configShard ? undefined : 1,
|
|
other: {configOptions: nodeOptions, rsOptions: nodeOptions},
|
|
});
|
|
setUpAllScenarios(st);
|
|
const mongos = st.s0;
|
|
const ns = dbName + "." + shardedCollName;
|
|
|
|
// snapshotReadsTest() inserts ids 0-9 and tries snapshot reads on the collection.
|
|
assert.commandWorked(st.splitAt(ns, {_id: 4}));
|
|
assert.commandWorked(st.splitAt(ns, {_id: 7}));
|
|
|
|
assert.commandWorked(mongos.adminCommand({moveChunk: ns, find: {_id: 0}, to: st.shard0.shardName}));
|
|
assert.commandWorked(mongos.adminCommand({moveChunk: ns, find: {_id: 4}, to: st.shard1.shardName}));
|
|
assert.commandWorked(mongos.adminCommand({moveChunk: ns, find: {_id: 7}, to: st.shard2.shardName}));
|
|
|
|
assert.eq(1, findChunksUtil.countChunksForNs(mongos.getDB("config"), ns, {shard: st.shard0.shardName}));
|
|
assert.eq(1, findChunksUtil.countChunksForNs(mongos.getDB("config"), ns, {shard: st.shard1.shardName}));
|
|
assert.eq(1, findChunksUtil.countChunksForNs(mongos.getDB("config"), ns, {shard: st.shard2.shardName}));
|
|
|
|
flushRoutersAndRefreshShardMetadata(st, {ns});
|
|
|
|
return st;
|
|
},
|
|
},
|
|
// Only two out of three shards have documents.
|
|
multiShardSomeShardReads: {
|
|
compatibleCollections: [shardedCollName],
|
|
setUp: function () {
|
|
let st = new ShardingTest({
|
|
shards: {
|
|
rs0: {nodes: 2},
|
|
rs1: {nodes: 2},
|
|
rs2: {nodes: 2},
|
|
},
|
|
mongos: 1,
|
|
config: TestData.configShard ? undefined : 1,
|
|
other: {configOptions: nodeOptions, rsOptions: nodeOptions},
|
|
});
|
|
setUpAllScenarios(st);
|
|
const mongos = st.s0;
|
|
const ns = dbName + "." + shardedCollName;
|
|
|
|
// snapshotReadsTest() inserts ids 0-9 and tries snapshot reads on the collection.
|
|
assert.commandWorked(st.splitAt(ns, {_id: 5}));
|
|
assert.commandWorked(mongos.adminCommand({moveChunk: ns, find: {_id: 0}, to: st.shard1.shardName}));
|
|
assert.commandWorked(mongos.adminCommand({moveChunk: ns, find: {_id: 7}, to: st.shard2.shardName}));
|
|
|
|
assert.eq(0, findChunksUtil.countChunksForNs(mongos.getDB("config"), ns, {shard: st.shard0.shardName}));
|
|
assert.eq(1, findChunksUtil.countChunksForNs(mongos.getDB("config"), ns, {shard: st.shard1.shardName}));
|
|
assert.eq(1, findChunksUtil.countChunksForNs(mongos.getDB("config"), ns, {shard: st.shard2.shardName}));
|
|
|
|
flushRoutersAndRefreshShardMetadata(st, {ns});
|
|
|
|
return st;
|
|
},
|
|
},
|
|
};
|
|
|
|
for (let [scenarioName, scenario] of Object.entries(shardingScenarios)) {
|
|
scenario.compatibleCollections.forEach(function (collName) {
|
|
jsTestLog(`Run scenario ${scenarioName} with collection ${collName}`);
|
|
let st = scenario.setUp();
|
|
let primaryAdmin = st.rs0.getPrimary().getDB("admin");
|
|
assert.eq(
|
|
assert.commandWorked(primaryAdmin.runCommand({getParameter: 1, minSnapshotHistoryWindowInSeconds: 1}))
|
|
.minSnapshotHistoryWindowInSeconds,
|
|
600,
|
|
);
|
|
|
|
function awaitCommittedFn() {
|
|
for (let i = 0; st["rs" + i] !== undefined; i++) {
|
|
st["rs" + i].awaitLastOpCommitted();
|
|
}
|
|
}
|
|
|
|
if (collName == unshardedCollName) {
|
|
// Skip testing with untracked unsharded collections because reads at a point-in-time
|
|
// earlier than the latest catalog change (including index DDL) will throw conflicts.
|
|
jsTestLog("Skip unsharded collection scenario");
|
|
st.stop();
|
|
return;
|
|
}
|
|
|
|
// Pass the same DB handle as "primaryDB" and "secondaryDB" params; the test functions will
|
|
// send readPreference to mongos to target primary/secondary shard servers.
|
|
let db = st.s.getDB(dbName);
|
|
let snapshotReadsTest = new SnapshotReadsTest({
|
|
primaryDB: db,
|
|
secondaryDB: db,
|
|
awaitCommittedFn: awaitCommittedFn,
|
|
});
|
|
|
|
snapshotReadsTest.cursorTest({testScenarioName: scenarioName, collName: collName});
|
|
|
|
if (collName === shardedCollName) {
|
|
// "distinct" prohibited on sharded collections.
|
|
assert.commandFailedWithCode(
|
|
db.runCommand({distinct: collName, key: "_id", readConcern: {level: "snapshot"}}),
|
|
ErrorCodes.InvalidOptions,
|
|
);
|
|
} else {
|
|
snapshotReadsTest.distinctTest({testScenarioName: scenarioName, collName: collName});
|
|
}
|
|
|
|
st.stop();
|
|
});
|
|
}
|