mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
SERVER-3208 refresh cached namespace pointers on update yield
This commit is contained in:
parent
23c7fefdfe
commit
789bd622ae
@ -447,16 +447,29 @@ namespace mongo {
|
||||
return rec;
|
||||
}
|
||||
|
||||
bool ClientCursor::yieldSometimes( RecordNeeds need ) {
|
||||
bool ClientCursor::yieldSometimes( RecordNeeds need, bool *yielded ) {
|
||||
if ( yielded ) {
|
||||
*yielded = false;
|
||||
}
|
||||
if ( ! _yieldSometimesTracker.ping() ) {
|
||||
Record* rec = _recordForYield( need );
|
||||
if ( rec )
|
||||
if ( rec ) {
|
||||
if ( yielded ) {
|
||||
*yielded = true;
|
||||
}
|
||||
return yield( yieldSuggest() , rec );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int micros = yieldSuggest();
|
||||
return ( micros > 0 ) ? yield( micros , _recordForYield( need ) ) : true;
|
||||
if ( micros > 0 ) {
|
||||
if ( yielded ) {
|
||||
*yielded = true;
|
||||
}
|
||||
return yield( micros , _recordForYield( need ) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientCursor::staticYield( int micros , const StringData& ns , Record * rec ) {
|
||||
|
@ -186,9 +186,10 @@ namespace mongo {
|
||||
/**
|
||||
* @param needRecord whether or not the next record has to be read from disk for sure
|
||||
* if this is true, will yield of next record isn't in memory
|
||||
* @param yielded true if a yield occurred, and potentially if a yield did not occur
|
||||
* @return same as yield()
|
||||
*/
|
||||
bool yieldSometimes( RecordNeeds need );
|
||||
bool yieldSometimes( RecordNeeds need, bool *yielded = 0 );
|
||||
|
||||
static int yieldSuggest();
|
||||
static void staticYield( int micros , const StringData& ns , Record * rec );
|
||||
|
@ -1060,11 +1060,10 @@ namespace mongo {
|
||||
|
||||
debug.updateobj = updateobj;
|
||||
|
||||
/* idea with these here it to make them loop invariant for multi updates, and thus be a bit faster for that case */
|
||||
/* NOTE: when yield() is added herein, these must be refreshed after each call to yield! */
|
||||
// idea with these here it to make them loop invariant for multi updates, and thus be a bit faster for that case
|
||||
// The pointers may be left invalid on a failed yield recovery.
|
||||
NamespaceDetails *d = nsdetails(ns); // can be null if an upsert...
|
||||
NamespaceDetailsTransient *nsdt = &NamespaceDetailsTransient::get_w(ns);
|
||||
/* end note */
|
||||
|
||||
auto_ptr<ModSet> mods;
|
||||
bool isOperatorUpdate = updateobj.firstElementFieldName()[0] == '$';
|
||||
@ -1105,6 +1104,9 @@ namespace mongo {
|
||||
shared_ptr< MultiCursor::CursorOp > opPtr( new UpdateOp( mods.get() && mods->hasDynamicArray() ) );
|
||||
shared_ptr< MultiCursor > c( new MultiCursor( ns, patternOrig, BSONObj(), opPtr, true ) );
|
||||
|
||||
d = nsdetails(ns);
|
||||
nsdt = &NamespaceDetailsTransient::get_w(ns);
|
||||
|
||||
if( c->ok() ) {
|
||||
set<DiskLoc> seenObjects;
|
||||
MatchDetails details;
|
||||
@ -1120,13 +1122,19 @@ namespace mongo {
|
||||
cc.reset( new ClientCursor( QueryOption_NoCursorTimeout , cPtr , ns ) );
|
||||
}
|
||||
|
||||
if ( ! cc->yieldSometimes( ClientCursor::WillNeed ) ) {
|
||||
bool didYield;
|
||||
if ( ! cc->yieldSometimes( ClientCursor::WillNeed, &didYield ) ) {
|
||||
cc.release();
|
||||
break;
|
||||
}
|
||||
if ( !c->ok() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( didYield ) {
|
||||
d = nsdetails(ns);
|
||||
nsdt = &NamespaceDetailsTransient::get_w(ns);
|
||||
}
|
||||
// *****************
|
||||
|
||||
// May have already matched in UpdateOp, but do again to get details set correctly
|
||||
@ -1146,6 +1154,8 @@ namespace mongo {
|
||||
if ( !c->ok() ) {
|
||||
break;
|
||||
}
|
||||
d = nsdetails(ns);
|
||||
nsdt = &NamespaceDetailsTransient::get_w(ns);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -1276,6 +1286,8 @@ namespace mongo {
|
||||
if ( !c->ok() ) {
|
||||
break;
|
||||
}
|
||||
d = nsdetails(ns);
|
||||
nsdt = &NamespaceDetailsTransient::get_w(ns);
|
||||
}
|
||||
|
||||
if (atomic)
|
||||
|
@ -1,7 +1,5 @@
|
||||
// Test unsafe management of nsdt on update command yield SERVER-3208
|
||||
|
||||
if ( 0 ) { // SERVER-3208
|
||||
|
||||
prefixNS = db.jstests_updatef;
|
||||
prefixNS.save( {} );
|
||||
|
||||
@ -24,5 +22,3 @@ for( i=0; i < 20; ++i ) {
|
||||
}
|
||||
|
||||
s();
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user