mirror of https://github.com/mongodb/mongo
88 lines
3.5 KiB
JavaScript
88 lines
3.5 KiB
JavaScript
/**
|
|
* Test that only the primary can reap a session and remove the config.transactions doc for the
|
|
* session, and that arbiters never try to a reap session.
|
|
*/
|
|
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
|
|
// This test makes assertions about the number of sessions, which are not compatible with
|
|
// implicit sessions.
|
|
TestData.disableImplicitSessions = true;
|
|
|
|
let replTest = new ReplSetTest({
|
|
name: "reaping",
|
|
nodes: [
|
|
{
|
|
/* primary */
|
|
},
|
|
{/* secondary */ rsConfig: {priority: 0}},
|
|
{/* arbiter */ rsConfig: {arbiterOnly: true}},
|
|
],
|
|
nodeOptions: {setParameter: {TransactionRecordMinimumLifetimeMinutes: 0}},
|
|
});
|
|
let nodes = replTest.startSet();
|
|
|
|
replTest.initiate();
|
|
let primary = replTest.getPrimary();
|
|
let sessionsCollOnPrimary = primary.getDB("config").system.sessions;
|
|
let transactionsCollOnPrimary = primary.getDB("config").transactions;
|
|
let imageCollOnPrimary = primary.getDB("config").image_collection;
|
|
|
|
replTest.awaitSecondaryNodes();
|
|
let secondary = replTest.getSecondary();
|
|
let arbiter = replTest.getArbiter();
|
|
|
|
const dbName = jsTestName();
|
|
const collName = "test";
|
|
const reapErrorMsgRegex = new RegExp("Sessions collection is not set up.*waiting until next sessions reap interval");
|
|
|
|
// Set up a session with a retryable insert and findAndModify.
|
|
let session = primary.startSession({retryWrites: 1});
|
|
assert.commandWorked(session.getDatabase(dbName)[collName].save({x: 1}));
|
|
let result = session.getDatabase(dbName)[collName].findAndModify({query: {x: 1}, update: {$set: {y: 1}}});
|
|
// The findAndModify helper returns the document and not the whole response. Assert on the value of
|
|
// `x`. Though it's expected a command error would become an exception that fails the test.
|
|
assert.eq(1, result["x"], "Whole result: " + result);
|
|
assert.commandWorked(primary.adminCommand({refreshLogicalSessionCacheNow: 1}));
|
|
assert.eq(1, sessionsCollOnPrimary.find().itcount());
|
|
assert.eq(1, transactionsCollOnPrimary.find().itcount());
|
|
assert.eq(1, imageCollOnPrimary.find().itcount());
|
|
|
|
// Remove the session doc so the session gets reaped when reapLogicalSessionCacheNow is run.
|
|
assert.commandWorked(sessionsCollOnPrimary.remove({}));
|
|
|
|
// Test that a reap on a secondary does not lead to the on-disk state reaping of the session
|
|
// since the session does not exist in the secondary's session catalog.
|
|
{
|
|
replTest.awaitReplication();
|
|
assert.commandWorked(secondary.adminCommand({clearLog: "global"}));
|
|
assert.commandWorked(secondary.adminCommand({reapLogicalSessionCacheNow: 1}));
|
|
|
|
assert.eq(1, transactionsCollOnPrimary.find().itcount());
|
|
assert.eq(false, checkLog.checkContainsOnce(secondary, reapErrorMsgRegex));
|
|
}
|
|
|
|
// Test that a reap on an arbiter does not lead to reaping of the session.
|
|
{
|
|
assert.commandWorked(arbiter.adminCommand({clearLog: "global"}));
|
|
assert.commandWorked(arbiter.adminCommand({reapLogicalSessionCacheNow: 1}));
|
|
|
|
assert.eq(1, transactionsCollOnPrimary.find().itcount());
|
|
|
|
if (!jsTest.options().useRandomBinVersionsWithinReplicaSet) {
|
|
// Verify that the arbiter did not try to reap the session.
|
|
assert.eq(false, checkLog.checkContainsOnce(arbiter, reapErrorMsgRegex));
|
|
}
|
|
}
|
|
|
|
// Test that a reap on the primary works as expected.
|
|
{
|
|
assert.commandWorked(primary.adminCommand({clearLog: "global"}));
|
|
assert.commandWorked(primary.adminCommand({reapLogicalSessionCacheNow: 1}));
|
|
|
|
assert.eq(0, transactionsCollOnPrimary.find().itcount());
|
|
assert.eq(0, imageCollOnPrimary.find().itcount());
|
|
}
|
|
|
|
replTest.stopSet();
|