Skip to content

MDEV-39468 Mariabackup: redo log copier stalls and fails with misleading error message - #5369

Closed
Thirunarayanan wants to merge 1 commit into
10.11from
10.11-MDEV-39648
Closed

MDEV-39468 Mariabackup: redo log copier stalls and fails with misleading error message#5369
Thirunarayanan wants to merge 1 commit into
10.11from
10.11-MDEV-39648

Conversation

@Thirunarayanan

Copy link
Copy Markdown
Member

Problem:

During backup process, log copier thread stalls at lsn and fails with the misleading "Was only able to copy log from X to Y, not Z; try increasing innodb_log_file_size", even when the redo was intact and the log far from full.

Problem is that copier advances recv_sys.lsn only on CRC-validated mtr, but it parses the redo at the server is concurrently writing. InnoDB rewrites the current partial write block repeatedly as mini-transaction fills it, so an mmap read (or) pread of a page being written can observe a torn/intermediate image of the tail block. If that tail block happens to parse as a longer, still valid crc valid mtr then recv_sys.lsn, recv_sys.offset gets advanced wrongly and points to middle of the mini-transaction. In that case, later parse return GOT_EOF always and copier thread never reaches target and fails

Solution:

Poll the server's durably-flushed LSN (status var Innodb_lsn_flushed) and limit the redo log copier based on it.

backup_log_parse(): parses one mtr and if it exceeds the limit rolls back recv_sys.lsn/offset and reports GOT_EOF; the copier re-parses those bytes on a later pass once the fence has advanced past them. Used on both the mmap and buffered paths.

parse_limit_from_flushed(): Rounds the flushed LSN down to a write-block boundary, excluding the tail block InnoDB may still be rewriting

log_copying_thread(): opens its own connection (it runs concurrently with the main thread, which owns mysql_connection) and refreshes the max_limit for parsing of redo log in each pass.

In the final backup phase (BACKUP STAGE BLOCK_COMMIT) it gates on the exact target max(metadata_last_lsn, metadata_to_lsn) with no block-align, so the last partial block is copied in full up to the target.

The stall diagnostic / retry spin is suppressed on a reached_parse_limit wait so a normal "caught up, wait" is not misreported as drift.

get_log_flushed_lsn(): Added to get log_flushed_lsn from SHOW STATUS outout;

@CLAassistant

Copy link
Copy Markdown

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.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

…ing error message

Problem:
========
During backup process, log copier thread stalls at lsn and fails with
the misleading "Was only able to copy log from X to Y, not Z; try increasing
innodb_log_file_size", even when the redo was intact and the log far
from full.

Problem is that copier advances recv_sys.lsn only on CRC-validated mtr,
but it parses the redo at the server is concurrently writing. InnoDB
rewrites the current partial write block repeatedly as mini-transaction
fills it, so an mmap read (or) pread of a page being written can observe
a torn/intermediate image of the tail block. If that tail block happens
to parse as a longer, still valid crc valid mtr then recv_sys.lsn,
recv_sys.offset gets advanced wrongly and points to middle of the
mini-transaction. In that case, later parse return GOT_EOF always
and copier thread never reaches target and fails

Solution:
=========
Poll the server's durably-flushed LSN (status var Innodb_lsn_flushed) and
limit the redo log copier based on it.

backup_log_parse(): parses one mtr and if it exceeds the limit
rolls back recv_sys.lsn/offset and reports GOT_EOF; the copier
re-parses those bytes on a later pass once the fence has
advanced past them. Used on both the mmap and buffered paths.

parse_limit_from_flushed(): Rounds the flushed LSN down to a write-block
boundary, excluding the tail block InnoDB may still be rewriting

log_copying_thread(): opens its own connection (it runs
concurrently with the main thread, which owns mysql_connection) and refreshes
the max_limit for parsing of redo log in each pass.

In the final backup phase (BACKUP STAGE BLOCK_COMMIT) it gates
on the exact target max(metadata_last_lsn, metadata_to_lsn) with no
block-align, so the last partial block is copied in full up to the target.

The stall diagnostic / retry spin is suppressed on a reached_parse_limit wait
so a normal "caught up, wait" is not misreported as drift.

get_log_flushed_lsn(): Added to get log_flushed_lsn from SHOW STATUS outout;
@Thirunarayanan Thirunarayanan changed the title MDEV-39648 Mariabackup: redo log copier stalls and fails with misleading error message MDEV-39468 Mariabackup: redo log copier stalls and fails with misleading error message Jul 10, 2026
@Thirunarayanan
Thirunarayanan deleted the 10.11-MDEV-39648 branch July 10, 2026 13:22
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