summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEliot Horowitz <eliot@10gen.com>2014-12-01 15:19:01 -0500
committerEliot Horowitz <eliot@10gen.com>2014-12-01 17:41:33 -0500
commit7e4de6184d876b7963946708d6e83ee57335211f (patch)
tree9319101e8a28195b6e7ff55afeda6a7e375c4e27
parent23fad5ee3e26b8d107401e4bfad86f9ada7b7d1f (diff)
downloadmongo-7e4de6184d876b7963946708d6e83ee57335211f.tar.gz
ERVER-965: Store the indexes of a collection on another partition/drive than the documents
-rw-r--r--jstests/noPassthrough/dir_per_db_and_split.js22
-rw-r--r--jstests/noPassthrough/split_collections_and_indexes.js18
-rw-r--r--src/mongo/db/storage/kv/kv_catalog.cpp12
-rw-r--r--src/mongo/db/storage/kv/kv_catalog.h9
-rw-r--r--src/mongo/db/storage/kv/kv_engine_test_harness.cpp8
-rw-r--r--src/mongo/db/storage/kv/kv_storage_engine.cpp2
-rw-r--r--src/mongo/db/storage/kv/kv_storage_engine.h4
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp16
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h3
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp2
10 files changed, 83 insertions, 13 deletions
diff --git a/jstests/noPassthrough/dir_per_db_and_split.js b/jstests/noPassthrough/dir_per_db_and_split.js
new file mode 100644
index 00000000000..b34a3d231f7
--- /dev/null
+++ b/jstests/noPassthrough/dir_per_db_and_split.js
@@ -0,0 +1,22 @@
+
+if ( jsTest.options().storageEngine &&
+ jsTest.options().storageEngine.toLowerCase() == "wiredtiger" ) {
+
+ var baseDir = "jstests_per_db_and_split_c_and_i";
+ port = allocatePorts( 1 )[ 0 ];
+ dbpath = MongoRunner.dataPath + baseDir + "/";
+
+ var m = startMongodTest(port,
+ baseDir,
+ false,
+ {wiredTigerDirectoryForIndexes : "",
+ directoryperdb : "" } );
+ db = m.getDB( "foo" );
+ db.bar.insert( { x : 1 } );
+ assert.eq( 1, db.bar.count() );
+
+ db.adminCommand( {fsync:1} );
+
+ assert( listFiles( dbpath + "/foo/index" ).length > 0 );
+ assert( listFiles( dbpath + "/foo/collection" ).length > 0 );
+}
diff --git a/jstests/noPassthrough/split_collections_and_indexes.js b/jstests/noPassthrough/split_collections_and_indexes.js
new file mode 100644
index 00000000000..fad6478a0cd
--- /dev/null
+++ b/jstests/noPassthrough/split_collections_and_indexes.js
@@ -0,0 +1,18 @@
+
+if ( jsTest.options().storageEngine &&
+ jsTest.options().storageEngine.toLowerCase() == "wiredtiger" ) {
+
+ var baseDir = "jstests_split_c_and_i";
+ port = allocatePorts( 1 )[ 0 ];
+ dbpath = MongoRunner.dataPath + baseDir + "/";
+
+ var m = startMongodTest(port, baseDir, false, {wiredTigerDirectoryForIndexes : ""} );
+ db = m.getDB( "foo" );
+ db.bar.insert( { x : 1 } );
+ assert.eq( 1, db.bar.count() );
+
+ db.adminCommand( {fsync:1} );
+
+ assert( listFiles( dbpath + "/index" ).length > 0 );
+ assert( listFiles( dbpath + "/collection" ).length > 0 );
+}
diff --git a/src/mongo/db/storage/kv/kv_catalog.cpp b/src/mongo/db/storage/kv/kv_catalog.cpp
index 096a1f9a676..213d68f9787 100644
--- a/src/mongo/db/storage/kv/kv_catalog.cpp
+++ b/src/mongo/db/storage/kv/kv_catalog.cpp
@@ -88,11 +88,11 @@ namespace {
KVCatalog::KVCatalog( RecordStore* rs,
bool isRsThreadSafe,
bool directoryPerDb,
- bool splitCollectionAndIndexes )
+ bool directoryForIndexes )
: _rs( rs )
, _isRsThreadSafe(isRsThreadSafe)
, _directoryPerDb(directoryPerDb)
- , _splitCollectionAndIndexes(splitCollectionAndIndexes)
+ , _directoryForIndexes(directoryForIndexes)
, _rand(_newRand())
{}
@@ -121,7 +121,7 @@ namespace {
buf << nsToDatabaseSubstring( ns ) << '/';
}
buf << kind;
- buf << ( _splitCollectionAndIndexes ? '/' : '_' );
+ buf << ( _directoryForIndexes ? '/' : '-' );
buf << _next.fetchAndAdd(1) << '-' << _rand;
return buf.str();
}
@@ -429,7 +429,11 @@ namespace {
}
bool KVCatalog::isUserDataIdent( const StringData& ident ) const {
- return ident.startsWith( "index-" ) || ident.startsWith( "collection-" );
+ return
+ ident.find( "index-" ) != std::string::npos ||
+ ident.find( "index/" ) != std::string::npos ||
+ ident.find( "collection-" ) != std::string::npos ||
+ ident.find( "collection/" ) != std::string::npos;
}
}
diff --git a/src/mongo/db/storage/kv/kv_catalog.h b/src/mongo/db/storage/kv/kv_catalog.h
index 0d665dbdcf1..6aec447d63d 100644
--- a/src/mongo/db/storage/kv/kv_catalog.h
+++ b/src/mongo/db/storage/kv/kv_catalog.h
@@ -54,7 +54,7 @@ namespace mongo {
KVCatalog( RecordStore* rs,
bool isRsThreadSafe,
bool directoryPerDb,
- bool splitCollectionAndIndexes );
+ bool directoryForIndexes );
~KVCatalog();
void init( OperationContext* opCtx );
@@ -100,6 +100,11 @@ namespace mongo {
const StringData& ns,
RecordId* out=NULL ) const;
+ /**
+ * Generates a new unique identifier for a new "thing".
+ * @param ns - the containing ns
+ * @param kind - what this "thing" is, likely collection or index
+ */
std::string _newUniqueIdent(const StringData& ns, const char* kind);
// Helpers only used by constructor and init(). Don't call from elsewhere.
@@ -109,7 +114,7 @@ namespace mongo {
RecordStore* _rs; // not owned
const bool _isRsThreadSafe;
const bool _directoryPerDb;
- const bool _splitCollectionAndIndexes;
+ const bool _directoryForIndexes;
// These two are only used for ident generation inside _newUniqueIdent.
std::string _rand; // effectively const after init() returns
diff --git a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
index 864d88e3e13..46c8b8f1965 100644
--- a/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
+++ b/src/mongo/db/storage/kv/kv_engine_test_harness.cpp
@@ -226,6 +226,7 @@ namespace mongo {
WriteUnitOfWork uow( &opCtx );
ASSERT_OK( catalog->newCollection( &opCtx, "a.b", CollectionOptions() ) );
ASSERT_NOT_EQUALS( "a.b", catalog->getCollectionIdent( "a.b" ) );
+ ASSERT_TRUE( catalog->isUserDataIdent( catalog->getCollectionIdent( "a.b" ) ) );
uow.commit();
}
@@ -252,6 +253,7 @@ namespace mongo {
{
MyOperationContext opCtx( engine );
ASSERT_EQUALS( idxIndent, catalog->getIndexIdent( &opCtx, "a.b", "foo" ) );
+ ASSERT_TRUE( catalog->isUserDataIdent( catalog->getIndexIdent( &opCtx, "a.b", "foo" ) ) );
}
{
@@ -296,6 +298,7 @@ namespace mongo {
WriteUnitOfWork uow( &opCtx );
ASSERT_OK( catalog->newCollection( &opCtx, "a.b", CollectionOptions() ) );
ASSERT_STRING_CONTAINS( catalog->getCollectionIdent( "a.b" ), "a/" );
+ ASSERT_TRUE( catalog->isUserDataIdent( catalog->getCollectionIdent( "a.b" ) ) );
uow.commit();
}
@@ -311,6 +314,7 @@ namespace mongo {
false ) );
catalog->putMetaData( &opCtx, "a.b", md );
ASSERT_STRING_CONTAINS( catalog->getIndexIdent( &opCtx, "a.b", "foo" ), "a/" );
+ ASSERT_TRUE( catalog->isUserDataIdent( catalog->getIndexIdent( &opCtx, "a.b", "foo" ) ) );
uow.commit();
}
@@ -336,6 +340,7 @@ namespace mongo {
WriteUnitOfWork uow( &opCtx );
ASSERT_OK( catalog->newCollection( &opCtx, "a.b", CollectionOptions() ) );
ASSERT_STRING_CONTAINS( catalog->getCollectionIdent( "a.b" ), "collection/" );
+ ASSERT_TRUE( catalog->isUserDataIdent( catalog->getCollectionIdent( "a.b" ) ) );
uow.commit();
}
@@ -351,6 +356,7 @@ namespace mongo {
false ) );
catalog->putMetaData( &opCtx, "a.b", md );
ASSERT_STRING_CONTAINS( catalog->getIndexIdent( &opCtx, "a.b", "foo" ), "index/" );
+ ASSERT_TRUE( catalog->isUserDataIdent( catalog->getIndexIdent( &opCtx, "a.b", "foo" ) ) );
uow.commit();
}
@@ -376,6 +382,7 @@ namespace mongo {
WriteUnitOfWork uow( &opCtx );
ASSERT_OK( catalog->newCollection( &opCtx, "a.b", CollectionOptions() ) );
ASSERT_STRING_CONTAINS( catalog->getCollectionIdent( "a.b" ), "a/collection/" );
+ ASSERT_TRUE( catalog->isUserDataIdent( catalog->getCollectionIdent( "a.b" ) ) );
uow.commit();
}
@@ -391,6 +398,7 @@ namespace mongo {
false ) );
catalog->putMetaData( &opCtx, "a.b", md );
ASSERT_STRING_CONTAINS( catalog->getIndexIdent( &opCtx, "a.b", "foo" ), "a/index/" );
+ ASSERT_TRUE( catalog->isUserDataIdent( catalog->getIndexIdent( &opCtx, "a.b", "foo" ) ) );
uow.commit();
}
diff --git a/src/mongo/db/storage/kv/kv_storage_engine.cpp b/src/mongo/db/storage/kv/kv_storage_engine.cpp
index ae8ef95cef8..1928cc6008e 100644
--- a/src/mongo/db/storage/kv/kv_storage_engine.cpp
+++ b/src/mongo/db/storage/kv/kv_storage_engine.cpp
@@ -93,7 +93,7 @@ namespace mongo {
_catalog.reset( new KVCatalog( _catalogRecordStore.get(),
_supportsDocLocking,
_options.directoryPerDB,
- _options.splitCollectionAndIndexes) );
+ _options.directoryForIndexes) );
_catalog->init( &opCtx );
std::vector<std::string> collections;
diff --git a/src/mongo/db/storage/kv/kv_storage_engine.h b/src/mongo/db/storage/kv/kv_storage_engine.h
index 766e50949a7..669d163520b 100644
--- a/src/mongo/db/storage/kv/kv_storage_engine.h
+++ b/src/mongo/db/storage/kv/kv_storage_engine.h
@@ -49,10 +49,10 @@ namespace mongo {
struct KVStorageEngineOptions {
KVStorageEngineOptions() :
directoryPerDB(false),
- splitCollectionAndIndexes(false) {}
+ directoryForIndexes(false) {}
bool directoryPerDB;
- bool splitCollectionAndIndexes;
+ bool directoryForIndexes;
};
class KVStorageEngine : public StorageEngine {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp
index f464eb1a4d6..51b0e7bfc46 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.cpp
@@ -47,6 +47,11 @@ namespace mongo {
wiredTigerOptions.addOptionChaining("storage.wiredTiger.indexConfig",
"wiredTigerIndexConfig", moe::String, "WiredTiger index configuration settings");
+ wiredTigerOptions.addOptionChaining("storage.wiredTiger.directoryForIndexes",
+ "wiredTigerDirectoryForIndexes",
+ moe::Switch,
+ "Put indexes and data in different directories" );
+
return options->addSection(wiredTigerOptions);
}
@@ -59,18 +64,23 @@ namespace mongo {
if (params.count("storage.wiredTiger.engineConfig")) {
wiredTigerGlobalOptions.engineConfig =
params["storage.wiredTiger.engineConfig"].as<string>();
- std::cerr << "Engine option: " << wiredTigerGlobalOptions.engineConfig << std::endl;
+ log() << "Engine option: " << wiredTigerGlobalOptions.engineConfig;
}
if (params.count("storage.wiredTiger.collectionConfig")) {
wiredTigerGlobalOptions.collectionConfig =
params["storage.wiredTiger.collectionConfig"].as<string>();
- std::cerr << "Collection option: " << wiredTigerGlobalOptions.collectionConfig << std::endl;
+ log() << "Collection option: " << wiredTigerGlobalOptions.collectionConfig;
}
if (params.count("storage.wiredTiger.indexConfig")) {
wiredTigerGlobalOptions.indexConfig =
params["storage.wiredTiger.indexConfig"].as<string>();
- std::cerr << "Index option: " << wiredTigerGlobalOptions.indexConfig << std::endl;
+ log() << "Index option: " << wiredTigerGlobalOptions.indexConfig;
+ }
+ if (params.count("storage.wiredTiger.directoryForIndexes")) {
+ wiredTigerGlobalOptions.directoryForIndexes =
+ params["storage.wiredTiger.directoryForIndexes"].as<bool>();
}
+
return Status::OK();
}
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h
index 558a3d97773..6afa99c109b 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_global_options.h
@@ -39,7 +39,7 @@ namespace mongo {
class WiredTigerGlobalOptions {
public:
- WiredTigerGlobalOptions() {};
+ WiredTigerGlobalOptions() : directoryForIndexes(false) {};
Status add(moe::OptionSection* options);
bool handlePreValidation(const moe::Environment& params);
@@ -48,6 +48,7 @@ namespace mongo {
std::string engineConfig;
std::string collectionConfig;
std::string indexConfig;
+ bool directoryForIndexes;
};
extern WiredTigerGlobalOptions wiredTigerGlobalOptions;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
index 0407c7746e0..9f8882aa70a 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_init.cpp
@@ -63,6 +63,8 @@ namespace mongo {
KVStorageEngineOptions options;
options.directoryPerDB = params.directoryperdb;
+ options.directoryForIndexes =
+ wiredTigerGlobalOptions.directoryForIndexes;
return new KVStorageEngine( kv, options );
}