0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

can get progress of index creation through db.currentOp and web console SERVER-707

This commit is contained in:
Eliot Horowitz 2010-03-15 11:18:08 -04:00
parent 6c250b7c23
commit 0d779a3fa8
5 changed files with 79 additions and 7 deletions

View File

@ -228,6 +228,17 @@ namespace mongo {
if ( _client )
b.append( "desc" , _client->desc() );
if ( ! _message.empty() ){
if ( _progressMeter.isActive() ){
StringBuilder buf(128);
buf << _message << " " << _progressMeter.toString();
b.append( "msg" , buf.str() );
}
else {
b.append( "msg" , _message );
}
}
return b.obj();
}

View File

@ -58,10 +58,13 @@ namespace mongo {
struct sockaddr_in _remote;
char _queryBuf[256];
void resetQuery(int x=0) { *((int *)_queryBuf) = x; }
OpDebug _debug;
ThreadSafeString _message;
ProgressMeter _progressMeter;
void _reset(){
_command = false;
@ -69,6 +72,7 @@ namespace mongo {
_dbprofile = 0;
_end = 0;
_waitingForLock = false;
_message = "";
}
void setNS(const char *ns) {
@ -236,6 +240,18 @@ namespace mongo {
return ss.str();
}
ProgressMeter& setMessage( const char * msg , long long progressMeterTotal = 0 , int secondsBetween = 3 ){
_message = msg;
if ( progressMeterTotal ){
assert( ! _progressMeter.isActive() );
_progressMeter.reset( progressMeterTotal , secondsBetween );
}
return _progressMeter;
}
string getMessage() const { return _message; }
ProgressMeter getProgressMeter() { return _progressMeter; }
friend class Client;
};

View File

@ -190,6 +190,8 @@ namespace mongo {
<< "<th>NameSpace</th>"
<< "<th>Query</th>"
<< "<th>client</th>"
<< "<th>msg</th>"
<< "<th>progress</th>"
<< "</tr>\n";
{
@ -215,6 +217,10 @@ namespace mongo {
tablecell( ss , "" );
tablecell( ss , co.getRemoteString() );
tablecell( ss , co.getMessage() );
tablecell( ss , co.getProgressMeter().toString() );
ss << "</tr>";
}
}

View File

@ -984,6 +984,7 @@ namespace mongo {
// throws DBException
unsigned long long fastBuildIndex(const char *ns, NamespaceDetails *d, IndexDetails& idx, int idxNo) {
assert( d->backgroundIndexBuildInProgress == 0 );
CurOp * op = cc().curop();
Timer t;
@ -1003,7 +1004,7 @@ namespace mongo {
BSONObjExternalSorter sorter(order);
sorter.hintNumObjects( d->nrecords );
unsigned long long nkeys = 0;
ProgressMeter pm( d->nrecords , 10 );
ProgressMeter & pm = op->setMessage( "index: (1/3) external sort" , d->nrecords , 10 );
while ( c->ok() ) {
BSONObj o = c->current();
DiskLoc loc = c->currLoc();
@ -1027,6 +1028,8 @@ namespace mongo {
}
};
pm.finished();
if ( logLevel > 1 ) printMemInfo( "before final sort" );
sorter.sort();
if ( logLevel > 1 ) printMemInfo( "after final sort" );
@ -1040,7 +1043,7 @@ namespace mongo {
BtreeBuilder btBuilder(dupsAllowed, idx);
BSONObj keyLast;
auto_ptr<BSONObjExternalSorter::Iterator> i = sorter.iterator();
ProgressMeter pm2( nkeys , 10 );
pm = op->setMessage( "index: (2/3) btree bottom up" , nkeys , 10 );
while( i->more() ) {
RARELY killCurrentOp.checkForInterrupt();
BSONObjExternalSorter::Data d = i->next();
@ -1066,8 +1069,10 @@ namespace mongo {
dupsToDrop.push_back(d.second);
uassert( 10092 , "too may dups on index build with dropDups=true", dupsToDrop.size() < 1000000 );
}
pm2.hit();
pm.hit();
}
pm.finished();
op->setMessage( "index: (3/3) btree-middle" );
log(t.seconds() > 10 ? 0 : 1 ) << "\t done building bottom layer, going to commit" << endl;
btBuilder.commit();
wassert( btBuilder.getn() == nkeys || dropDups );

View File

@ -410,12 +410,37 @@ namespace mongo {
class ProgressMeter {
public:
ProgressMeter( long long total , int secondsBetween = 3 , int checkInterval = 100 )
: _total( total ) , _secondsBetween( secondsBetween ) , _checkInterval( checkInterval ) ,
_done(0) , _hits(0) , _lastTime( (int) time(0) ){
ProgressMeter( long long total , int secondsBetween = 3 , int checkInterval = 100 ){
reset( total , secondsBetween , checkInterval );
}
ProgressMeter(){
_active = 0;
}
void reset( long long total , int secondsBetween = 3 , int checkInterval = 100 ){
_total = total;
_secondsBetween = secondsBetween;
_checkInterval = checkInterval;
_done = 0;
_hits = 0;
_lastTime = (int)time(0);
_active = 1;
}
void finished(){
_active = 0;
}
bool isActive(){
return _active;
}
bool hit( int n = 1 ){
if ( ! _active ) cout << "warning: hit on in-active ProgressMeter" << endl;
_done += n;
_hits++;
if ( _hits % _checkInterval )
@ -441,7 +466,16 @@ namespace mongo {
return _hits;
}
string toString() const {
if ( ! _active )
return "";
stringstream buf;
buf << _done << "/" << _total << " " << (_done*100)/_total << "%";
return buf.str();
}
private:
bool _active;
long long _total;
int _secondsBetween;