Read-only queries that perform index scans have the potential to return the wrong keys if they scan near recently-committed prepared transactions.
The bug is as follows, in this order:
- An index has a key for "a" and it is visible to all operations.
- A key for "b" is not visible because it is prepared and uncommitted by a transaction.
- Another operation queries for a key, "c". This operation uses search_near() for a key starting with "c". Because there are no keys afterward and because read-only queries ignore prepared updates, the cursor lands on an adjacent key, "a".
- The prepared transaction involving "b" commits.
- Because "a" compares less than "c", we call next() on the cursor to uphold our contract to return a key that will compare greater than or equal to "c" (note this is the case for the actual key we would store for "c"). Due to the concurrently committed transaction, the call to next() actually lands on "b", which is newly visible, as it compares after "a". We expect that a call to next() guarantees we land on a key after "c", however, that is not the case, and leads us to return keys other than the ones we were searching for.
This does not affect write operations since they enforce and block on prepare conflicts. This only affects read-only queries.
- is related to
-
SERVER-57270 Disable prepare_read_cursor_out_of_bounds.js on ephemeralForTest
- Closed