diff options
author | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2015-08-24 23:51:27 -0400 |
---|---|---|
committer | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2015-08-24 23:51:27 -0400 |
commit | 764e0c45471d5ca63c708f362be0e6d01ee72eb0 (patch) | |
tree | 77c6693c1c1003d802a40a30eda8a79a4e0d7704 /src/mongo/db/exec/delete.cpp | |
parent | 564f8089c0d4541215d1aa31dae331115e68b95f (diff) | |
download | mongo-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.cpp | 16 |
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; |