summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
Diffstat (limited to 'db')
-rw-r--r--db/cloner.cpp6
-rw-r--r--db/compact.cpp5
-rw-r--r--db/dbwebserver.cpp11
-rw-r--r--db/queryoptimizer.cpp51
-rw-r--r--db/queryoptimizer.h1
-rw-r--r--db/repl.cpp2
-rw-r--r--db/repl/rs_initialsync.cpp45
-rw-r--r--db/security_common.h4
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: