don't delete old chunk data until there aren't cursors iterating it SERVER-937

This commit is contained in:
Eliot Horowitz
2010-07-22 17:24:51 -04:00
parent aeb3276abc
commit 4308df6f3b
5 changed files with 64 additions and 14 deletions

View File

@@ -193,7 +193,7 @@ namespace mongo {
if ( doauth )
_auth( lockState );
{
if ( _client->_curOp->getOp() != dbGetMore ){ // getMore's are special and should be handled else where
string errmsg;
if ( ! shardVersionOk( _ns , errmsg ) ){
msgasserted( StaleConfigInContextCode , (string)"shard version not ok in Client::Context: " + errmsg );

View File

@@ -357,6 +357,16 @@ namespace mongo {
client.shutdown();
}
void ClientCursor::find( const string& ns , set<CursorId>& all ){
recursive_scoped_lock lock(ccmutex);
for ( CCById::iterator i=clientCursorsById.begin(); i!=clientCursorsById.end(); ++i ){
if ( i->second->ns == ns )
all.insert( i->first );
}
}
ClientCursorMonitor clientCursorMonitor;
} // namespace mongo

View File

@@ -338,6 +338,8 @@ public:
static void informAboutToDeleteBucket(const DiskLoc& b);
static void aboutToDelete(const DiskLoc& dl);
static void find( const string& ns , set<CursorId>& all );
};
class ClientCursorMonitor : public BackgroundJob {

View File

@@ -38,8 +38,8 @@ s.adminCommand( { movechunk : "test.foo" , find : { _id : 5 } , to : secondary.g
assert.eq( 2, s.config.chunks.count() );
// the cursors should not have been affected
assert.eq( numObjs , cursor1.itcount() );
assert.eq( numObjs , cursor2.itcount() );
assert.eq( numObjs , cursor3.itcount() );
assert.eq( numObjs , cursor1.itcount() , "c1" );
assert.eq( numObjs , cursor2.itcount() , "c2" );
assert.eq( numObjs , cursor3.itcount() , "c3" );
s.stop()
s.stop()

View File

@@ -133,7 +133,47 @@ namespace mongo {
ofstream* _out;
};
struct OldDataCleanup {
string ns;
BSONObj min;
BSONObj max;
};
void cleanupOldData( OldDataCleanup cleanup ){
Client::initThread( "moveChunkPostClean" );
set<CursorId> initial;
ClientCursor::find( cleanup.ns , initial );
Timer t;
while ( t.seconds() < 600 ){ // 10 minutes
sleepmillis( 20 );
set<CursorId> now;
ClientCursor::find( cleanup.ns , now );
set<CursorId> left;
for ( set<CursorId>::iterator i=initial.begin(); i!=initial.end(); ++i ){
CursorId id = *i;
if ( now.count(id) )
left.insert( id );
}
if ( left.size() == 0 )
break;
initial = left;
}
ShardForceModeBlock sf;
writelock lk(cleanup.ns);
RemoveSaver rs(cleanup.ns,"post-cleanup");
long long num = Helpers::removeRange( cleanup.ns , cleanup.min , cleanup.max , true , false , &rs );
log() << "moveChunk deleted: " << num << endl;
cc().shutdown();
}
class ChunkCommandHelper : public Command {
public:
ChunkCommandHelper( const char * name )
@@ -598,17 +638,15 @@ namespace mongo {
log( LL_WARNING ) << " deleting data before ensuring no more cursors TODO" << endl;
timing.done(6);
// 7
{
ShardForceModeBlock sf;
writelock lk(ns);
RemoveSaver rs(ns,"post-cleanup");
long long num = Helpers::removeRange( ns , min , max , true , false , &rs );
log() << "moveChunk deleted: " << num << endl;
result.appendNumber( "numDeleted" , num );
{ // 7.
OldDataCleanup c;
c.ns = ns;
c.min = min.getOwned();
c.max = max.getOwned();
boost::thread t( boost::bind( &cleanupOldData , c ) );
}
timing.done(7);
return true;