mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
260 lines
8.5 KiB
JavaScript
260 lines
8.5 KiB
JavaScript
/**
|
|
* Tests that --repair deletes documents containing duplicate unique keys and inserts them into a
|
|
* local lost and found collection.
|
|
*
|
|
* @tags: [requires_wiredtiger]
|
|
*/
|
|
|
|
(function() {
|
|
|
|
load('jstests/disk/libs/wt_file_helper.js');
|
|
load("jstests/libs/uuid_util.js");
|
|
|
|
const baseName = "repair_duplicate_keys";
|
|
const localBaseName = "local";
|
|
const collName = "test";
|
|
const lostAndFoundCollBaseName = "lost_and_found.";
|
|
|
|
const dbpath = MongoRunner.dataPath + baseName + "/";
|
|
const indexName = "a_1";
|
|
const doc1 = {
|
|
a: 1,
|
|
};
|
|
const doc2 = {
|
|
a: 10,
|
|
};
|
|
const doc3 = {
|
|
a: 100,
|
|
};
|
|
const docWithId = {
|
|
a: 1,
|
|
_id: 1
|
|
};
|
|
const dupDocWithId = {
|
|
a: 1,
|
|
_id: 1
|
|
};
|
|
|
|
resetDbpath(dbpath);
|
|
let port;
|
|
|
|
// Initializes test collection for tests 1-3.
|
|
let createIndexedCollWithDocs = function(coll) {
|
|
assert.commandWorked(coll.insert(doc1));
|
|
assert.commandWorked(coll.createIndex({a: 1}, {name: indexName, unique: true}));
|
|
assert.commandWorked(coll.insert(doc2));
|
|
assert.commandWorked(coll.insert(doc3));
|
|
|
|
assertQueryUsesIndex(coll, doc1, indexName);
|
|
assertQueryUsesIndex(coll, doc2, indexName);
|
|
assertQueryUsesIndex(coll, doc3, indexName);
|
|
return coll;
|
|
};
|
|
|
|
// Bypasses DuplicateKey insertion error for testing via failpoint.
|
|
let addDuplicateDocumentToCol = function(db, coll, doc) {
|
|
jsTestLog("Insert document without index entries.");
|
|
assert.commandWorked(
|
|
db.adminCommand({configureFailPoint: "skipIndexNewRecords", mode: "alwaysOn"}));
|
|
|
|
assert.commandWorked(coll.insert(doc));
|
|
|
|
assert.commandWorked(db.adminCommand({configureFailPoint: "skipIndexNewRecords", mode: "off"}));
|
|
};
|
|
|
|
// Runs repair on collection with possible duplicate keys and verifies original documents in
|
|
// collection initialized with "createIndexedCollWithDocs" are still present.
|
|
let runRepairAndVerifyCollectionDocs = function() {
|
|
jsTestLog("Entering runRepairAndVerifyCollectionDocs...");
|
|
|
|
assertRepairSucceeds(dbpath, port);
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
let testColl = mongod.getDB(baseName)[collName];
|
|
|
|
assert.eq(testColl.find(doc1).itcount(), 1);
|
|
assert.eq(testColl.find(doc2).itcount(), 1);
|
|
assert.eq(testColl.find(doc3).itcount(), 1);
|
|
assert.eq(testColl.count(), 3);
|
|
|
|
MongoRunner.stopMongod(mongod);
|
|
jsTestLog("Exiting runRepairAndVerifyCollectionDocs.");
|
|
};
|
|
|
|
/* Test 1: Insert unique documents and verify that no local database is generated. */
|
|
(function startStandaloneWithNoDup() {
|
|
jsTestLog("Entering startStandaloneWithNoDup...");
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
port = mongod.port;
|
|
let testColl = mongod.getDB(baseName)[collName];
|
|
|
|
testColl = createIndexedCollWithDocs(testColl);
|
|
assert.commandFailedWithCode(testColl.insert(doc1), [ErrorCodes.DuplicateKey]);
|
|
assert.commandFailedWithCode(testColl.insert(doc2), [ErrorCodes.DuplicateKey]);
|
|
assert.commandFailedWithCode(testColl.insert(doc3), [ErrorCodes.DuplicateKey]);
|
|
|
|
assert.eq(testColl.count(), 3);
|
|
|
|
MongoRunner.stopMongod(mongod);
|
|
jsTestLog("Exiting startStandaloneWithNoDup.");
|
|
})();
|
|
|
|
runRepairAndVerifyCollectionDocs();
|
|
|
|
(function checkLostAndFoundCollForNoDup() {
|
|
jsTestLog("Entering checkLostAndFoundCollForNoDup...");
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
const uuid_obj = getUUIDFromListCollections(mongod.getDB(baseName), collName);
|
|
const uuid = extractUUIDFromObject(uuid_obj);
|
|
|
|
let localColl = mongod.getDB(localBaseName)[lostAndFoundCollBaseName + uuid];
|
|
assert.isnull(localColl.exists());
|
|
|
|
MongoRunner.stopMongod(mongod);
|
|
jsTestLog("Exiting checkLostAndFoundCollForNoDup.");
|
|
})();
|
|
|
|
/* Test 2: Insert one duplicate document into test collection and verify that repair deletes the
|
|
* document from the collection, generates a "local.lost_and_found" collection and inserts
|
|
* duplicate document into it. */
|
|
(function startStandaloneWithOneDup() {
|
|
jsTestLog("Entering startStandaloneWithOneDup...");
|
|
resetDbpath(dbpath);
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
port = mongod.port;
|
|
let db = mongod.getDB(baseName);
|
|
let testColl = mongod.getDB(baseName)[collName];
|
|
|
|
testColl = createIndexedCollWithDocs(testColl);
|
|
assert.commandFailedWithCode(testColl.insert(doc1), [ErrorCodes.DuplicateKey]);
|
|
|
|
addDuplicateDocumentToCol(db, testColl, doc1);
|
|
|
|
assert.eq(testColl.count(), 4);
|
|
|
|
MongoRunner.stopMongod(mongod, undefined, {skipValidation: true});
|
|
jsTestLog("Exiting startStandaloneWithOneDup.");
|
|
})();
|
|
|
|
runRepairAndVerifyCollectionDocs();
|
|
|
|
(function checkLostAndFoundCollForOneDup() {
|
|
jsTestLog("Entering checkLostAndFoundCollForOneDup...");
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
const uuid_obj = getUUIDFromListCollections(mongod.getDB(baseName), collName);
|
|
const uuid = extractUUIDFromObject(uuid_obj);
|
|
|
|
let localColl = mongod.getDB(localBaseName)[lostAndFoundCollBaseName + uuid];
|
|
assert.eq(localColl.find(doc1).itcount(), 1);
|
|
assert.eq(localColl.count(), 1);
|
|
|
|
MongoRunner.stopMongod(mongod);
|
|
jsTestLog("Exiting checkLostAndFoundCollForOneDup.");
|
|
})();
|
|
|
|
/* Test 3: Insert multiple duplicate documents into the test collection and verify that repair
|
|
* deletes the documents from the collection, generates a "local.lost_and_found" collection and
|
|
* inserts duplicate document into it.
|
|
*/
|
|
(function startStandaloneWithMultipleDups() {
|
|
jsTestLog("Entering startStandaloneWithMultipleDups...");
|
|
resetDbpath(dbpath);
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
port = mongod.port;
|
|
let db = mongod.getDB(baseName);
|
|
let testColl = mongod.getDB(baseName)[collName];
|
|
|
|
testColl = createIndexedCollWithDocs(testColl);
|
|
assert.commandFailedWithCode(testColl.insert(doc1), [ErrorCodes.DuplicateKey]);
|
|
|
|
addDuplicateDocumentToCol(db, testColl, doc1);
|
|
addDuplicateDocumentToCol(db, testColl, doc2);
|
|
addDuplicateDocumentToCol(db, testColl, doc3);
|
|
|
|
assert.eq(testColl.count(), 6);
|
|
|
|
MongoRunner.stopMongod(mongod, undefined, {skipValidation: true});
|
|
jsTestLog("Exiting startStandaloneWithMultipleDups.");
|
|
})();
|
|
|
|
runRepairAndVerifyCollectionDocs();
|
|
|
|
(function checkLostAndFoundCollForDups() {
|
|
jsTestLog("Entering checkLostAndFoundCollForDups...");
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
const uuid_obj = getUUIDFromListCollections(mongod.getDB(baseName), collName);
|
|
const uuid = extractUUIDFromObject(uuid_obj);
|
|
|
|
let localColl = mongod.getDB(localBaseName)[lostAndFoundCollBaseName + uuid];
|
|
|
|
assert.eq(localColl.find(doc1).itcount(), 1);
|
|
assert.eq(localColl.find(doc2).itcount(), 1);
|
|
assert.eq(localColl.find(doc3).itcount(), 1);
|
|
assert.eq(localColl.count(), 3);
|
|
|
|
MongoRunner.stopMongod(mongod);
|
|
jsTestLog("Exiting checkLostAndFoundCollForDups.");
|
|
})();
|
|
|
|
/* Test 4: Insert document with both duplicate "a" field and duplicate _id field. Verify that repair
|
|
* deletes the duplicate document from test collection, generates a "local.lost_and_found"
|
|
* collection and inserts duplicate document into it.
|
|
*/
|
|
(function startStandaloneWithDoubleDup() {
|
|
jsTestLog("Entering startStandaloneWithDoubleDup...");
|
|
resetDbpath(dbpath);
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
port = mongod.port;
|
|
let db = mongod.getDB(baseName);
|
|
let testColl = mongod.getDB(baseName)[collName];
|
|
|
|
assert.commandWorked(testColl.insert(docWithId));
|
|
assert.commandWorked(testColl.createIndex({a: 1}, {name: indexName, unique: true}));
|
|
|
|
addDuplicateDocumentToCol(db, testColl, dupDocWithId);
|
|
|
|
assert.eq(testColl.count(), 2);
|
|
|
|
MongoRunner.stopMongod(mongod, undefined, {skipValidation: true});
|
|
jsTestLog("Exiting startStandaloneWithDoubleDup.");
|
|
})();
|
|
|
|
(function runRepairAndVerifyCollectionDoc() {
|
|
jsTestLog("Running repair...");
|
|
|
|
assertRepairSucceeds(dbpath, port);
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
let testColl = mongod.getDB(baseName)[collName];
|
|
|
|
assert.eq(testColl.find(docWithId).itcount(), 1);
|
|
assert.eq(testColl.count(), 1);
|
|
|
|
MongoRunner.stopMongod(mongod);
|
|
|
|
jsTestLog("Finished repairing.");
|
|
})();
|
|
|
|
(function checkLostAndFoundCollForDoubleDup() {
|
|
jsTestLog("Entering checkLostAndFoundCollForDoubleDup...");
|
|
|
|
let mongod = startMongodOnExistingPath(dbpath);
|
|
const uuid_obj = getUUIDFromListCollections(mongod.getDB(baseName), collName);
|
|
const uuid = extractUUIDFromObject(uuid_obj);
|
|
|
|
let localColl = mongod.getDB(localBaseName)[lostAndFoundCollBaseName + uuid];
|
|
assert.eq(localColl.find(docWithId).itcount(), 1);
|
|
assert.eq(localColl.count(), 1);
|
|
|
|
MongoRunner.stopMongod(mongod);
|
|
jsTestLog("Exiting checkLostAndFoundCollForDoubleDup.");
|
|
})();
|
|
})();
|