Skip to content

Commit 3f145f2

Browse files
author
Hari Khalsa
committed
SERVER-10026 stages can die natural deaths
1 parent 23ebec9 commit 3f145f2

File tree

7 files changed

+48
-10
lines changed

7 files changed

+48
-10
lines changed

src/mongo/db/exec/collection_scan.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ namespace mongo {
4747

4848
PlanStage::StageState CollectionScan::work(WorkingSetID* out) {
4949
++_commonStats.works;
50-
if (_nsDropped) { return PlanStage::IS_EOF; }
50+
if (_nsDropped) { return PlanStage::DEAD; }
5151

5252
if (NULL == _iter) {
5353
Collection* collection = cc().database()->getCollection( _params.ns );
5454
if ( collection == NULL ) {
5555
_nsDropped = true;
56-
return PlanStage::IS_EOF;
56+
return PlanStage::DEAD;
5757
}
5858

5959
_iter.reset( collection->getIterator( _params.start,
@@ -128,6 +128,7 @@ namespace mongo {
128128
++_commonStats.unyields;
129129
if (NULL != _iter) {
130130
if (!_iter->recoverFromYield()) {
131+
warning() << "collection dropped during yield of collscan or state deleted";
131132
_nsDropped = true;
132133
}
133134
}

src/mongo/db/exec/fetch.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ namespace mongo {
7373

7474
// If we asked our parent for a page-in last time work(...) was called, finish the fetch.
7575
if (WorkingSet::INVALID_ID != _idBeingPagedIn) {
76-
cout << "fetch completed, id being paged on " << _idBeingPagedIn << endl;
7776
return fetchCompleted(out);
7877
}
7978

src/mongo/db/exec/plan_stage.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ namespace mongo {
119119
// nothing output in the out parameter.
120120
NEED_TIME,
121121

122+
// Something went wrong but it's not an internal error. Perhaps our collection was
123+
// dropped or state deleted.
124+
DEAD,
125+
122126
// Something has gone unrecoverably wrong. Stop running this query. There is nothing
123127
// output in the out parameter.
124128
FAILURE,

src/mongo/db/query/multi_plan_runner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ namespace mongo {
309309
planHitEOF = true;
310310
}
311311
else {
312-
// FAILURE. Do we want to just tank that plan and try the rest? We probably want
313-
// to fail globally as this shouldn't happen anyway.
312+
// FAILURE or DEAD. Do we want to just tank that plan and try the rest? We
313+
// probably want to fail globally as this shouldn't happen anyway.
314314

315315
candidate.failed = true;
316316
++_failureCount;

src/mongo/db/query/new_find.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ namespace mongo {
311311
// This is a read lock. TODO: There is a cursor flag for not needing this. Do we care?
312312
Client::ReadContext ctx(ns);
313313

314-
//cout << "running getMore in new system, cursorid " << cursorid << endl;
314+
QLOG() << "running getMore in new system, cursorid " << cursorid << endl;
315315

316316
// This checks to make sure the operation is allowed on a replicated node. Since we are not
317317
// passing in a query object (necessary to check SlaveOK query option), the only state where
@@ -413,6 +413,15 @@ namespace mongo {
413413
if (Runner::RUNNER_DEAD == state || Runner::RUNNER_ERROR == state) {
414414
// If we're dead there's no way to get more results.
415415
saveClientCursor = false;
416+
// In the old system tailable capped cursors would be killed off at the
417+
// cursorid level. If a tailable capped cursor is nuked the cursorid
418+
// would vanish.
419+
//
420+
// In the new system they die and are cleaned up later (or time out).
421+
// So this is where we get to remove the cursorid.
422+
if (0 == numResults) {
423+
resultFlags = ResultFlag_CursorNotFound;
424+
}
416425
}
417426
else if (Runner::RUNNER_EOF == state) {
418427
// EOF is also end of the line unless it's tailable.
@@ -428,11 +437,17 @@ namespace mongo {
428437
// cc is now invalid, as is the runner
429438
cursorid = 0;
430439
cc = NULL;
440+
QLOG() << "getMore NOT saving client cursor, ended w/state "
441+
<< Runner::statestr(state)
442+
<< endl;
431443
}
432444
else {
433445
// Continue caching the ClientCursor.
434446
cc->incPos(numResults);
435447
runner->saveState();
448+
QLOG() << "getMore saving client cursor ended w/state "
449+
<< Runner::statestr(state)
450+
<< endl;
436451

437452
// Possibly note slave's position in the oplog.
438453
if ((queryOptions & QueryOption_OplogReplay) && !slaveReadTill.isNull()) {
@@ -455,7 +470,7 @@ namespace mongo {
455470
qr->startingFrom = startingResult;
456471
qr->nReturned = numResults;
457472
bb.decouple();
458-
//cout << "getMore returned " << numResults << " results\n";
473+
QLOG() << "getMore returned " << numResults << " results\n";
459474
return qr;
460475
}
461476

@@ -749,8 +764,8 @@ namespace mongo {
749764
cq->getParsed().getFilter());
750765
ccId = cc->cursorid();
751766

752-
//cout << "caching runner with cursorid " << ccId
753-
//<< " after returning " << numResults << " results" << endl;
767+
QLOG() << "caching runner with cursorid " << ccId
768+
<< " after returning " << numResults << " results" << endl;
754769

755770
// ClientCursor takes ownership of runner. Release to make sure it's not deleted.
756771
runner.release();
@@ -774,7 +789,7 @@ namespace mongo {
774789
cc->setLeftoverMaxTimeMicros(curop.getRemainingMaxTimeMicros());
775790
}
776791
else {
777-
//cout << "not caching runner but returning " << numResults << " results\n";
792+
QLOG() << "not caching runner but returning " << numResults << " results\n";
778793
}
779794

780795
// Add the results from the query into the output buffer.

src/mongo/db/query/plan_executor.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ namespace mongo {
154154
else if (PlanStage::IS_EOF == code) {
155155
return Runner::RUNNER_EOF;
156156
}
157+
else if (PlanStage::DEAD == code) {
158+
return Runner::RUNNER_DEAD;
159+
}
157160
else {
158161
verify(PlanStage::FAILURE == code);
159162
return Runner::RUNNER_ERROR;

src/mongo/db/query/runner.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ namespace mongo {
5858
RUNNER_ERROR,
5959
};
6060

61+
static string statestr(RunnerState s) {
62+
if (RUNNER_ADVANCED == s) {
63+
return "RUNNER_ADVANCED";
64+
}
65+
else if (RUNNER_EOF == s) {
66+
return "RUNNER_EOF";
67+
}
68+
else if (RUNNER_DEAD == s) {
69+
return "RUNNER_DEAD";
70+
}
71+
else {
72+
verify(RUNNER_ERROR == s);
73+
return "RUNNER_ERROR";
74+
}
75+
}
76+
6177
/**
6278
* The yielding policy of the runner. By default, a runner does not yield itself
6379
* (YIELD_MANUAL).

0 commit comments

Comments
 (0)