summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec/delete.cpp
diff options
context:
space:
mode:
authorMax Hirschhorn <max.hirschhorn@mongodb.com>2015-08-24 23:51:27 -0400
committerMax Hirschhorn <max.hirschhorn@mongodb.com>2015-08-24 23:51:27 -0400
commit764e0c45471d5ca63c708f362be0e6d01ee72eb0 (patch)
tree77c6693c1c1003d802a40a30eda8a79a4e0d7704 /src/mongo/db/exec/delete.cpp
parent564f8089c0d4541215d1aa31dae331115e68b95f (diff)
downloadmongo-764e0c45471d5ca63c708f362be0e6d01ee72eb0.tar.gz
SERVER-16444 Copy data in the query subsystem as needed.
A WorkingSetMember in the LOC_AND_OBJ state must be made owned when: 1. Its WorkingSetID is cached across multiple calls to work(). 2. Multiple calls to next(), seekExact(), saveState(), etc. are performed on the same WiredTiger cursor in a single work() call. No longer necessary to always copy data out of WiredTiger buffers.
Diffstat (limited to 'src/mongo/db/exec/delete.cpp')
-rw-r--r--src/mongo/db/exec/delete.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/mongo/db/exec/delete.cpp b/src/mongo/db/exec/delete.cpp
index 1b970a475fc..b58354aa5d5 100644
--- a/src/mongo/db/exec/delete.cpp
+++ b/src/mongo/db/exec/delete.cpp
@@ -154,24 +154,27 @@ PlanStage::StageState DeleteStage::work(WorkingSetID* out) {
}
}
+ // Ensure that the BSONObj underlying the WorkingSetMember is owned because saveState()
+ // is allowed to free the memory.
+ if (_params.returnDeleted) {
+ member->makeObjOwned();
+ }
+
// TODO: Do we want to buffer docs and delete them in a group rather than
// saving/restoring state repeatedly?
try {
- child()->saveState();
if (supportsDocLocking()) {
- // Doc-locking engines require this after saveState() since they don't use
+ // Doc-locking engines require this before saveState() since they don't use
// invalidations.
WorkingSetCommon::prepareForSnapshotChange(_ws);
}
+ child()->saveState();
} catch (const WriteConflictException& wce) {
std::terminate();
}
if (_params.returnDeleted) {
- // Save a copy of the document that is about to get deleted.
- BSONObj deletedDoc = member->obj.value();
- member->obj.setValue(deletedDoc.getOwned());
member->loc = RecordId();
member->transitionToOwnedObj();
}
@@ -185,6 +188,9 @@ PlanStage::StageState DeleteStage::work(WorkingSetID* out) {
++_specificStats.docsDeleted;
} catch (const WriteConflictException& wce) {
+ // Ensure that the BSONObj underlying the WorkingSetMember is owned because it may be
+ // freed when we yield.
+ member->makeObjOwned();
_idRetrying = id;
memberFreer.Dismiss(); // Keep this member around so we can retry deleting it.
*out = WorkingSet::INVALID_ID;