mirror of https://github.com/mongodb/mongo
158 lines
5.3 KiB
JavaScript
158 lines
5.3 KiB
JavaScript
/**
|
|
* Tests that session information are properly transferred to the destination shard while
|
|
* new writes are being sent to the source shard.
|
|
*/
|
|
|
|
/**
|
|
* Test outline:
|
|
* 1. Pause migration.
|
|
* 2. Perform writes and allow it to be capture via OpObserver
|
|
* 3. Unpause migration.
|
|
* 4. Retry writes and confirm that writes are not duplicated.
|
|
*/
|
|
|
|
import {
|
|
moveChunkParallel,
|
|
moveChunkStepNames,
|
|
pauseMoveChunkAtStep,
|
|
unpauseMoveChunkAtStep,
|
|
waitForMoveChunkStep,
|
|
} from "jstests/libs/chunk_manipulation_util.js";
|
|
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
|
|
|
let staticMongod = MongoRunner.runMongod({}); // For startParallelOps.
|
|
|
|
let st = new ShardingTest({shards: {rs0: {nodes: 1}, rs1: {nodes: 1}}});
|
|
st.adminCommand({enableSharding: "test", primaryShard: st.shard0.shardName});
|
|
st.adminCommand({shardCollection: "test.user", key: {x: 1}});
|
|
assert.commandWorked(st.s.adminCommand({split: "test.user", middle: {x: 0}}));
|
|
|
|
pauseMoveChunkAtStep(st.shard0, moveChunkStepNames.reachedSteadyState);
|
|
let joinMoveChunk = moveChunkParallel(staticMongod, st.s.host, {x: 0}, null, "test.user", st.shard1.shardName);
|
|
|
|
waitForMoveChunkStep(st.shard0, moveChunkStepNames.reachedSteadyState);
|
|
|
|
const insertCmd = {
|
|
insert: "user",
|
|
documents: [
|
|
// For findAndModify not touching chunk being migrated.
|
|
{x: -30},
|
|
// For changing doc to become owned by chunk being migrated.
|
|
{x: -20},
|
|
{x: -20},
|
|
// For basic insert.
|
|
{x: 10},
|
|
// For changing doc to become owned by another chunk not being migrated.
|
|
{x: 20},
|
|
{x: 20},
|
|
// For basic findAndModify.
|
|
{x: 30},
|
|
],
|
|
ordered: false,
|
|
lsid: {id: UUID()},
|
|
txnNumber: NumberLong(34),
|
|
};
|
|
|
|
let testDB = st.getDB("test");
|
|
const insertResult = assert.commandWorked(testDB.runCommand(insertCmd));
|
|
|
|
const findAndModCmd = {
|
|
findAndModify: "user",
|
|
query: {x: 30},
|
|
update: {$inc: {y: 1}},
|
|
new: true,
|
|
upsert: true,
|
|
lsid: {id: UUID()},
|
|
txnNumber: NumberLong(37),
|
|
};
|
|
|
|
const findAndModifyResult = assert.commandWorked(testDB.runCommand(findAndModCmd));
|
|
|
|
const changeDocToChunkNotMigrated = {
|
|
findAndModify: "user",
|
|
query: {x: 20},
|
|
update: {$set: {x: -120}, $inc: {y: 1}},
|
|
new: false,
|
|
upsert: true,
|
|
lsid: {id: UUID()},
|
|
txnNumber: NumberLong(37),
|
|
};
|
|
|
|
const changeDocToNotMigratedResult = assert.commandWorked(testDB.runCommand(changeDocToChunkNotMigrated));
|
|
|
|
const changeDocToChunkMigrated = {
|
|
findAndModify: "user",
|
|
query: {x: -20},
|
|
update: {$set: {x: 120}, $inc: {y: 1}},
|
|
new: false,
|
|
upsert: true,
|
|
lsid: {id: UUID()},
|
|
txnNumber: NumberLong(37),
|
|
};
|
|
|
|
const changeDocToMigratedResult = assert.commandWorked(testDB.runCommand(changeDocToChunkMigrated));
|
|
|
|
const findAndModifyNotMigrated = {
|
|
findAndModify: "user",
|
|
query: {x: -30},
|
|
update: {$inc: {y: 1}},
|
|
new: false,
|
|
upsert: true,
|
|
lsid: {id: UUID()},
|
|
txnNumber: NumberLong(37),
|
|
};
|
|
|
|
const findAndModifyNotMigratedResult = assert.commandWorked(testDB.runCommand(findAndModifyNotMigrated));
|
|
|
|
unpauseMoveChunkAtStep(st.shard0, moveChunkStepNames.reachedSteadyState);
|
|
joinMoveChunk();
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Retry phase
|
|
|
|
let insertRetryResult = assert.commandWorked(testDB.runCommand(insertCmd));
|
|
|
|
assert.eq(insertResult.ok, insertRetryResult.ok);
|
|
assert.eq(insertResult.n, insertRetryResult.n);
|
|
assert.eq(insertResult.writeErrors, insertRetryResult.writeErrors);
|
|
assert.eq(insertResult.writeConcernErrors, insertRetryResult.writeConcernErrors);
|
|
|
|
assert.eq(1, testDB.user.find({x: 10}).itcount());
|
|
assert.eq(1, testDB.user.find({x: 30}).itcount());
|
|
|
|
let findAndModifyRetryResult = assert.commandWorked(testDB.runCommand(findAndModCmd));
|
|
|
|
assert.eq(findAndModifyResult.ok, findAndModifyRetryResult.ok);
|
|
assert.eq(findAndModifyResult.value, findAndModifyRetryResult.value);
|
|
assert.eq(findAndModifyResult.lastErrorObject, findAndModifyRetryResult.lastErrorObject);
|
|
|
|
assert.eq(1, testDB.user.findOne({x: 30}).y);
|
|
|
|
let changeDocToNotMigratedRetryResult = assert.commandWorked(testDB.runCommand(changeDocToChunkNotMigrated));
|
|
|
|
assert.eq(changeDocToNotMigratedResult.ok, changeDocToNotMigratedRetryResult.ok);
|
|
assert.eq(changeDocToNotMigratedResult.value, changeDocToNotMigratedRetryResult.value);
|
|
assert.eq(changeDocToNotMigratedResult.lastErrorObject, changeDocToNotMigratedRetryResult.lastErrorObject);
|
|
|
|
assert.eq(1, testDB.user.find({x: -120}).itcount());
|
|
|
|
let changeDocToMigratedRetryResult = assert.commandWorked(testDB.runCommand(changeDocToChunkMigrated));
|
|
|
|
assert.eq(changeDocToMigratedResult.ok, changeDocToMigratedRetryResult.ok);
|
|
assert.eq(changeDocToMigratedResult.value, changeDocToMigratedRetryResult.value);
|
|
assert.eq(changeDocToMigratedResult.lastErrorObject, changeDocToMigratedRetryResult.lastErrorObject);
|
|
|
|
assert.eq(1, testDB.user.find({x: 120}).itcount());
|
|
|
|
let findAndModifyNotMigratedRetryResult = assert.commandWorked(testDB.runCommand(findAndModifyNotMigrated));
|
|
|
|
assert.eq(findAndModifyNotMigratedResult.ok, findAndModifyNotMigratedRetryResult.ok);
|
|
assert.eq(findAndModifyNotMigratedResult.value, findAndModifyNotMigratedRetryResult.value);
|
|
assert.eq(findAndModifyNotMigratedResult.lastErrorObject, findAndModifyNotMigratedRetryResult.lastErrorObject);
|
|
|
|
assert.eq(1, testDB.user.findOne({x: -30}).y);
|
|
|
|
st.stop();
|
|
|
|
MongoRunner.stopMongod(staticMongod);
|