summaryrefslogtreecommitdiff
path: root/jstests/disk
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2018-06-15 16:17:17 -0400
committerLouis Williams <louis.williams@mongodb.com>2018-06-28 16:49:55 -0400
commitc41426385e88d1b8cd08b5fa39f445e184f86dc1 (patch)
treece0db4b98346339e916caae4af67ea8e6ad2e0bb /jstests/disk
parentc467afb7b0c2c3c8f1f12ddcff01400466a53fed (diff)
downloadmongo-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.js154
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);
+})();