Skip to content
Snippets Groups Projects
user avatar
Vladimir Davydov authored
The tuple cache doesn't store historical data. It stores only the newest
tuple versions, including prepared but not yet confirmed (committed but
not written to WAL) tuples. This means that transactions sent to a read
view shouldn't add any new chains to the cache because such a chain may
bypass a tuple invisible from the read view.

A transaction may be sent to a read view in two cases:

 1. If some other transactions updates data read by it.
 2. If the transaction is operating in the 'read-confirmed' isolation
    mode and skips an unconfirmed tuple while scanning the memory level.
    This was added in commit 588170a7 ("vinyl: implement transaction
    isolation levels").

The second point should be checked by the read iterator itself, and it
is indeed for the standard case when we scan the memory level before
reading the disk. However, there's the second case: if some other tuples
are inserted into the memory level while the read iterator was waiting
for a disk read to complete, it rescans the memory level and may skip
a new unconfirmed tuple that wasn't there the first time we scanned
the memory level. Currently, if this happens, it won't send itself to
a read view and may corrupt the cache by inserting a chain that skips
over the unconfirmed tuple. Fix this by adding the missing check.

While we are at it, let's simplify the code a bit by moving the check
inside `vy_read_iterator_scan_mem()`. It's okay because sending to
a read view a transaction that's already in the read view is handled
correctly by `vy_tx_send_to_read_view()`.

Closes #10558

NO_DOC=bug fix

(cherry picked from commit a3feee322e76a1e10ab874e63f17f97b6457b59d)
eef3d7d2
History
Name Last commit Last update