MongoDataFile* Database::suitableFile( const char *ns, int sizeNeeded, bool preallocate, bool enforceQuota ) { // check existing files for ( int i=numFiles()-1; i>=0; i-- ) { MongoDataFile* f = getFile( i ); if ( f->getHeader()->unusedLength >= sizeNeeded ) { // we don't enforce the quota on "special" namespaces as that could lead to problems -- e.g. // rejecting an index insert after inserting the main record. if( cmdLine.quota && enforceQuota && i > cmdLine.quotaFiles && !NamespaceString::special(ns) ) ; else return f; } } if( cmdLine.quota && enforceQuota && numFiles() >= cmdLine.quotaFiles && !NamespaceString::special(ns) ) uasserted(12501, "quota exceeded"); // allocate files until we either get one big enough or hit maxSize for ( int i = 0; i < 8; i++ ) { MongoDataFile* f = addAFile( sizeNeeded, preallocate ); if ( f->getHeader()->unusedLength >= sizeNeeded ) return f; if ( f->getHeader()->fileLength >= MongoDataFile::maxSize() ) // this is as big as they get so might as well stop return f; } uasserted(14810, "couldn't allocate space (suitableFile)"); // callers don't check for null return code return 0; }
MongoDataFile* Database::suitableFile( const char *ns, int sizeNeeded, bool preallocate, bool enforceQuota ) { // check existing files for ( int i=numFiles()-1; i>=0; i-- ) { MongoDataFile* f = getFile( i ); if ( f->getHeader()->unusedLength >= sizeNeeded ) { if ( fileIndexExceedsQuota( ns, i-1, enforceQuota ) ) // NOTE i-1 is the value used historically for this check. ; else return f; } } if ( fileIndexExceedsQuota( ns, numFiles(), enforceQuota ) ) uasserted(12501, "quota exceeded"); // allocate files until we either get one big enough or hit maxSize for ( int i = 0; i < 8; i++ ) { MongoDataFile* f = addAFile( sizeNeeded, preallocate ); if ( f->getHeader()->unusedLength >= sizeNeeded ) return f; if ( f->getHeader()->fileLength >= MongoDataFile::maxSize() ) // this is as big as they get so might as well stop return f; } uasserted(14810, "couldn't allocate space (suitableFile)"); // callers don't check for null return code return 0; }
// ran at startup. static void repairDatabasesAndCheckVersion() { // LastError * le = lastError.get( true ); Client::GodScope gs; log(1) << "enter repairDatabases (to check pdfile version #)" << endl; //verify(checkNsFilesOnLoad); checkNsFilesOnLoad = false; // we are mainly just checking the header - don't scan the whole .ns file for every db here. Lock::GlobalWrite lk; vector< string > dbNames; getDatabaseNames( dbNames ); for ( vector< string >::iterator i = dbNames.begin(); i != dbNames.end(); ++i ) { string dbName = *i; log(1) << "\t" << dbName << endl; Client::Context ctx( dbName ); MongoDataFile *p = cc().database()->getFile( 0 ); DataFileHeader *h = p->getHeader(); if ( !h->isCurrentVersion() || forceRepair ) { if( h->version <= 0 ) { uasserted(14026, str::stream() << "db " << dbName << " appears corrupt pdfile version: " << h->version << " info: " << h->versionMinor << ' ' << h->fileLength); } log() << "****" << endl; log() << "****" << endl; log() << "need to upgrade database " << dbName << " with pdfile version " << h->version << "." << h->versionMinor << ", " << "new version: " << PDFILE_VERSION << "." << PDFILE_VERSION_MINOR << endl; if ( shouldRepairDatabases ) { // QUESTION: Repair even if file format is higher version than code? log() << "\t starting upgrade" << endl; string errmsg; verify( doDBUpgrade( dbName , errmsg , h ) ); } else { log() << "\t Not upgrading, exiting" << endl; log() << "\t run --upgrade to upgrade dbs, then start again" << endl; log() << "****" << endl; dbexit( EXIT_NEED_UPGRADE ); shouldRepairDatabases = 1; return; } } else { Database::closeDatabase( dbName.c_str(), dbpath ); } } log(1) << "done repairDatabases" << endl; if ( shouldRepairDatabases ) { log() << "finished checking dbs" << endl; cc().shutdown(); dbexit( EXIT_CLEAN ); } checkNsFilesOnLoad = true; }
MongoDataFile* Database::suitableFile( int sizeNeeded, bool preallocate ) { // check existing files for ( int i=numFiles()-1; i>=0; i-- ) { MongoDataFile* f = getFile( i ); if ( f->getHeader()->unusedLength >= sizeNeeded ) return f; } // allocate files until we either get one big enough or hit maxSize for ( int i = 0; i < 8; i++ ) { MongoDataFile* f = addAFile( sizeNeeded, preallocate ); if ( f->getHeader()->unusedLength >= sizeNeeded ) return f; if ( f->getHeader()->fileLength >= MongoDataFile::maxSize() ) // this is as big as they get so might as well stop return f; } return 0; }
void repairDatabases() { dblock lk; vector< string > dbNames; getDatabaseNames( dbNames ); for ( vector< string >::iterator i = dbNames.begin(); i != dbNames.end(); ++i ) { string dbName = *i; assert( !setClientTempNs( dbName.c_str() ) ); MongoDataFile *p = database->getFile( 0 ); MDFHeader *h = p->getHeader(); if ( !h->currentVersion() ) { log() << "****" << endl; log() << "****" << endl; log() << "need to upgrade database " << dbName << " with pdfile version " << h->version << "." << h->versionMinor << ", " << "new version: " << VERSION << "." << VERSION_MINOR << endl; if ( shouldRepairDatabases ){ // QUESTION: Repair even if file format is higher version than code? log() << "\t starting repair" << endl; string errmsg; assert( repairDatabase( dbName.c_str(), errmsg ) ); } else { log() << "\t Not repairing, exiting!" << endl; log() << "\t run --upgrade to upgrade dbs, then start again" << endl; log() << "****" << endl; dbexit( EXIT_NEED_UPGRADE ); shouldRepairDatabases = 1; return; } } else { closeClient( dbName.c_str() ); } } if ( shouldRepairDatabases ){ log() << "finished checking dbs" << endl; dbexit( EXIT_CLEAN ); } }