Skip to content

Conversation

@mariadb-TafzeelShams
Copy link

  • The Jira issue number for this PR is: MDEV-38140

Description

MDEV-38140: InnoDB index corruption after UPDATE affecting virtual
columns

Issue:

  • Purge thread attempts to purge a secondary index record that is not
    delete-marked.

Root Cause:

  • When a secondary index includes a virtual column whose v_pos is
    greater than the number of fields in the clustered index record, the
    virtual column is incorrectly skipped while reading from the undo
    record.
  • This leads the purge logic to incorrectly assume it is safe to purge
    the secondary index record.
  • The code also confuses the nth virtual column with the nth stored
    column when writing ordering columns at the end of the undo record.

Fix:

  • In trx_undo_update_rec_get_update(): Skip a virtual column only
    when v_pos == FIL_NULL, not when v_pos is greater than the number
    of fields.
  • In trx_undo_page_report_modify(): Ensure ordering columns are
    written based on the correct stored-column positions, without
    confusing them with virtual-column positions.

Release Notes

Fixed a potential corruption issue for virtual index.

How can this PR be tested?

Modified mysql-test/suite/innodb/t/innodb-virtual-columns.test and mysql-test/suite/innodb/r/innodb-virtual-columns.result to cover the changes.

Basing the PR against the correct MariaDB version

  • This is a new feature or a refactoring, and the PR is based against the main branch.
  • This is a bug fix, and the PR is based against the earliest maintained branch in which the bug can be reproduced.

PR quality check

  • I checked the CODING_STANDARDS.md file and my PR conforms to this where appropriate.
  • For any trivial modifications to the PR, I am ok with the reviewer making the changes themselves.

columns

Issue:
- Purge thread attempts to purge a secondary index record that is not
  delete-marked.

Root Cause:
- When a secondary index includes a virtual column whose v_pos is
  greater than the number of fields in the clustered index record, the
  virtual column is incorrectly skipped while reading from the undo
  record.
- This leads the purge logic to incorrectly assume it is safe to purge
  the secondary index record.
- The code also confuses the nth virtual column with the nth stored
  column when writing ordering columns at the end of the undo record.

Fix:
- In trx_undo_update_rec_get_update(): Skip a virtual column only
  when v_pos == FIL_NULL, not when v_pos is greater than the number
  of fields.
- In trx_undo_page_report_modify(): Ensure ordering columns are
  written based on the correct stored-column positions, without
  confusing them with virtual-column positions.
Comment on lines 1224 to 1233
for (i = 0; i < update->n_fields; i++) {
const upd_field_t* fld =
upd_get_nth_field(update, i);
if (upd_fld_is_virtual_col(fld))
continue;
const ulint field_no
= upd_get_nth_field(update, i)
->field_no;
= fld->field_no;
if (field_no >= index->n_fields
|| dict_index_get_nth_field(
index, field_no)->col
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changing the way how UPDATE of indexed virtual columns is logged. However, there is no mention how upgrades or downgrades are being affected by this.

I see that you posted some analysis to MDEV-38140. However, you did not comment on my earlier comment regarding the function row_purge_vc_matches_cluster(). Can you please review that logic as well?

Copy link
Author

@mariadb-TafzeelShams mariadb-TafzeelShams Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is changing the way how UPDATE of indexed virtual columns is logged.

  • Hmm, actually this code part is about decision of whether to write non-virtual indexed columns to undo record. After we have completed writing the UPDATE changes of both non-virtual and virtual columns.
    (Before this code change we are incorrectly skipping writing the nth non-virtual indexed column into undo record if we already have nth virtual indexed column written as part of UPDATE changes.)

  • After completing the writing of non-virtual indexed columns we then jump to writing the virtual indexed columns.
    (Have made no changes to its logic)

However, there is no mention how upgrades or downgrades are being affected by this.

Regarding upgrades and downgrades, I don't see any issues because, even without patch we do write the non-virtual indexed columns into undo record. And while reading from undo record we handle these columns. For example in row_upd_replace_vcol()

Can you please review that logic as well?

Will do..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

3 participants