diff options
author | Eliot Horowitz <eliot@10gen.com> | 2011-01-21 14:19:20 -0500 |
---|---|---|
committer | Eliot Horowitz <eliot@10gen.com> | 2011-01-21 14:19:49 -0500 |
commit | b331e1c7aed7d85dd14f86e1396f5c091aaa3f0f (patch) | |
tree | bed9d99f5714067d312e8f5c28220dd72687696e | |
parent | 124193c25929b70baa9fdd00127d87159b9b64ca (diff) | |
download | mongo-b331e1c7aed7d85dd14f86e1396f5c091aaa3f0f.tar.gz |
make sure getLastError fields are correct after writeback SERVER-1467
-rw-r--r-- | jstests/slowNightly/sharding_balance4.js | 18 | ||||
-rw-r--r-- | s/client.cpp | 41 | ||||
-rw-r--r-- | s/client.h | 8 | ||||
-rw-r--r-- | s/strategy_shard.cpp | 7 | ||||
-rw-r--r-- | s/writeback_listener.cpp | 11 | ||||
-rw-r--r-- | s/writeback_listener.h | 2 |
6 files changed, 62 insertions, 25 deletions
diff --git a/jstests/slowNightly/sharding_balance4.js b/jstests/slowNightly/sharding_balance4.js index c9907af77e7..4cbbba6f2fa 100644 --- a/jstests/slowNightly/sharding_balance4.js +++ b/jstests/slowNightly/sharding_balance4.js @@ -1,5 +1,7 @@ // sharding_balance4.js +// check that doing updates done during a migrate all go to the right place + s = new ShardingTest( "slow_sharding_balance4" , 2 , 1 , 1 , { chunksize : 1 } ) s.adminCommand( { enablesharding : "test" } ); @@ -36,9 +38,8 @@ for ( i=0; i<N*10; i++ ){ } db.getLastError(); -s.printChunks( "test.foo" ) - -for ( var i=0; i<10; i++ ){ +for ( var i=0; i<50; i++ ){ + s.printChunks( "test.foo" ) if ( check( "initial:" + i , true ) ) break; sleep( 5000 ) @@ -56,8 +57,12 @@ function check( msg , dontAssert ){ if ( z && z.x == e ) continue; - if ( dontAssert ) + if ( dontAssert ){ + if ( z ) + delete z.s; + print( "not asserting for key failure: " + x + " want: " + e + " got: " + tojson(z) ) return false; + } // we will assert past this point but wait a bit to see if it is because the missing update // was being held in the writeback roundtrip @@ -81,9 +86,14 @@ function check( msg , dontAssert ){ function diff(){ var myid = doUpdate( false ) var le = db.getLastErrorCmd(); + if ( le.err ) print( "ELIOT ELIOT : " + tojson( le ) + "\t" + myid ); + assert( le.updatedExisting , "GLE diff 1: " + tojson(le) ) + assert.eq( 1 , le.n , "GLE diff 2: " + tojson(le) ) + + if ( Math.random() > .99 ){ db.getLastError() check( "random late check" ); // SERVER-1430 diff --git a/s/client.cpp b/s/client.cpp index c1c3da8ea7e..18f598a03d3 100644 --- a/s/client.cpp +++ b/s/client.cpp @@ -39,6 +39,7 @@ namespace mongo { ClientInfo::ClientInfo( int clientId ) : _id( clientId ) { _cur = &_a; _prev = &_b; + _autoSplitOk = true; newRequest(); } @@ -123,14 +124,13 @@ namespace mongo { _clients.erase( i ); } - void ClientInfo::_addWriteBack( vector<WBInfo>& all , const BSONObj& o ) { - BSONElement w = o["writeback"]; + void ClientInfo::_addWriteBack( vector<WBInfo>& all , const BSONObj& gle ) { + BSONElement w = gle["writeback"]; if ( w.type() != jstOID ) return; - BSONElement cid = o["connectionId"]; - cout << "ELIOT : " << cid << endl; + BSONElement cid = gle["connectionId"]; if ( cid.eoo() ) { error() << "getLastError writeback can't work because of version mis-match" << endl; @@ -140,13 +140,17 @@ namespace mongo { all.push_back( WBInfo( cid.numberLong() , w.OID() ) ); } - void ClientInfo::_handleWriteBacks( vector<WBInfo>& all ) { + vector<BSONObj> ClientInfo::_handleWriteBacks( vector<WBInfo>& all ) { + vector<BSONObj> res; + if ( all.size() == 0 ) - return; + return res; for ( unsigned i=0; i<all.size(); i++ ) { - WriteBackListener::waitFor( all[i].connectionId , all[i].id ); + res.push_back( WriteBackListener::waitFor( all[i].connectionId , all[i].id ) ); } + + return res; } @@ -164,14 +168,15 @@ namespace mongo { // handle single server if ( shards->size() == 1 ) { string theShard = *(shards->begin() ); - result.append( "theshard" , theShard.c_str() ); + ShardConnection conn( theShard , "" ); + BSONObj res; bool ok = conn->runCommand( "admin" , options , res ); - //log() << "\t" << res << endl; - result.appendElements( res ); + res = res.getOwned(); conn.done(); - result.append( "singleShard" , theShard ); + + _addWriteBack( writebacks , res ); // hit other machines just to block @@ -185,7 +190,19 @@ namespace mongo { conn.done(); } clearSinceLastGetError(); - _handleWriteBacks( writebacks ); + + if ( writebacks.size() ){ + vector<BSONObj> v = _handleWriteBacks( writebacks ); + assert( v.size() == 1 ); + result.appendElements( v[0] ); + result.appendElementsUnique( res ); + result.append( "initialGLEHost" , theShard ); + } + else { + result.append( "singleShard" , theShard ); + result.appendElements( res ); + } + return ok; } diff --git a/s/client.h b/s/client.h index 016300c481a..7e3d96d7ce9 100644 --- a/s/client.h +++ b/s/client.h @@ -72,6 +72,10 @@ namespace mongo { */ bool getLastError( const BSONObj& options , BSONObjBuilder& result ); + /** @return if its ok to auto split from this client */ + bool autoSplitOk() const { return _autoSplitOk; } + + void noAutoSplit() { _autoSplitOk = false; } static ClientInfo * get( int clientId = 0 , bool create = true ); static void disconnect( int clientId ); @@ -86,7 +90,7 @@ namespace mongo { // for getLastError void _addWriteBack( vector<WBInfo>& all , const BSONObj& o ); - void _handleWriteBacks( vector<WBInfo>& all ); + vector<BSONObj> _handleWriteBacks( vector<WBInfo>& all ); int _id; // unique client id @@ -105,7 +109,7 @@ namespace mongo { set<string> _sinceLastGetError; // all shards accessed since last getLastError int _lastAccess; - + bool _autoSplitOk; static mongo::mutex _clientsLock; static Cache& _clients; diff --git a/s/strategy_shard.cpp b/s/strategy_shard.cpp index 7d2c09fd623..2a71a832c1f 100644 --- a/s/strategy_shard.cpp +++ b/s/strategy_shard.cpp @@ -21,6 +21,7 @@ #include "chunk.h" #include "cursors.h" #include "stats.h" +#include "client.h" #include "../client/connpool.h" #include "../db/commands.h" @@ -158,7 +159,8 @@ namespace mongo { insert( c->getShard() , r.getns() , o ); r.gotInsert(); - c->splitIfShould( o.objsize() ); + if ( r.getClientInfo()->autoSplitOk() ) + c->splitIfShould( o.objsize() ); gotThrough = true; break; } @@ -258,7 +260,8 @@ namespace mongo { try { ChunkPtr c = manager->findChunk( chunkFinder ); doWrite( dbUpdate , r , c->getShard() ); - c->splitIfShould( d.msg().header()->dataLen() ); + if ( r.getClientInfo()->autoSplitOk() ) + c->splitIfShould( d.msg().header()->dataLen() ); break; } catch ( StaleConfigException& e ) { diff --git a/s/writeback_listener.cpp b/s/writeback_listener.cpp index c2b359901be..41240e1b42d 100644 --- a/s/writeback_listener.cpp +++ b/s/writeback_listener.cpp @@ -53,22 +53,24 @@ namespace mongo { } /* static */ - void WriteBackListener::waitFor( ConnectionId connectionId, const OID& oid ) { + BSONObj WriteBackListener::waitFor( ConnectionId connectionId, const OID& oid ) { Timer t; for ( int i=0; i<5000; i++ ) { { scoped_lock lk( _seenWritebacksLock ); WBStatus s = _seenWritebacks[connectionId]; if ( oid <= s.id ) { - // TODO return gle - return; + assert( oid == s.id ); + return s.gle; } + } sleepmillis( 10 ); } stringstream ss; ss << "didn't get writeback for: " << oid << " after: " << t.millis() << " ms"; uasserted( 13403 , ss.str() ); + return BSONObj(); // never gets here } void WriteBackListener::run() { @@ -139,10 +141,11 @@ namespace mongo { try { Request r( m , 0 ); r.init(); + r.getClientInfo()->noAutoSplit(); r.process(); BSONObjBuilder b; - if ( ! r.getClientInfo()->getLastError( BSONObj() , b ) ) { + if ( ! r.getClientInfo()->getLastError( BSON( "getLastError" << 1 ) , b ) ) { b.appendBool( "commandFailed" , true ); } gle = b.obj(); diff --git a/s/writeback_listener.h b/s/writeback_listener.h index bcb039a404b..5bd08f2a2b4 100644 --- a/s/writeback_listener.h +++ b/s/writeback_listener.h @@ -37,7 +37,7 @@ namespace mongo { public: static void init( DBClientBase& conn ); - static void waitFor( ConnectionId connectionId, const OID& oid ); + static BSONObj waitFor( ConnectionId connectionId, const OID& oid ); protected: WriteBackListener( const string& addr ); |