0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-21 20:49:10 +01:00
mongodb/jstests/disk/repair_clustered_collection.js
2023-08-06 20:48:04 +00:00

91 lines
3.4 KiB
JavaScript

/**
* Tests that --repair on WiredTiger correctly and gracefully handles a missing _mdb_catalog when
* a clustered collection exists on the server instance.
*
* @tags: [requires_wiredtiger]
*/
import {
assertRepairSucceeds,
getUriForColl,
startMongodOnExistingPath
} from "jstests/disk/libs/wt_file_helper.js";
import {
assertCreateCollection,
assertDropCollection
} from "jstests/libs/collection_drop_recreate.js";
const dbName = jsTestName();
const collName = "test";
const dbpath = MongoRunner.dataPath + dbName + "/";
const runRepairTest = function runRepairTestOnMongoDInstance(
collectionOptions, docToInsert, isTimeseries) {
let mongod = startMongodOnExistingPath(dbpath);
let db = mongod.getDB(dbName);
assertDropCollection(db, collName);
assertCreateCollection(db, collName, collectionOptions);
let testColl = db[collName];
let testCollUri = getUriForColl(testColl);
let testCollFile = dbpath + testCollUri + ".wt";
assert.commandWorked(testColl.insert(docToInsert));
// A document repaired from a timeseries collection will be in a different format than the
// original document. This is because the timeseries's system.views collection will be not be
// associated with the orphaned clustered collection. Thus, the data will show up as it would
// have in the raw system.buckets collection for the timeseries collection.
const expectedOrphanDoc =
isTimeseries ? db["system.buckets." + collName].findOne() : testColl.findOne();
MongoRunner.stopMongod(mongod);
// Delete the _mdb_catalog.
let mdbCatalogFile = dbpath + "_mdb_catalog.wt";
jsTestLog("deleting catalog file: " + mdbCatalogFile);
removeFile(mdbCatalogFile);
assertRepairSucceeds(dbpath, mongod.port);
// Verify that repair succeeds in creating an empty catalog and MongoDB starts up normally with
// no data.
mongod = startMongodOnExistingPath(dbpath);
db = mongod.getDB(dbName);
testColl = db[collName];
assert.isnull(testColl.exists());
assert.eq(testColl.find(docToInsert).itcount(), 0);
assert.eq(testColl.count(), 0);
// Ensure the orphaned collection is valid and the document is preserved.
const orphanedImportantCollName = "orphan." + testCollUri.replace(/-/g, "_");
const localDb = mongod.getDB("local");
let orphanedCollection = localDb[orphanedImportantCollName];
assert(orphanedCollection.exists());
assert.eq(orphanedCollection.count(expectedOrphanDoc),
1,
`Expected to find document ${tojson(expectedOrphanDoc)} but collection has contents ${
tojson(orphanedCollection.find().toArray())}`);
const validateResult = orphanedCollection.validate();
assert(validateResult.valid);
MongoRunner.stopMongod(mongod);
};
// Standard clustered collection test.
let isTimeseries = false;
let clusteredCollOptions = {clusteredIndex: {key: {_id: 1}, unique: true}};
let docToInsert = {_id: 1};
runRepairTest(clusteredCollOptions, docToInsert, isTimeseries);
// Timeseries test since all timeseries collections are implicitly clustered.
isTimeseries = true;
clusteredCollOptions = {
timeseries: {timeField: "timestamp", metaField: "metadata", granularity: "hours"}
};
docToInsert = {
"metadata": {"sensorId": 5578, "type": "temperature"},
"timestamp": ISODate("2021-05-18T00:00:00.000Z"),
"temp": 12
};
runRepairTest(clusteredCollOptions, docToInsert, isTimeseries);