diff options
author | Antonin Kral <a.kral@bobek.cz> | 2012-06-05 19:50:36 +0200 |
---|---|---|
committer | Antonin Kral <a.kral@bobek.cz> | 2012-06-05 19:50:36 +0200 |
commit | 291c9687fb2307dc22d1f269eb4d0aa98fe8cadc (patch) | |
tree | f46fac7bf8530d100aa55da89dfaa53490fbb350 /db | |
parent | 6d0f215499dda50fdba4a6f60ab359efe0054e0d (diff) | |
parent | 3703a282eca7e79e91f4bd651b1b861b76dc6c68 (diff) | |
download | mongodb-291c9687fb2307dc22d1f269eb4d0aa98fe8cadc.tar.gz |
Merge tag 'upstream/2.0.6'
Upstream version 2.0.6
Diffstat (limited to 'db')
-rw-r--r-- | db/cloner.cpp | 6 | ||||
-rw-r--r-- | db/compact.cpp | 5 | ||||
-rw-r--r-- | db/dbwebserver.cpp | 11 | ||||
-rw-r--r-- | db/queryoptimizer.cpp | 51 | ||||
-rw-r--r-- | db/queryoptimizer.h | 1 | ||||
-rw-r--r-- | db/repl.cpp | 2 | ||||
-rw-r--r-- | db/repl/rs_initialsync.cpp | 45 | ||||
-rw-r--r-- | db/security_common.h | 4 |
8 files changed, 86 insertions, 39 deletions
diff --git a/db/cloner.cpp b/db/cloner.cpp index 26c2f74..6d5b095 100644 --- a/db/cloner.cpp +++ b/db/cloner.cpp @@ -169,7 +169,8 @@ namespace mongo { getDur().commitIfNeeded(); } catch( UserException& e ) { - log() << "warning: exception cloning object in " << from_collection << ' ' << e.what() << " obj:" << js.toString() << '\n'; + error() << "error: exception cloning object in " << from_collection << ' ' << e.what() << " obj:" << js.toString() << '\n'; + throw; } RARELY if ( time( 0 ) - saveLast > 60 ) { @@ -238,7 +239,8 @@ namespace mongo { getDur().commitIfNeeded(); } catch( UserException& e ) { - log() << "warning: exception cloning object in " << from_collection << ' ' << e.what() << " obj:" << js.toString() << '\n'; + error() << "error: exception cloning object in " << from_collection << ' ' << e.what() << " obj:" << js.toString() << '\n'; + throw; } } } diff --git a/db/compact.cpp b/db/compact.cpp index c6e5f77..c100006 100644 --- a/db/compact.cpp +++ b/db/compact.cpp @@ -180,6 +180,11 @@ namespace mongo { d->deletedList[i].writing().Null(); } + + + // Start over from scratch with our extent sizing and growth + d->lastExtentSize=0; + // before dropping indexes, at least make sure we can allocate one extent! uassert(14025, "compact error no space available to allocate", !allocateSpaceForANewRecord(ns, d, Record::HeaderSize+1, false).isNull()); diff --git a/db/dbwebserver.cpp b/db/dbwebserver.cpp index 78c09c0..eb19ba3 100644 --- a/db/dbwebserver.cpp +++ b/db/dbwebserver.cpp @@ -79,11 +79,10 @@ namespace mongo { } bool allowed( const char * rq , vector<string>& headers, const SockAddr &from ) { - if ( from.isLocalHost() ) - return true; - - if ( ! _webUsers->haveAdminUsers() ) + if ( from.isLocalHost() || !_webUsers->haveAdminUsers() ) { + cmdAuthenticate.authenticate( "admin", "RestUser", false ); return true; + } string auth = getHeader( rq , "Authorization" ); @@ -118,8 +117,10 @@ namespace mongo { r << ha2; string r1 = md5simpledigest( r.str() ); - if ( r1 == parms["response"] ) + if ( r1 == parms["response"] ) { + cmdAuthenticate.authenticate( "admin", user["user"].str(), user[ "readOnly" ].isBoolean() && user[ "readOnly" ].boolean() ); return true; + } } } diff --git a/db/queryoptimizer.cpp b/db/queryoptimizer.cpp index 71ca657..8ec4cb4 100644 --- a/db/queryoptimizer.cpp +++ b/db/queryoptimizer.cpp @@ -214,22 +214,6 @@ doneCheckOrder: if ( willScanTable() ) { if ( _frs.nNontrivialRanges() ) { checkTableScanAllowed( _frs.ns() ); - - // if we are doing a table scan on _id - // and its a capped collection - // we disallow as its a common user error - // .system. and local collections are exempt - if ( _d && _d->capped && _frs.range( "_id" ).nontrivial() ) { - if ( cc().isSyncThread() || - str::contains( _frs.ns() , ".system." ) || - str::startsWith( _frs.ns() , "local." ) ) { - // ok - } - else { - warning() << "_id query on capped collection without an _id index, performance will be poor collection: " << _frs.ns() << endl; - //uassert( 14820, str::stream() << "doing _id query on a capped collection without an index is not allowed: " << _frs.ns() , - } - } } return findTableScan( _frs.ns(), _order, startLoc ); } @@ -486,12 +470,14 @@ doneCheckOrder: _usingPrerecordedPlan = true; _mayRecordPlan = false; _plans.push_back( p ); + warnOnCappedIdTableScan(); return; } } } addOtherPlans( false ); + warnOnCappedIdTableScan(); } void QueryPlanSet::addOtherPlans( bool checkFirst ) { @@ -633,6 +619,31 @@ doneCheckOrder: } return _plans[0]; } + + void QueryPlanSet::warnOnCappedIdTableScan() const { + // if we are doing a table scan on _id + // and it's a capped collection + // we warn as it's a common user error + // .system. and local collections are exempt + const char *ns = _frsp->ns(); + NamespaceDetails *d = nsdetails( ns ); + if ( d && + d->capped && + nPlans() == 1 && + firstPlan()->willScanTable() && + firstPlan()->multikeyFrs().range( "_id" ).nontrivial() ) { + if ( cc().isSyncThread() || + str::contains( ns , ".system." ) || + str::startsWith( ns , "local." ) ) { + // ok + } + else { + warning() + << "unindexed _id query on capped collection, " + << "performance will be poor collection: " << ns << endl; + } + } + } QueryPlanSet::Runner::Runner( QueryPlanSet &plans, QueryOp &op ) : _op( op ), @@ -1247,8 +1258,12 @@ doneCheckOrder: void QueryUtilIndexed::clearIndexesForPatterns( const FieldRangeSetPair &frsp, const BSONObj &order ) { SimpleMutex::scoped_lock lk(NamespaceDetailsTransient::_qcMutex); NamespaceDetailsTransient& nsd = NamespaceDetailsTransient::get_inlock( frsp.ns() ); - nsd.registerIndexForPattern( frsp._singleKey.pattern( order ), BSONObj(), 0 ); - nsd.registerIndexForPattern( frsp._multiKey.pattern( order ), BSONObj(), 0 ); + if ( frsp._singleKey.matchPossible() ) { + nsd.registerIndexForPattern( frsp._singleKey.pattern( order ), BSONObj(), 0 ); + } + if ( frsp._multiKey.matchPossible() ) { + nsd.registerIndexForPattern( frsp._multiKey.pattern( order ), BSONObj(), 0 ); + } } pair< BSONObj, long long > QueryUtilIndexed::bestIndexForPatterns( const FieldRangeSetPair &frsp, const BSONObj &order ) { diff --git a/db/queryoptimizer.h b/db/queryoptimizer.h index fea6c0b..78d169d 100644 --- a/db/queryoptimizer.h +++ b/db/queryoptimizer.h @@ -314,6 +314,7 @@ namespace mongo { } void init(); void addHint( IndexDetails &id ); + void warnOnCappedIdTableScan() const; class Runner { public: Runner( QueryPlanSet &plans, QueryOp &op ); diff --git a/db/repl.cpp b/db/repl.cpp index 5edf0c2..8dcdd13 100644 --- a/db/repl.cpp +++ b/db/repl.cpp @@ -1115,7 +1115,7 @@ namespace mongo { bool OplogReader::commonConnect(const string& hostName) { if( conn() == 0 ) { - _conn = shared_ptr<DBClientConnection>(new DBClientConnection( false, 0, 0 /* tcp timeout */)); + _conn = shared_ptr<DBClientConnection>(new DBClientConnection( false, 0, 60*10 /* tcp timeout */)); string errmsg; ReplInfo r("trying to connect to sync source"); if ( !_conn->connect(hostName.c_str(), errmsg) || diff --git a/db/repl/rs_initialsync.cpp b/db/repl/rs_initialsync.cpp index 112d739..7065487 100644 --- a/db/repl/rs_initialsync.cpp +++ b/db/repl/rs_initialsync.cpp @@ -43,18 +43,24 @@ namespace mongo { } void ReplSetImpl::syncDoInitialSync() { + const static int maxFailedAttempts = 3; createOplog(); - - while( 1 ) { + int failedAttempts = 0; + while ( failedAttempts < maxFailedAttempts ) { try { _syncDoInitialSync(); break; } catch(DBException& e) { - sethbmsg("initial sync exception " + e.toString(), 0); + failedAttempts++; + str::stream msg; + msg << "initial sync exception: "; + msg << e.toString() << " " << (maxFailedAttempts - failedAttempts) << " attempts remaining" ; + sethbmsg(msg, 0); sleepsecs(30); } } + if ( failedAttempts >= maxFailedAttempts ) ::abort(); } /* todo : progress metering to sethbmsg. */ @@ -80,7 +86,7 @@ namespace mongo { } const Member* ReplSetImpl::getMemberToSyncTo() { - Member *closest = 0; + bool buildIndexes = true; // wait for 2N pings before choosing a sync target @@ -95,16 +101,31 @@ namespace mongo { buildIndexes = myConfig().buildIndexes; } + Member *closest = 0; + // find the member with the lowest ping time that has more data than me - for (Member *m = _members.head(); m; m = m->next()) { - if (m->hbinfo().up() && - // make sure members with buildIndexes sync from other members w/indexes - (!buildIndexes || (buildIndexes && m->config().buildIndexes)) && - (m->state() == MemberState::RS_PRIMARY || - (m->state() == MemberState::RS_SECONDARY && m->hbinfo().opTime > lastOpTimeWritten)) && - (!closest || m->hbinfo().ping < closest->hbinfo().ping)) { - closest = m; + + // Make two attempts. The first attempt, we ignore those nodes with + // slave delay higher than our own. The second attempt includes such + // nodes, in case those are the only ones we can reach. + for (int attempts = 0; attempts < 2; ++attempts) { + for (Member *m = _members.head(); m; m = m->next()) { + if (m->hbinfo().up() && + // make sure members with buildIndexes sync from other members w/indexes + (!buildIndexes || (buildIndexes && m->config().buildIndexes)) && + (m->state() == MemberState::RS_PRIMARY || + (m->state() == MemberState::RS_SECONDARY && + m->hbinfo().opTime > lastOpTimeWritten)) && + (!closest || m->hbinfo().ping < closest->hbinfo().ping)) { + + if ( attempts == 0 && + myConfig().slaveDelay < m->config().slaveDelay ) { + break; // skip this one in the first attempt + } + closest = m; + } } + if (closest) break; // no need for second attempt } { diff --git a/db/security_common.h b/db/security_common.h index c9a3e3a..80a7450 100644 --- a/db/security_common.h +++ b/db/security_common.h @@ -61,10 +61,12 @@ namespace mongo { virtual void help(stringstream& ss) const { ss << "internal"; } CmdAuthenticate() : Command("authenticate") {} bool run(const string& dbname , BSONObj& cmdObj, int options, string& errmsg, BSONObjBuilder& result, bool fromRepl); + void authenticate(const string& dbname, const string& user, const bool readOnly); private: bool getUserObj(const string& dbname, const string& user, BSONObj& userObj, string& pwd); - void authenticate(const string& dbname, const string& user, const bool readOnly); }; + + extern CmdAuthenticate cmdAuthenticate; class CmdLogout : public Command { public: |