diff options
author | Louis Williams <louis.williams@mongodb.com> | 2018-06-15 16:17:17 -0400 |
---|---|---|
committer | Louis Williams <louis.williams@mongodb.com> | 2018-06-28 16:49:55 -0400 |
commit | c41426385e88d1b8cd08b5fa39f445e184f86dc1 (patch) | |
tree | ce0db4b98346339e916caae4af67ea8e6ad2e0bb /jstests/disk | |
parent | c467afb7b0c2c3c8f1f12ddcff01400466a53fed (diff) | |
download | mongo-c41426385e88d1b8cd08b5fa39f445e184f86dc1.tar.gz |
SERVER-35627 Repair should recreate missing collection data files with the existing metadata.
Diffstat (limited to 'jstests/disk')
-rw-r--r-- | jstests/disk/wt_repair_missing_files.js | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/jstests/disk/wt_repair_missing_files.js b/jstests/disk/wt_repair_missing_files.js new file mode 100644 index 00000000000..c0273f7b647 --- /dev/null +++ b/jstests/disk/wt_repair_missing_files.js @@ -0,0 +1,154 @@ +/** + * Tests that --repair on WiredTiger correctly and gracefully handles missing data files and + * directories. + * + * @tags: [requires_wiredtiger] + */ + +(function() { + + const baseName = "wt_repair_missing_files"; + const collName = "test"; + const dbpath = MongoRunner.dataPath + baseName + "/"; + + resetDbpath(dbpath); + + let getUriForColl = function(coll) { + let ret = coll.stats(); + assert.commandWorked(ret); + let uri = ret.wiredTiger.uri.split("table:")[1]; + assert.neq(typeof(uri), 'undefined'); + return uri; + }; + + let getUriForIndex = function(coll, indexName) { + let ret = coll.getDB().runCommand({collStats: coll.getName()}); + assert.commandWorked(ret); + + let uri = ret.indexDetails[indexName].uri.split("table:")[1]; + assert.neq(typeof(uri), 'undefined'); + return uri; + }; + + /** + * Test 1. Create a collection, delete it's .wt file, run repair. Verify that repair succeeds at + * re-creating it. The collection should be visible on normal startup. + */ + + let mongod = MongoRunner.runMongod({dbpath: dbpath}); + let testColl = mongod.getDB(baseName)[collName]; + + const doc = {a: 1}; + assert.writeOK(testColl.insert(doc)); + + let testCollUri = getUriForColl(testColl); + let testCollFile = dbpath + testCollUri + ".wt"; + + MongoRunner.stopMongod(mongod); + + jsTestLog("deleting collection file: " + testCollFile); + removeFile(testCollFile); + + assert.eq(0, runMongoProgram("mongod", "--repair", "--port", mongod.port, "--dbpath", dbpath)); + + mongod = MongoRunner.runMongod({dbpath: dbpath, noCleanData: true}); + testColl = mongod.getDB(baseName)[collName]; + + assert.eq(testCollUri, getUriForColl(testColl)); + assert.eq(testColl.find({}).itcount(), 0); + assert.eq(testColl.count(), 0); + + /** + * Test 2. Delete an index file. Verify that repair rebuilds and allows MongoDB to start up + * normally. + */ + + let assertQueryUsesIndex = function(coll, query, indexName) { + let res = coll.find(query).explain(); + assert.commandWorked(res); + + let inputStage = res.queryPlanner.winningPlan.inputStage; + assert.eq(inputStage.stage, "IXSCAN"); + assert.eq(inputStage.indexName, indexName); + }; + + assert.writeOK(testColl.insert(doc)); + + const indexName = "a_1"; + assert.commandWorked(testColl.createIndex({a: 1}, {name: indexName})); + assertQueryUsesIndex(testColl, doc, indexName); + + let indexUri = getUriForIndex(testColl, indexName); + + MongoRunner.stopMongod(mongod); + + let indexFile = dbpath + indexUri + ".wt"; + jsTestLog("deleting index file: " + indexFile); + removeFile(indexFile); + + assert.eq(0, runMongoProgram("mongod", "--repair", "--port", mongod.port, "--dbpath", dbpath)); + mongod = MongoRunner.runMongod({dbpath: dbpath, noCleanData: true}); + testColl = mongod.getDB(baseName)[collName]; + + // Repair creates new idents. + assert.neq(indexUri, getUriForIndex(testColl, indexName)); + + assertQueryUsesIndex(testColl, doc, indexName); + assert.eq(testColl.find(doc).itcount(), 1); + assert.eq(testColl.count(), 1); + + MongoRunner.stopMongod(mongod); + + /** + * Test 3. Delete the _mdb_catalog. Verify that repair suceeds in creating an empty catalog and + * MongoDB starts up normally with no data. + */ + + let mdbCatalogFile = dbpath + "_mdb_catalog.wt"; + jsTestLog("deleting catalog file: " + mdbCatalogFile); + removeFile(mdbCatalogFile); + + assert.eq(0, runMongoProgram("mongod", "--repair", "--port", mongod.port, "--dbpath", dbpath)); + + mongod = MongoRunner.runMongod({dbpath: dbpath, noCleanData: true}); + testColl = mongod.getDB(baseName)[collName]; + assert.commandFailed(testColl.stats()); + + assert.eq(testColl.find(doc).itcount(), 0); + assert.eq(testColl.count(), 0); + + /** + * Test 4. Verify that using repair with --directoryperdb creates a missing directory and its + * files, allowing MongoDB to start up normally. + */ + + MongoRunner.stopMongod(mongod); + resetDbpath(dbpath); + + mongod = MongoRunner.runMongod({dbpath: dbpath, directoryperdb: "", noCleanData: true}); + testColl = mongod.getDB(baseName)[collName]; + + assert.writeOK(testColl.insert(doc)); + + testCollUri = getUriForColl(testColl); + + MongoRunner.stopMongod(mongod); + + let dataDir = dbpath + baseName; + jsTestLog("deleting data directory: " + dataDir); + removeFile(dataDir); + + assert.eq( + 0, + runMongoProgram( + "mongod", "--repair", "--directoryperdb", "--port", mongod.port, "--dbpath", dbpath)); + + mongod = MongoRunner.runMongod({dbpath: dbpath, directoryperdb: "", noCleanData: true}); + testColl = mongod.getDB(baseName)[collName]; + + assert.eq(testCollUri, getUriForColl(testColl)); + assert.eq(testColl.find({}).itcount(), 0); + assert.eq(testColl.count(), 0); + + MongoRunner.stopMongod(mongod); +})(); |