Skip to content

Commit

Permalink
when doing large delete, unlock so other things can go: SERVER-494
Browse files Browse the repository at this point in the history
  • Loading branch information
erh committed Dec 17, 2009
1 parent fbbbdd3 commit a7635d3
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 20 deletions.
16 changes: 9 additions & 7 deletions db/clientcursor.cpp
Expand Up @@ -135,13 +135,15 @@ namespace mongo {
}

wassert( toAdvance.size() < 5000 );

for ( vector<ClientCursor*>::iterator i = toAdvance.begin(); i != toAdvance.end(); ++i ){
ClientCursor* cc = *i;

if ( cc->_doingDeletes ) continue;

for ( vector<ClientCursor*>::iterator i = toAdvance.begin();
i != toAdvance.end(); ++i )
{
Cursor *c = (*i)->c.get();
Cursor *c = cc->c.get();
if ( c->capped() ){
delete *i;
delete cc;
continue;
}

Expand All @@ -154,11 +156,11 @@ namespace mongo {
c->advance();
if ( c->eof() ) {
// advanced to end -- delete cursor
delete *i;
delete cc;
}
else {
wassert( c->refLoc() != dl );
(*i)->updateLocation();
cc->updateLocation();
}
}
}
Expand Down
11 changes: 8 additions & 3 deletions db/clientcursor.h
Expand Up @@ -51,11 +51,12 @@ namespace mongo {
DiskLoc _lastLoc; // use getter and setter not this (important)
unsigned _idleAgeMillis; // how long has the cursor been around, relative to server idle time
bool _liveForever; // if true, never time out cursor

bool _doingDeletes;

static CCById clientCursorsById;
static CCByLoc byLoc;
static boost::recursive_mutex ccmutex; // must use this for all statics above!

static CursorId allocCursorId_inlock();

public:
Expand All @@ -66,7 +67,7 @@ namespace mongo {
int pos; // # objects into the cursor so far
BSONObj query;

ClientCursor() : _idleAgeMillis(0), _liveForever(false), pos(0) {
ClientCursor() : _idleAgeMillis(0), _liveForever(false), _doingDeletes(false), pos(0) {
recursive_boostlock lock(ccmutex);
cursorid = allocCursorId_inlock();
clientCursorsById.insert( make_pair(cursorid, this) );
Expand Down Expand Up @@ -147,6 +148,10 @@ namespace mongo {
_liveForever = true;
}

void setDoingDeletes( bool doingDeletes ){
_doingDeletes = doingDeletes;
}

static unsigned byLocSize(); // just for diagnostics
// static void idleTimeReport(unsigned millis);

Expand Down
36 changes: 26 additions & 10 deletions db/query.cpp
Expand Up @@ -132,29 +132,43 @@ namespace mongo {
int best = 0;
DeleteOp original( justOne, best );
shared_ptr< DeleteOp > bestOp = s.runOp( original );
auto_ptr< Cursor > c = bestOp->newCursor();
auto_ptr< Cursor > creal = bestOp->newCursor();

if( !c->ok() )
if( !creal->ok() )
return nDeleted;

KeyValJSMatcher matcher(pattern, c->indexKeyPattern());
KeyValJSMatcher matcher(pattern, creal->indexKeyPattern());

ClientCursor cc;
cc.c = creal;
cc.ns = ns;
cc.liveForever();
cc.setDoingDeletes( true );
do {
DiskLoc rloc = c->currLoc();
BSONObj key = c->currKey();

c->advance();
if ( nDeleted % 100 == 99 ){
cc.updateLocation();
cc.setDoingDeletes( false );
dbtemprelease unlock;
}
cc.setDoingDeletes( true );

DiskLoc rloc = cc.c->currLoc();
BSONObj key = cc.c->currKey();

cc.c->advance();
cc.updateLocation();

if ( ! matcher.matches( key , rloc ) )
continue;

assert( !c->getsetdup(rloc) ); // can't be a dup, we deleted it!
assert( !cc.c->getsetdup(rloc) ); // can't be a dup, we deleted it!

if ( !justOne ) {
/* NOTE: this is SLOW. this is not good, noteLocation() was designed to be called across getMore
blocks. here we might call millions of times which would be bad.
*/
c->noteLocation();
cc.c->noteLocation();
}

if ( logop ) {
Expand All @@ -168,12 +182,14 @@ namespace mongo {
problem() << "deleted object without id, not logging" << endl;
}
}

theDataFileMgr.deleteRecord(ns, rloc.rec(), rloc);
nDeleted++;
if ( justOne )
break;
c->checkLocation();
} while ( c->ok() );
cc.c->checkLocation();

} while ( cc.c->ok() );

return nDeleted;
}
Expand Down

0 comments on commit a7635d3

Please sign in to comment.