don't delete old chunk data until there aren't cursors iterating it SERVER-937
This commit is contained in:
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user