diff options
author | Scott Hernandez <scotthernandez@gmail.com> | 2014-12-30 14:46:29 -0500 |
---|---|---|
committer | Scott Hernandez <scotthernandez@gmail.com> | 2015-01-02 14:21:08 -0500 |
commit | 8b37507dd51cdf058377a24ca0171e7fae6f2c6b (patch) | |
tree | 1bea2528edb8df7cf70fda21f6894e59af820f60 /src/mongo/db | |
parent | 430bafbd8643bd1d30513ad231850c6927e8553d (diff) | |
download | mongo-8b37507dd51cdf058377a24ca0171e7fae6f2c6b.tar.gz |
SERVER-16502: open database after repair is done
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repair_database.cpp | 27 | ||||
-rw-r--r-- | src/mongo/db/repair_database.h | 5 |
3 files changed, 27 insertions, 7 deletions
diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index a16a16c22e1..9e9d16f4159 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -290,6 +290,8 @@ namespace mongo { IndexBuilder::restoreIndexes(indexesInProg); + // Open database before returning + dbHolder().openDb(txn, dbname); return appendCommandStatus( result, status ); } } cmdRepairDatabase; diff --git a/src/mongo/db/repair_database.cpp b/src/mongo/db/repair_database.cpp index af27db45098..8f49e4df300 100644 --- a/src/mongo/db/repair_database.cpp +++ b/src/mongo/db/repair_database.cpp @@ -55,7 +55,6 @@ namespace { DatabaseCatalogEntry* dbce, const std::string& collectionName) { - Database db(txn, dbce->name(), dbce); CollectionCatalogEntry* cce = dbce->getCollectionCatalogEntry(txn, collectionName); std::vector<string> indexNames; @@ -81,6 +80,7 @@ namespace { // Skip the rest if there are no indexes to rebuild. if (indexSpecs.empty()) return Status::OK(); + boost::scoped_ptr<Database> db; Collection* collection; boost::scoped_ptr<MultiIndexBlock> indexer; { @@ -102,7 +102,8 @@ namespace { // Indexes must be dropped before we open the Collection otherwise we could attempt to // open a bad index and fail. // TODO see if MultiIndexBlock can be made to work without a Collection. - collection = db.getCollection(txn, collectionName); + db.reset(new Database(txn, dbce->name(), dbce)); + collection = db->getCollection(txn, collectionName); invariant(collection); indexer.reset(new MultiIndexBlock(txn, collection)); @@ -166,6 +167,8 @@ namespace { bool preserveClonedFilesOnFailure, bool backupOriginalFiles) { + + // We must hold some form of lock here invariant(txn->lockState()->isLocked()); invariant( dbName.find( '.' ) == string::npos ); @@ -192,12 +195,22 @@ namespace { return Status( ErrorCodes::BadValue, "backupOriginalFiles not supported" ); } - // Close and reopen the db to invalidate all current users and caches. - // WARNING: it is important that the opened Database object isn't used for anything as its - // cache must remain empty until we return. + // Close the db to invalidate all current users and caches. dbHolder().close(txn, dbName); - dbHolder().openDb(txn, dbName); - + // Open the db after everything finishes + class OpenDbInDestructor { + public: + OpenDbInDestructor(OperationContext* txn, const std::string& db) : + _dbName(db) + , _txn(txn) + {} + ~OpenDbInDestructor() { + dbHolder().openDb(_txn, _dbName); + } + private: + const std::string& _dbName; + OperationContext* _txn; + } dbOpener(txn, dbName); DatabaseCatalogEntry* dbce = engine->getDatabaseCatalogEntry(txn, dbName); std::list<std::string> colls; diff --git a/src/mongo/db/repair_database.h b/src/mongo/db/repair_database.h index 85d2729a277..17fb58274aa 100644 --- a/src/mongo/db/repair_database.h +++ b/src/mongo/db/repair_database.h @@ -36,6 +36,11 @@ namespace mongo { class StorageEngine; class StringData; + /** + * Repairs a database using a storage engine-specific, best-effort process. + * Some data may be lost or modified in the process but the output will + * be structurally valid on successful return. + */ Status repairDatabase(OperationContext* txn, StorageEngine* engine, const std::string& dbName, |