[SERVER-60716] Remove out of order writes on unique, non _id indexes Created: 14/Oct/21  Updated: 16/Nov/21  Resolved: 01/Nov/21

Status: Closed
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Daniel Gottlieb (Inactive) Assignee: Yuhong Zhang
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-59831 WTUniqueIndex::_insert expects second... Closed
Related
related to SERVER-61521 Complete TODO listed in SERVER-60716 Closed
Operating System: ALL
Sprint: Execution Team 2021-11-15
Participants:

 Description   

Suppose the document being inserted into a collection is of the form:
RecordId(1) -> X
and the logical key/value being inserted into the index is of the form:
KeyString(X) -> RecordId(1)

WT (non _id) unique indexes will make writes to two keys:

  1. KeyString(X) + RecordId(1)
  2. KeyString(X)

The first key is persisted (on a successful WT txn commit). The second key is deleted before committing. The purpose of the second key is to correctly maintain the unique index constraint in the face of concurrent transactions at snapshot isolation that can possibly observe write skew .

For primaries this works fine. For secondaries, we can process oplog entries out of order. This has a consequence for the common key two separate inserts can touch. Consider the following oplog entries being applied to collection with a unique index on x:

| Oplog                         |
|-------------------------------|
| Insert {_id: 1, x: 1} @ TS(1) |
| Delete {_id: 1}       @ TS(2) |
| Insert {_id: 2, x: 1} @ TS(3) |

Those oplog entries can be applied with the following interleaving:

| Applier 1                         | Applier 2                         |
|-----------------------------------+-----------------------------------|
|                                   | BeginTxn                          |
|                                   | SetTimestamp 3                    |
|                                   | Insert KeyString(1)               |
|                                   | Delete KeyString(1)               |
|                                   | Insert KeyString(1) + RecordId(2) |
|                                   | Commit                            |
|                                   |                                   |
| BeginTxn                          |                                   |
| SetTimestamp 1                    |                                   |
| Insert KeyString(1)               |                                   |
| Delete KeyString(1)               |                                   |
| Insert KeyString(1) + RecordId(1) |                                   |
| Commit                            |                                   |



 Comments   
Comment by Daniel Gottlieb (Inactive) [ 15/Oct/21 ]

Without going into my proof of correctness case analysis, I'm thinking we can solve this problem by simply omitting this insert/delete pair of writes on secondaries.

Generated at Thu Feb 08 05:50:33 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.