[SERVER-34369] LastOpFixer can set Client optime backwards in sessions Created: 06/Apr/18 Updated: 27/Oct/23 Resolved: 12/Apr/18 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Replication |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Matthew Russotto | Assignee: | Backlog - Replication Team |
| Resolution: | Gone away | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||
| Assigned Teams: |
Replication
|
||||
| Operating System: | ALL | ||||
| Participants: | |||||
| Linked BF Score: | 45 | ||||
| Description |
|
In write_ops_exec.cpp, there is a class called LastOpsFixer, which sets the client's optime to the system time in the case of a failed or no-op write (e.g. a $set of a field to the value it is already set to). As long as LastOpsFixer runs outside any WriteUnitOfWork (the normal case), this is fine. However, with sessions we can have a long-lived outer WUOW. In this case, if we have multiple operations, one of them can succeed and one can be a no-op. The successful operation will set the client optime to its optime on WUOW commit. The no-op will set the client optime to the system optime immediately. If other operations happen in between the successful operation and the no-op, advancing the system optime, this results in the commit setting the client optime backwards (and hitting an invariant). This currently happens only when writing in a snapshot read. |
| Comments |
| Comment by Matthew Russotto [ 06/Apr/18 ] |
|
If we're going to disallow writing in a snapshot read, this might not need fixing; it doesn't happen with transactions currently (because they write oplog entries only on commit), and shouldn't happen when we're logging oplog entries in advance of the commit (because those entries will commit outside the main transaction). |