diff options
author | David Storch <david.storch@10gen.com> | 2015-02-26 11:22:34 -0500 |
---|---|---|
committer | Ramon Fernandez <ramon@mongodb.com> | 2015-03-09 13:38:22 -0400 |
commit | 618eb359064fe06ab11487ac5cc1394879c1216b (patch) | |
tree | b9b0880b90b21722dcfcbff9b47b8535155ca147 /src | |
parent | 5c5b5b0a794490314b0b01db27ade099a1f49fcd (diff) | |
download | mongo-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.cpp | 25 |
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; } |