[SERVER-12694] Upsert atomicity confusion Created: 12/Feb/14 Updated: 19/Feb/14 Resolved: 12/Feb/14 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Concurrency, Storage |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Question | Priority: | Major - P3 |
| Reporter: | Remon van Vliet | Assignee: | Unassigned |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||
| Participants: | |||||||||
| Description |
|
There is some confusion about upsert behaviour and its atomicity. Given the following write :
The expectation is that there should never be more than one document in the database with {a:1, b:1}in the collection. Now recently this line was added to the "Warning To avoid inserting the same document more than once, only use upsert: true if the query field is uniquely indexed.". This seems to apply that without such a unique index this behaviour is no longer guaranteed. Questions : 1) Is this unique index needed and if so why (isn't this atomicity guaranteed by the write lock?) |
| Comments |
| Comment by Remon van Vliet [ 12/Feb/14 ] |
|
Hi Scott, Thanks for your answers. Can you confirm since when this is possible. I'm aware various yielding was present since 1.6 or before (afaik mostly for long running updates/removes and with $atomic disable if wanted) but I'm just about positive this wasn't possible until recently given the vast amount of data we've safely upserted through this pattern without unique indexes. The documentation here : http://docs.mongodb.org/manual/faq/concurrency/#does-a-read-or-write-operation-ever-yield-the-lock seems to confirm that more fancy yielding was added recently. The only scenario where the above can occur is if the entire update/upsert (including the query part) is not protected by a write lock which seems to be implied in the documentation. It would also seem to be isolated to the upsert case since I'm assuming invoking update( {a:1}, {$inc:{a:1}}) twice cannot result in anything but an {a:2}document as a result regardless of unique indexes. Would you be able to go into more detail on why this behaviour is specific to upserts and perhaps more relevant why this seems to be intended behaviour as it is clearly counter intuitive? EDIT : {a:3}-> {a:2} |
| Comment by Scott Hernandez (Inactive) [ 12/Feb/14 ] |
|
1.) The unique index is required to ensure only one document with the given fields. Queries/writes can yield, and have for a long time (since 1.6 or earlier), and will continue to, to increase concurrency. |