summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Midvidy <amidvidy@gmail.com>2016-03-17 14:10:29 -0400
committerAdam Midvidy <amidvidy@gmail.com>2016-03-17 14:10:29 -0400
commit2bcd664e5eba0b9ac8b356d435de9e2deb904a9b (patch)
tree0279c2ad1eb8ee340e56c84ed0902539ac06d64d
parent7857db1be27eff695394381d022e1640a7c48444 (diff)
downloadmongo-2bcd664e5eba0b9ac8b356d435de9e2deb904a9b.tar.gz
SERVER-22956 abstract ExtentManager construction
-rw-r--r--src/mongo/db/storage/mmap_v1/extent_manager.h17
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp60
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.h13
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp15
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_engine.h5
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp7
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h12
-rw-r--r--src/mongo/db/storage/mmap_v1/record_store_v1_test_help.cpp10
-rw-r--r--src/mongo/db/storage/mmap_v1/record_store_v1_test_help.h8
-rw-r--r--src/mongo/db/storage/mmap_v1/repair_database.cpp8
10 files changed, 114 insertions, 41 deletions
diff --git a/src/mongo/db/storage/mmap_v1/extent_manager.h b/src/mongo/db/storage/mmap_v1/extent_manager.h
index 052634d639b..4ce623ffc8a 100644
--- a/src/mongo/db/storage/mmap_v1/extent_manager.h
+++ b/src/mongo/db/storage/mmap_v1/extent_manager.h
@@ -41,6 +41,7 @@
namespace mongo {
class DataFile;
+class DataFileVersion;
class MmapV1RecordHeader;
class RecordFetcher;
class OperationContext;
@@ -66,6 +67,14 @@ class ExtentManager {
public:
ExtentManager() {}
+ class Factory {
+ public:
+ virtual ~Factory() = default;
+ virtual std::unique_ptr<ExtentManager> create(StringData dbname,
+ StringData path,
+ bool directoryPerDB) = 0;
+ };
+
virtual ~ExtentManager() {}
/**
@@ -176,5 +185,11 @@ public:
* Caller takes owernship of CacheHint
*/
virtual CacheHint* cacheHint(const DiskLoc& extentLoc, const HintType& hint) = 0;
+
+ virtual DataFileVersion getFileFormat(OperationContext* txn) const = 0;
+ virtual void setFileFormat(OperationContext* txn, DataFileVersion newVersion) = 0;
+
+ virtual const DataFile* getOpenFile(int n) const = 0;
};
-}
+
+} // 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 dc1e6bd3af1..4f97ed08f4c 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
@@ -152,12 +152,16 @@ private:
Entry* const _cachedEntry;
};
-MMAPV1DatabaseCatalogEntry::MMAPV1DatabaseCatalogEntry(
- OperationContext* txn, StringData name, StringData path, bool directoryPerDB, bool transient)
+MMAPV1DatabaseCatalogEntry::MMAPV1DatabaseCatalogEntry(OperationContext* txn,
+ StringData name,
+ StringData path,
+ bool directoryPerDB,
+ bool transient,
+ std::unique_ptr<ExtentManager> extentManager)
: DatabaseCatalogEntry(name),
_path(path.toString()),
_namespaceIndex(_path, name.toString()),
- _extentManager(name, path, directoryPerDB) {
+ _extentManager(std::move(extentManager)) {
invariant(txn->lockState()->isDbLockedForMode(name, MODE_X));
try {
@@ -168,9 +172,9 @@ MMAPV1DatabaseCatalogEntry::MMAPV1DatabaseCatalogEntry(
// Initialize the extent manager. This will create the first data file (.0) if needed
// and if this fails we would leak the .ns file above. Leaking the .ns or .0 file is
// acceptable, because subsequent openDB calls will exercise the code path again.
- Status s = _extentManager.init(txn);
+ Status s = _extentManager->init(txn);
if (!s.isOK()) {
- msgasserted(16966, str::stream() << "_extentManager.init failed: " << s.toString());
+ msgasserted(16966, str::stream() << "_extentManager->init failed: " << s.toString());
}
// This is the actual loading of the on-disk structures into cache.
@@ -231,7 +235,7 @@ Status MMAPV1DatabaseCatalogEntry::dropCollection(OperationContext* txn, StringD
// free extents
if (!details->firstExtent.isNull()) {
- _extentManager.freeExtents(txn, details->firstExtent, details->lastExtent);
+ _extentManager->freeExtents(txn, details->firstExtent, details->lastExtent);
*txn->recoveryUnit()->writing(&details->firstExtent) = DiskLoc().setInvalid();
*txn->recoveryUnit()->writing(&details->lastExtent) = DiskLoc().setInvalid();
}
@@ -384,13 +388,13 @@ void MMAPV1DatabaseCatalogEntry::appendExtraStats(OperationContext* opCtx,
if (isEmpty()) {
output->appendNumber("fileSize", 0);
} else {
- output->appendNumber("fileSize", _extentManager.fileSize() / scale);
+ output->appendNumber("fileSize", _extentManager->fileSize() / scale);
output->appendNumber("nsSizeMB",
static_cast<int>(_namespaceIndex.fileLength() / (1024 * 1024)));
int freeListSize = 0;
int64_t freeListSpace = 0;
- _extentManager.freeListStats(opCtx, &freeListSize, &freeListSpace);
+ _extentManager->freeListStats(opCtx, &freeListSize, &freeListSpace);
BSONObjBuilder extentFreeList(output->subobjStart("extentFreeList"));
extentFreeList.append("num", freeListSize);
@@ -398,7 +402,7 @@ void MMAPV1DatabaseCatalogEntry::appendExtraStats(OperationContext* opCtx,
extentFreeList.done();
{
- const DataFileVersion version = _extentManager.getFileFormat(opCtx);
+ const DataFileVersion version = _extentManager->getFileFormat(opCtx);
BSONObjBuilder dataFileVersion(output->subobjStart("dataFileVersion"));
dataFileVersion.append("major", version.majorRaw());
@@ -409,10 +413,10 @@ void MMAPV1DatabaseCatalogEntry::appendExtraStats(OperationContext* opCtx,
}
bool MMAPV1DatabaseCatalogEntry::isOlderThan24(OperationContext* opCtx) const {
- if (_extentManager.numFiles() == 0)
+ if (_extentManager->numFiles() == 0)
return false;
- const DataFileVersion version = _extentManager.getFileFormat(opCtx);
+ const DataFileVersion version = _extentManager->getFileFormat(opCtx);
invariant(version.isCompatibleWithCurrentCode());
@@ -420,10 +424,10 @@ bool MMAPV1DatabaseCatalogEntry::isOlderThan24(OperationContext* opCtx) const {
}
void MMAPV1DatabaseCatalogEntry::markIndexSafe24AndUp(OperationContext* opCtx) {
- if (_extentManager.numFiles() == 0)
+ if (_extentManager->numFiles() == 0)
return;
- DataFileVersion version = _extentManager.getFileFormat(opCtx);
+ DataFileVersion version = _extentManager->getFileFormat(opCtx);
invariant(version.isCompatibleWithCurrentCode());
@@ -431,14 +435,14 @@ void MMAPV1DatabaseCatalogEntry::markIndexSafe24AndUp(OperationContext* opCtx) {
return; // nothing to do
version.setIs24IndexClean();
- _extentManager.setFileFormat(opCtx, version);
+ _extentManager->setFileFormat(opCtx, version);
}
bool MMAPV1DatabaseCatalogEntry::currentFilesCompatible(OperationContext* opCtx) const {
- if (_extentManager.numFiles() == 0)
+ if (_extentManager->numFiles() == 0)
return true;
- return _extentManager.getOpenFile(0)->getHeader()->version.isCompatibleWithCurrentCode();
+ return _extentManager->getOpenFile(0)->getHeader()->version.isCompatibleWithCurrentCode();
}
void MMAPV1DatabaseCatalogEntry::getCollectionNamespaces(std::list<std::string>* tofill) const {
@@ -477,14 +481,14 @@ void MMAPV1DatabaseCatalogEntry::_init(OperationContext* txn) {
}
if (!freeListDetails->firstExtent.isNull()) {
- _extentManager.freeExtents(
+ _extentManager->freeExtents(
txn, freeListDetails->firstExtent, freeListDetails->lastExtent);
}
_namespaceIndex.kill_ns(txn, oldFreeList.ns());
}
- DataFileVersion version = _extentManager.getFileFormat(txn);
+ DataFileVersion version = _extentManager->getFileFormat(txn);
if (version.isCompatibleWithCurrentCode() && !version.mayHave28Freelist()) {
if (storageGlobalParams.readOnly) {
severe() << "Legacy storage format detected, but server was started with the "
@@ -494,7 +498,7 @@ void MMAPV1DatabaseCatalogEntry::_init(OperationContext* txn) {
// Any DB that can be opened and written to gets this flag set.
version.setMayHave28Freelist();
- _extentManager.setFileFormat(txn, version);
+ _extentManager->setFileFormat(txn, version);
}
const NamespaceString nsi(name(), "system.indexes");
@@ -532,7 +536,7 @@ void MMAPV1DatabaseCatalogEntry::_init(OperationContext* txn) {
NamespaceDetailsRSV1MetaData* md =
new NamespaceDetailsRSV1MetaData(nsn.toString(), nsDetails);
nsEntry->recordStore.reset(
- new SimpleRecordStoreV1(txn, nsn.toString(), md, &_extentManager, false));
+ new SimpleRecordStoreV1(txn, nsn.toString(), md, _extentManager.get(), false));
}
if (!indexEntry) {
@@ -542,7 +546,7 @@ void MMAPV1DatabaseCatalogEntry::_init(OperationContext* txn) {
new NamespaceDetailsRSV1MetaData(nsi.toString(), indexDetails);
indexEntry->recordStore.reset(
- new SimpleRecordStoreV1(txn, nsi.toString(), md, &_extentManager, true));
+ new SimpleRecordStoreV1(txn, nsi.toString(), md, _extentManager.get(), true));
}
RecordId indexNamespaceId;
@@ -632,14 +636,14 @@ Status MMAPV1DatabaseCatalogEntry::createCollection(OperationContext* txn,
if (allocateDefaultSpace) {
RecordStoreV1Base* rs = _getRecordStore(ns);
if (options.initialNumExtents > 0) {
- int size = _massageExtentSize(&_extentManager, options.cappedSize);
+ int size = _massageExtentSize(_extentManager.get(), options.cappedSize);
for (int i = 0; i < options.initialNumExtents; i++) {
rs->increaseStorageSize(txn, size, false);
}
} else if (!options.initialExtentSizes.empty()) {
for (size_t i = 0; i < options.initialExtentSizes.size(); i++) {
int size = options.initialExtentSizes[i];
- size = _massageExtentSize(&_extentManager, size);
+ size = _massageExtentSize(_extentManager.get(), size);
rs->increaseStorageSize(txn, size, false);
}
} else if (options.capped) {
@@ -647,13 +651,13 @@ Status MMAPV1DatabaseCatalogEntry::createCollection(OperationContext* txn,
do {
// Must do this at least once, otherwise we leave the collection with no
// extents, which is invalid.
- int sz =
- _massageExtentSize(&_extentManager, options.cappedSize - rs->storageSize(txn));
+ int sz = _massageExtentSize(_extentManager.get(),
+ options.cappedSize - rs->storageSize(txn));
sz &= 0xffffff00;
rs->increaseStorageSize(txn, sz, false);
} while (rs->storageSize(txn) < options.cappedSize);
} else {
- rs->increaseStorageSize(txn, _extentManager.initialSize(128), false);
+ rs->increaseStorageSize(txn, _extentManager->initialSize(128), false);
}
}
@@ -700,10 +704,10 @@ void MMAPV1DatabaseCatalogEntry::_insertInCache(OperationContext* txn,
if (details->isCapped) {
entry->recordStore.reset(new CappedRecordStoreV1(
- txn, NULL, ns, md.release(), &_extentManager, nss.coll() == "system.indexes"));
+ txn, NULL, ns, md.release(), _extentManager.get(), nss.coll() == "system.indexes"));
} else {
entry->recordStore.reset(new SimpleRecordStoreV1(
- txn, ns, md.release(), &_extentManager, nss.coll() == "system.indexes"));
+ txn, ns, md.release(), _extentManager.get(), nss.coll() == "system.indexes"));
}
}
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 4211e26096a..c907ba2b2ab 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
@@ -57,7 +57,8 @@ public:
StringData name,
StringData path,
bool directoryperdb,
- bool transient);
+ bool transient,
+ std::unique_ptr<ExtentManager> extentManager);
virtual ~MMAPV1DatabaseCatalogEntry();
@@ -110,11 +111,11 @@ public:
const CollectionCatalogEntry* collection,
IndexCatalogEntry* index);
- const MmapV1ExtentManager* getExtentManager() const {
- return &_extentManager;
+ const ExtentManager* getExtentManager() const {
+ return _extentManager.get();
}
- MmapV1ExtentManager* getExtentManager() {
- return &_extentManager;
+ ExtentManager* getExtentManager() {
+ return _extentManager.get();
}
CollectionOptions getCollectionOptions(OperationContext* txn, StringData ns) const;
@@ -186,7 +187,7 @@ private:
const std::string _path;
NamespaceIndex _namespaceIndex;
- MmapV1ExtentManager _extentManager;
+ std::unique_ptr<ExtentManager> _extentManager;
CollectionMap _collections;
};
}
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 4f29d366b38..a448ee579ad 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.cpp
@@ -220,7 +220,12 @@ void clearTmpFiles() {
}
} // namespace
-MMAPV1Engine::MMAPV1Engine(const StorageEngineLockFile* lockFile) {
+MMAPV1Engine::MMAPV1Engine(const StorageEngineLockFile* lockFile)
+ : MMAPV1Engine(lockFile, stdx::make_unique<MmapV1ExtentManager::Factory>()) {}
+
+MMAPV1Engine::MMAPV1Engine(const StorageEngineLockFile* lockFile,
+ std::unique_ptr<ExtentManager::Factory> extentManagerFactory)
+ : _extentManagerFactory(std::move(extentManagerFactory)) {
// TODO check non-journal subdirs if using directory-per-db
checkReadAhead(storageGlobalParams.dbpath);
@@ -272,7 +277,13 @@ DatabaseCatalogEntry* MMAPV1Engine::getDatabaseCatalogEntry(OperationContext* op
// can be creating the same database concurrenty. We need to create the database outside of
// the _entryMapMutex so we do not deadlock (see SERVER-15880).
MMAPV1DatabaseCatalogEntry* entry = new MMAPV1DatabaseCatalogEntry(
- opCtx, db, storageGlobalParams.dbpath, storageGlobalParams.directoryperdb, false);
+ opCtx,
+ db,
+ storageGlobalParams.dbpath,
+ storageGlobalParams.directoryperdb,
+ false,
+ _extentManagerFactory->create(
+ db, storageGlobalParams.dbpath, storageGlobalParams.directoryperdb));
stdx::lock_guard<stdx::mutex> lk(_entryMapMutex);
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 00f2f655f98..83704c8093b 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_engine.h
@@ -33,6 +33,7 @@
#include <map>
#include "mongo/db/storage/mmap_v1/record_access_tracker.h"
+#include "mongo/db/storage/mmap_v1/extent_manager.h"
#include "mongo/db/storage/storage_engine.h"
#include "mongo/stdx/mutex.h"
@@ -44,6 +45,8 @@ class MMAPV1DatabaseCatalogEntry;
class MMAPV1Engine : public StorageEngine {
public:
MMAPV1Engine(const StorageEngineLockFile* lockFile);
+ MMAPV1Engine(const StorageEngineLockFile* lockFile,
+ std::unique_ptr<ExtentManager::Factory> extentManagerFactory);
virtual ~MMAPV1Engine();
void finishInit();
@@ -109,6 +112,8 @@ private:
// addresses. It is used when higher layers (e.g. the query system) need to ask
// the storage engine whether data is likely in physical memory.
RecordAccessTracker _recordAccessTracker;
+
+ std::unique_ptr<ExtentManager::Factory> _extentManagerFactory;
};
void _deleteDataFiles(const std::string& database);
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 d7c44aabfab..2076ca868b1 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
@@ -119,6 +119,13 @@ MmapV1ExtentManager::MmapV1ExtentManager(StringData dbname, StringData path, boo
_recordAccessTracker = &mmapEngine->getRecordAccessTracker();
}
+std::unique_ptr<ExtentManager> MmapV1ExtentManager::Factory::create(StringData dbname,
+ StringData path,
+ bool directoryPerDB) {
+ return stdx::make_unique<MmapV1ExtentManager>(
+ std::move(dbname), std::move(path), directoryPerDB);
+}
+
boost::filesystem::path MmapV1ExtentManager::_fileName(int n) const {
stringstream ss;
ss << _dbname << '.' << n;
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 a2f2931e1b4..a66a19f8fb3 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
@@ -76,6 +76,12 @@ class MmapV1ExtentManager : public ExtentManager {
MONGO_DISALLOW_COPYING(MmapV1ExtentManager);
public:
+ class Factory : public ExtentManager::Factory {
+ virtual std::unique_ptr<ExtentManager> create(StringData dbname,
+ StringData path,
+ bool directoryPerDB) final;
+ };
+
/**
* @param freeListDetails this is a reference into the .ns file
* while a bit odd, this is not a layer violation as extents
@@ -141,10 +147,10 @@ public:
/**
* Not thread safe, requires a database exclusive lock
*/
- DataFileVersion getFileFormat(OperationContext* txn) const;
- void setFileFormat(OperationContext* txn, DataFileVersion newVersion);
+ DataFileVersion getFileFormat(OperationContext* txn) const final;
+ void setFileFormat(OperationContext* txn, DataFileVersion newVersion) final;
- const DataFile* getOpenFile(int n) const {
+ const DataFile* getOpenFile(int n) const final {
return _getOpenFile(n);
}
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 12801124b95..234acf8695e 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
@@ -295,6 +295,16 @@ DummyExtentManager::CacheHint* DummyExtentManager::cacheHint(const DiskLoc& exte
return new CacheHint();
}
+DataFileVersion DummyExtentManager::getFileFormat(OperationContext* txn) const {
+ return DataFileVersion::defaultForNewFiles();
+}
+
+void DummyExtentManager::setFileFormat(OperationContext* txn, DataFileVersion newVersion) {}
+
+const DataFile* DummyExtentManager::getOpenFile(int n) const {
+ return nullptr;
+}
+
namespace {
void accumulateExtentSizeRequirements(const LocAndSize* las, std::map<int, size_t>* sizes) {
if (!las)
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 0a038f9e9f3..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
@@ -32,6 +32,7 @@
#include <vector>
+#include "mongo/db/storage/mmap_v1/data_file.h"
#include "mongo/db/storage/mmap_v1/extent_manager.h"
#include "mongo/db/storage/mmap_v1/record_store_v1_base.h"
@@ -141,6 +142,13 @@ public:
virtual CacheHint* cacheHint(const DiskLoc& extentLoc, const HintType& hint);
+ DataFileVersion getFileFormat(OperationContext* txn) const final;
+
+ virtual void setFileFormat(OperationContext* txn, DataFileVersion newVersion) final;
+
+ const DataFile* getOpenFile(int n) const final;
+
+
protected:
struct ExtentInfo {
char* data;
diff --git a/src/mongo/db/storage/mmap_v1/repair_database.cpp b/src/mongo/db/storage/mmap_v1/repair_database.cpp
index a6b31ba784f..b73d346a708 100644
--- a/src/mongo/db/storage/mmap_v1/repair_database.cpp
+++ b/src/mongo/db/storage/mmap_v1/repair_database.cpp
@@ -322,7 +322,13 @@ Status MMAPV1Engine::repairDatabase(OperationContext* txn,
{
dbEntry.reset(new MMAPV1DatabaseCatalogEntry(
- txn, dbName, reservedPathString, storageGlobalParams.directoryperdb, true));
+ txn,
+ dbName,
+ reservedPathString,
+ storageGlobalParams.directoryperdb,
+ true,
+ _extentManagerFactory->create(
+ dbName, reservedPathString, storageGlobalParams.directoryperdb)));
tempDatabase.reset(new Database(txn, dbName, dbEntry.get()));
}