Skip to content

Conversation

@mariadb-DenisProtivensky
  • The Jira issue number for this PR is: MDEV-37229

Description

Every applier thread in Galera should run with READ_COMMITTED transaction isolation level to prevent applying issues caused by InnoDB gap locks. The exception is statement-based replication, where REPEATABLE_READ is required by the server code.

Apparently, there was a separate issue with applier thread variables: wsrep_plugins_post_init() would overwrite thd->variables for every applier thread and forget to restore proper default isolation level. Then, upon every server transaction termination,
trans_reset_one_shot_statistics() would set thread's isolation level to the one stored in thd->variables, thus spoiling the isolation level value for appliers.

Release Notes

TODO: What should the release notes say about this change?
Include any changed system variables, status variables or behaviour. Optionally list any https://mariadb.com/kb/ pages that need changing.

How can this PR be tested?

MTR test is updated.

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.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Every applier thread in Galera should run with READ_COMMITTED transaction
isolation level to prevent applying issues caused by InnoDB gap locks.
The exception is statement-based replication, where REPEATABLE_READ is
required by the server code.

Apparently, there was a separate issue with applier thread variables:
wsrep_plugins_post_init() would overwrite thd->variables for every
applier thread and forget to restore proper default isolation level.
Then, upon every server transaction termination,
trans_reset_one_shot_statistics() would set thread's isolation
level to the one stored in thd->variables, thus spoiling the isolation
level value for appliers.
@svoj svoj added the Codership Codership Galera label Nov 5, 2025
}
}

/* Statement-based replication requires InnoDB repeatable read

Choose a reason for hiding this comment

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

I think some elaboration is needed in this comment:

  • As the transaction is already started in Wsrep_high_priority_service::start_transaction(), is the change of thd->tx_isolation fully effective here or does it just suppress some server level checks?
  • Is it possible that the write set contains both row and query events? In this case a row event could start a transaction with ISO_READ_COMMITTED and the following query event would be actually executed with read-committed isolation as the thd->tx_isolation is effective only when the transaction is started.
  • Should this apply only to DML or also to DDLs (which are replicated as TOI)?

Choose a reason for hiding this comment

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

  • it seems that changing the isolation level only affects server transactions that haven't started yet (maybe some extra check should be performed to determine if we have a transaction already running and skip this code)
  • I don't know, but there's a mixed replication setting available. If intermixing row and query events is allowed, then we're in trouble. I don't see a good way of fixing that except we specifically add a documentation statement that such mode should not be used on the producer (master)
  • the isolation level is reset to default after every applied event, so TOI will run with read committed. As we're replicating SQL statements with TOI, maybe read committed is enough? Ideally, we might want to replicate the isolation level used for TOI on the initiator node, but I don't think it's possible right now.

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

Labels

Codership Codership Galera

Development

Successfully merging this pull request may close these issues.

4 participants