diff options
author | Mathias Stearn <mathias@10gen.com> | 2014-04-30 15:17:52 -0400 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2014-04-30 16:11:50 -0400 |
commit | 16c9c3ec7bcff067c7bccef307e2039a13048153 (patch) | |
tree | f0443470a7b8e6d639dd34b4d622ae7c94a94989 /src/mongo/db | |
parent | c7625872ea64c1846c6799966a700d57c6e2ad6e (diff) | |
download | mongo-16c9c3ec7bcff067c7bccef307e2039a13048153.tar.gz |
SERVER-13643 Plumb TransactionExperiment through repairDatabase
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/db.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/repair_database.cpp | 38 | ||||
-rw-r--r-- | src/mongo/db/repair_database.h | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_transaction.cpp | 8 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_transaction.h | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/transaction.h | 13 |
7 files changed, 49 insertions, 26 deletions
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index f98e36c847e..00fb0cd9762 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -301,6 +301,7 @@ namespace mongo { void doDBUpgrade( const string& dbName, DataFileHeader* h ) { static DBDirectClient db; + DurTransaction txn; if ( h->version == 4 && h->versionMinor == 4 ) { verify( PDFILE_VERSION == 4 ); @@ -318,12 +319,12 @@ namespace mongo { } } - getDur().writingInt(h->versionMinor) = 5; + txn.writingInt(h->versionMinor) = 5; return; } // do this in the general case - fassert( 17401, repairDatabase( dbName ) ); + fassert( 17401, repairDatabase( &txn, dbName ) ); } void checkForIdIndexes( Database* db ) { diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index a19f7146b6c..e6b9ba8a038 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -287,6 +287,7 @@ namespace mongo { // called within, and that requires a global lock i believe. Lock::GlobalWrite lk; Client::Context context( dbname ); + DurTransaction txn; log() << "repairDatabase " << dbname; std::vector<BSONObj> indexesInProg = stopIndexBuilds(context.db(), cmdObj); @@ -296,7 +297,7 @@ namespace mongo { e = cmdObj.getField( "backupOriginalFiles" ); bool backupOriginalFiles = e.isBoolean() && e.boolean(); Status status = - repairDatabase( dbname, preserveClonedFilesOnFailure, backupOriginalFiles ); + repairDatabase( &txn, dbname, preserveClonedFilesOnFailure, backupOriginalFiles ); IndexBuilder::restoreIndexes(indexesInProg); diff --git a/src/mongo/db/repair_database.cpp b/src/mongo/db/repair_database.cpp index d7bcdc40d7e..cceba1f26fc 100644 --- a/src/mongo/db/repair_database.cpp +++ b/src/mongo/db/repair_database.cpp @@ -40,8 +40,6 @@ #include "mongo/db/client.h" #include "mongo/db/cloner.h" #include "mongo/db/index/index_descriptor.h" -#include "mongo/db/kill_current_op.h" -#include "mongo/db/storage/mmap_v1/dur_transaction.h" #include "mongo/util/file.h" #include "mongo/util/file_allocator.h" @@ -228,10 +226,12 @@ namespace mongo { class RepairFileDeleter { public: - RepairFileDeleter( const string& dbName, + RepairFileDeleter( TransactionExperiment* txn, + const string& dbName, const string& pathString, const Path& path ) - : _dbName( dbName ), + : _txn(txn), + _dbName( dbName ), _pathString( pathString ), _path( path ), _success( false ) { @@ -245,7 +245,7 @@ namespace mongo { << "db: " << _dbName << " path: " << _pathString; try { - getDur().syncDataAndTruncateJournal(); + _txn->syncDataAndTruncateJournal(); MongoFile::flushAll(true); // need both in case journaling is disabled { Client::Context tempContext( _dbName, _pathString ); @@ -265,16 +265,17 @@ namespace mongo { } private: + TransactionExperiment* _txn; string _dbName; string _pathString; Path _path; bool _success; }; - Status repairDatabase( string dbName, + Status repairDatabase( TransactionExperiment* txn, + string dbName, bool preserveClonedFilesOnFailure, bool backupOriginalFiles ) { - DurTransaction txn; // XXX scoped_ptr<RepairFileDeleter> repairFileDeleter; doingRepair dr; dbName = nsToDatabase( dbName ); @@ -283,7 +284,7 @@ namespace mongo { BackgroundOperation::assertNoBgOpInProgForDb(dbName); - getDur().syncDataAndTruncateJournal(); // Must be done before and after repair + txn->syncDataAndTruncateJournal(); // Must be done before and after repair intmax_t totalSize = dbSize( dbName ); intmax_t freeSize = File::freeSpace(storageGlobalParams.repairpath); @@ -295,7 +296,7 @@ namespace mongo { << " (bytes) because free disk space is: " << freeSize << " (bytes)" ); } - killCurrentOp.checkForInterrupt(); + txn->checkForInterrupt(); Path reservedPath = uniqueReservedPath( ( preserveClonedFilesOnFailure || backupOriginalFiles ) ? @@ -304,7 +305,8 @@ namespace mongo { string reservedPathString = reservedPath.string(); if ( !preserveClonedFilesOnFailure ) - repairFileDeleter.reset( new RepairFileDeleter( dbName, + repairFileDeleter.reset( new RepairFileDeleter( txn, + dbName, reservedPathString, reservedPath ) ); @@ -366,16 +368,16 @@ namespace mongo { Collection* tempCollection = NULL; { Client::Context tempContext( ns, tempDatabase ); - tempCollection = tempDatabase->createCollection( &txn, ns, options, true, false ); + tempCollection = tempDatabase->createCollection( txn, ns, options, true, false ); } Client::Context readContext( ns, originalDatabase ); - Collection* originalCollection = originalDatabase->getCollection( &txn, ns ); + Collection* originalCollection = originalDatabase->getCollection( txn, ns ); invariant( originalCollection ); // data - MultiIndexBlock indexBlock(&txn, tempCollection ); + MultiIndexBlock indexBlock(txn, tempCollection ); { vector<BSONObj> indexes; IndexCatalog::IndexIterator ii = @@ -402,12 +404,12 @@ namespace mongo { BSONObj doc = originalCollection->docFor( loc ); Client::Context tempContext( ns, tempDatabase ); - StatusWith<DiskLoc> result = tempCollection->insertDocument( &txn, doc, indexBlock ); + StatusWith<DiskLoc> result = tempCollection->insertDocument( txn, doc, indexBlock ); if ( !result.isOK() ) return result.getStatus(); - getDur().commitIfNeeded(); - killCurrentOp.checkForInterrupt(false); + txn->commitIfNeeded(); + txn->checkForInterrupt(false); } { @@ -419,10 +421,10 @@ namespace mongo { } - getDur().syncDataAndTruncateJournal(); + txn->syncDataAndTruncateJournal(); MongoFile::flushAll(true); // need both in case journaling is disabled - killCurrentOp.checkForInterrupt(false); + txn->checkForInterrupt(false); Client::Context tempContext( dbName, reservedPathString ); Database::closeDatabase( dbName, reservedPathString ); diff --git a/src/mongo/db/repair_database.h b/src/mongo/db/repair_database.h index 4fffe435558..16f5ae1d747 100644 --- a/src/mongo/db/repair_database.h +++ b/src/mongo/db/repair_database.h @@ -36,6 +36,7 @@ #include "mongo/platform/cstdint.h" namespace mongo { + class TransactionExperiment; // TODO: move intmax_t dbSize( const std::string& database ); @@ -44,7 +45,8 @@ namespace mongo { void _deleteDataFiles(const std::string& database); // must have a global lock - Status repairDatabase( std::string db, + Status repairDatabase( TransactionExperiment* txn, + std::string db, bool preserveClonedFilesOnFailure = false, bool backupOriginalFiles = false ); diff --git a/src/mongo/db/storage/mmap_v1/dur_transaction.cpp b/src/mongo/db/storage/mmap_v1/dur_transaction.cpp index f235c6dad21..b322431bf2b 100644 --- a/src/mongo/db/storage/mmap_v1/dur_transaction.cpp +++ b/src/mongo/db/storage/mmap_v1/dur_transaction.cpp @@ -45,8 +45,12 @@ namespace mongo { return getDur().writingPtr(data, len); } - void DurTransaction::checkForInterrupt() const { - killCurrentOp.checkForInterrupt(); + void DurTransaction::syncDataAndTruncateJournal() { + return getDur().syncDataAndTruncateJournal(); + } + + void DurTransaction::checkForInterrupt(bool heedMutex) const { + killCurrentOp.checkForInterrupt(heedMutex); } Status DurTransaction::checkForInterruptNoAssert() const { diff --git a/src/mongo/db/storage/mmap_v1/dur_transaction.h b/src/mongo/db/storage/mmap_v1/dur_transaction.h index 66a8c015144..626735b3845 100644 --- a/src/mongo/db/storage/mmap_v1/dur_transaction.h +++ b/src/mongo/db/storage/mmap_v1/dur_transaction.h @@ -47,7 +47,9 @@ namespace mongo { virtual void* writingPtr(void* data, size_t len); - virtual void checkForInterrupt() const; + virtual void syncDataAndTruncateJournal(); + + virtual void checkForInterrupt(bool heedMutex = true) const; virtual Status checkForInterruptNoAssert() const; diff --git a/src/mongo/db/storage/transaction.h b/src/mongo/db/storage/transaction.h index 6846331e7a7..dced8b6d2d1 100644 --- a/src/mongo/db/storage/transaction.h +++ b/src/mongo/db/storage/transaction.h @@ -47,8 +47,9 @@ namespace mongo { /** * throws an exception if the operation is interrupted + * @param heedMutex if true and have a write lock, won't kill op since it might be unsafe */ - virtual void checkForInterrupt() const = 0; + virtual void checkForInterrupt(bool heedMutex = true) const = 0; /** * @return Status::OK() if not interrupted @@ -73,6 +74,16 @@ namespace mongo { */ virtual void* writingPtr(void* data, size_t len) = 0; + /** + * Commits pending changes, flushes all changes to main data files, then removes the + * journal. + * + * This is useful as a "barrier" to ensure that writes before this call will never go + * through recovery and be applied to files that have had changes made after this call + * applied. + */ + virtual void syncDataAndTruncateJournal() = 0; + // // Sugar methods // |