summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHari Khalsa <hkhalsa@10gen.com>2014-05-14 15:48:32 -0400
committerHari Khalsa <hkhalsa@10gen.com>2014-05-15 10:14:59 -0400
commit1b218e1f1ca73f8d373d54b59f6137e167345997 (patch)
tree706de3a6d0690ab798f1254f940fd00e5dcedd0d
parentd750344eebf1406abe40fee3948577fbefea8002 (diff)
downloadmongo-1b218e1f1ca73f8d373d54b59f6137e167345997.tar.gz
SERVER-13641 split out dur from transactionexperiment part 1
-rw-r--r--src/mongo/SConscript1
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp55
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_recovery_unit.h57
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_transaction.cpp22
-rw-r--r--src/mongo/db/storage/mmap_v1/dur_transaction.h17
-rw-r--r--src/mongo/db/storage/recovery_unit.h108
-rw-r--r--src/mongo/db/storage/transaction.h103
7 files changed, 277 insertions, 86 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index 4564cf07316..49b66d50ede 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -552,6 +552,7 @@ serverOnlyFiles = [ "db/curop.cpp",
"db/storage/mmap_v1/dur_commitjob.cpp",
"db/storage/mmap_v1/dur_recover.cpp",
"db/storage/mmap_v1/dur_journal.cpp",
+ "db/storage/mmap_v1/dur_recovery_unit.cpp",
"db/storage/mmap_v1/dur_transaction.cpp",
"db/storage/mmap_v1/mmap_v1_extent_manager.cpp",
"db/introspect.cpp",
diff --git a/src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp b/src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp
new file mode 100644
index 00000000000..7766a615365
--- /dev/null
+++ b/src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include "mongo/db/storage/mmap_v1/dur_recovery_unit.h"
+
+#include "mongo/db/storage/mmap_v1/dur.h"
+
+namespace mongo {
+
+ bool DurRecoveryUnit::commitIfNeeded(bool force) {
+ return getDur().commitIfNeeded(force);
+ }
+
+ bool DurRecoveryUnit::isCommitNeeded() const {
+ return getDur().isCommitNeeded();
+ }
+
+ void* DurRecoveryUnit::writingPtr(void* data, size_t len) {
+ return getDur().writingPtr(data, len);
+ }
+
+ void DurRecoveryUnit::createdFile(const std::string& filename, unsigned long long len) {
+ getDur().createdFile(filename, len);
+ }
+
+ void DurRecoveryUnit::syncDataAndTruncateJournal() {
+ return getDur().syncDataAndTruncateJournal();
+ }
+
+} // namespace mongo
diff --git a/src/mongo/db/storage/mmap_v1/dur_recovery_unit.h b/src/mongo/db/storage/mmap_v1/dur_recovery_unit.h
new file mode 100644
index 00000000000..3b6ce9f85d4
--- /dev/null
+++ b/src/mongo/db/storage/mmap_v1/dur_recovery_unit.h
@@ -0,0 +1,57 @@
+/**
+ * Copyright (C) 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#include <string>
+
+#include "mongo/db/storage/recovery_unit.h"
+
+#pragma once
+
+namespace mongo {
+
+ /**
+ * Just pass through to getDur().
+ */
+ class DurRecoveryUnit : public RecoveryUnit {
+ public:
+ DurRecoveryUnit() { }
+
+ virtual ~DurRecoveryUnit() { }
+
+ virtual bool commitIfNeeded(bool force = false);
+
+ virtual bool isCommitNeeded() const;
+
+ virtual void* writingPtr(void* data, size_t len);
+
+ virtual void createdFile(const std::string& filename, unsigned long long len);
+
+ virtual void syncDataAndTruncateJournal();
+ };
+
+} // namespace mongo
diff --git a/src/mongo/db/storage/mmap_v1/dur_transaction.cpp b/src/mongo/db/storage/mmap_v1/dur_transaction.cpp
index 147dc9a71e2..8dbf008d5d3 100644
--- a/src/mongo/db/storage/mmap_v1/dur_transaction.cpp
+++ b/src/mongo/db/storage/mmap_v1/dur_transaction.cpp
@@ -31,16 +31,16 @@
#include "mongo/db/client.h"
#include "mongo/db/curop.h"
#include "mongo/db/kill_current_op.h"
-#include "mongo/db/storage/mmap_v1/dur.h"
+#include "mongo/db/storage/mmap_v1/dur_recovery_unit.h"
namespace mongo {
- bool DurTransaction::commitIfNeeded(bool force) {
- return getDur().commitIfNeeded(force);
+ DurTransaction::DurTransaction() {
+ _recovery.reset(new DurRecoveryUnit());
}
- bool DurTransaction::isCommitNeeded() const {
- return getDur().isCommitNeeded();
+ RecoveryUnit* DurTransaction::recoveryUnit() const {
+ return _recovery.get();
}
ProgressMeter* DurTransaction::setMessage(const char* msg,
@@ -50,18 +50,6 @@ namespace mongo {
return &cc().curop()->setMessage( msg, name, progressMeterTotal, secondsBetween );
}
- void* DurTransaction::writingPtr(void* data, size_t len) {
- return getDur().writingPtr(data, len);
- }
-
- void DurTransaction::createdFile(const std::string& filename, unsigned long long len) {
- getDur().createdFile(filename, len);
- }
-
- void DurTransaction::syncDataAndTruncateJournal() {
- return getDur().syncDataAndTruncateJournal();
- }
-
void DurTransaction::checkForInterrupt(bool heedMutex) const {
killCurrentOp.checkForInterrupt(heedMutex);
}
diff --git a/src/mongo/db/storage/mmap_v1/dur_transaction.h b/src/mongo/db/storage/mmap_v1/dur_transaction.h
index b4a2bd009e3..a0dc1029e6a 100644
--- a/src/mongo/db/storage/mmap_v1/dur_transaction.h
+++ b/src/mongo/db/storage/mmap_v1/dur_transaction.h
@@ -26,6 +26,7 @@
* it in the license file.
*/
+#include <boost/scoped_ptr.hpp>
#include <string>
#include "mongo/db/storage/transaction.h"
@@ -35,29 +36,21 @@
namespace mongo {
/**
- * Just pass through to getDur().
+ * TODO(hk): Move to db/ and rename to OperationContextMongoDImpl or something better?
*/
class DurTransaction : public TransactionExperiment {
public:
- DurTransaction() { }
+ DurTransaction();
virtual ~DurTransaction() { }
- virtual bool commitIfNeeded(bool force = false);
-
- virtual bool isCommitNeeded() const;
+ virtual RecoveryUnit* recoveryUnit() const;
virtual ProgressMeter* setMessage(const char* msg,
const std::string& name ,
unsigned long long progressMeterTotal,
int secondsBetween);
- virtual void* writingPtr(void* data, size_t len);
-
- virtual void createdFile(const std::string& filename, unsigned long long len);
-
- virtual void syncDataAndTruncateJournal();
-
virtual void checkForInterrupt(bool heedMutex = true) const;
virtual Status checkForInterruptNoAssert() const;
@@ -67,6 +60,8 @@ namespace mongo {
*/
static TransactionExperiment* factory();
+ private:
+ boost::scoped_ptr<RecoveryUnit> _recovery;
};
} // namespace mongo
diff --git a/src/mongo/db/storage/recovery_unit.h b/src/mongo/db/storage/recovery_unit.h
new file mode 100644
index 00000000000..7a4506c1ad6
--- /dev/null
+++ b/src/mongo/db/storage/recovery_unit.h
@@ -0,0 +1,108 @@
+/**
+ * Copyright (C) 2014 MongoDB Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * As a special exception, the copyright holders give permission to link the
+ * code of portions of this program with the OpenSSL library under certain
+ * conditions as described in each individual source file and distribute
+ * linked combinations including the program with the OpenSSL library. You
+ * must comply with the GNU Affero General Public License in all respects for
+ * all of the code used other than as permitted herein. If you modify file(s)
+ * with this exception, you may extend this exception to your version of the
+ * file(s), but you are not obligated to do so. If you do not wish to do so,
+ * delete this exception statement from your version. If you delete this
+ * exception statement from all source files in the program, then also delete
+ * it in the license file.
+ */
+
+#pragma once
+
+#include <stdlib.h>
+
+#include "mongo/base/disallow_copying.h"
+
+namespace mongo {
+
+ /**
+ * A RecoveryUnit is responsible for ensuring that data is persisted.
+ * All on-disk information must be mutated through this interface.
+ */
+ class RecoveryUnit {
+ MONGO_DISALLOW_COPYING(RecoveryUnit);
+ public:
+ virtual ~RecoveryUnit() { }
+
+ /**
+ * Commit if required. May take a long time. Returns true if committed.
+ *
+ * WARNING: Data *must* be in a crash-recoverable state when this is called.
+ */
+ virtual bool commitIfNeeded(bool force = false) = 0;
+
+ /**
+ * Returns true if a commit is needed but does not commit.
+ */
+ virtual bool isCommitNeeded() const = 0;
+
+ /**
+ * Declare that the data at [x, x + len) is being written.
+ */
+ virtual void* writingPtr(void* data, size_t len) = 0;
+
+ /**
+ * Declare that a file has been created
+ *
+ * Normally writes are applied only after journaling, for safety. But here the file
+ * is created first, and the journal will just replay the creation if the create didn't
+ * happen because of crashing.
+ */
+ virtual void createdFile(const std::string& filename, unsigned long long len) = 0;
+
+ /**
+ * Commits pending changes, flushes all changes to main data files, then removes the
+ * journal.
+ *
+ * WARNING: Data *must* be in a crash-recoverable state when this is called.
+ *
+ * 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;
+
+ //
+ // Syntactic sugar
+ //
+
+ /**
+ * Declare write intent for an int
+ */
+ inline int& writingInt(int& d) {
+ return *writing(&d);
+ }
+
+ /**
+ * A templated helper for writingPtr.
+ */
+ template <typename T>
+ inline T* writing(T* x) {
+ writingPtr(x, sizeof(T));
+ return x;
+ }
+
+ protected:
+ RecoveryUnit() { }
+ };
+
+} // namespace mongo
diff --git a/src/mongo/db/storage/transaction.h b/src/mongo/db/storage/transaction.h
index 2684342e542..e76e1ab49ca 100644
--- a/src/mongo/db/storage/transaction.h
+++ b/src/mongo/db/storage/transaction.h
@@ -32,6 +32,7 @@
#include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h"
+#include "mongo/db/storage/recovery_unit.h"
namespace mongo {
@@ -39,21 +40,65 @@ namespace mongo {
/**
* This name and this class are both a work in progress.
+ *
+ * TODO(hk): move up a level, rename to OperationContext (or OpCtx if you're into the whole
+ * brevity thing)
*/
class TransactionExperiment {
MONGO_DISALLOW_COPYING(TransactionExperiment);
public:
virtual ~TransactionExperiment() { }
+ /**
+ * Interface for durability. Caller DOES NOT own pointer.
+ *
+ * XXX: what's a better name for this
+ */
+ virtual RecoveryUnit* recoveryUnit() const = 0;
+
+ // XXX: migrate callers use the recoveryUnit() directly
+ template <typename T>
+ T* writing(T* x) {
+ return recoveryUnit()->writing(x);
+ }
+
+ int& writingInt(int& d) {
+ return recoveryUnit()->writingInt(d);
+ }
+
+ void syncDataAndTruncateJournal() {
+ recoveryUnit()->syncDataAndTruncateJournal();
+ }
+
+ void createdFile(const std::string& filename, unsigned long long len) {
+ recoveryUnit()->createdFile(filename, len);
+ }
+
+ void* writingPtr(void* data, size_t len) {
+ return recoveryUnit()->writingPtr(data, len);
+ }
+
+ bool isCommitNeeded() const {
+ return recoveryUnit()->isCommitNeeded();
+ }
+
+ bool commitIfNeeded(bool force = false) {
+ return recoveryUnit()->commitIfNeeded(force);
+ }
+ // XXX: migrate callers use the recoveryUnit() directly
+
+
// --- operation level info? ---
/**
+ * TODO: Get rid of this and just have one interrupt func?
* 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(bool heedMutex = true) const = 0;
/**
+ * TODO: Where do I go
* @return Status::OK() if not interrupted
* otherwise returns reasons
*/
@@ -67,64 +112,6 @@ namespace mongo {
unsigned long long progressMeterTotal = 0,
int secondsBetween = 3) = 0;
- // --- write unit of work methods ---
-
- /**
- * Commit if required. May take a long time. Returns true if committed.
- *
- * WARNING: Data *must* be in a crash-recoverable state when this is called.
- */
- virtual bool commitIfNeeded(bool force = false) = 0;
-
- /**
- * Returns true if a commit is needed but does not commit.
- */
- virtual bool isCommitNeeded() const = 0;
-
- /**
- * Declare that the data at [x, x + len) is being written.
- */
- virtual void* writingPtr(void* data, size_t len) = 0;
-
- /**
- * Declare that a file has been created
- *
- * Normally writes are applied only after journaling, for safety. But here the file
- * is created first, and the journal will just replay the creation if the create didn't
- * happen because of crashing.
- */
- virtual void createdFile(const std::string& filename, unsigned long long len) = 0;
-
- /**
- * Commits pending changes, flushes all changes to main data files, then removes the
- * journal.
- *
- * WARNING: Data *must* be in a crash-recoverable state when this is called.
- *
- * 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
- //
-
- /**
- * Declare write intent for an int
- */
- inline int& writingInt(int& d) { return *writing( &d ); }
-
- /**
- * A templated helper for writingPtr.
- */
- template <typename T>
- inline T* writing(T* x) {
- writingPtr(x, sizeof(T));
- return x;
- }
-
/**
* Returns a TransactionExperiment. Caller takes ownership.
*