0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-24 08:30:56 +01:00
mongodb/jstests/noPassthrough/compact/interrupt_compact_commands.js
Stephanie fd05a7c3b3 SERVER-95806: Break up storage_execution directory in jstests/noPassthrough (#28100)
GitOrigin-RevId: f7d2485163e820162f33c4d600cf18c4bf89b6d0
2024-10-17 17:22:38 +00:00

131 lines
4.2 KiB
JavaScript

/**
* Tests that the compact command is interruptible in the storage engine (WT) layer.
* Loads data such that the storage engine compact command finds data to compress and actually runs.
* Pauses a compact command in the MDB layer, sets interrupt via killOp, and then releases the
* command to discover the interrupt in the storage engine layer.
*
* @tags: [
* requires_persistence,
* ]
*/
import {configureFailPoint} from "jstests/libs/fail_point_util.js";
import {Thread} from "jstests/libs/parallelTester.js";
/**
* Loads 30000 * 20 documents into collection <dbName>.<collName> via 20 threads.
* Tags each insert with a thread ID. Then deletes half the data, by thread ID, to create holes such
* that WT::compact finds compaction work to do.
*/
function loadData(conn, dbName, collName, coll) {
const kThreads = 20;
coll.createIndex({t: 1});
jsTestLog("Loading data...");
const threads = [];
for (let t = 0; t < kThreads; t++) {
let thread = new Thread(function(t, port, dbName, collName) {
const mongo = new Mongo('localhost:' + port);
const testDB = mongo.getDB(dbName);
const testColl = testDB.getCollection(collName);
// This is a sufficient amount of data for WT::compact to run. If the data size is too
// small, WT::compact skips.
// This also needs to be large enough to pass the "available bytes" check in WT-11332.
const size = 4096;
const count = 25000;
const doc = {a: -1, x: 'x'.repeat(size), b: -1, t: t};
let bulkInsert = testColl.initializeUnorderedBulkOp();
for (var i = 0; i < count; ++i) {
bulkInsert.insert(doc);
}
jsTestLog("Committing inserts, t: " + t);
assert.commandWorked(bulkInsert.execute());
}, t, conn.port, dbName, collName);
threads.push(thread);
thread.start();
}
for (let t = 0; t < kThreads; ++t) {
threads[t].join();
}
jsTestLog("Pruning data...");
for (var t = 0; t < kThreads; t = t + 2) {
coll.deleteMany({t: t});
}
jsTestLog("Data setup complete.");
}
const dbName = jsTestName();
const collName = 'testColl';
const conn = MongoRunner.runMongod();
assert.neq(conn, null);
const testDB = conn.getDB(dbName);
const testColl = testDB.getCollection(collName);
loadData(conn, dbName, collName, testColl);
let fp;
let fpOn = false;
try {
jsTestLog("Setting the failpoint...");
fp = configureFailPoint(testDB, "pauseCompactCommandBeforeWTCompact");
fpOn = true;
TestData.comment = "commentOpIdentifier";
TestData.dbName = dbName;
let compactJoin = startParallelShell(() => {
jsTestLog("Starting the compact command, which should stall on a failpoint...");
assert.commandFailedWithCode(
db.getSiblingDB(TestData.dbName)
.runCommand({"compact": "testColl", "comment": TestData.comment}),
ErrorCodes.Interrupted);
}, conn.port);
jsTestLog("Waiting for the compact command to hit the failpoint...");
fp.wait();
jsTestLog("Finding the compact command opId in order to call killOp...");
let opId = null;
assert.soon(function() {
const ops = testDB.getSiblingDB("admin")
.aggregate([
{$currentOp: {allUsers: true}},
{$match: {"command.comment": TestData.comment}}
])
.toArray();
if (ops.length == 0) {
return false;
}
assert.eq(ops.length, 1);
opId = ops[0].opid;
return true;
});
jsTestLog("Calling killOp to interrupt the compact command, opId: " + tojson(opId));
assert.commandWorked(testDB.killOp(opId));
jsTestLog("Releasing the failpoint and waiting for the compact command to finish...");
fp.off();
fpOn = false;
compactJoin();
// Make sure that WT::compact did not skip because of too little data.
assert(
!checkLog.checkContainsOnce(testDB, "there is no useful work to do - skipping compaction"));
} finally {
if (fpOn) {
jsTestLog("Release the failpoint");
fp.off();
}
}
jsTestLog("Done");
MongoRunner.stopMongod(conn);