[SERVER-86250] Consider changing findAndModify behavior when concurrent operation changes the sort key Created: 06/Feb/24 Updated: 06/Feb/24 |
|
| Status: | Needs Scheduling |
| Project: | Core Server |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Task | Priority: | Major - P3 |
| Reporter: | Ian Boros | Assignee: | Backlog - Query Execution |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||
| Assigned Teams: |
Query Execution
|
||||||||
| Participants: | |||||||||
| Description |
|
The findAndModify command takes a sort parameter which indicates how the server should choose which document to modify when multiple documents match the filter. Once the operation "chooses" a document to modify, it may get a write conflict attempting to modify it. If that happens, the update portion of the plan will retry updating the same document (by RID). However, the concurrent operation which caused the WriteConflict to happen may have changed the document so that it's position in the sort order is different, and it's no longer first. For example: The collection contains three documents:
Then the following sequence happens (this example is from daniel.gomezferro@mongodb.com and ivan.fefer@mongodb.com):
The fAM essentially does its "read" before the other transaction which changes the sort key, but then does its write afterwards. This is technically legal with read committed semantics, though very counter intuitive. It's worth pointing out that similar anomalies will always be possible. For example, it's possible another thread could have inserted a document with b: 0 while the fAM was running. This could only be prevented with coarse grain locks (ie preventing writes to the entire collection). Options
|