diff options
author | Daniel Gottlieb <daniel.gottlieb@10gen.com> | 2017-02-26 12:01:02 -0500 |
---|---|---|
committer | Daniel Gottlieb <daniel.gottlieb@10gen.com> | 2017-02-26 12:01:02 -0500 |
commit | b94dd91adb6d8859ab5e5f91731be2e8571eed0c (patch) | |
tree | ef3116315d0f79c9e4f690fffc5bdabb93f4751c /src/mongo/db/storage | |
parent | ce23378926659bc50604032782485c2f962c37ac (diff) | |
download | mongo-b94dd91adb6d8859ab5e5f91731be2e8571eed0c.tar.gz |
revert "SERVER-18410: Replace RWLock with OperationContext/LockManager"
This reverts commit 9c9bbf3318113cfdd4d9b72f493b6ebd23f1837e.
Diffstat (limited to 'src/mongo/db/storage')
34 files changed, 242 insertions, 430 deletions
diff --git a/src/mongo/db/storage/kv/kv_engine.h b/src/mongo/db/storage/kv/kv_engine.h index 04c5acb1dfa..e6dd1f8cbbe 100644 --- a/src/mongo/db/storage/kv/kv_engine.h +++ b/src/mongo/db/storage/kv/kv_engine.h @@ -91,7 +91,7 @@ public: virtual Status dropIdent(OperationContext* opCtx, StringData ident) = 0; // optional - virtual int flushAllFiles(OperationContext* txn, bool sync) { + virtual int flushAllFiles(bool sync) { return 0; } diff --git a/src/mongo/db/storage/kv/kv_storage_engine.cpp b/src/mongo/db/storage/kv/kv_storage_engine.cpp index ee02c447bdf..f825cb3a1c2 100644 --- a/src/mongo/db/storage/kv/kv_storage_engine.cpp +++ b/src/mongo/db/storage/kv/kv_storage_engine.cpp @@ -251,8 +251,8 @@ Status KVStorageEngine::dropDatabase(OperationContext* txn, StringData db) { return Status::OK(); } -int KVStorageEngine::flushAllFiles(OperationContext* txn, bool sync) { - return _engine->flushAllFiles(txn, sync); +int KVStorageEngine::flushAllFiles(bool sync) { + return _engine->flushAllFiles(sync); } Status KVStorageEngine::beginBackup(OperationContext* txn) { diff --git a/src/mongo/db/storage/kv/kv_storage_engine.h b/src/mongo/db/storage/kv/kv_storage_engine.h index ba656ae85c1..32bab2ee252 100644 --- a/src/mongo/db/storage/kv/kv_storage_engine.h +++ b/src/mongo/db/storage/kv/kv_storage_engine.h @@ -93,7 +93,7 @@ public: virtual Status dropDatabase(OperationContext* txn, StringData db); - virtual int flushAllFiles(OperationContext* txn, bool sync); + virtual int flushAllFiles(bool sync); virtual Status beginBackup(OperationContext* txn); diff --git a/src/mongo/db/storage/mmap_v1/SConscript b/src/mongo/db/storage/mmap_v1/SConscript index ba8fd96c097..4fa273fe408 100644 --- a/src/mongo/db/storage/mmap_v1/SConscript +++ b/src/mongo/db/storage/mmap_v1/SConscript @@ -115,11 +115,9 @@ env.Library( 'mmap_${TARGET_OS_FAMILY}.cpp', ], LIBDEPS=[ - '$BUILD_DIR/mongo/db/concurrency/lock_manager', - '$BUILD_DIR/mongo/db/service_context', - '$BUILD_DIR/mongo/db/storage/storage_options', - '$BUILD_DIR/mongo/util/progress_meter', 'file_allocator', + '$BUILD_DIR/mongo/util/progress_meter', + '$BUILD_DIR/mongo/db/storage/storage_options' ], ) diff --git a/src/mongo/db/storage/mmap_v1/catalog/namespace_index.cpp b/src/mongo/db/storage/mmap_v1/catalog/namespace_index.cpp index 173c2afceca..ffca8474db3 100644 --- a/src/mongo/db/storage/mmap_v1/catalog/namespace_index.cpp +++ b/src/mongo/db/storage/mmap_v1/catalog/namespace_index.cpp @@ -51,10 +51,8 @@ using std::endl; using std::list; using std::string; -NamespaceIndex::NamespaceIndex(OperationContext* txn, - const std::string& dir, - const std::string& database) - : _dir(dir), _database(database), _f(txn, MongoFile::Options::SEQUENTIAL), _ht(nullptr) {} +NamespaceIndex::NamespaceIndex(const std::string& dir, const std::string& database) + : _dir(dir), _database(database), _ht(nullptr) {} NamespaceIndex::~NamespaceIndex() {} @@ -158,7 +156,7 @@ void NamespaceIndex::init(OperationContext* txn) { void* p = 0; if (boost::filesystem::exists(nsPath)) { - if (_f.open(txn, pathString)) { + if (_f.open(pathString)) { len = _f.length(); if (len % (1024 * 1024) != 0) { @@ -217,7 +215,7 @@ void NamespaceIndex::init(OperationContext* txn) { massert(18826, str::stream() << "failure writing file " << pathString, !file.bad()); } - if (_f.create(txn, pathString, l)) { + if (_f.create(pathString, l)) { // The writes done in this function must not be rolled back. This will leave the // file empty, but available for future use. That is why we go directly to the // global dur dirty list rather than going through the OperationContext. diff --git a/src/mongo/db/storage/mmap_v1/catalog/namespace_index.h b/src/mongo/db/storage/mmap_v1/catalog/namespace_index.h index 51aae08ea61..8bcf836518c 100644 --- a/src/mongo/db/storage/mmap_v1/catalog/namespace_index.h +++ b/src/mongo/db/storage/mmap_v1/catalog/namespace_index.h @@ -51,17 +51,9 @@ class NamespaceIndex { MONGO_DISALLOW_COPYING(NamespaceIndex); public: - NamespaceIndex(OperationContext* txn, const std::string& dir, const std::string& database); + NamespaceIndex(const std::string& dir, const std::string& database); ~NamespaceIndex(); - /** - * Must be called before destruction. - */ - void close(OperationContext* txn) { - LockMongoFilesExclusive lock(txn); - _f.close(txn); - } - /* returns true if the file represented by this file exists on disk */ bool pathExists() const; @@ -94,7 +86,7 @@ private: const std::string _dir; const std::string _database; - DurableMappedFile _f; + DurableMappedFile _f{MongoFile::Options::SEQUENTIAL}; std::unique_ptr<NamespaceHashTable> _ht; }; } diff --git a/src/mongo/db/storage/mmap_v1/data_file.cpp b/src/mongo/db/storage/mmap_v1/data_file.cpp index d81aa591817..c90ff1f74da 100644 --- a/src/mongo/db/storage/mmap_v1/data_file.cpp +++ b/src/mongo/db/storage/mmap_v1/data_file.cpp @@ -104,14 +104,14 @@ int DataFile::_defaultSize() const { } /** @return true if found and opened. if uninitialized (prealloc only) does not open. */ -Status DataFile::openExisting(OperationContext* txn, const char* filename) { +Status DataFile::openExisting(const char* filename) { invariant(_mb == 0); if (!boost::filesystem::exists(filename)) { return Status(ErrorCodes::InvalidPath, "DataFile::openExisting - file does not exist"); } - if (!mmf.open(txn, filename)) { + if (!mmf.open(filename)) { return Status(ErrorCodes::InternalError, "DataFile::openExisting - mmf.open failed"); } @@ -170,7 +170,7 @@ void DataFile::open(OperationContext* txn, { invariant(_mb == 0); unsigned long long sz = size; - if (mmf.create(txn, filename, sz)) { + if (mmf.create(filename, sz)) { _mb = mmf.getView(); } diff --git a/src/mongo/db/storage/mmap_v1/data_file.h b/src/mongo/db/storage/mmap_v1/data_file.h index 57b5fb223f9..e28a5ebcc6e 100644 --- a/src/mongo/db/storage/mmap_v1/data_file.h +++ b/src/mongo/db/storage/mmap_v1/data_file.h @@ -195,10 +195,10 @@ public: class DataFile { public: - DataFile(OperationContext* txn, int fn) : _fileNo(fn), mmf(txn), _mb(NULL) {} + DataFile(int fn) : _fileNo(fn), _mb(NULL) {} /** @return true if found and opened. if uninitialized (prealloc only) does not open. */ - Status openExisting(OperationContext* txn, const char* filename); + Status openExisting(const char* filename); /** creates if DNE */ void open(OperationContext* txn, @@ -206,14 +206,6 @@ public: int requestedDataSize = 0, bool preallocateOnly = false); - /** - * Must be called before destruction. - */ - void close(OperationContext* txn) { - LockMongoFilesExclusive lock(txn); - mmf.close(txn); - } - DiskLoc allocExtentArea(OperationContext* txn, int size); DataFileHeader* getHeader() { diff --git a/src/mongo/db/storage/mmap_v1/data_file_sync.cpp b/src/mongo/db/storage/mmap_v1/data_file_sync.cpp index e1bc51d29f3..24be15045f0 100644 --- a/src/mongo/db/storage/mmap_v1/data_file_sync.cpp +++ b/src/mongo/db/storage/mmap_v1/data_file_sync.cpp @@ -35,7 +35,6 @@ #include "mongo/db/client.h" #include "mongo/db/commands/server_status_metric.h" #include "mongo/db/diag_log.h" -#include "mongo/db/operation_context.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/mmap_v1/dur_journal.h" #include "mongo/db/storage/mmap_v1/mmap.h" @@ -81,12 +80,11 @@ void DataFileSync::run() { break; } - auto txn = cc().makeOperationContext(); Date_t start = jsTime(); StorageEngine* storageEngine = getGlobalServiceContext()->getGlobalStorageEngine(); dur::notifyPreDataFileFlush(); - int numFiles = storageEngine->flushAllFiles(txn.get(), true); + int numFiles = storageEngine->flushAllFiles(true); dur::notifyPostDataFileFlush(); time_flushing = durationCount<Milliseconds>(jsTime() - start); @@ -127,7 +125,7 @@ class MemJournalServerStatusMetric : public ServerStatusMetric { public: MemJournalServerStatusMetric() : ServerStatusMetric(".mem.mapped") {} virtual void appendAtLeaf(BSONObjBuilder& b) const { - int m = MemoryMappedFile::totalMappedLengthInMB(); + int m = static_cast<int>(MemoryMappedFile::totalMappedLength() / (1024 * 1024)); b.appendNumber("mapped", m); if (storageGlobalParams.dur) { @@ -135,5 +133,6 @@ public: b.appendNumber("mappedWithJournal", m); } } + } memJournalServerStatusMetric; } diff --git a/src/mongo/db/storage/mmap_v1/dur.cpp b/src/mongo/db/storage/mmap_v1/dur.cpp index 1ed496c3a6d..ab1d1988cba 100644 --- a/src/mongo/db/storage/mmap_v1/dur.cpp +++ b/src/mongo/db/storage/mmap_v1/dur.cpp @@ -204,7 +204,7 @@ public: return false; } virtual void closingFileNotification() {} - virtual void commitAndStopDurThread(OperationContext* txn) {} + virtual void commitAndStopDurThread() {} }; @@ -226,7 +226,7 @@ public: return true; } virtual void closingFileNotification(); - virtual void commitAndStopDurThread(OperationContext* txn); + virtual void commitAndStopDurThread(); void start(ClockSource* cs, int64_t serverStartMs); @@ -318,7 +318,7 @@ void debugValidateFileMapsMatch(const DurableMappedFile* mmf) { /** * Main code of the remap private view function. */ -void remapPrivateViewImpl(OperationContext* txn, double fraction) { +void remapPrivateViewImpl(double fraction) { LOG(4) << "journal REMAPPRIVATEVIEW" << endl; // There is no way that the set of files can change while we are in this method, because @@ -335,9 +335,9 @@ void remapPrivateViewImpl(OperationContext* txn, double fraction) { // See SERVER-5680 to see why this code is necessary on Windows. // See SERVER-8795 to see why this code is necessary on Solaris. #if defined(_WIN32) || defined(__sun) - LockMongoFilesExclusive lk(txn); + LockMongoFilesExclusive lk; #else - LockMongoFilesShared lk(txn); + LockMongoFilesShared lk; #endif std::set<MongoFile*>& files = MongoFile::getAllFiles(); @@ -381,7 +381,7 @@ void remapPrivateViewImpl(OperationContext* txn, double fraction) { } if (mmf->willNeedRemap()) { - mmf->remapThePrivateView(txn); + mmf->remapThePrivateView(); } i++; @@ -570,7 +570,7 @@ void DurableImpl::syncDataAndTruncateJournal(OperationContext* txn) { commitNow(txn); // Flush the shared view to disk. - MongoFile::flushAll(txn, true); + MongoFile::flushAll(true); // Once the shared view has been flushed, we do not need the journal files anymore. journalCleanup(true); @@ -588,7 +588,7 @@ void DurableImpl::closingFileNotification() { } } -void DurableImpl::commitAndStopDurThread(OperationContext* txn) { +void DurableImpl::commitAndStopDurThread() { CommitNotifier::When when = commitNotify.now(); // There is always just one waiting anyways @@ -600,7 +600,7 @@ void DurableImpl::commitAndStopDurThread(OperationContext* txn) { applyToDataFilesNotify.waitFor(when); // Flush the shared view to disk. - MongoFile::flushAll(txn, true); + MongoFile::flushAll(true); // Once the shared view has been flushed, we do not need the journal files anymore. journalCleanup(true); @@ -630,14 +630,14 @@ void DurableImpl::start(ClockSource* cs, int64_t serverStartMs) { * @param fraction Value between (0, 1] indicating what fraction of the memory to remap. * Remapping too much or too frequently incurs copy-on-write page fault cost. */ -static void remapPrivateView(OperationContext* txn, double fraction) { +static void remapPrivateView(double fraction) { // Remapping private views must occur after WRITETODATAFILES otherwise we wouldn't see any // newly written data on reads. invariant(!commitJob.hasWritten()); try { Timer t; - remapPrivateViewImpl(txn, fraction); + remapPrivateViewImpl(fraction); stats.curr()->_remapPrivateViewMicros += t.micros(); LOG(4) << "remapPrivateView end"; @@ -828,7 +828,7 @@ static void durThread(ClockSource* cs, int64_t serverStartMs) { // accessing it. Technically this step could be avoided on systems, which // support atomic remap. autoFlushLock.upgradeFlushLockToExclusive(); - remapPrivateView(txnPtr.get(), remapFraction); + remapPrivateView(remapFraction); autoFlushLock.release(); diff --git a/src/mongo/db/storage/mmap_v1/dur.h b/src/mongo/db/storage/mmap_v1/dur.h index e4aec954749..cf5e4ec2b14 100644 --- a/src/mongo/db/storage/mmap_v1/dur.h +++ b/src/mongo/db/storage/mmap_v1/dur.h @@ -112,7 +112,7 @@ public: * * Must be called under the global X lock. */ - virtual void commitAndStopDurThread(OperationContext* txn) = 0; + virtual void commitAndStopDurThread() = 0; /** * Commits pending changes, flushes all changes to main data files, then removes the diff --git a/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp b/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp index 5c9fe117d52..4eb0b4ea16b 100644 --- a/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp +++ b/src/mongo/db/storage/mmap_v1/dur_journal_writer.cpp @@ -56,14 +56,12 @@ namespace { * (2) TODO should we do this using N threads? Would be quite easy see Hackenberg paper table * 5 and 6. 2 threads might be a good balance. */ -void WRITETODATAFILES(OperationContext* txn, - const JSectHeader& h, - const AlignedBuilder& uncompressed) { +void WRITETODATAFILES(const JSectHeader& h, const AlignedBuilder& uncompressed) { Timer t; LOG(4) << "WRITETODATAFILES BEGIN"; - RecoveryJob::get().processSection(txn, &h, uncompressed.buf(), uncompressed.len(), NULL); + RecoveryJob::get().processSection(&h, uncompressed.buf(), uncompressed.len(), NULL); const long long m = t.micros(); stats.curr()->_writeToDataFilesMicros += m; @@ -246,7 +244,7 @@ void JournalWriter::_journalWriterThread() { // Apply the journal entries on top of the shared view so that when flush is // requested it would write the latest. - WRITETODATAFILES(cc().makeOperationContext().get(), buffer->_header, buffer->_builder); + WRITETODATAFILES(buffer->_header, buffer->_builder); // Data is now persisted on the shared view, so notify any potential journal file // cleanup waiters. diff --git a/src/mongo/db/storage/mmap_v1/dur_recover.cpp b/src/mongo/db/storage/mmap_v1/dur_recover.cpp index cdd3d4e3db2..ec6b945455e 100644 --- a/src/mongo/db/storage/mmap_v1/dur_recover.cpp +++ b/src/mongo/db/storage/mmap_v1/dur_recover.cpp @@ -58,7 +58,6 @@ #include "mongo/util/hex.h" #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" -#include "mongo/util/scopeguard.h" #include "mongo/util/startup_test.h" namespace mongo { @@ -265,26 +264,22 @@ RecoveryJob::RecoveryJob() _appliedAnySections(false) {} RecoveryJob::~RecoveryJob() { - invariant(!"RecoveryJob is intentionally leaked with a bare call to operator new()"); + DESTRUCTOR_GUARD(if (!_mmfs.empty()) {} close();) } -void RecoveryJob::close(OperationContext* txn) { +void RecoveryJob::close() { stdx::lock_guard<stdx::mutex> lk(_mx); - _close(txn); + _close(); } -void RecoveryJob::_close(OperationContext* txn) { - MongoFile::flushAll(txn, true); - LockMongoFilesExclusive lock(txn); - for (auto& durFile : _mmfs) { - durFile->close(txn); - } +void RecoveryJob::_close() { + MongoFile::flushAll(true); _mmfs.clear(); } -RecoveryJob::Last::Last(OperationContext* txn) : _txn(txn), mmf(NULL), fileNo(-1) { +RecoveryJob::Last::Last() : mmf(NULL), fileNo(-1) { // Make sure the files list does not change from underneath - LockMongoFilesShared::assertAtLeastReadLocked(txn); + LockMongoFilesShared::assertAtLeastReadLocked(); } DurableMappedFile* RecoveryJob::Last::newEntry(const dur::ParsedJournalEntry& entry, @@ -296,7 +291,7 @@ DurableMappedFile* RecoveryJob::Last::newEntry(const dur::ParsedJournalEntry& en string fn = fileName(entry.dbName, num); MongoFile* file; { - MongoFileFinder finder(_txn); // must release lock before creating new DurableMappedFile + MongoFileFinder finder; // must release lock before creating new DurableMappedFile file = finder.findByPath(fn); } @@ -308,8 +303,8 @@ DurableMappedFile* RecoveryJob::Last::newEntry(const dur::ParsedJournalEntry& en log() << "journal error applying writes, file " << fn << " is not open" << endl; verify(false); } - std::shared_ptr<DurableMappedFile> sp(new DurableMappedFile(_txn)); - verify(sp->open(_txn, fn)); + std::shared_ptr<DurableMappedFile> sp(new DurableMappedFile); + verify(sp->open(fn)); rj._mmfs.push_back(sp); mmf = sp.get(); } @@ -363,14 +358,14 @@ void RecoveryJob::applyEntry(Last& last, const ParsedJournalEntry& entry, bool a } if (apply) { if (entry.op->needFilesClosed()) { - _close(last.txn()); // locked in processSection + _close(); // locked in processSection } entry.op->replay(); } } } -void RecoveryJob::applyEntries(OperationContext* txn, const vector<ParsedJournalEntry>& entries) { +void RecoveryJob::applyEntries(const vector<ParsedJournalEntry>& entries) { const bool apply = (mmapv1GlobalOptions.journalOptions & MMAPV1Options::JournalScanOnly) == 0; const bool dump = (mmapv1GlobalOptions.journalOptions & MMAPV1Options::JournalDumpJournal); @@ -378,7 +373,7 @@ void RecoveryJob::applyEntries(OperationContext* txn, const vector<ParsedJournal log() << "BEGIN section" << endl; } - Last last(txn); + Last last; for (vector<ParsedJournalEntry>::const_iterator i = entries.begin(); i != entries.end(); ++i) { applyEntry(last, *i, apply, dump); } @@ -388,12 +383,11 @@ void RecoveryJob::applyEntries(OperationContext* txn, const vector<ParsedJournal } } -void RecoveryJob::processSection(OperationContext* txn, - const JSectHeader* h, +void RecoveryJob::processSection(const JSectHeader* h, const void* p, unsigned len, const JSectFooter* f) { - LockMongoFilesShared lkFiles(txn); // for RecoveryJob::Last + LockMongoFilesShared lkFiles; // for RecoveryJob::Last stdx::lock_guard<stdx::mutex> lk(_mx); if (_recovering) { @@ -467,14 +461,14 @@ void RecoveryJob::processSection(OperationContext* txn, } // got all the entries for one group commit. apply them: - applyEntries(txn, entries); + applyEntries(entries); } /** apply a specific journal file, that is already mmap'd @param p start of the memory mapped file @return true if this is detected to be the last file (ends abruptly) */ -bool RecoveryJob::processFileBuffer(OperationContext* txn, const void* p, unsigned len) { +bool RecoveryJob::processFileBuffer(const void* p, unsigned len) { try { unsigned long long fileId; BufReader br(p, len); @@ -529,7 +523,7 @@ bool RecoveryJob::processFileBuffer(OperationContext* txn, const void* p, unsign const char* hdr = (const char*)br.skip(h.sectionLenWithPadding()); const char* data = hdr + sizeof(JSectHeader); const char* footer = data + dataLen; - processSection(txn, (const JSectHeader*)hdr, data, dataLen, (const JSectFooter*)footer); + processSection((const JSectHeader*)hdr, data, dataLen, (const JSectFooter*)footer); // ctrl c check uassert(ErrorCodes::Interrupted, @@ -550,7 +544,7 @@ bool RecoveryJob::processFileBuffer(OperationContext* txn, const void* p, unsign } /** apply a specific journal file */ -bool RecoveryJob::processFile(OperationContext* txn, boost::filesystem::path journalfile) { +bool RecoveryJob::processFile(boost::filesystem::path journalfile) { log() << "recover " << journalfile.string() << endl; try { @@ -564,20 +558,16 @@ bool RecoveryJob::processFile(OperationContext* txn, boost::filesystem::path jou log() << "recover exception checking filesize" << endl; } - MemoryMappedFile f{txn, MongoFile::Options::READONLY | MongoFile::Options::SEQUENTIAL}; - ON_BLOCK_EXIT([&f, &txn] { - LockMongoFilesExclusive lock(txn); - f.close(txn); - }); - void* p = f.map(txn, journalfile.string().c_str()); + MemoryMappedFile f{MongoFile::Options::READONLY | MongoFile::Options::SEQUENTIAL}; + void* p = f.map(journalfile.string().c_str()); massert(13544, str::stream() << "recover error couldn't open " << journalfile.string(), p); - return processFileBuffer(txn, p, (unsigned)f.length()); + return processFileBuffer(p, (unsigned)f.length()); } /** @param files all the j._0 style files we need to apply for recovery */ -void RecoveryJob::go(OperationContext* txn, vector<boost::filesystem::path>& files) { +void RecoveryJob::go(vector<boost::filesystem::path>& files) { log() << "recover begin" << endl; - LockMongoFilesExclusive lkFiles(txn); // for RecoveryJob::Last + LockMongoFilesExclusive lkFiles; // for RecoveryJob::Last _recovering = true; // load the last sequence number synced to the datafiles on disk before the last crash @@ -585,11 +575,11 @@ void RecoveryJob::go(OperationContext* txn, vector<boost::filesystem::path>& fil log() << "recover lsn: " << _lastDataSyncedFromLastRun << endl; for (unsigned i = 0; i != files.size(); ++i) { - bool abruptEnd = processFile(txn, files[i]); + bool abruptEnd = processFile(files[i]); if (abruptEnd && i + 1 < files.size()) { log() << "recover error: abrupt end to file " << files[i].string() << ", yet it isn't the last journal file" << endl; - close(txn); + close(); uasserted(13535, "recover abrupt journal file end"); } } @@ -600,7 +590,7 @@ void RecoveryJob::go(OperationContext* txn, vector<boost::filesystem::path>& fil << "Last skipped sections had sequence number " << _lastSeqSkipped; } - close(txn); + close(); if (mmapv1GlobalOptions.journalOptions & MMAPV1Options::JournalScanOnly) { uasserted(13545, @@ -615,7 +605,7 @@ void RecoveryJob::go(OperationContext* txn, vector<boost::filesystem::path>& fil _recovering = false; } -void _recover(OperationContext* txn) { +void _recover() { verify(storageGlobalParams.dur); boost::filesystem::path p = getJournalDir(); @@ -635,7 +625,7 @@ void _recover(OperationContext* txn) { return; } - RecoveryJob::get().go(txn, journalFiles); + RecoveryJob::get().go(journalFiles); } /** recover from a crash @@ -645,18 +635,18 @@ void _recover(OperationContext* txn) { void replayJournalFilesAtStartup() { // we use a lock so that exitCleanly will wait for us // to finish (or at least to notice what is up and stop) - auto txn = cc().makeOperationContext(); - ScopedTransaction transaction(txn.get(), MODE_X); - Lock::GlobalWrite lk(txn->lockState()); + const ServiceContext::UniqueOperationContext txnPtr = cc().makeOperationContext(); + OperationContext& txn = *txnPtr; + ScopedTransaction transaction(&txn, MODE_X); + Lock::GlobalWrite lk(txn.lockState()); - _recover(txn.get()); // throws on interruption + _recover(); // throws on interruption } struct BufReaderY { int a, b; }; class BufReaderUnitTest : public StartupTest { - public: void run() { BufReader r((void*)"abcdabcdabcd", 12); diff --git a/src/mongo/db/storage/mmap_v1/dur_recover.h b/src/mongo/db/storage/mmap_v1/dur_recover.h index 9447044b607..b9b7c5ddfdb 100644 --- a/src/mongo/db/storage/mmap_v1/dur_recover.h +++ b/src/mongo/db/storage/mmap_v1/dur_recover.h @@ -34,7 +34,6 @@ #include <list> #include <memory> -#include "mongo/db/service_context.h" #include "mongo/db/storage/mmap_v1/dur_journalformat.h" #include "mongo/stdx/mutex.h" #include "mongo/util/concurrency/mutex.h" @@ -56,17 +55,13 @@ public: RecoveryJob(); ~RecoveryJob(); - void go(OperationContext* txn, std::vector<boost::filesystem::path>& files); + void go(std::vector<boost::filesystem::path>& files); /** @param data data between header and footer. compressed if recovering. */ - void processSection(OperationContext* txn, - const JSectHeader* h, - const void* data, - unsigned len, - const JSectFooter* f); + void processSection(const JSectHeader* h, const void* data, unsigned len, const JSectFooter* f); // locks and calls _close() - void close(OperationContext* txn); + void close(); static RecoveryJob& get() { return _instance; @@ -75,16 +70,10 @@ public: private: class Last { public: - Last(OperationContext* txn); - + Last(); DurableMappedFile* newEntry(const ParsedJournalEntry&, RecoveryJob&); - OperationContext* txn() { - return _txn; - } - private: - OperationContext* _txn; DurableMappedFile* mmf; std::string dbName; int fileNo; @@ -93,10 +82,11 @@ private: void write(Last& last, const ParsedJournalEntry& entry); // actually writes to the file void applyEntry(Last& last, const ParsedJournalEntry& entry, bool apply, bool dump); - void applyEntries(OperationContext* txn, const std::vector<ParsedJournalEntry>& entries); - bool processFileBuffer(OperationContext* txn, const void*, unsigned len); - bool processFile(OperationContext* txn, boost::filesystem::path journalfile); - void _close(OperationContext* txn); // doesn't lock + void applyEntries(const std::vector<ParsedJournalEntry>& entries); + bool processFileBuffer(const void*, unsigned len); + bool processFile(boost::filesystem::path journalfile); + void _close(); // doesn't lock + // Set of memory mapped files and a mutex to protect them stdx::mutex _mx; diff --git a/src/mongo/db/storage/mmap_v1/durable_mapped_file.cpp b/src/mongo/db/storage/mmap_v1/durable_mapped_file.cpp index 548cb8c9f05..a7e8e2e429f 100644 --- a/src/mongo/db/storage/mmap_v1/durable_mapped_file.cpp +++ b/src/mongo/db/storage/mmap_v1/durable_mapped_file.cpp @@ -61,7 +61,7 @@ using std::map; using std::pair; using std::string; -void DurableMappedFile::remapThePrivateView(OperationContext* txn) { +void DurableMappedFile::remapThePrivateView() { verify(storageGlobalParams.dur); _willNeedRemap = false; @@ -70,7 +70,7 @@ void DurableMappedFile::remapThePrivateView(OperationContext* txn) { // so the remove / add isn't necessary and can be removed? void* old = _view_private; // privateViews.remove(_view_private); - _view_private = remapPrivateView(txn, _view_private); + _view_private = remapPrivateView(_view_private); // privateViews.add(_view_private, this); fassert(16112, _view_private == old); } @@ -241,24 +241,22 @@ void DurableMappedFile::setPath(const std::string& f) { _p = RelativePath::fromFullPath(storageGlobalParams.dbpath, prefix); } -bool DurableMappedFile::open(OperationContext* txn, const std::string& fname) { +bool DurableMappedFile::open(const std::string& fname) { LOG(3) << "mmf open " << fname; invariant(!_view_write); setPath(fname); - _view_write = map(txn, fname.c_str()); + _view_write = map(fname.c_str()); fassert(16333, _view_write); return finishOpening(); } -bool DurableMappedFile::create(OperationContext* txn, - const std::string& fname, - unsigned long long& len) { +bool DurableMappedFile::create(const std::string& fname, unsigned long long& len) { LOG(3) << "mmf create " << fname; invariant(!_view_write); setPath(fname); - _view_write = map(txn, fname.c_str(), len); + _view_write = map(fname.c_str(), len); fassert(16332, _view_write); return finishOpening(); } @@ -285,7 +283,12 @@ bool DurableMappedFile::finishOpening() { return false; } -void DurableMappedFile::close(OperationContext* txn) { +DurableMappedFile::DurableMappedFile(OptionSet options) + : MemoryMappedFile(options), _willNeedRemap(false) { + _view_write = _view_private = 0; +} + +DurableMappedFile::~DurableMappedFile() { try { LOG(3) << "mmf close " << filename(); @@ -296,20 +299,12 @@ void DurableMappedFile::close(OperationContext* txn) { getDur().closingFileNotification(); } + LockMongoFilesExclusive lk; privateViews.remove(_view_private, length()); - MemoryMappedFile::close(txn); + MemoryMappedFile::close(); } catch (...) { - error() << "exception in DurableMappedFile::close"; + error() << "exception in ~DurableMappedFile"; } } - -DurableMappedFile::DurableMappedFile(OperationContext* txn, OptionSet options) - : MemoryMappedFile(txn, options), _willNeedRemap(false) { - _view_write = _view_private = 0; -} - -DurableMappedFile::~DurableMappedFile() { - invariant(isClosed()); -} } diff --git a/src/mongo/db/storage/mmap_v1/durable_mapped_file.h b/src/mongo/db/storage/mmap_v1/durable_mapped_file.h index 7c6e99bfc7e..3175fa8fa73 100644 --- a/src/mongo/db/storage/mmap_v1/durable_mapped_file.h +++ b/src/mongo/db/storage/mmap_v1/durable_mapped_file.h @@ -32,7 +32,6 @@ #pragma once #include "mongo/base/static_assert.h" -#include "mongo/db/operation_context.h" #include "mongo/db/storage/mmap_v1/mmap.h" #include "mongo/db/storage/paths.h" #include "mongo/stdx/mutex.h" @@ -51,16 +50,11 @@ protected: } public: - explicit DurableMappedFile(OperationContext* txn, OptionSet options = NONE); + DurableMappedFile(OptionSet options = NONE); virtual ~DurableMappedFile(); - /** - * Callers must be holding a `LockMongoFilesExclusive`. - */ - virtual void close(OperationContext* txn); - /** @return true if opened ok. */ - bool open(OperationContext* txn, const std::string& fname); + bool open(const std::string& fname); /** @return file length */ unsigned long long length() const { @@ -79,7 +73,7 @@ public: passed length. @return true for ok */ - bool create(OperationContext* txn, const std::string& fname, unsigned long long& len); + bool create(const std::string& fname, unsigned long long& len); /* Get the "standard" view (which is the private one). @return the private view. @@ -123,7 +117,7 @@ public: _willNeedRemap = true; } - void remapThePrivateView(OperationContext* txn); + void remapThePrivateView(); virtual bool isDurableMappedFile() { return true; diff --git a/src/mongo/db/storage/mmap_v1/extent_manager.h b/src/mongo/db/storage/mmap_v1/extent_manager.h index 1ca0ab7b9f1..4ce623ffc8a 100644 --- a/src/mongo/db/storage/mmap_v1/extent_manager.h +++ b/src/mongo/db/storage/mmap_v1/extent_manager.h @@ -77,8 +77,6 @@ public: virtual ~ExtentManager() {} - virtual void close(OperationContext* txn) = 0; - /** * opens all current files */ diff --git a/src/mongo/db/storage/mmap_v1/mmap.cpp b/src/mongo/db/storage/mmap_v1/mmap.cpp index bdce2bd6468..c8eaacd2f63 100644 --- a/src/mongo/db/storage/mmap_v1/mmap.cpp +++ b/src/mongo/db/storage/mmap_v1/mmap.cpp @@ -36,10 +36,8 @@ #include <boost/filesystem/operations.hpp> #include "mongo/base/owned_pointer_vector.h" -#include "mongo/db/client.h" -#include "mongo/db/concurrency/locker.h" -#include "mongo/db/operation_context.h" #include "mongo/db/storage/storage_options.h" +#include "mongo/util/concurrency/rwlock.h" #include "mongo/util/log.h" #include "mongo/util/map_util.h" #include "mongo/util/mongoutils/str.h" @@ -69,33 +67,16 @@ map<string, MongoFile*> pathToFile; mongo::AtomicUInt64 mmfNextId(0); } // namespace -MemoryMappedFile::MemoryMappedFile(OperationContext* txn, OptionSet options) +MemoryMappedFile::MemoryMappedFile(OptionSet options) : MongoFile(options), _uniqueId(mmfNextId.fetchAndAdd(1)) { - created(txn); + created(); } -MemoryMappedFile::~MemoryMappedFile() { - invariant(isClosed()); - - auto txn = cc().getOperationContext(); - invariant(txn); - - LockMongoFilesShared lock(txn); - for (std::set<MongoFile*>::const_iterator it = mmfiles.begin(); it != mmfiles.end(); it++) { - invariant(*it != this); - } -} - -/*static*/ AtomicUInt64 MemoryMappedFile::totalMappedLength; - -void* MemoryMappedFile::create(OperationContext* txn, - const std::string& filename, - unsigned long long len, - bool zero) { +void* MemoryMappedFile::create(const std::string& filename, unsigned long long len, bool zero) { uassert(13468, string("can't create file already exists ") + filename, !boost::filesystem::exists(filename)); - void* p = map(txn, filename.c_str(), len); + void* p = map(filename.c_str(), len); fassert(16331, p); if (zero) { size_t sz = (size_t)len; @@ -113,7 +94,7 @@ void* MemoryMappedFile::create(OperationContext* txn, length = l; } -void* MemoryMappedFile::map(OperationContext* txn, const char* filename) { +void* MemoryMappedFile::map(const char* filename) { unsigned long long l; try { l = boost::filesystem::file_size(filename); @@ -125,7 +106,7 @@ void* MemoryMappedFile::map(OperationContext* txn, const char* filename) { << e.what()); } - void* ret = map(txn, filename, l); + void* ret = map(filename, l); fassert(16334, ret); return ret; } @@ -138,7 +119,7 @@ MongoFile::MongoFile(OptionSet options) : _options(storageGlobalParams.readOnly ? (options | READONLY) : options) {} -Lock::ResourceMutex LockMongoFilesShared::mmmutex("MMapMutex"); +RWLockRecursiveNongreedy LockMongoFilesShared::mmmutex("mmmutex", 10 * 60 * 1000 /* 10 minutes */); unsigned LockMongoFilesShared::era = 99; // note this rolls over set<MongoFile*>& MongoFile::getAllFiles() { @@ -150,14 +131,14 @@ set<MongoFile*>& MongoFile::getAllFiles() { safe to call more than once, albeit might be wasted work ideal to call close to the close, if the close is well before object destruction */ -void MongoFile::destroyed(OperationContext* txn) { - LockMongoFilesShared::assertExclusivelyLocked(txn); +void MongoFile::destroyed() { + LockMongoFilesShared::assertExclusivelyLocked(); mmfiles.erase(this); pathToFile.erase(filename()); } /*static*/ -void MongoFile::closeAllFiles(OperationContext* txn, stringstream& message) { +void MongoFile::closeAllFiles(stringstream& message) { static int closingAllFiles = 0; if (closingAllFiles) { message << "warning closingAllFiles=" << closingAllFiles << endl; @@ -165,26 +146,37 @@ void MongoFile::closeAllFiles(OperationContext* txn, stringstream& message) { } ++closingAllFiles; - LockMongoFilesExclusive lk(txn); + LockMongoFilesExclusive lk; ProgressMeter pm(mmfiles.size(), 2, 1, "files", "File Closing Progress"); set<MongoFile*> temp = mmfiles; for (set<MongoFile*>::iterator i = temp.begin(); i != temp.end(); i++) { - (*i)->close(txn); // close() now removes from mmfiles + (*i)->close(); // close() now removes from mmfiles pm.hit(); } message << "closeAllFiles() finished"; --closingAllFiles; } -/*static*/ int MongoFile::flushAll(OperationContext* txn, bool sync) { - return _flushAll(txn, sync); +/*static*/ long long MongoFile::totalMappedLength() { + unsigned long long total = 0; + + LockMongoFilesShared lk; + + for (set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++) + total += (*i)->length(); + + return total; +} + +/*static*/ int MongoFile::flushAll(bool sync) { + return _flushAll(sync); } -/*static*/ int MongoFile::_flushAll(OperationContext* txn, bool sync) { +/*static*/ int MongoFile::_flushAll(bool sync) { if (!sync) { int num = 0; - LockMongoFilesShared lk(txn); + LockMongoFilesShared lk; for (set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++) { num++; MongoFile* mmf = *i; @@ -204,7 +196,7 @@ void MongoFile::closeAllFiles(OperationContext* txn, stringstream& message) { OwnedPointerVector<Flushable> thingsToFlushWrapper; vector<Flushable*>& thingsToFlush = thingsToFlushWrapper.mutableVector(); { - LockMongoFilesShared lk(txn); + LockMongoFilesShared lk; for (set<MongoFile*>::iterator i = mmfiles.begin(); i != mmfiles.end(); i++) { MongoFile* mmf = *i; if (!mmf) @@ -214,22 +206,22 @@ void MongoFile::closeAllFiles(OperationContext* txn, stringstream& message) { } for (size_t i = 0; i < thingsToFlush.size(); i++) { - thingsToFlush[i]->flush(txn); + thingsToFlush[i]->flush(); } return thingsToFlush.size(); } -void MongoFile::created(OperationContext* txn) { +void MongoFile::created() { // If we're a READONLY mapping, we don't want to ever flush. if (!isOptionSet(READONLY)) { - LockMongoFilesExclusive lk(txn); + LockMongoFilesExclusive lk; mmfiles.insert(this); } } -void MongoFile::setFilename(OperationContext* txn, const std::string& fn) { - LockMongoFilesExclusive lk(txn); +void MongoFile::setFilename(const std::string& fn) { + LockMongoFilesExclusive lk; verify(_filename.empty()); _filename = boost::filesystem::absolute(fn).generic_string(); MongoFile*& ptf = pathToFile[_filename]; @@ -243,6 +235,23 @@ MongoFile* MongoFileFinder::findByPath(const std::string& path) const { static_cast<MongoFile*>(NULL)); } + +void printMemInfo(const char* where) { + LogstreamBuilder out = log(); + out << "mem info: "; + if (where) + out << where << " "; + + ProcessInfo pi; + if (!pi.supported()) { + out << " not supported"; + return; + } + + out << "vsize: " << pi.getVirtualMemorySize() << " resident: " << pi.getResidentSize() + << " mapped: " << (MemoryMappedFile::totalMappedLength() / (1024 * 1024)); +} + void dataSyncFailedHandler() { log() << "error syncing data to disk, probably a disk error"; log() << " shutting down immediately to avoid corruption"; diff --git a/src/mongo/db/storage/mmap_v1/mmap.h b/src/mongo/db/storage/mmap_v1/mmap.h index fc28d56e1d9..af559c7db63 100644 --- a/src/mongo/db/storage/mmap_v1/mmap.h +++ b/src/mongo/db/storage/mmap_v1/mmap.h @@ -33,10 +33,7 @@ #include <sstream> #include <vector> -#include "mongo/base/disallow_copying.h" -#include "mongo/db/client.h" -#include "mongo/db/concurrency/d_concurrency.h" -#include "mongo/db/operation_context.h" +#include "mongo/util/concurrency/rwlock.h" namespace mongo { @@ -65,24 +62,12 @@ private: // lock order: lock dbMutex before this if you lock both class LockMongoFilesShared { friend class LockMongoFilesExclusive; - static Lock::ResourceMutex mmmutex; + static RWLockRecursiveNongreedy mmmutex; static unsigned era; - - Lock::SharedLock lk; + RWLockRecursive::Shared lk; public: - explicit LockMongoFilesShared(OperationContext* txn) : lk(txn->lockState(), mmmutex) { - // JS worker threads may not have cc() setup, as they work on behalf of other clients - dassert(txn == cc().getOperationContext() || !cc().getOperationContext()); - } - - static void assertExclusivelyLocked(OperationContext* txn) { - invariant(mmmutex.isExclusivelyLocked(txn->lockState())); - } - - static void assertAtLeastReadLocked(OperationContext* txn) { - invariant(mmmutex.isAtLeastReadLocked(txn->lockState())); - } + LockMongoFilesShared() : lk(mmmutex) {} /** era changes anytime memory maps come and go. thus you can use this as a cheap way to check if nothing has changed since the last time you locked. Of course you must be shared locked @@ -93,16 +78,20 @@ public: static unsigned getEra() { return era; } + + static void assertExclusivelyLocked() { + mmmutex.assertExclusivelyLocked(); + } + static void assertAtLeastReadLocked() { + mmmutex.assertAtLeastReadLocked(); + } }; class LockMongoFilesExclusive { - Lock::ExclusiveLock lk; + RWLockRecursive::Exclusive lk; public: - explicit LockMongoFilesExclusive(OperationContext* txn) - : lk(txn->lockState(), LockMongoFilesShared::mmmutex) { - // JS worker threads may not have cc() setup, as they work on behalf of other clients - dassert(txn == cc().getOperationContext() || !cc().getOperationContext()); + LockMongoFilesExclusive() : lk(LockMongoFilesShared::mmmutex) { LockMongoFilesShared::era++; } }; @@ -116,7 +105,7 @@ public: class Flushable { public: virtual ~Flushable() {} - virtual void flush(OperationContext* txn) = 0; + virtual void flush() = 0; }; enum Options { @@ -135,7 +124,7 @@ public: called from within a mutex that MongoFile uses. so be careful not to deadlock. */ template <class F> - static void forEach(OperationContext* txn, F fun); + static void forEach(F fun); /** * note: you need to be in mmmutex when using this. forEach (above) handles that for you @@ -143,8 +132,9 @@ public: */ static std::set<MongoFile*>& getAllFiles(); - static int flushAll(OperationContext* txn, bool sync); // returns n flushed - static void closeAllFiles(OperationContext* txn, std::stringstream& message); + static int flushAll(bool sync); // returns n flushed + static long long totalMappedLength(); + static void closeAllFiles(std::stringstream& message); virtual bool isDurableMappedFile() { return false; @@ -153,20 +143,17 @@ public: std::string filename() const { return _filename; } - void setFilename(OperationContext* txn, const std::string& fn); + void setFilename(const std::string& fn); virtual uint64_t getUniqueId() const = 0; private: std::string _filename; - static int _flushAll(OperationContext* txn, bool sync); // returns n flushed + static int _flushAll(bool sync); // returns n flushed const OptionSet _options; protected: - /** - * Implementations may assume this is called from within `LockMongoFilesExclusive`. - */ - virtual void close(OperationContext* txn) = 0; + virtual void close() = 0; virtual void flush(bool sync) = 0; /** * returns a thread safe object that you can call flush on @@ -174,22 +161,14 @@ protected: */ virtual Flushable* prepareFlush() = 0; - /** - * Returns true iff the file is closed. - */ - virtual bool isClosed() = 0; - - void created(OperationContext* txn); /* subclass must call after create */ + void created(); /* subclass must call after create */ - /** - * Implementations may assume this is called from within `LockMongoFilesExclusive`. - * - * subclass must call in destructor (or at close). - * removes this from pathToFile and other maps - * safe to call more than once, albeit might be wasted work - * ideal to call close to the close, if the close is well before object destruction - */ - void destroyed(OperationContext* txn); + /* subclass must call in destructor (or at close). + removes this from pathToFile and other maps + safe to call more than once, albeit might be wasted work + ideal to call close to the close, if the close is well before object destruction + */ + void destroyed(); virtual unsigned long long length() const = 0; @@ -208,7 +187,7 @@ class MongoFileFinder { MONGO_DISALLOW_COPYING(MongoFileFinder); public: - MongoFileFinder(OperationContext* txn) : _lk(txn) {} + MongoFileFinder() {} /** @return The MongoFile object associated with the specified file name. If no file is open with the specified name, returns null. @@ -229,33 +208,27 @@ protected: } public: - MemoryMappedFile(OperationContext* txn, OptionSet options = NONE); + MemoryMappedFile(OptionSet options = NONE); - virtual ~MemoryMappedFile(); + virtual ~MemoryMappedFile() { + LockMongoFilesExclusive lk; + close(); + } - /** - * Callers must be holding a `LockMongoFilesExclusive`. - */ - virtual void close(OperationContext* txn); + virtual void close(); /** * uasserts if file doesn't exist. fasserts on mmap error. */ - void* map(OperationContext* txn, const char* filename); + void* map(const char* filename); /** * uasserts if file exists. fasserts on mmap error. * @param zero fill file with zeros when true */ - void* create(OperationContext* txn, - const std::string& filename, - unsigned long long len, - bool zero); + void* create(const std::string& filename, unsigned long long len, bool zero); void flush(bool sync); - - virtual bool isClosed(); - virtual Flushable* prepareFlush(); long shortLength() const { @@ -278,10 +251,6 @@ public: return _uniqueId; } - static int totalMappedLengthInMB() { - return static_cast<int>(totalMappedLength.load() / 1024 / 1024); - } - private: static void updateLength(const char* filename, unsigned long long& length); @@ -289,7 +258,6 @@ private: HANDLE maphandle = 0; std::vector<void*> views; unsigned long long len = 0u; - static AtomicUInt64 totalMappedLength; const uint64_t _uniqueId; #ifdef _WIN32 // flush Mutex @@ -307,18 +275,18 @@ protected: * Creates with length if DNE, otherwise validates input length. Returns nullptr on mmap * error. */ - void* map(OperationContext* txn, const char* filename, unsigned long long& length); + void* map(const char* filename, unsigned long long& length); /** * Close the current private view and open a new replacement. Returns nullptr on mmap error. */ - void* remapPrivateView(OperationContext* txn, void* oldPrivateAddr); + void* remapPrivateView(void* oldPrivateAddr); }; /** p is called from within a mutex that MongoFile uses. so be careful not to deadlock. */ template <class F> -inline void MongoFile::forEach(OperationContext* txn, F p) { - LockMongoFilesShared lklk(txn); +inline void MongoFile::forEach(F p) { + LockMongoFilesShared lklk; const std::set<MongoFile*>& mmfiles = MongoFile::getAllFiles(); for (std::set<MongoFile*>::const_iterator i = mmfiles.begin(); i != mmfiles.end(); i++) p(*i); diff --git a/src/mongo/db/storage/mmap_v1/mmap_posix.cpp b/src/mongo/db/storage/mmap_v1/mmap_posix.cpp index 02589421b44..e63e74923a7 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_posix.cpp +++ b/src/mongo/db/storage/mmap_v1/mmap_posix.cpp @@ -54,23 +54,6 @@ using namespace mongoutils; namespace mongo { - -namespace { -void printMemInfo() { - LogstreamBuilder out = log(); - out << "mem info: "; - - ProcessInfo pi; - if (!pi.supported()) { - out << " not supported"; - return; - } - - out << "vsize: " << pi.getVirtualMemorySize() << " resident: " << pi.getResidentSize() - << " mapped: " << MemoryMappedFile::totalMappedLengthInMB(); -} -} // namespace - static size_t fetchMinOSPageSizeBytes() { size_t minOSPageSizeBytes = sysconf(_SC_PAGESIZE); minOSPageSizeBytesTest(minOSPageSizeBytes); @@ -79,19 +62,17 @@ static size_t fetchMinOSPageSizeBytes() { const size_t g_minOSPageSizeBytes = fetchMinOSPageSizeBytes(); -void MemoryMappedFile::close(OperationContext* txn) { +void MemoryMappedFile::close() { + LockMongoFilesShared::assertExclusivelyLocked(); for (vector<void*>::iterator i = views.begin(); i != views.end(); i++) { munmap(*i, len); } views.clear(); - totalMappedLength.fetchAndSubtract(len); - len = 0; - if (fd) { + if (fd) ::close(fd); - fd = 0; - } - destroyed(txn); // cleans up from the master list of mmaps + fd = 0; + destroyed(); // cleans up from the master list of mmaps } #ifndef O_NOATIME @@ -159,12 +140,11 @@ MAdvise::~MAdvise() { } #endif -void* MemoryMappedFile::map(OperationContext* txn, - const char* filename, - unsigned long long& length) { +void* MemoryMappedFile::map(const char* filename, unsigned long long& length) { // length may be updated by callee. - setFilename(txn, filename); + setFilename(filename); FileAllocator::get()->allocateAsap(filename, length); + len = length; const bool readOnly = isOptionSet(READONLY); @@ -213,10 +193,6 @@ void* MemoryMappedFile::map(OperationContext* txn, } #endif - // MemoryMappedFile successfully created, now update state. - len = length; - MemoryMappedFile::totalMappedLength.fetchAndAdd(len); - views.push_back(view); return view; @@ -243,9 +219,9 @@ void* MemoryMappedFile::createPrivateMap() { return x; } -void* MemoryMappedFile::remapPrivateView(OperationContext* txn, void* oldPrivateAddr) { +void* MemoryMappedFile::remapPrivateView(void* oldPrivateAddr) { #if defined(__sun) // SERVER-8795 - LockMongoFilesExclusive lockMongoFiles(txn); + LockMongoFilesExclusive lockMongoFiles; #endif // don't unmap, just mmap over the old region @@ -279,16 +255,12 @@ void MemoryMappedFile::flush(bool sync) { } } -bool MemoryMappedFile::isClosed() { - return !len && !fd && !views.size(); -} - class PosixFlushable : public MemoryMappedFile::Flushable { public: PosixFlushable(MemoryMappedFile* theFile, void* view, HANDLE fd, long len) : _theFile(theFile), _view(view), _fd(fd), _len(len), _id(_theFile->getUniqueId()) {} - void flush(OperationContext* txn) { + void flush() { if (_view == NULL || _fd == 0) return; @@ -303,7 +275,7 @@ public: } // some error, lets see if we're supposed to exist - LockMongoFilesShared mmfilesLock(txn); + LockMongoFilesShared mmfilesLock; std::set<MongoFile*> mmfs = MongoFile::getAllFiles(); std::set<MongoFile*>::const_iterator it = mmfs.find(_theFile); if ((it == mmfs.end()) || ((*it)->getUniqueId() != _id)) { @@ -329,4 +301,5 @@ MemoryMappedFile::Flushable* MemoryMappedFile::prepareFlush() { return new PosixFlushable(this, viewForFlushing(), fd, len); } + } // namespace mongo diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp index 69978fb4b53..f27dcc935e8 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp +++ b/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp @@ -56,7 +56,6 @@ #include "mongo/db/storage/mmap_v1/record_store_v1_simple.h" #include "mongo/db/storage/record_data.h" #include "mongo/util/log.h" -#include "mongo/util/scopeguard.h" namespace mongo { @@ -163,12 +162,8 @@ MMAPV1DatabaseCatalogEntry::MMAPV1DatabaseCatalogEntry(OperationContext* txn, std::unique_ptr<ExtentManager> extentManager) : DatabaseCatalogEntry(name), _path(path.toString()), - _namespaceIndex(txn, _path, name.toString()), + _namespaceIndex(_path, name.toString()), _extentManager(std::move(extentManager)) { - ScopeGuard onErrorClose = MakeGuard([&] { - _namespaceIndex.close(txn); - _extentManager->close(txn); - }); massert(34469, str::stream() << name << " is not a valid database name", NamespaceString::validDBName(name)); @@ -198,8 +193,6 @@ MMAPV1DatabaseCatalogEntry::MMAPV1DatabaseCatalogEntry(OperationContext* txn, warning() << "database " << path << " " << name << " could not be opened " << e.what(); throw; } - - onErrorClose.Dismiss(); } MMAPV1DatabaseCatalogEntry::~MMAPV1DatabaseCatalogEntry() { diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.h b/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.h index ea4342bb868..5934ded8a11 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.h +++ b/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.h @@ -62,14 +62,6 @@ public: virtual ~MMAPV1DatabaseCatalogEntry(); - /** - * Must be called before destruction. - */ - virtual void close(OperationContext* txn) { - _extentManager->close(txn); - _namespaceIndex.close(txn); - } - // these two seem the same and yet different // TODO(ERH): consolidate into one ideally virtual bool exists() const { diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp index 36af8f3f06a..e185afe03c7 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp +++ b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp @@ -36,9 +36,7 @@ #include <boost/filesystem/path.hpp> #include <fstream> -#include "mongo/db/client.h" #include "mongo/db/mongod_options.h" -#include "mongo/db/operation_context.h" #include "mongo/db/storage/mmap_v1/data_file_sync.h" #include "mongo/db/storage/mmap_v1/dur.h" #include "mongo/db/storage/mmap_v1/dur_journal.h" @@ -313,9 +311,6 @@ Status MMAPV1Engine::closeDatabase(OperationContext* txn, StringData db) { stdx::lock_guard<stdx::mutex> lk(_entryMapMutex); MMAPV1DatabaseCatalogEntry* entry = _entryMap[db.toString()]; - if (entry) { - entry->close(txn); - } delete entry; _entryMap.erase(db.toString()); return Status::OK(); @@ -350,8 +345,8 @@ void MMAPV1Engine::_listDatabases(const std::string& directory, std::vector<std: } } -int MMAPV1Engine::flushAllFiles(OperationContext* txn, bool sync) { - return MongoFile::flushAll(txn, sync); +int MMAPV1Engine::flushAllFiles(bool sync) { + return MongoFile::flushAll(sync); } Status MMAPV1Engine::beginBackup(OperationContext* txn) { @@ -379,32 +374,21 @@ void MMAPV1Engine::cleanShutdown() { // we would only hang here if the file_allocator code generates a // synchronous signal, which we don't expect log() << "shutdown: waiting for fs preallocator..." << endl; - auto txn = cc().getOperationContext(); - - // In some cases we may shutdown early before we have any operation context yet, but we need - // one for synchronization purposes. - ServiceContext::UniqueOperationContext newTxn; - if (!txn) { - newTxn = cc().makeOperationContext(); - txn = newTxn.get(); - invariant(txn); - } - FileAllocator::get()->waitUntilFinished(); if (storageGlobalParams.dur) { log() << "shutdown: final commit..." << endl; - getDur().commitAndStopDurThread(txn); + getDur().commitAndStopDurThread(); } log() << "shutdown: closing all files..." << endl; stringstream ss3; - MemoryMappedFile::closeAllFiles(txn, ss3); + MemoryMappedFile::closeAllFiles(ss3); log() << ss3.str() << endl; } void MMAPV1Engine::setJournalListener(JournalListener* jl) { dur::setJournalListener(jl); } -} // namespace +} diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h index b5d19950d7b..54e8594e053 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h +++ b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h @@ -57,7 +57,7 @@ public: RecoveryUnit* newRecoveryUnit(); void listDatabases(std::vector<std::string>* out) const; - int flushAllFiles(OperationContext* txn, bool sync); + int flushAllFiles(bool sync); Status beginBackup(OperationContext* txn); void endBackup(OperationContext* txn); diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp index 3f9b6019802..761fecfb075 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp +++ b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp @@ -79,9 +79,9 @@ class MmapV1RecordFetcher : public RecordFetcher { public: explicit MmapV1RecordFetcher(const MmapV1RecordHeader* record) : _record(record) {} - virtual void setup(OperationContext* txn) { + virtual void setup() { invariant(!_filesLock.get()); - _filesLock.reset(new LockMongoFilesShared(txn)); + _filesLock.reset(new LockMongoFilesShared()); } virtual void fetch() { @@ -172,11 +172,10 @@ Status MmapV1ExtentManager::init(OperationContext* txn) { } } - unique_ptr<DataFile> df(new DataFile(txn, n)); + unique_ptr<DataFile> df(new DataFile(n)); - Status s = df->openExisting(txn, fullNameString.c_str()); + Status s = df->openExisting(fullNameString.c_str()); if (!s.isOK()) { - df->close(txn); return s; } @@ -241,17 +240,12 @@ DataFile* MmapV1ExtentManager::_addAFile(OperationContext* txn, } { - unique_ptr<DataFile> allocFile(new DataFile(txn, allocFileId)); + unique_ptr<DataFile> allocFile(new DataFile(allocFileId)); const string allocFileName = _fileName(allocFileId).string(); Timer t; - try { - allocFile->open(txn, allocFileName.c_str(), minSize, false); - } catch (...) { - allocFile->close(txn); - throw; - } + allocFile->open(txn, allocFileName.c_str(), minSize, false); if (t.seconds() > 1) { log() << "MmapV1ExtentManager took " << t.seconds() << " seconds to open: " << allocFileName; @@ -263,15 +257,10 @@ DataFile* MmapV1ExtentManager::_addAFile(OperationContext* txn, // Preallocate is asynchronous if (preallocateNextFile) { - unique_ptr<DataFile> nextFile(new DataFile(txn, allocFileId + 1)); + unique_ptr<DataFile> nextFile(new DataFile(allocFileId + 1)); const string nextFileName = _fileName(allocFileId + 1).string(); - try { - nextFile->open(txn, nextFileName.c_str(), minSize, false); - } catch (...) { - nextFile->close(txn); - throw; - } + nextFile->open(txn, nextFileName.c_str(), minSize, false); } // Returns the last file added @@ -644,12 +633,6 @@ MmapV1ExtentManager::FilesArray::~FilesArray() { } } -void MmapV1ExtentManager::FilesArray::close(OperationContext* txn) { - for (int i = 0; i < size(); i++) { - _files[i]->close(txn); - } -} - void MmapV1ExtentManager::FilesArray::push_back(DataFile* val) { stdx::lock_guard<stdx::mutex> lk(_writersMutex); const int n = _size.load(); diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h index fb891ee8227..573396f76af 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h +++ b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h @@ -90,13 +90,6 @@ public: MmapV1ExtentManager(StringData dbname, StringData path, bool directoryPerDB); /** - * Must be called before destruction. - */ - void close(OperationContext* txn) { - _files.close(txn); - } - - /** * opens all current files, not thread safe */ Status init(OperationContext* txn); @@ -217,11 +210,6 @@ private: ~FilesArray(); /** - * Must be called before destruction. - */ - void close(OperationContext* txn); - - /** * Returns file at location 'n' in the array, with 'n' less than number of files added. * Will always return the same pointer for a given file. */ diff --git a/src/mongo/db/storage/mmap_v1/mmap_windows.cpp b/src/mongo/db/storage/mmap_v1/mmap_windows.cpp index d8e8d61e624..0922e5de7ea 100644 --- a/src/mongo/db/storage/mmap_v1/mmap_windows.cpp +++ b/src/mongo/db/storage/mmap_v1/mmap_windows.cpp @@ -148,8 +148,8 @@ static void* getNextMemoryMappedFileLocation(unsigned long long mmfSize) { return reinterpret_cast<void*>(static_cast<uintptr_t>(thisMemoryMappedFileLocation)); } -void MemoryMappedFile::close(OperationContext* txn) { - LockMongoFilesShared::assertExclusivelyLocked(txn); +void MemoryMappedFile::close() { + LockMongoFilesShared::assertExclusivelyLocked(); // Prevent flush and close from concurrently running stdx::lock_guard<stdx::mutex> lk(_flushMutex); @@ -163,29 +163,20 @@ void MemoryMappedFile::close(OperationContext* txn) { } views.clear(); - totalMappedLength.fetchAndSubtract(len); - len = 0; - if (maphandle) CloseHandle(maphandle); maphandle = 0; - if (fd) { + if (fd) CloseHandle(fd); - fd = 0; - } - - destroyed(txn); // cleans up from the master list of mmaps + fd = 0; + destroyed(); // cleans up from the master list of mmaps } -bool MemoryMappedFile::isClosed() { - return !len && !fd && !views.size(); -} +unsigned long long mapped = 0; -void* MemoryMappedFile::map(OperationContext* txn, - const char* filenameIn, - unsigned long long& length) { +void* MemoryMappedFile::map(const char* filenameIn, unsigned long long& length) { verify(fd == 0 && len == 0); // can't open more than once - setFilename(txn, filenameIn); + setFilename(filenameIn); FileAllocator::get()->allocateAsap(filenameIn, length); /* big hack here: Babble uses db names with colons. doesn't seem to work on windows. temporary * perhaps. */ @@ -231,6 +222,8 @@ void* MemoryMappedFile::map(OperationContext* txn, } } + mapped += length; + { DWORD flProtect = readOnly ? PAGE_READONLY : PAGE_READWRITE; maphandle = CreateFileMappingW(fd, @@ -244,8 +237,7 @@ void* MemoryMappedFile::map(OperationContext* txn, severe() << "CreateFileMappingW for " << filename << " failed with " << errnoWithDescription(dosError) << " (file size is " << length << ")" << " in MemoryMappedFile::map" << endl; - LockMongoFilesExclusive lock(txn); - close(txn); + close(); fassertFailed(16225); } } @@ -296,8 +288,7 @@ void* MemoryMappedFile::map(OperationContext* txn, << length << ")" << " in MemoryMappedFile::map" << endl; - LockMongoFilesExclusive lock(txn); - close(txn); + close(); fassertFailed(16166); } @@ -305,12 +296,8 @@ void* MemoryMappedFile::map(OperationContext* txn, } } - // MemoryMappedFile successfully created, now update state. - len = length; - totalMappedLength.fetchAndAdd(len); - views.push_back(view); - + len = length; return view; } @@ -359,8 +346,8 @@ void* MemoryMappedFile::createPrivateMap() { return privateMapAddress; } -void* MemoryMappedFile::remapPrivateView(OperationContext* txn, void* oldPrivateAddr) { - LockMongoFilesExclusive lockMongoFiles(txn); +void* MemoryMappedFile::remapPrivateView(void* oldPrivateAddr) { + LockMongoFilesExclusive lockMongoFiles; privateViews.clearWritableBits(oldPrivateAddr, len); @@ -406,12 +393,12 @@ public: _filename(filename), _flushMutex(flushMutex) {} - void flush(OperationContext* txn) { + void flush() { if (!_view || !_fd) return; { - LockMongoFilesShared mmfilesLock(txn); + LockMongoFilesShared mmfilesLock; std::set<MongoFile*> mmfs = MongoFile::getAllFiles(); std::set<MongoFile*>::const_iterator it = mmfs.find(_theFile); @@ -475,9 +462,7 @@ void MemoryMappedFile::flush(bool sync) { uassert(13056, "Async flushing not supported on windows", sync); if (!views.empty()) { WindowsFlushable f(this, viewForFlushing(), fd, _uniqueId, filename(), _flushMutex); - auto txn = cc().getOperationContext(); - invariant(txn); - f.flush(txn); + f.flush(); } } diff --git a/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp b/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp index 6f4d3993cbe..0c56ef9e6f1 100644 --- a/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp +++ b/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp @@ -204,8 +204,6 @@ DummyExtentManager::~DummyExtentManager() { } } -void DummyExtentManager::close(OperationContext* txn) {} - Status DummyExtentManager::init(OperationContext* txn) { return Status::OK(); } diff --git a/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.h b/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.h index eac135dd24a..1f29b59334c 100644 --- a/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.h +++ b/src/mongo/db/storage/mmap_v1/record_store_v1_test_help.h @@ -113,8 +113,6 @@ class DummyExtentManager : public ExtentManager { public: virtual ~DummyExtentManager(); - virtual void close(OperationContext* txn); - virtual Status init(OperationContext* txn); virtual int numFiles() const; diff --git a/src/mongo/db/storage/mmap_v1/repair_database.cpp b/src/mongo/db/storage/mmap_v1/repair_database.cpp index 3ae8e9d7fdc..d82a89031d6 100644 --- a/src/mongo/db/storage/mmap_v1/repair_database.cpp +++ b/src/mongo/db/storage/mmap_v1/repair_database.cpp @@ -253,7 +253,7 @@ public: getDur().syncDataAndTruncateJournal(_txn); // need both in case journaling is disabled - MongoFile::flushAll(_txn, true); + MongoFile::flushAll(true); MONGO_ASSERT_ON_EXCEPTION(boost::filesystem::remove_all(_path)); } catch (DBException& e) { @@ -320,7 +320,6 @@ Status MMAPV1Engine::repairDatabase(OperationContext* txn, // Must call this before MMAPV1DatabaseCatalogEntry's destructor closes the DB files ON_BLOCK_EXIT(&dur::DurableInterface::syncDataAndTruncateJournal, &getDur(), txn); - ON_BLOCK_EXIT([&dbEntry, &txn] { dbEntry->close(txn); }); { dbEntry.reset(new MMAPV1DatabaseCatalogEntry( @@ -432,7 +431,7 @@ Status MMAPV1Engine::repairDatabase(OperationContext* txn, getDur().syncDataAndTruncateJournal(txn); // need both in case journaling is disabled - MongoFile::flushAll(txn, true); + MongoFile::flushAll(true); txn->checkForInterrupt(); } diff --git a/src/mongo/db/storage/record_fetcher.h b/src/mongo/db/storage/record_fetcher.h index e133e28bdf0..66c626ea4d5 100644 --- a/src/mongo/db/storage/record_fetcher.h +++ b/src/mongo/db/storage/record_fetcher.h @@ -30,8 +30,6 @@ namespace mongo { -class OperationContext; - /** * Used for yielding while data is fetched from disk. * @@ -44,7 +42,7 @@ public: /** * Performs any setup which is needed prior to yielding locks. */ - virtual void setup(OperationContext* txn) = 0; + virtual void setup() = 0; /** * Called after locks are yielded in order to bring data into memory. diff --git a/src/mongo/db/storage/storage_engine.h b/src/mongo/db/storage/storage_engine.h index 02e9c1ff7aa..f3dc6b1bf0f 100644 --- a/src/mongo/db/storage/storage_engine.h +++ b/src/mongo/db/storage/storage_engine.h @@ -207,7 +207,7 @@ public: /** * @return number of files flushed */ - virtual int flushAllFiles(OperationContext* txn, bool sync) = 0; + virtual int flushAllFiles(bool sync) = 0; /** * Transitions the storage engine into backup mode. diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp index 682fd842aaf..0c3c006a6fa 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp @@ -401,7 +401,7 @@ Status WiredTigerKVEngine::_salvageIfNeeded(const char* uri) { return wtRCToStatus(session->salvage(session, uri, NULL), "Salvage failed:"); } -int WiredTigerKVEngine::flushAllFiles(OperationContext* txn, bool sync) { +int WiredTigerKVEngine::flushAllFiles(bool sync) { LOG(1) << "WiredTigerKVEngine::flushAllFiles"; if (_ephemeral) { return 0; diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h index 8f632ef537c..f46b677f218 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h @@ -108,7 +108,7 @@ public: StringData ident, const RecordStore* originalRecordStore) const; - virtual int flushAllFiles(OperationContext* txn, bool sync); + virtual int flushAllFiles(bool sync); virtual Status beginBackup(OperationContext* txn); |