summaryrefslogtreecommitdiff
path: root/src/mongo/db/ops
diff options
context:
space:
mode:
authorJason Rassi <rassi@10gen.com>2014-07-30 15:12:11 -0400
committerJason Rassi <rassi@10gen.com>2014-07-30 16:12:02 -0400
commit13fe3b061fa3c5970c40973d6f36f69fa06130a5 (patch)
tree22f051cf09c9c64149f68580aa001b0195983ef0 /src/mongo/db/ops
parent76be742def16b4081e559374d66ede6a00cf3ff0 (diff)
downloadmongo-13fe3b061fa3c5970c40973d6f36f69fa06130a5.tar.gz
SERVER-14498 Add DeleteStage, rewrite DeleteExecutor to use it
Diffstat (limited to 'src/mongo/db/ops')
-rw-r--r--src/mongo/db/ops/delete_executor.cpp97
1 files changed, 21 insertions, 76 deletions
diff --git a/src/mongo/db/ops/delete_executor.cpp b/src/mongo/db/ops/delete_executor.cpp
index 42459e77f05..ba36650e634 100644
--- a/src/mongo/db/ops/delete_executor.cpp
+++ b/src/mongo/db/ops/delete_executor.cpp
@@ -32,15 +32,11 @@
#include "mongo/db/catalog/collection.h"
#include "mongo/db/catalog/database.h"
-#include "mongo/db/client.h"
-#include "mongo/db/curop.h"
+#include "mongo/db/exec/delete.h"
#include "mongo/db/ops/delete_request.h"
#include "mongo/db/query/canonical_query.h"
#include "mongo/db/query/get_executor.h"
-#include "mongo/db/query/lite_parsed_query.h"
-#include "mongo/db/query/query_planner_common.h"
#include "mongo/db/repl/repl_coordinator_global.h"
-#include "mongo/db/repl/oplog.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/mongoutils/str.h"
@@ -87,7 +83,7 @@ namespace mongo {
mongoutils::str::stream() <<
"DeleteExecutor::prepare() failed to parse query " << _request->getQuery(),
_isQueryParsed);
- const bool logop = _request->shouldCallLogOp();
+
const NamespaceString& ns(_request->getNamespaceString());
if (!_request->isGod()) {
if (ns.isSystem()) {
@@ -97,7 +93,7 @@ namespace mongo {
}
if (ns.ns().find('$') != string::npos) {
log() << "cannot delete from collection with reserved $ in name: " << ns << endl;
- uasserted( 10100, "cannot delete from collection with reserved $ in name" );
+ uasserted(10100, "cannot delete from collection with reserved $ in name");
}
}
@@ -112,86 +108,35 @@ namespace mongo {
uassert(ErrorCodes::NotMaster,
str::stream() << "Not primary while removing from " << ns.ns(),
- !logop ||
+ !_request->shouldCallLogOp() ||
repl::getGlobalReplicationCoordinator()->canAcceptWritesForDatabase(ns.db()));
- long long nDeleted = 0;
-
PlanExecutor* rawExec;
if (_canonicalQuery.get()) {
- uassertStatusOK(getExecutor(_request->getOpCtx(),
- collection,
- _canonicalQuery.release(),
- &rawExec));
+ // This is the non-idhack branch.
+ uassertStatusOK(getExecutorDelete(_request->getOpCtx(), collection,
+ _canonicalQuery.release(), _request->isMulti(),
+ _request->shouldCallLogOp(), &rawExec));
}
else {
- uassertStatusOK(getExecutor(_request->getOpCtx(),
- collection,
- ns.ns(),
- _request->getQuery(),
- &rawExec));
+ // This is the idhack branch.
+ uassertStatusOK(getExecutorDelete(_request->getOpCtx(), collection, ns.ns(),
+ _request->getQuery(), _request->isMulti(),
+ _request->shouldCallLogOp(), &rawExec));
}
-
- auto_ptr<PlanExecutor> exec(rawExec);
+ scoped_ptr<PlanExecutor> exec(rawExec);
// Concurrently mutating state (by us) so we need to register 'exec'.
- ScopedExecutorRegistration safety(exec.get());
-
- DiskLoc rloc;
- PlanExecutor::ExecState state;
- CurOp* curOp = _request->getOpCtx()->getCurOp();
- int oldYieldCount = curOp->numYields();
- while (PlanExecutor::ADVANCED == (state = exec->getNext(NULL, &rloc))) {
- if (oldYieldCount != curOp->numYields()) {
- uassert(ErrorCodes::NotMaster,
- str::stream() << "No longer primary while removing from " << ns.ns(),
- !logop ||
- repl::getGlobalReplicationCoordinator()->canAcceptWritesForDatabase(
- ns.db()));
- oldYieldCount = curOp->numYields();
- }
- BSONObj toDelete;
-
- WriteUnitOfWork wunit(_request->getOpCtx()->recoveryUnit());
-
- // TODO: do we want to buffer docs and delete them in a group rather than
- // saving/restoring state repeatedly?
- exec->saveState();
- collection->deleteDocument(
- _request->getOpCtx(), rloc, false, false, logop ? &toDelete : NULL);
- exec->restoreState(_request->getOpCtx());
-
- nDeleted++;
-
- if (logop) {
- if ( toDelete.isEmpty() ) {
- log() << "Deleted object without id in collection " << collection->ns()
- << ", not logging.";
- }
- else {
- bool replJustOne = true;
- repl::logOp(
- _request->getOpCtx(), "d", ns.ns().c_str(), toDelete, 0, &replJustOne);
- }
- }
-
- wunit.commit();
+ const ScopedExecutorRegistration safety(exec.get());
- if (!_request->isMulti()) {
- break;
- }
-
- if (!_request->isGod()) {
- _request->getOpCtx()->recoveryUnit()->commitIfNeeded();
- }
-
- if (debug && _request->isGod() && nDeleted == 100) {
- log() << "warning high number of deletes with god=true "
- << " which could use significant memory b/c we don't commit journal";
- }
- }
+ uassertStatusOK(exec->executePlan());
- return nDeleted;
+ // Extract the number of documents deleted from the DeleteStage stats.
+ invariant(exec->getRootStage()->stageType() == STAGE_DELETE);
+ DeleteStage* deleteStage = static_cast<DeleteStage*>(exec->getRootStage());
+ const DeleteStats* deleteStats =
+ static_cast<const DeleteStats*>(deleteStage->getSpecificStats());
+ return deleteStats->docsDeleted;
}
} // namespace mongo