Skip to content

MDEV-39092 Copy Aria data and logs as part of backup - #4971

Open
mariadb-andrzejjarzabek wants to merge 35 commits into
MariaDB:MDEV-14992from
mariadb-andrzejjarzabek:MDEV-39092
Open

MDEV-39092 Copy Aria data and logs as part of backup#4971
mariadb-andrzejjarzabek wants to merge 35 commits into
MariaDB:MDEV-14992from
mariadb-andrzejjarzabek:MDEV-39092

Conversation

@mariadb-andrzejjarzabek

@mariadb-andrzejjarzabek mariadb-andrzejjarzabek commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

An interim solution with some room for optimization:

  • All DDL is blcoked while Aria is being backed up
  • All table caches purged when Aria backup starts (including for non-Aria tables)
  • Writes to non-transactional, but not to transactional tables are blocked when table files are being backed up
  • All commits blocked when Aria log files are being backed up

@CLAassistant

CLAassistant commented Apr 22, 2026

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.

Comment thread include/my_backup.h Outdated
Comment thread include/my_backup.h Outdated
Comment thread include/my_backup.h Outdated
Comment thread mysys/CMakeLists.txt Outdated
Comment thread mysys/my_backup.cc Outdated
Comment thread sql/handler.h Outdated
Comment thread sql/sql_backup.cc Outdated
Comment thread storage/maria/ma_backup.cc Outdated
Comment thread storage/maria/ma_backup.cc Outdated
Comment thread storage/maria/ma_backup.cc Outdated
Comment thread sql/sql_backup.cc Outdated
@mariadb-andrzejjarzabek
mariadb-andrzejjarzabek force-pushed the MDEV-39092 branch 2 times, most recently from 8565956 to 04e3bc2 Compare May 21, 2026 10:53
@mariadb-andrzejjarzabek
mariadb-andrzejjarzabek force-pushed the MDEV-39092 branch 2 times, most recently from 14ca552 to c9429eb Compare May 29, 2026 09:47
@mariadb-andrzejjarzabek
mariadb-andrzejjarzabek force-pushed the MDEV-39092 branch 2 times, most recently from d35cd47 to 824afeb Compare June 1, 2026 15:15
@mariadb-andrzejjarzabek
mariadb-andrzejjarzabek marked this pull request as ready for review June 1, 2026 15:16
@mariadb-andrzejjarzabek
mariadb-andrzejjarzabek marked this pull request as draft June 1, 2026 15:17
dr-m added 7 commits August 6, 2026 16:50
btr_search_drop_page_hash_index() is being invoked on a non-file page
(state < FREED). Everywhere else, the more readable
!is_read_fixed() or !is_io_fixed() assertions are safe to use.
buf_page_t::set_freed(), buf_page_t::flush(),
buf_page_t::write_fix_try(), buf_page_t::write_unfix_try():
Use a compare-and-exchange loop to set or clear a write-fix.
While set_freed() and flush() are protected by a page latch,
write_fix_try() and write_unfix_try() are not.

innodb_backup_batch_wait(): Look up any pages that we are about
to back up. For any dirty pages, invoke buf_page_t::write_fix_try()
to try to set a fake "write fix" lock-free. If the page is
currently write-fixed, acquire and release a page latch to wait
wait for the write to complete.
buf_page_create_low(): Invoke buf_page_t::set_freed() to clear a
fake "write fix".
log_t::set_archive(false, thd): Ensure that the sequence bit value 0
will be expected on crash recovery and backup.

log_t::circular_recovery_from_0(): Accessor for
log_sys.circular_recovery_from_sequence_bit_0.

buf_flush_wait(), log_checkpoint_low(): Ensure that a checkpoint
will be written to reset log_sys.circular_recovery_from_sequence_bit_0.

log_t::write_checkpoint(): Reset circular_recovery_from_sequence_bit_0
whenever applicable. We used to blindly reset it in log_t::set_archive().

(cherry picked from commit a848493)
dr-m and others added 17 commits August 10, 2026 16:21
buf_page_t::set_reinit(): Use std::atomic::compare_exchange_weak
to prevent races with write_fix_try() and write_unfix_try().
…RENAME

fil_name_process(): Simplify the logic. If no matching tablespace is
found but file_name_t::create_lsn had been set in response to parsing
a FILE_CREATE record, try to apply FILE_RENAME to deferred_spaces.

fil_delete_apply(): A wrapper for fil_space_free(). When recovering
a log in innodb_log_archive=ON format, we must apply FILE_DELETE
records in order to avoid a future clash with FILE_CREATE or FILE_RENAME.

(cherry picked from commit 7d106c2)
The doublewrite buffer in the system tablespace is only useful for
crash recovery in case a data page had been incompletely written
by the time the server was killed. If the server is killed during a
backup, the backup will be incomplete and unusable anyway.
Furthermore, the page range locking makes page writes and backup
mutually exclusive.
file_name_t::page0_lsn: Keep track of the last applied
recv_sys_t::parse_page0() so that a multi-batch recovery
will not reset the file to a smaller size.

(cherry picked from commit 0c4039b)
On top of the provisional Aria backup solution provisionally incorporated
into MDEV-14992, the following improvements have been made:

Aria data and index files are copied under DDL-locked lock level instead
of commit-locked, making the backup operation less disruptive. Only log
files are copied in the commit-locked phase. Writes to non-transactional
Aria tables are blocked in the DDL-locked phase, while writes to
transactional tables are written to the log file, allowing consistent
point-in-time backup at the time of acquiring the commit lock.

Data, index and log files are now copied as a "step" action rather than
"end phase" action, allowing them to be copied in parallel using the
CONCURRENT option.

Non-Aria files, including common SQL-layer metadata and files from other
storage engines are copied by the SQL layer rather than the Aria plugin.
Note these files are at this time not copied concurrently when the
concurrent option is used.
Non-resilient engine files need to be flushed before they are copied to
backup at a time when they cannot be further written to. The method
of purging table caches is not sufficient for this purpose, as it
doesn't flush tables that are in use at the time of the purge. Although
the backup lock ensures that they cannot be written to, they can still
be opened for reading, in which case the purge does not flush them and
the files may be copied incomplete.

Instead of purging table caches directly, we call flush_tables(), which
in addition to purging, also flushes tables using the HA_EXTRA_FLUSH
handler call. This flusing is based on the type of table, only
affecting "non-transactional" user tables, which exclude InnoDB tables
and transactional Aria tables.

The flushing has also been moved from Aria plugin to general SQL code.
The rules for acquiring table locks are different for system tables
than for user tables. System tables only become blocked for writing
at the MDL_BACKUP_WAIT_COMMIT lock level. At least for statistics
tables, which are non-transactional, this means that if they are copied
at the same time as the user tables, the files may be copied torn
resulting in a corrupt backup.

The solution needs to be to flush these files and copy them in
BACKUP_PHASE_NO_COMMIT. The actual solution is to flush all system
tables at the beginning of that phase and to copy all Aria tables in
"mysql" schema also in that phase. This somewhat suboptimal in that
some tables in "mysql" are copied under MDL_BACKUP_WAIT_COMMIT, where
they could be copied under a lower lock level; however the impact of
this is limited by the small number and typically small size of
these tables and the trade-off is the (also small) cost of
determining their table category and transactionality.
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.

7 participants