mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-24 08:30:56 +01:00
fd05a7c3b3
GitOrigin-RevId: f7d2485163e820162f33c4d600cf18c4bf89b6d0
131 lines
4.2 KiB
JavaScript
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);
|