summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/db.cpp5
-rw-r--r--src/mongo/db/dbcommands.cpp3
-rw-r--r--src/mongo/db/repair_database.cpp38
-rw-r--r--src/mongo/db/repair_database.h4
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_transaction.cpp8
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_transaction.h4
-rw-r--r--src/mongo/db/storage/transaction.h13
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
//