summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Storch <david.storch@10gen.com>2015-02-26 11:22:34 -0500
committerRamon Fernandez <ramon@mongodb.com>2015-03-09 13:38:22 -0400
commit618eb359064fe06ab11487ac5cc1394879c1216b (patch)
treeb9b0880b90b21722dcfcbff9b47b8535155ca147 /src
parent5c5b5b0a794490314b0b01db27ade099a1f49fcd (diff)
downloadmongo-618eb359064fe06ab11487ac5cc1394879c1216b.tar.gz
SERVER-17387 prevent invalid projections from causing findAndModify to trigger a logOp() rollback
(cherry picked from commit 98276a11bdbd5ef863f0fead63c14f5a7a13440d)
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/commands/find_and_modify.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/mongo/db/commands/find_and_modify.cpp b/src/mongo/db/commands/find_and_modify.cpp
index 38d75deb5b9..acd9dbed9b1 100644
--- a/src/mongo/db/commands/find_and_modify.cpp
+++ b/src/mongo/db/commands/find_and_modify.cpp
@@ -372,6 +372,14 @@ namespace mongo {
if ( found ) {
deleteObjects(txn, ctx.db(), ns, queryModified, PlanExecutor::YIELD_MANUAL,
true, true);
+
+ // Committing the WUOW can close the current snapshot. Until this happens, the
+ // snapshot id should not have changed.
+ invariant(txn->recoveryUnit()->getSnapshotId() == snapshotDoc.snapshotId());
+
+ // Must commit the write before doing anything that could throw.
+ wuow.commit();
+
BSONObjBuilder le( result.subobjStart( "lastErrorObject" ) );
le.appendNumber( "n" , 1 );
le.done();
@@ -424,6 +432,9 @@ namespace mongo {
// for some BSON manipulation).
repl::logOp(txn, "i", collection->ns().ns().c_str(), newDoc);
+ // Must commit the write and logOp() before doing anything that could throw.
+ wuow.commit();
+
// The third argument indicates whether or not we have something for the
// 'value' field returned by a findAndModify command.
//
@@ -470,6 +481,13 @@ namespace mongo {
invariant(res.existing);
LOG(3) << "update result: " << res;
+ // Committing the WUOW can close the current snapshot. Until this happens, the
+ // snapshot id should not have changed.
+ invariant(txn->recoveryUnit()->getSnapshotId() == snapshotDoc.snapshotId());
+
+ // Must commit the write before doing anything that could throw.
+ wuow.commit();
+
if (returnNew) {
dassert(!res.newObj.isEmpty());
_appendHelper(result, res.newObj, true, fields, whereCallback);
@@ -485,13 +503,6 @@ namespace mongo {
}
}
- // Committing the WUOW can close the current snapshot. Until this happens, the
- // snapshot id should not have changed.
- if (found) {
- invariant(txn->recoveryUnit()->getSnapshotId() == snapshotDoc.snapshotId());
- }
- wuow.commit();
-
return true;
}