mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-28 07:59:02 +01:00
SERVER-17282 fix use after free in the case of a database drop during a yield
This commit is contained in:
parent
b91ea55090
commit
eac8d16add
@ -43,6 +43,7 @@
|
||||
#include "mongo/db/query/explain.h"
|
||||
#include "mongo/db/query/find.h"
|
||||
#include "mongo/db/query/get_executor.h"
|
||||
#include "mongo/db/server_parameters.h"
|
||||
#include "mongo/db/stats/counters.h"
|
||||
#include "mongo/s/d_state.h"
|
||||
#include "mongo/util/log.h"
|
||||
@ -220,6 +221,9 @@ namespace mongo {
|
||||
AutoGetCollectionForRead ctx(txn, nss);
|
||||
Collection* collection = ctx.getCollection();
|
||||
|
||||
const int dbProfilingLevel = ctx.getDb() ? ctx.getDb()->getProfilingLevel() :
|
||||
serverGlobalParams.defaultProfile;
|
||||
|
||||
// 3) Get the execution plan for the query.
|
||||
//
|
||||
// TODO: Do we need to handle oplog replay here?
|
||||
@ -251,7 +255,8 @@ namespace mongo {
|
||||
// there is no ClientCursor id, and then return.
|
||||
const int numResults = 0;
|
||||
const CursorId cursorId = 0;
|
||||
endQueryOp(ctx, execHolder.get(), numResults, cursorId, txn->getCurOp());
|
||||
endQueryOp(execHolder.get(), dbProfilingLevel, numResults, cursorId,
|
||||
txn->getCurOp());
|
||||
Command::appendCursorResponseObject(cursorId, nss.ns(), BSONArray(), &result);
|
||||
return true;
|
||||
}
|
||||
@ -333,7 +338,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
// Fill out curop based on the results.
|
||||
endQueryOp(ctx, exec, numResults, cursorId, txn->getCurOp());
|
||||
endQueryOp(exec, dbProfilingLevel, numResults, cursorId, txn->getCurOp());
|
||||
|
||||
// 7) Generate the response object to send to the client.
|
||||
Command::appendCursorResponseObject(cursorId, nss.ns(), firstBatch.arr(), &result);
|
||||
|
@ -166,8 +166,8 @@ namespace mongo {
|
||||
curop->setQuery(queryObj);
|
||||
}
|
||||
|
||||
void endQueryOp(const AutoGetCollectionForRead& ctx,
|
||||
PlanExecutor* exec,
|
||||
void endQueryOp(PlanExecutor* exec,
|
||||
int dbProfilingLevel,
|
||||
int numResults,
|
||||
CursorId cursorId,
|
||||
CurOp* curop) {
|
||||
@ -186,8 +186,6 @@ namespace mongo {
|
||||
curop->debug().nscannedObjects = summaryStats.totalDocsExamined;
|
||||
curop->debug().idhack = summaryStats.isIdhack;
|
||||
|
||||
const int dbProfilingLevel = (ctx.getDb() != NULL) ? ctx.getDb()->getProfilingLevel() :
|
||||
serverGlobalParams.defaultProfile;
|
||||
const logger::LogComponent queryLogComponent = logger::LogComponent::kQuery;
|
||||
const logger::LogSeverity logLevelOne = logger::LogSeverity::Debug(1);
|
||||
|
||||
@ -733,6 +731,9 @@ namespace mongo {
|
||||
AutoGetCollectionForRead ctx(txn, nss);
|
||||
Collection* collection = ctx.getCollection();
|
||||
|
||||
const int dbProfilingLevel = ctx.getDb() ? ctx.getDb()->getProfilingLevel() :
|
||||
serverGlobalParams.defaultProfile;
|
||||
|
||||
// We'll now try to get the query executor that will execute this query for us. There
|
||||
// are a few cases in which we know upfront which executor we should get and, therefore,
|
||||
// we shortcut the selection process here.
|
||||
@ -896,7 +897,7 @@ namespace mongo {
|
||||
// Fill out curop based on query results. If we have a cursorid, we will fill out curop with
|
||||
// this cursorid later.
|
||||
long long ccId = 0;
|
||||
endQueryOp(ctx, exec.get(), numResults, ccId, &curop);
|
||||
endQueryOp(exec.get(), dbProfilingLevel, numResults, ccId, &curop);
|
||||
|
||||
if (shouldSaveCursor(txn, collection, state, exec.get())) {
|
||||
// We won't use the executor until it's getMore'd.
|
||||
|
@ -71,11 +71,13 @@ namespace mongo {
|
||||
/**
|
||||
* Fills out CurOp with information regarding this query's execution.
|
||||
*
|
||||
* Uses explain functionality to extract stats from 'exec'. 'ctx' is used to conditionalize
|
||||
* whether or not we do expensive stats gathering based on the database profiling level.
|
||||
* Uses explain functionality to extract stats from 'exec'.
|
||||
*
|
||||
* The database profiling level, 'dbProfilingLevel', is used to conditionalize whether or not we
|
||||
* do expensive stats gathering.
|
||||
*/
|
||||
void endQueryOp(const AutoGetCollectionForRead& ctx,
|
||||
PlanExecutor* exec,
|
||||
void endQueryOp(PlanExecutor* exec,
|
||||
int dbProfilingLevel,
|
||||
int numResults,
|
||||
CursorId cursorId,
|
||||
CurOp* curop);
|
||||
|
Loading…
Reference in New Issue
Block a user