From 650e5b099fd9f56084954aec025b4acd458ce4af Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 24 May 2010 17:33:01 -0700 Subject: fix preallocation --- db/database.h | 17 ++++++++++++----- db/pdfile.cpp | 7 +------ jstests/disk/preallocate.js | 12 +++++++----- jstests/disk/preallocate2.js | 11 +++++++++++ 4 files changed, 31 insertions(+), 16 deletions(-) create mode 100644 jstests/disk/preallocate2.js diff --git a/db/database.h b/db/database.h index 868af0bab26..23bca7ce87f 100644 --- a/db/database.h +++ b/db/database.h @@ -154,7 +154,7 @@ namespace mongo { return preallocateOnly ? 0 : p; } - MongoDataFile* addAFile( int sizeNeeded = 0, bool preallocateNextFile = false ) { + MongoDataFile* addAFile( int sizeNeeded, bool preallocateNextFile ) { int n = (int) files.size(); MongoDataFile *ret = getFile( n, sizeNeeded ); if ( preallocateNextFile ) @@ -168,12 +168,15 @@ namespace mongo { getFile( n, 0, true ); } - MongoDataFile* suitableFile( int sizeNeeded ) { + MongoDataFile* suitableFile( int sizeNeeded, bool preallocate ) { MongoDataFile* f = newestFile(); + if ( !f ) { + f = addAFile( sizeNeeded, preallocate ); + } for ( int i = 0; i < 8; i++ ) { if ( f->getHeader()->unusedLength >= sizeNeeded ) break; - f = addAFile( sizeNeeded ); + f = addAFile( sizeNeeded, preallocate ); if ( f->getHeader()->fileLength >= MongoDataFile::maxSize() ) // this is as big as they get so might as well stop break; } @@ -183,12 +186,16 @@ namespace mongo { Extent* allocExtent( const char *ns, int size, bool capped ) { Extent *e = DataFileMgr::allocFromFreeList( ns, size, capped ); if( e ) return e; - return suitableFile( size )->createExtent( ns, size, capped ); + return suitableFile( size, !capped )->createExtent( ns, size, capped ); } MongoDataFile* newestFile() { int n = (int) files.size(); - if ( n > 0 ) n--; + if ( n > 0 ) { + n--; + } else { + return 0; + } return getFile(n); } diff --git a/db/pdfile.cpp b/db/pdfile.cpp index 80ae649306e..65ced5aa589 100644 --- a/db/pdfile.cpp +++ b/db/pdfile.cpp @@ -197,7 +197,7 @@ namespace mongo { // $nExtents is just for testing - always allocate new extents // rather than reuse existing extents so we have some predictibility // in the extent size used by our tests - database->suitableFile( (int) size )->createExtent( ns, (int) size, newCapped ); + database->suitableFile( (int) size, false )->createExtent( ns, (int) size, newCapped ); } } else { while ( size > 0 ) { @@ -206,11 +206,6 @@ namespace mongo { Extent *e = database->allocExtent( ns, desiredExtentSize, newCapped ); size -= e->length; } - if ( !newCapped ) { - // check if it's time to preallocate a new file, and if so queue that job for a bg thread - // safe to call this multiple times - the implementation will only preallocate one file - database->preallocateAFile(); - } } NamespaceDetails *d = nsdetails(ns); diff --git a/jstests/disk/preallocate.js b/jstests/disk/preallocate.js index c3c9bd09093..d772fbbf3d4 100644 --- a/jstests/disk/preallocate.js +++ b/jstests/disk/preallocate.js @@ -1,15 +1,17 @@ -port = allocatePorts( 1 )[ 0 ]; +// check that there is preallocation on explicit createCollection() and no unncessary preallocation after restart -var baseName = "jstests_preallocate"; +port = allocatePorts( 1 )[ 0 ]; -vsize = function() { - return m.getDB( "admin" ).runCommand( "serverStatus" ).mem.virtual; -} +var baseName = "jstests_preallocate2"; var m = startMongod( "--port", port, "--dbpath", "/data/db/" + baseName ); +assert.eq( 0, m.getDBs().totalSize ); + m.getDB( baseName ).createCollection( baseName + "1" ); +assert.soon( function() { return m.getDBs().totalSize > 100000000; }, "expected second file to bring total size over 100MB" ); + stopMongod( port ); var m = startMongoProgram( "mongod", "--port", port, "--dbpath", "/data/db/" + baseName ); diff --git a/jstests/disk/preallocate2.js b/jstests/disk/preallocate2.js new file mode 100644 index 00000000000..ee9382cfe8d --- /dev/null +++ b/jstests/disk/preallocate2.js @@ -0,0 +1,11 @@ +// check that there is preallocation on insert + +port = allocatePorts( 1 )[ 0 ]; + +var baseName = "jstests_preallocate2"; + +var m = startMongod( "--port", port, "--dbpath", "/data/db/" + baseName ); + +m.getDB( baseName )[ baseName ].save( {i:1} ); + +assert.soon( function() { return m.getDBs().totalSize > 100000000; }, "expected second file to bring total size over 100MB" ); \ No newline at end of file -- cgit v1.2.1