diff options
author | dwight <dwight@dwights-MacBook-Pro.local> | 2011-04-28 19:41:36 -0400 |
---|---|---|
committer | dwight <dwight@dwights-MacBook-Pro.local> | 2011-04-28 19:41:36 -0400 |
commit | eb964f15842390f4790ad0572107fa40fd98f6c1 (patch) | |
tree | 70833889ab7d10658fee06e6ffb7af5697ee389a | |
parent | 87ab46c3a49ea857dba6dad8c60f51e974139cdf (diff) | |
parent | ef042e49915d2699049fc94caf386c58d1548842 (diff) | |
download | mongo-eb964f15842390f4790ad0572107fa40fd98f6c1.tar.gz |
Merge branch 'master' of git@github.com:mongodb/mongo
38 files changed, 225 insertions, 81 deletions
diff --git a/buildscripts/smoke.py b/buildscripts/smoke.py index 2568acbe00e..6ae8b32aa97 100755 --- a/buildscripts/smoke.py +++ b/buildscripts/smoke.py @@ -145,7 +145,7 @@ class mongod(object): utils.ensureDir(dir_name) argv = [mongod_executable, "--port", str(self.port), "--dbpath", dir_name] if self.kwargs.get('small_oplog'): - argv += ["--master", "--oplogSize", "128"] + argv += ["--master", "--oplogSize", "256"] if self.slave: argv += ['--slave', '--source', 'localhost:' + str(srcport)] print "running " + " ".join(argv) diff --git a/client/dbclient.h b/client/dbclient.h index 5d6d87cc129..03030a3c6be 100644 --- a/client/dbclient.h +++ b/client/dbclient.h @@ -884,7 +884,7 @@ namespace mongo { */ bool isFailed() const { return _failed; } - MessagingPort& port() { return *p; } + MessagingPort& port() { assert(p); return *p; } string toStringLong() const { stringstream ss; diff --git a/client/dbclient_rs.cpp b/client/dbclient_rs.cpp index 9cf6a18440f..217c38804a5 100644 --- a/client/dbclient_rs.cpp +++ b/client/dbclient_rs.cpp @@ -74,7 +74,7 @@ namespace mongo { ReplicaSetMonitor::ReplicaSetMonitor( const string& name , const vector<HostAndPort>& servers ) - : _lock( "ReplicaSetMonitor instance" ) , _checkConnectionLock( "ReplicaSetMonitor check connection lock" ), _name( name ) , _master(-1) { + : _lock( "ReplicaSetMonitor instance" ) , _checkConnectionLock( "ReplicaSetMonitor check connection lock" ), _name( name ) , _master(-1), _nextSlave(0) { uassert( 13642 , "need at least 1 node for a replica set" , servers.size() > 0 ); @@ -221,19 +221,19 @@ namespace mongo { } HostAndPort ReplicaSetMonitor::getSlave() { - int x = rand() % _nodes.size(); + { scoped_lock lk( _lock ); for ( unsigned i=0; i<_nodes.size(); i++ ) { - int p = ( i + x ) % _nodes.size(); - if ( p == _master ) + _nextSlave = ( _nextSlave + 1 ) % _nodes.size(); + if ( _nextSlave == _master ) continue; - if ( _nodes[p].ok ) - return _nodes[p].addr; + if ( _nodes[ _nextSlave ].ok ) + return _nodes[ _nextSlave ].addr; } } - return _nodes[0].addr; + return _nodes[ 0 ].addr; } /** @@ -309,7 +309,7 @@ namespace mongo { BSONObj o; c->isMaster(isMaster, &o); - log( ! verbose ) << "ReplicaSetMonitor::_checkConnection: " << c->toString() << ' ' << o << '\n'; + log( ! verbose ) << "ReplicaSetMonitor::_checkConnection: " << c->toString() << ' ' << o << endl; // add other nodes string maybePrimary; @@ -530,12 +530,12 @@ namespace mongo { // we're ok sending to a slave // we'll try 2 slaves before just using master // checkSlave will try a different slave automatically after a failure - for ( int i=0; i<2; i++ ) { + for ( int i=0; i<3; i++ ) { try { return checkSlave()->query(ns,query,nToReturn,nToSkip,fieldsToReturn,queryOptions,batchSize); } - catch ( DBException & ) { - LOG(1) << "can't query replica set slave: " << _slaveHost << endl; + catch ( DBException &e ) { + LOG(1) << "can't query replica set slave " << i << " : " << _slaveHost << causedBy( e ) << endl; } } } @@ -548,12 +548,12 @@ namespace mongo { // we're ok sending to a slave // we'll try 2 slaves before just using master // checkSlave will try a different slave automatically after a failure - for ( int i=0; i<2; i++ ) { + for ( int i=0; i<3; i++ ) { try { return checkSlave()->findOne(ns,query,fieldsToReturn,queryOptions); } - catch ( DBException & ) { - LOG(1) << "can't query replica set slave: " << _slaveHost << endl; + catch ( DBException &e ) { + LOG(1) << "can't findone replica set slave " << i << " : " << _slaveHost << causedBy( e ) << endl; } } } @@ -581,12 +581,12 @@ namespace mongo { DbMessage dm( toSend ); QueryMessage qm( dm ); if ( qm.queryOptions & QueryOption_SlaveOk ) { - for ( int i=0; i<2; i++ ) { + for ( int i=0; i<3; i++ ) { try { return checkSlave()->callLazy( toSend ); } - catch ( DBException & ) { - log(1) << "can't query replica set slave: " << _slaveHost << endl; + catch ( DBException &e ) { + LOG(1) << "can't callLazy replica set slave " << i << " : " << _slaveHost << causedBy( e ) << endl; } } } @@ -601,15 +601,15 @@ namespace mongo { DbMessage dm( toSend ); QueryMessage qm( dm ); if ( qm.queryOptions & QueryOption_SlaveOk ) { - for ( int i=0; i<2; i++ ) { + for ( int i=0; i<3; i++ ) { try { DBClientConnection* s = checkSlave(); if ( actualServer ) *actualServer = s->getServerAddress(); return s->call( toSend , response , assertOk ); } - catch ( DBException & ) { - log(1) << "can't query replica set slave: " << _slaveHost << endl; + catch ( DBException &e ) { + LOG(1) << "can't call replica set slave " << i << " : " << _slaveHost << causedBy( e ) << endl; if ( actualServer ) *actualServer = ""; } diff --git a/client/dbclient_rs.h b/client/dbclient_rs.h index f65fe3d3ad4..f0e855ae8c4 100644 --- a/client/dbclient_rs.h +++ b/client/dbclient_rs.h @@ -147,7 +147,7 @@ namespace mongo { vector<Node> _nodes; int _master; // which node is the current master. -1 means no master is known - + int _nextSlave; // which node is the current slave static mongo::mutex _setsLock; // protects _sets static map<string,ReplicaSetMonitorPtr> _sets; // set name to Monitor diff --git a/client/examples/clientTest.cpp b/client/examples/clientTest.cpp index 96c014e245c..aaea6bd1bdf 100644 --- a/client/examples/clientTest.cpp +++ b/client/examples/clientTest.cpp @@ -246,5 +246,34 @@ int main( int argc, const char **argv ) { //MONGO_PRINT(out); } + { + // test timeouts + + DBClientConnection conn( true , 0 , 2 ); + if ( ! conn.connect( string( "127.0.0.1:" ) + port , errmsg ) ) { + cout << "couldn't connect : " << errmsg << endl; + throw -11; + } + conn.insert( "test.totest" , BSON( "x" << 1 ) ); + BSONObj res; + + bool gotError = false; + assert( conn.eval( "test" , "return db.totest.findOne().x" , res ) ); + try { + conn.eval( "test" , "sleep(5000); return db.totest.findOne().x" , res ); + } + catch ( std::exception& e ) { + gotError = true; + log() << e.what() << endl; + } + assert( gotError ); + // sleep so the server isn't locked anymore + sleepsecs( 4 ); + + assert( conn.eval( "test" , "return db.totest.findOne().x" , res ) ); + + + } + cout << "client test finished!" << endl; } diff --git a/db/db.vcxproj b/db/db.vcxproj index a032653c94c..eb56d6fe77f 100644 --- a/db/db.vcxproj +++ b/db/db.vcxproj @@ -493,6 +493,10 @@ <ClCompile Include="mongommf.cpp" />
<ClCompile Include="oplog.cpp" />
<ClCompile Include="projection.cpp" />
+ <ClCompile Include="querypattern.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="repl.cpp" />
<ClCompile Include="repl\consensus.cpp" />
<ClCompile Include="repl\heartbeat.cpp" />
@@ -658,6 +662,7 @@ <ClInclude Include="namespace-inl.h" />
<ClInclude Include="oplogreader.h" />
<ClInclude Include="projection.h" />
+ <ClInclude Include="queryutil.h" />
<ClInclude Include="repl.h" />
<ClInclude Include="replpair.h" />
<ClInclude Include="repl\connections.h" />
diff --git a/db/db.vcxproj.filters b/db/db.vcxproj.filters index 1ab8438371b..936d0da5d5e 100755 --- a/db/db.vcxproj.filters +++ b/db/db.vcxproj.filters @@ -155,6 +155,7 @@ <ClCompile Include="repl\rs_config.cpp" />
<ClCompile Include="security_key.cpp" />
<ClCompile Include="..\util\file_allocator.cpp" />
+ <ClCompile Include="querypattern.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\client\dbclientcursor.h" />
@@ -293,6 +294,7 @@ <ClInclude Include="dur_journalimpl.h" />
<ClInclude Include="..\util\concurrency\race.h" />
<ClInclude Include="..\util\alignedbuilder.h" />
+ <ClInclude Include="queryutil.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="db.rc" />
diff --git a/db/dur_journal.cpp b/db/dur_journal.cpp index 52498b900e3..b8c259a6763 100644 --- a/db/dur_journal.cpp +++ b/db/dur_journal.cpp @@ -457,7 +457,7 @@ namespace mongo { if something highly surprising, throws to abort */ unsigned long long LSNFile::get() { - uassert(13614, "unexpected version number of lsn file in journal/ directory", ver == 0); + uassert(13614, str::stream() << "unexpected version number of lsn file in journal/ directory got: " << ver , ver == 0); if( ~lsn != checkbytes ) { log() << "lsnfile not valid. recovery will be from log start. lsn: " << hex << lsn << " checkbytes: " << hex << checkbytes << endl; return 0; @@ -486,6 +486,11 @@ namespace mongo { File f; f.open(lsnPath().string().c_str()); assert(f.is_open()); + if( f.len() == 0 ) { + // this could be 'normal' if we crashed at the right moment + log() << "info lsn file is zero bytes long" << endl; + return 0; + } f.read(0,(char*)&L, sizeof(L)); unsigned long long lsn = L.get(); return lsn; diff --git a/db/queryutil.h b/db/queryutil.h index 99a6b874254..a817764246d 100644 --- a/db/queryutil.h +++ b/db/queryutil.h @@ -278,7 +278,7 @@ namespace mongo { FieldRangeSet _singleKey; FieldRangeSet _multiKey; friend class FieldRangeOrSet; - friend class QueryUtilIndexed; + friend struct QueryUtilIndexed; }; class IndexSpec; @@ -407,7 +407,7 @@ namespace mongo { // ensure memory is owned list<FieldRangeSetPair> _oldOrSets; bool _orFound; - friend class QueryUtilIndexed; + friend struct QueryUtilIndexed; }; /** returns a string that when used as a matcher, would match a super set of regex() diff --git a/db/repl/rs.cpp b/db/repl/rs.cpp index eea51e3f2e2..84ef3935a3b 100644 --- a/db/repl/rs.cpp +++ b/db/repl/rs.cpp @@ -465,9 +465,14 @@ namespace mongo { forgetPrimary(); setSelfTo(0); + + // For logging + string members = ""; + for( vector<ReplSetConfig::MemberCfg>::iterator i = _cfg->members.begin(); i != _cfg->members.end(); i++ ) { const ReplSetConfig::MemberCfg& m = *i; Member *mi; + members += ( members == "" ? "" : ", " ) + m.h.toString(); if( m.h.isSelf() ) { assert( _self == 0 ); mi = new Member(m.h, m._id, &m, true); @@ -484,6 +489,11 @@ namespace mongo { box.setOtherPrimary(mi); } } + + if( ! _self ){ + log() << "replSet warning did not detect own host in full reconfig, members " << members << " config: " << c << rsLog; + } + return true; } diff --git a/db/repl/rs.h b/db/repl/rs.h index 9c1948e67a4..5b8863aa161 100644 --- a/db/repl/rs.h +++ b/db/repl/rs.h @@ -379,7 +379,7 @@ namespace mongo { void loadConfig(); list<HostAndPort> memberHostnames() const; - const ReplSetConfig::MemberCfg& myConfig() const { return _self->config(); } + const ReplSetConfig::MemberCfg& myConfig() const { assert( _self ); return _self->config(); } bool iAmArbiterOnly() const { return myConfig().arbiterOnly; } bool iAmPotentiallyHot() const { return myConfig().potentiallyHot() && elect.steppedDown <= time(0); } protected: @@ -505,6 +505,7 @@ namespace mongo { inline Member::Member(HostAndPort h, unsigned ord, const ReplSetConfig::MemberCfg *c, bool self) : _config(*c), _h(h), _hbinfo(ord) { + assert(c); if( self ) _hbinfo.health = 1.0; } diff --git a/db/repl/rs_config.cpp b/db/repl/rs_config.cpp index 28b26154836..229bddc120e 100644 --- a/db/repl/rs_config.cpp +++ b/db/repl/rs_config.cpp @@ -68,7 +68,7 @@ namespace mongo { cx.db()->flushFiles(true); } - DEV log() << "replSet saveConfigLocally done" << rsLog; + log() << "replSet saveConfigLocally done" << rsLog; } bo ReplSetConfig::MemberCfg::asBson() const { diff --git a/db/repl/rs_sync.cpp b/db/repl/rs_sync.cpp index d14581fab4a..535796b5a25 100644 --- a/db/repl/rs_sync.cpp +++ b/db/repl/rs_sync.cpp @@ -34,7 +34,7 @@ namespace mongo { if ( *ns == '.' || *ns == 0 ) { if( *o.getStringField("op") == 'n' ) return; - log() << "replSet skipping bad op in oplog: " << o.toString() << endl; + log() << "replSet skipping bad op in oplog: " << o.toString() << rsLog; return; } @@ -141,7 +141,7 @@ namespace mongo { time_t now = time(0); if (now - start > 10) { // simple progress metering - log() << "initialSyncOplogApplication applied " << n << " operations, synced to " + log() << "replSet initialSyncOplogApplication applied " << n << " operations, synced to " << ts.toStringPretty() << rsLog; start = now; } @@ -322,8 +322,8 @@ namespace mongo { OpTime ts = o["ts"]._opTime(); long long h = o["h"].numberLong(); if( ts != lastOpTimeWritten || h != lastH ) { - log() << "replSet our last op time written: " << lastOpTimeWritten.toStringPretty() << endl; - log() << "replset source's GTE: " << ts.toStringPretty() << endl; + log() << "replSet our last op time written: " << lastOpTimeWritten.toStringPretty() << rsLog; + log() << "replset source's GTE: " << ts.toStringPretty() << rsLog; syncRollback(r); return; } @@ -467,8 +467,13 @@ namespace mongo { */ while( 1 ) { - if( myConfig().arbiterOnly ) + // After a reconfig, we may not be in the replica set anymore, so + // check that we are in the set (and not an arbiter) before + // trying to sync with other replicas. + if( ! _self || myConfig().arbiterOnly ){ + if( ! _self ) log() << "replSet warning did not detect own host and port, not syncing, config: " << theReplSet->config() << rsLog; return; + } try { _syncThread(); @@ -488,7 +493,11 @@ namespace mongo { are no heartbeat threads, so we do it here to be sure. this is relevant if the singleton member has done a stepDown() and needs to come back up. */ - OCCASIONALLY mgr->send( boost::bind(&Manager::msgCheckNewState, theReplSet->mgr) ); + OCCASIONALLY { + log() << "replSet default heartbeat starting..." << rsLog; + mgr->send( boost::bind(&Manager::msgCheckNewState, theReplSet->mgr) ); + log() << "replSet heartbeat finished" << rsLog; + } } } diff --git a/dbtests/test.vcxproj b/dbtests/test.vcxproj index 984272d6429..66c890e9d44 100644 --- a/dbtests/test.vcxproj +++ b/dbtests/test.vcxproj @@ -285,6 +285,10 @@ <ClCompile Include="..\db\geo\haystack.cpp" />
<ClCompile Include="..\db\mongommf.cpp" />
<ClCompile Include="..\db\projection.cpp" />
+ <ClCompile Include="..\db\querypattern.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="..\db\repl\consensus.cpp" />
<ClCompile Include="..\db\repl\heartbeat.cpp" />
<ClCompile Include="..\db\repl\manager.cpp" />
diff --git a/dbtests/test.vcxproj.filters b/dbtests/test.vcxproj.filters index c576e5386e4..15d2c98d329 100755 --- a/dbtests/test.vcxproj.filters +++ b/dbtests/test.vcxproj.filters @@ -773,6 +773,9 @@ <ClCompile Include="..\db\dbcommands_admin.cpp">
<Filter>db\cpp</Filter>
</ClCompile>
+ <ClCompile Include="..\db\querypattern.cpp">
+ <Filter>db</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\SConstruct">
diff --git a/jstests/check_shard_index.js b/jstests/check_shard_index.js index a5a1fc14c47..e63b79ddc23 100644 --- a/jstests/check_shard_index.js +++ b/jstests/check_shard_index.js @@ -42,4 +42,9 @@ assert.eq( 3 , f.count() , "2. count after initial insert should be 3" ); res = db.runCommand( { checkShardingIndex: "test.jstests_shardingindex" , keyPattern: {x:1, y:1} , force: true }); assert.eq( false , res.ok , "2b " + tojson(res) ); +// +res = db.runCommand( { checkShardingIndex: "test.jstests_shardingindex" , keyPattern: {_id:1} , force: true }); +assert.eq( true , res.ok , "3a " + tojson(res) ); +assert( res.idskip , "3b " + tojson(res) ) + print("PASSED"); diff --git a/jstests/delx.js b/jstests/delx.js index 3f8c88c1648..aa858e92cbd 100644 --- a/jstests/delx.js +++ b/jstests/delx.js @@ -23,6 +23,7 @@ x.next(); y.next(); a.foo.remove( { _id : { $gt : 50 } } ); +db.getLastError(); assert.eq( 51 , a.foo.find().itcount() , "B1" ) assert.eq( 100 , b.foo.find().itcount() , "B2" ) diff --git a/jstests/drop3.js b/jstests/drop3.js index 1badf07d54b..b2ca94a1550 100644 --- a/jstests/drop3.js +++ b/jstests/drop3.js @@ -19,6 +19,7 @@ assert.eq( cursor.objsLeftInBatch(), 1 ); assert.eq( subcursor.objsLeftInBatch(), 1 ); t.drop(); // should invalidate cursor, but not subcursor +db.getLastError(); assert.throws( function(){ cursor.itcount() } ); // throws "cursor doesn't exist on server" error on getMore assert.eq( subcursor.itcount(), 9 ); //one already seen diff --git a/jstests/dropdb.js b/jstests/dropdb.js index 424cfca2b38..0b838846bde 100644 --- a/jstests/dropdb.js +++ b/jstests/dropdb.js @@ -7,6 +7,7 @@ baseName = "jstests_dropdb"; ddb = db.getSisterDB( baseName ); ddb.c.save( {} ); +ddb.getLastError(); assert.neq( -1, m.getDBNames().indexOf( baseName ) ); ddb.dropDatabase(); diff --git a/jstests/evalc.js b/jstests/evalc.js index 8a9e889c6ef..0320ecd5133 100644 --- a/jstests/evalc.js +++ b/jstests/evalc.js @@ -1,17 +1,24 @@ t = db.jstests_evalc; t.drop(); +t2 = db.evalc_done +t2.drop() + for( i = 0; i < 10; ++i ) { t.save( {i:i} ); } // SERVER-1610 -s = startParallelShell( "print( 'starting forked:' + Date() ); for ( i=0; i<500000; i++ ){ db.currentOp(); } print( 'ending forked:' + Date() ); " ) +assert.eq( 0 , t2.count() , "X1" ) + +s = startParallelShell( "print( 'starting forked:' + Date() ); for ( i=0; i<50000; i++ ){ db.currentOp(); } print( 'ending forked:' + Date() ); db.evalc_done.insert( { x : 1 } ); " ) print( "starting eval: " + Date() ) -for ( i=0; i<20000; i++ ){ +while ( true ) { db.eval( "db.jstests_evalc.count( {i:10} );" ); + if ( t2.count() > 0 ) + break; } print( "end eval: " + Date() ) diff --git a/jstests/indexs.js b/jstests/indexs.js new file mode 100644 index 00000000000..3a52584bfd3 --- /dev/null +++ b/jstests/indexs.js @@ -0,0 +1,23 @@ +// Test index key generation issue with parent and nested fields in same index and array containing subobject SERVER-3005. + +t = db.jstests_indexs; + +t.drop(); +t.ensureIndex( {a:1} ); +t.save( { a: [ { b: 3 } ] } ); +assert.eq( 1, t.count( { a:{ b:3 } } ) ); + +t.drop(); +t.ensureIndex( {a:1,'a.b':1} ); +t.save( { a: { b: 3 } } ); +assert.eq( 1, t.count( { a:{ b:3 } } ) ); +ib = t.find( { a:{ b:3 } } ).explain().indexBounds; + +t.drop(); +t.ensureIndex( {a:1,'a.b':1} ); +t.save( { a: [ { b: 3 } ] } ); +assert.eq( ib, t.find( { a:{ b:3 } } ).explain().indexBounds ); +if ( 0 ) { // SERVER-3005 +assert.eq( 1, t.find( { a:{ b:3 } } ).explain().nscanned ); +assert.eq( 1, t.count( { a:{ b:3 } } ) ); +}
\ No newline at end of file diff --git a/jstests/or5.js b/jstests/or5.js index baa6bd6f847..98ff141f575 100644 --- a/jstests/or5.js +++ b/jstests/or5.js @@ -70,6 +70,7 @@ assert.eq.automsg( "6", "t.find( {$or:[{a:2},{b:3},{c:4}]} ).batchSize( 2 ).itco c = t.find( {$or:[{a:2},{b:3},{c:4}]} ).batchSize( 2 ); c.next(); t.remove( {b:3} ); +db.getLastError(); assert.eq.automsg( "3", c.itcount() ); reset(); @@ -78,6 +79,7 @@ c = t.find( {$or:[{a:2},{b:3},{c:4}]} ).batchSize( 2 ); c.next(); c.next(); t.remove( {b:3} ); +db.getLastError(); assert.eq.automsg( "2", c.itcount() ); reset(); @@ -87,6 +89,7 @@ c.next(); c.next(); c.next(); t.remove( {b:3} ); +db.getLastError(); assert.eq.automsg( "3", c.itcount() ); reset(); @@ -97,6 +100,7 @@ c.next(); c.next(); c.next(); t.remove( {b:3} ); +db.getLastError(); assert.eq.automsg( "2", c.itcount() ); t.drop(); diff --git a/jstests/ord.js b/jstests/ord.js index 4612f218f64..f78e5044074 100644 --- a/jstests/ord.js +++ b/jstests/ord.js @@ -28,6 +28,7 @@ for( i = 0; i < 90; ++i ) { // the index key {a:1} t.dropIndex( {a:1} ); +db.getLastError(); // Dropping an index kills all cursors on the indexed namespace, not just those // cursors using the dropped index. diff --git a/jstests/replsets/remove1.js b/jstests/replsets/remove1.js index b5f9a4f1a00..d6d36e40f25 100644 --- a/jstests/replsets/remove1.js +++ b/jstests/replsets/remove1.js @@ -82,8 +82,9 @@ wait(function() { printjson(master.getDB("admin").runCommand({replSetGetStatus:1})); master.setSlaveOk(); var newConfig = master.getDB("local").system.replset.findOne(); + print( "newConfig: " + tojson(newConfig) ); return newConfig.version == 4; - }); +} , "wait1" ); print("Make sure everyone's secondary"); @@ -103,7 +104,7 @@ wait(function() { } } return true; - }); +} , "wait2" ); replTest.stopSet(); diff --git a/jstests/replsets/rslib.js b/jstests/replsets/rslib.js index 6434cddcf96..19271c9e13d 100644 --- a/jstests/replsets/rslib.js +++ b/jstests/replsets/rslib.js @@ -2,7 +2,7 @@ var count = 0; var w = 0; -var wait = function(f) { +var wait = function(f,msg) { w++; var n = 0; while (!f()) { @@ -11,7 +11,7 @@ var wait = function(f) { if (++n == 4) { print("" + f); } - assert(n < 200, 'tried 200 times, giving up'); + assert(n < 200, 'tried 200 times, giving up on ' + msg ); sleep(1000); } }; diff --git a/jstests/replsets/sync1.js b/jstests/replsets/sync1.js index de824d0989b..5e862106efa 100644 --- a/jstests/replsets/sync1.js +++ b/jstests/replsets/sync1.js @@ -80,12 +80,17 @@ doTest = function (signal) { assert(count < 300); + // Need to be careful here, allocating datafiles for the slaves can take a *long* time on slow systems + sleep(7000); + print("\nsync1.js ********************************************************************** part 6"); dbs[0].getSisterDB("admin").runCommand({ replSetTest: 1, blind: true }); print("\nsync1.js ********************************************************************** part 7"); sleep(5000); + // If we start getting error hasNext: false with done alloc datafile msgs - may need to up the sleep again in part 5 + var max1; var max2; diff --git a/jstests/sharding/migrateBig.js b/jstests/sharding/migrateBig.js index f6ba18a7c02..917f152a4d2 100644 --- a/jstests/sharding/migrateBig.js +++ b/jstests/sharding/migrateBig.js @@ -40,6 +40,6 @@ for ( i=0; i<20; i+= 2 ) db.printShardingStatus() -assert.soon( function(){ var x = s.chunkDiff( "foo" , "test" ); print( "chunk diff: " + x ); return x < 2; } , "no balance happened" , 120 * 1000 , 2000 ) +assert.soon( function(){ var x = s.chunkDiff( "foo" , "test" ); print( "chunk diff: " + x ); return x < 2; } , "no balance happened" , 8 * 60 * 1000 , 2000 ) s.stop() diff --git a/jstests/sharding/shard_insert_getlasterror_w2.js b/jstests/sharding/shard_insert_getlasterror_w2.js index c722f216e64..1e0266dcc7d 100644 --- a/jstests/sharding/shard_insert_getlasterror_w2.js +++ b/jstests/sharding/shard_insert_getlasterror_w2.js @@ -75,7 +75,8 @@ function go() { return false; } return true; - }); + }, "Queries took too long to complete correctly.", + 2 * 60 * 1000 ); // Done routerSpec.end() diff --git a/jstests/sharding/sync7.js b/jstests/sharding/sync7.js index 0badd9ebeb7..a8ff0944a00 100644 --- a/jstests/sharding/sync7.js +++ b/jstests/sharding/sync7.js @@ -7,7 +7,7 @@ s._connections[1].getDB( "admin" ).runCommand( { _skewClockCommand : 1, skew : - // We need to start another mongos after skewing the clock, since the first mongos will have already // tested the config servers (via the balancer) before we manually skewed them -otherMongos = startMongos( { port : 30020, v : 0, configdb : s._configDB, logpath : "/dev/null" } ); +otherMongos = startMongos( { port : 30020, v : 0, configdb : s._configDB } ); // Initialize DB data initDB = function(name) { diff --git a/s/balance.cpp b/s/balance.cpp index 40d542b9111..ffa23ed794b 100644 --- a/s/balance.cpp +++ b/s/balance.cpp @@ -275,20 +275,21 @@ namespace mongo { try { - // first make sure we should even be running + ScopedDbConnection conn( config ); + + // ping has to be first so we keep things in the config server in sync + _ping( conn.conn() ); + + // now make sure we should even be running if ( ! grid.shouldBalance() ) { log(1) << "skipping balancing round because balancing is disabled" << endl; + conn.done(); + sleepsecs( 30 ); continue; } - - ScopedDbConnection conn( config ); - - _ping( conn.conn() ); - if ( ! _checkOIDs() ) { - uassert( 13258 , "oids broken after resetting!" , _checkOIDs() ); - } + uassert( 13258 , "oids broken after resetting!" , _checkOIDs() ); // use fresh shard state Shard::reloadShardInfo(); diff --git a/s/chunk.cpp b/s/chunk.cpp index 0fb2fca1237..e63c38bae44 100644 --- a/s/chunk.cpp +++ b/s/chunk.cpp @@ -726,7 +726,6 @@ namespace mongo { void ChunkManager::getShardsForQuery( set<Shard>& shards , const BSONObj& query ) { rwlock lk( _lock , false ); - DEV PRINT(query); //TODO look into FieldRangeSetOr FieldRangeOrSet fros(_ns.c_str(), query, false); @@ -762,9 +761,6 @@ namespace mongo { BSONObj minObj = it->first.replaceFieldNames(_key.key()); BSONObj maxObj = it->second.replaceFieldNames(_key.key()); - DEV PRINT(minObj); - DEV PRINT(maxObj); - ChunkRangeMap::const_iterator min, max; min = _chunkRanges.upper_bound(minObj); max = _chunkRanges.upper_bound(maxObj); diff --git a/s/d_migrate.cpp b/s/d_migrate.cpp index fe4c0efe355..22b600a8db1 100644 --- a/s/d_migrate.cpp +++ b/s/d_migrate.cpp @@ -1008,6 +1008,7 @@ namespace mongo { conn.done(); } catch ( DBException& e ) { + warning() << e << endl; ok = false; BSONObjBuilder b; e.getInfo().append( b ); diff --git a/s/d_split.cpp b/s/d_split.cpp index 59a07420956..6eaf4cf502e 100644 --- a/s/d_split.cpp +++ b/s/d_split.cpp @@ -138,6 +138,11 @@ namespace mongo { const char* ns = jsobj.getStringField( "checkShardingIndex" ); BSONObj keyPattern = jsobj.getObjectField( "keyPattern" ); + if ( keyPattern.nFields() == 1 && str::equals( "_id" , keyPattern.firstElement().fieldName() ) ) { + result.appendBool( "idskip" , true ); + return true; + } + // If min and max are not provided use the "minKey" and "maxKey" for the sharding key pattern. BSONObj min = jsobj.getObjectField( "min" ); BSONObj max = jsobj.getObjectField( "max" ); @@ -211,6 +216,9 @@ namespace mongo { return false; } cc->advance(); + + if ( ! cc->yieldSometimes() ) + break; } return true; diff --git a/s/dbgrid.vcxproj b/s/dbgrid.vcxproj index 9affd0e0b6c..507d2126b1a 100644 --- a/s/dbgrid.vcxproj +++ b/s/dbgrid.vcxproj @@ -193,6 +193,10 @@ <ClCompile Include="..\client\distlock.cpp" />
<ClCompile Include="..\db\dbcommands_generic.cpp" />
<ClCompile Include="..\db\dbwebserver.cpp" />
+ <ClCompile Include="..\db\querypattern.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>
+ </ClCompile>
<ClCompile Include="..\db\security_key.cpp" />
<ClCompile Include="..\scripting\bench.cpp" />
<ClCompile Include="..\util\alignedbuilder.cpp">
diff --git a/s/dbgrid.vcxproj.filters b/s/dbgrid.vcxproj.filters index 1fa39311400..46c441feba6 100755 --- a/s/dbgrid.vcxproj.filters +++ b/s/dbgrid.vcxproj.filters @@ -323,6 +323,9 @@ <ClCompile Include="..\db\dbcommands_generic.cpp">
<Filter>Shared Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\db\querypattern.cpp">
+ <Filter>Shared Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="gridconfig.h">
diff --git a/tools/sniffer.cpp b/tools/sniffer.cpp index 4e9cfd21bf3..024a37475cc 100644 --- a/tools/sniffer.cpp +++ b/tools/sniffer.cpp @@ -104,6 +104,9 @@ struct sniff_ip { #define IP_V(ip) (((ip)->ip_vhl) >> 4) /* TCP header */ +#ifdef _WIN32 +typedef unsigned __int32 uint32_t; +#endif typedef uint32_t tcp_seq; struct sniff_tcp { diff --git a/util/file.h b/util/file.h index f61c2c7f645..704dc536211 100644 --- a/util/file.h +++ b/util/file.h @@ -38,6 +38,8 @@ namespace mongo { typedef boost::uint64_t fileofs; #endif + /* NOTE: not thread-safe. (at least the windows implementation isn't. */ + class FileInterface { public: void open(const char *fn) {} @@ -171,12 +173,23 @@ namespace mongo { err( ::pwrite(fd, data, len, o) == (int) len ); } void read(fileofs o, char *data, unsigned len) { - err( ::pread(fd, data, len, o) == (int) len ); + ssize_t s = ::pread(fd, data, len, o); + if( s == -1 ) { + err(false); + } + else if( s != (int) len ) { + _bad = true; + log() << "File error read:" << s << " bytes, wanted:" << len << " ofs:" << o << endl; + } } bool bad() { return _bad; } bool is_open() { return fd > 0; } fileofs len() { - return lseek(fd, 0, SEEK_END); + off_t o = lseek(fd, 0, SEEK_END); + if( o != (off_t) -1 ) + return o; + err(false); + return 0; } void fsync() { ::fsync(fd); } static boost::intmax_t freeSpace ( const string &path ) { diff --git a/util/message.cpp b/util/message.cpp index c58d0ddca63..892d64c7bdb 100644 --- a/util/message.cpp +++ b/util/message.cpp @@ -364,7 +364,7 @@ namespace mongo { ConnectBG(int sock, SockAddr farEnd) : _sock(sock), _farEnd(farEnd) { } void run() { _res = ::connect(_sock, _farEnd.raw(), _farEnd.addressSize); } - string name() const { return ""; /* too short lived to need to name */ } + string name() const { return "ConnectBG"; } int inError() const { return _res; } private: @@ -634,12 +634,20 @@ again: unsigned retries = 0; while( len > 0 ) { int ret = ::recv( sock , buf , len , portRecvFlags ); - if ( ret == 0 ) { + if ( ret > 0 ) { + if ( len <= 4 && ret != len ) + log(_logLevel) << "MessagingPort recv() got " << ret << " bytes wanted len=" << len << endl; + assert( ret <= len ); + len -= ret; + buf += ret; + } + else if ( ret == 0 ) { log(3) << "MessagingPort recv() conn closed? " << farEnd.toString() << endl; throw SocketException( SocketException::CLOSED ); } - if ( ret < 0 ) { + else { /* ret < 0 */ int e = errno; + #if defined(EINTR) && !defined(_WIN32) if( e == EINTR ) { if( ++retries == 1 ) { @@ -648,29 +656,18 @@ again: } } #endif - if ( e != EAGAIN || _timeout == 0 ) { - SocketException::Type t = SocketException::RECV_ERROR; -#if defined(_WINDOWS) - if( e == WSAETIMEDOUT ) t = SocketException::RECV_TIMEOUT; -#else - /* todo: what is the error code on an SO_RCVTIMEO on linux? EGAIN? EWOULDBLOCK? */ + if ( ( e == EAGAIN +#ifdef _WINDOWS + || e == WSAETIMEDOUT #endif - log(_logLevel) << "MessagingPort recv() " << errnoWithDescription(e) << " " << farEnd.toString() <<endl; - throw SocketException(t); - } - else { - if ( !serverAlive( farEnd.toString() ) ) { - log(_logLevel) << "MessagingPort recv() remote dead " << farEnd.toString() << endl; - throw SocketException( SocketException::RECV_ERROR ); - } + ) && _timeout > 0 ) { + // this is a timeout + log(_logLevel) << "MessagingPort recv() timeout " << farEnd.toString() <<endl; + throw SocketException(SocketException::RECV_TIMEOUT); } - } - else { - if ( len <= 4 && ret != len ) - log(_logLevel) << "MessagingPort recv() got " << ret << " bytes wanted len=" << len << endl; - assert( ret <= len ); - len -= ret; - buf += ret; + + log(_logLevel) << "MessagingPort recv() " << errnoWithDescription(e) << " " << farEnd.toString() <<endl; + throw SocketException(SocketException::RECV_ERROR); } } } |