diff options
author | Hari Khalsa <hkhalsa@10gen.com> | 2014-05-14 15:48:32 -0400 |
---|---|---|
committer | Hari Khalsa <hkhalsa@10gen.com> | 2014-05-15 10:14:59 -0400 |
commit | 1b218e1f1ca73f8d373d54b59f6137e167345997 (patch) | |
tree | 706de3a6d0690ab798f1254f940fd00e5dcedd0d | |
parent | d750344eebf1406abe40fee3948577fbefea8002 (diff) | |
download | mongo-1b218e1f1ca73f8d373d54b59f6137e167345997.tar.gz |
SERVER-13641 split out dur from transactionexperiment part 1
-rw-r--r-- | src/mongo/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_recovery_unit.cpp | 55 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_recovery_unit.h | 57 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_transaction.cpp | 22 | ||||
-rw-r--r-- | src/mongo/db/storage/mmap_v1/dur_transaction.h | 17 | ||||
-rw-r--r-- | src/mongo/db/storage/recovery_unit.h | 108 | ||||
-rw-r--r-- | src/mongo/db/storage/transaction.h | 103 |
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. * |