Skip to content

Conversation

vmg
Copy link

@vmg vmg commented Jul 11, 2024

When performing a row search via the internal InnoDB API, row_search_mvcc locates the relevant record in the B-tree and, if there are one or more concurrent transactions modifying such record, it reconstructs the correct (previous) version of the record that the local transaction should see given its transaction isolation level.

This reconstructed record is stored in prebuilt->innodb_api_rec so it can be accessed by the internal InnoDB API in ib_cursor_read_row.

Commit d9bc5e0 fixed a use-after-free with the stored record, but it also introduced an extra check for rec_get_deleted_flag before attempting to fetch the reconstructed record. This check appears to be incorrect: the flags on the record are not meaningful at this point because the record as it comes out of pcur could be a newer version of the record that the current transaction should not be able to see.

Hence, by checking for a deleted flag on the record, we're instantly materializing any DELETE operations performed by concurrent transactions, breaking transaction isolation, whilst only UPDATEs to the underlying record are properly isolated.

When performing a row search via the internal InnoDB API, `row_search_mvcc`
locates the relevant record in the B-tree and, if there are one or more
concurrent transactions modifying such record, it reconstructs the correct
(previous) version of the record that the local transaction should see given
its transaction isolation level.

This reconstructed record is stored in `prebuilt->innodb_api_rec` so it
can be accessed by the internal InnoDB API in `ib_cursor_read_row`.

Commit d9bc5e0 fixed a use-after-free with the stored record, but it
also introduced an extra check for `rec_get_deleted_flag` before
attempting to fetch the reconstructed record. This check appears to be
incorrect: the flags on the record are not meaningful at this point
because the record as it comes out of `pcur` could be a newer version of
the record that the current transaction should **not** be able to see.

Hence, by checking for a deleted flag on the record, we're instantly
materializing any DELETE operations performed by concurrent
transactions, breaking transaction isolation, whilst only UPDATEs to
the underlying record are properly isolated.

Signed-off-by: Vicent Marti <vmg@strn.cat>
@mysql-oca-bot
Copy link

Hi, thank you for submitting this pull request. In order to consider your code we need you to sign the Oracle Contribution Agreement (OCA). Please review the details and follow the instructions at https://oca.opensource.oracle.com/
Please make sure to include your MySQL bug system user (email) in the returned form.
Thanks

@mysql-oca-bot
Copy link

Hi, thank you for your contribution. Please confirm this code is submitted under the terms of the OCA (Oracle's Contribution Agreement) you have previously signed by cutting and pasting the following text as a comment:
"I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it."
Thanks

@vmg
Copy link
Author

vmg commented Jul 17, 2024

I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

@mysql-oca-bot
Copy link

Hi, thank you for your contribution. Your code has been assigned to an internal queue. Please follow
bug http://bugs.mysql.com/bug.php?id=115668 for updates.
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants