MDEV-14992 BACKUP SERVER - #4817
Open
dr-m wants to merge 28 commits into
Open
Conversation
|
|
dr-m
force-pushed
the
MDEV-14992
branch
2 times, most recently
from
March 18, 2026 11:01
2723322 to
1703796
Compare
vuvova
reviewed
Mar 18, 2026
dr-m
force-pushed
the
MDEV-14992
branch
2 times, most recently
from
March 23, 2026 08:28
9a529de to
857edeb
Compare
dr-m
force-pushed
the
MDEV-14992
branch
3 times, most recently
from
March 27, 2026 09:48
8149b3d to
c08d121
Compare
dr-m
commented
Apr 15, 2026
dr-m
commented
May 19, 2026
dr-m
commented
May 27, 2026
dr-m
commented
Jun 15, 2026
fil_space_t::create_lsn: Change to Atomic_relaxed and use this to indicate tablespace creation LSN, in addition to indicate undo tablespace rebuild LSN. fil_ibd_create(): Set space->create_lsn after the file has been created. InnoDB_backup::step(): Do not attempt to copy beyond the current end of ROW_FORMAT=COMPRESSED files that use a page size of 1024 or 2048 bytes.
buf_page_t::flush(): Refuse to write if the block is already write-fixed. fil_space_t::backup_page_end(): Assert that buf_pool.mutex is being held. fil_space_t::backup_end: Make Atomic_relaxed, so that it can be zeroed while not holding buf_pool.mutex. buf_page_t::write_fix_try(): Try to write-fix a block. InnoDB_backup::backup_batch_start(): Write-fix all blocks that reside in the range and are located in the buffer pool. InnoDB_backup::backup_batch_stop(): Write-unfix all blocks.
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.
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)
(cherry picked from commit 1370d5a)
…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)
dr-m
commented
Aug 12, 2026
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.
dr-m
commented
Aug 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The following SQL statements will be introduced:
In place of the
1, any positive number of threads may be specified. For the first variant,'/path/to'must exist and'/path/to/directory'must not exist; that is where the backup will be written to.For the second variant,
'command'must be the name of a script or command that will be executed in a child process. The standard input of that command will be in a format that is compatible with GNUtar --format=oldgnu(and also BSDtarvariants that are also part of Microsoft Windows and Apple macOS). The command is expected to optionally compress and encrypt the stream and redirect it to a file on a local or a remote server. TheBACKUP SERVER WITH willappend an additional argument, a positive base-ten number in ASCII, starting with1, to identify the current thread. In this way, each concurrent stream can write a separate file.The backup or the first stream will contain a file
backup.cnf, which includes parameters needed for restoring the backup. Currently, these areinnodb_log_recovery_startandinnodb_log_recovery_target. Ifinnodb_log_recovery_target>0, InnoDB will be in read-only mode, not allowing any writes to persistent files other than via the log application.To restore a streaming backup made with
BACKUP SERVER WITH, an empty directory needs to be created and all streams be extracted there using the standardtarutility of the operating system, optionally after undoing any encryption or compression that had been added by the backup command. Then, the backup is prepared or MariaDB server started up on the extracted directory, similar to as if theBACKUP SERVER TOstatement had been used.Note: The parameter
innodb_log_recovery_startinbackup.cnfis STRICTLY NECESSARY TO AVOID CORRUPTION! By default, InnoDB crash recovery starts from the latest available log checkpoint. However, for restoring a backup, recovery must start from the checkpoint that was the latest when the backup was started. Starting recovery from a possible later checkpoint will result in a corrupted database!The following will be implemented separately:
MDEV-39061
mariadb-backupcompatible wrapper script forBACKUP SERVERMDEV-40163 Partial backup and restore
MDEV-39091 Back up
ENGINE=RocksDBMDEV-39092 Less blocking backup of
ENGINE=AriaThe implementation introduces a basic driver
Sql_cmd_backup, storage engine interfaces, and basic copying of the storage engines InnoDB, Aria, MyISAM, MERGE (MyISAM), Archive, CSV.backup_target: A structured data type to represent a target directory. On Microsoft Windows, we must use directory paths because there is no variant ofCopyFileEx()that would work on file handles.backup_sink: Wraps a per-thread output stream as well as storage engine specific context.handlerton::backup_start(),handlerton::backup_end(): Invoked at the start or end of a backup phase, in the thread that executes aBACKUP SERVERstatement.handlerton::backup_step(): A backup step that can be invoked from multiple threads concurrently, between the execution of the correspondinghandlerton::backup_start()andhandlerton::backup_end()of the same phase.copy_entire_file(): A file copying service for POSIX systems.copy_file(): A partial or sparse file-copying service for all systems.backup_stream_append(): Equivalent tocopy_file(), but appending to a stream. On Linux, this usessendfile(2), which assumes that the source data will not be changed before the data has been consumed from the pipe.backup_stream_append_async(): A variant ofbackup_stream_append()where the source file region is guaranteed to be immutable after the call returns. We must not use Linuxsendfile(2)for copying data files that may be modified in place, because it could introduce a race condition between a page write that runs concurrently with a child process that is reading the data from the pipe.InnoDB_backup::context: Backup context, attached tobackup_sinkso that context can continue to exist between the time aBACKUP SERVERreleases all locks and anotherBACKUP SERVERstarts executing, withinnodb_backuppointing to the new backup, while the old backup is still being finished.fil_space_t::write_or_backup: Keep track of in-flight page writes and pending backup operation. We must not allow them concurrently, because that could lead into torn pages in the backup.fil_space_t::backup_end: The first page number that is not being backed up (by default 0, to indicate that no backup is in progress).fil_space_t::BACKUP_BATCH_SIZE: The number of preceding pages that will be covered byfil_space_t::backup_end. This is the unit of "page range locking" during InnoDB backup.log_sys.backup: WhetherBACKUP SERVERis in progress. The purpose of this is to makeBACKUP SERVERprevent the concurrent execution ofSET GLOBAL innodb_log_archive=OFForSET GLOBAL innodb_log_file_sizewheninnodb_log_archive=OFF.log_sys.archived_checkpoint: Keep track of the earliest available checkpoint, corresponding tolog_sys.archived_lsn. This reflectsSET GLOBAL innodb_log_recovery_start(which is settable now), for incremental backup.buf_flush_list_space(): Check for concurrent backup before writing each page. This is inefficient, but this function may be invoked from multiple threads concurrently, and it cannot be changed easily, especially forfil_crypt_thread().fil_system.have_all_spaces: Whether all tablespace metadata is guaranteed to be known. To speed up startup, InnoDB does not normally open all tablespace files.