Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7f207a2
WIP MDEV-14992 BACKUP SERVER
dr-m May 29, 2026
c0e48fc
WIP MDEV-39092, and back up non-InnoDB files
dr-m May 29, 2026
c90f391
fixup! c0e48fc966d3d3926bade68c7c5bfdb9fe88ad3a
dr-m Jun 1, 2026
e2e57f2
Correctly copy the last one or two log files
dr-m Jun 1, 2026
e096bd3
fixup! e2e57f2c81f9d691947634168a37bf3fdfe530d9
dr-m Jun 1, 2026
32cea98
fixup! 7f207a291cb8b9903c08a05b0daa0a7eb90c3921
dr-m Jun 1, 2026
56b8e27
Preserve the backup directory
dr-m Jun 2, 2026
c310d7c
Fix up the checkpoint headers on Windows
dr-m Jun 2, 2026
afbafab
fixup! c310d7cf477e8db2b4911d69985fc237cba5133f
dr-m Jun 2, 2026
d803c8b
Revert "Preserve the backup directory"
dr-m Jun 2, 2026
5633fc2
Avoid CopyFileEx() when copying parts of InnoDB log
dr-m Jun 2, 2026
180f79d
fixup! 5633fc2bf7fd070fd482f60063fd41c3298d36ac
dr-m Jun 3, 2026
5d04c41
fixup! 5633fc2bf7fd070fd482f60063fd41c3298d36ac
dr-m Jun 3, 2026
da86ec2
Use copy_file() for copying data files on Windows
dr-m Jun 3, 2026
bcdcf85
Implement page range locking
dr-m Jun 3, 2026
30cc18d
fixup! bcdcf854ea15aaf41d4c7de7d6e00f6389451c6f
dr-m Jun 3, 2026
9a7b3cd
fixup! da86ec2fc00f9c24677f7018069f1f62e6fc9f7d
dr-m Jun 3, 2026
2723b13
fixup! 9a7b3cd13bca6ae5b38408d9dfdb3908e6f2108d
dr-m Jun 3, 2026
e058dd9
fixup! bcdcf854ea15aaf41d4c7de7d6e00f6389451c6f
dr-m Jun 4, 2026
f2b8d0f
Create and use backup.cnf; do not copy too much log
dr-m Jun 4, 2026
e22c809
Revert "fixup! 5633fc2bf7fd070fd482f60063fd41c3298d36ac"
dr-m Jun 4, 2026
d93494e
Chase ERROR_ACCESS_DENIED
dr-m Jun 4, 2026
f218500
fixup! f2b8d0f8b222d1b439243095f4bd5b1452c81ab8
dr-m Jun 4, 2026
b98be03
Fix the Windows glitch
dr-m Jun 5, 2026
6e37d3a
MDEV-39061 mariadb-backup compatible wrappers for BACKUP SERVER
Thirunarayanan May 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libmysqld/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/opt_hints.cc ../sql/opt_hints.h
../sql/opt_trace_ddl_info.cc ../sql/opt_trace_ddl_info.h
../sql/sql_path.cc
../sql/sql_backup.cc
${GEN_SOURCES}
${MYSYS_LIBWRAP_SOURCE}
)
Expand Down
1 change: 1 addition & 0 deletions mysql-test/collections/buildbot_suites.bat
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ innodb,^
versioning,^
plugins,^
mariabackup,^
backup,^
roles,^
auth_gssapi,^
mysql_sha2,^
Expand Down
56 changes: 56 additions & 0 deletions mysql-test/include/have_mariabackup_wrapper.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# ==== Purpose ====
#
# Redirect `$XTRABACKUP` so existing test invocations like
#
# --exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf \
# --backup --target-dir=$targetdir
#
# run through scripts/mariabackup/mariabackup.sh — the BACKUP SERVER
# compatibility wrapper — without any change to the test body.
#
#
# Skip the test if any of these are missing:
# - the wrapper script
# - bash
# - the mariadb client (wrapper shells out to it)
#
# ==== Usage ====
#
# --source include/have_mariabackup_wrapper.inc
# # ... rest of the test, using $XTRABACKUP as usual ...
#
# ==== Exposed variables ====
#
# $XTRABACKUP — now points at mariabackup.sh

--source include/linux.inc

--let MARIABACKUP_WRAPPER=$MYSQL_TEST_DIR/../scripts/mariabackup/mariabackup.sh

--error 0,1
perl;
use strict;
use warnings;
use File::Basename;

my $wrapper = $ENV{MARIABACKUP_WRAPPER};
exit 1 unless $wrapper && -x $wrapper;

chomp(my $bash = `command -v bash 2>/dev/null`);
exit 1 unless $bash && -x $bash;

# Prepend its directory to PATH so the bare `mariadb` invocation
# inside the wrapper resolves.
my ($mariadb) = split /\s+/, ($ENV{MYSQL} // '');
exit 1 unless $mariadb && -x $mariadb;
$ENV{PATH} = dirname($mariadb) . ":$ENV{PATH}";

exit 0;
EOF

if ($errno)
{
--skip mariabackup.sh wrapper unavailable (script, bash, or mariadb client missing)
}

--let XTRABACKUP=$MARIABACKUP_WRAPPER
6 changes: 6 additions & 0 deletions mysql-test/main/backup_server.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
BACKUP SERVER TO '$datadir/some_directory';
ERROR HY000: Incorrect arguments to BACKUP SERVER TO
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
ERROR HY000: Can't create directory 'MYSQLTEST_VARDIR/some_directory' (Errcode: 17 "File exists")
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
10 changes: 10 additions & 0 deletions mysql-test/main/backup_server.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
--let $datadir=`select @@datadir`
--error ER_WRONG_ARGUMENTS
evalp BACKUP SERVER TO '$datadir/some_directory';
evalp BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 21
evalp BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
--rmdir $MYSQLTEST_VARDIR/some_directory
evalp BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
--rmdir $MYSQLTEST_VARDIR/some_directory
17 changes: 17 additions & 0 deletions mysql-test/main/backup_server_locking.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
ERROR HY000: Can't create directory 'MYSQLTEST_VARDIR/some_directory' (Errcode: 17 "File exists")
BACKUP STAGE START;
connect backup,localhost,root;
SET STATEMENT max_statement_time=0.1 FOR
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
ERROR 70100: Query was interrupted: execution time limit 0.1 sec exceeded
connection default;
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
ERROR HY000: Can't execute the command as you have a BACKUP STAGE active
BACKUP STAGE END;
connection backup;
SET STATEMENT max_statement_time=0.1 FOR
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
ERROR HY000: Can't create directory 'MYSQLTEST_VARDIR/some_directory' (Errcode: 17 "File exists")
disconnect backup;
connection default;
31 changes: 31 additions & 0 deletions mysql-test/main/backup_server_locking.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--source include/not_embedded.inc
--source include/count_sessions.inc

--mkdir $MYSQLTEST_VARDIR/some_directory
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 21
evalp BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';

BACKUP STAGE START;
--connect (backup,localhost,root)
--error ER_STATEMENT_TIMEOUT
evalp SET STATEMENT max_statement_time=0.1 FOR
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';

--connection default

--error ER_BACKUP_LOCK_IS_ACTIVE
evalp BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';

BACKUP STAGE END;
--connection backup
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 21
evalp SET STATEMENT max_statement_time=0.1 FOR
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
--disconnect backup
--connection default

--rmdir $MYSQLTEST_VARDIR/some_directory

--source include/wait_until_count_sessions.inc
41 changes: 41 additions & 0 deletions mysql-test/main/backup_server_restore.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Prepare database
CREATE TABLE tinno (i INTEGER) ENGINE=InnoDB;
INSERT INTO tinno VALUES (1), (2), (3), (4);
CREATE TABLE tariatr (i INTEGER) ENGINE=Aria TRANSACTIONAL=1;
INSERT INTO tariatr VALUES (2), (3), (5), (7);
CREATE TABLE tariant (i INTEGER) ENGINE=Aria TRANSACTIONAL=0;
INSERT INTO tariant VALUES (1), (1), (2), (3), (5);
Back up the database
BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';
Restore the database
# restart: --datadir=MYSQLTEST_VARDIR/some_directory
Check contents after restore
SELECT * FROM tinno;
i
1
2
3
4
SELECT * FROM tariatr;
i
2
3
5
7
SELECT * FROM tariant;
i
1
1
2
3
5
Warnings:
Error 145 Got error '145 "Table was marked as crashed and should be repaired"' for './test/tariant'
Warning 1034 1 client is using or hasn't closed the table properly
Note 1034 Table is fixed
Restart database in original data directory
# restart
Clean up
DROP TABLE tinno;
DROP TABLE tariatr;
DROP TABLE tariant;
38 changes: 38 additions & 0 deletions mysql-test/main/backup_server_restore.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--source include/not_windows.inc
--source include/have_innodb.inc

--echo Prepare database
CREATE TABLE tinno (i INTEGER) ENGINE=InnoDB;
INSERT INTO tinno VALUES (1), (2), (3), (4);
CREATE TABLE tariatr (i INTEGER) ENGINE=Aria TRANSACTIONAL=1;
INSERT INTO tariatr VALUES (2), (3), (5), (7);
CREATE TABLE tariant (i INTEGER) ENGINE=Aria TRANSACTIONAL=0;
INSERT INTO tariant VALUES (1), (1), (2), (3), (5);

--echo Back up the database
evalp BACKUP SERVER TO '$MYSQLTEST_VARDIR/some_directory';

--echo Restore the database
--disable_query_log
call mtr.add_suppression("InnoDB: Did not find any checkpoint after LSN=");
call mtr.add_suppression("InnoDB: Renaming ib_[0-9]+.log to ib_logfile0");
call mtr.add_suppression("mariadbd: Got error '145 \"Table was marked as crashed and should be repaired\"' for ");
call mtr.add_suppression("Checking table: ");
--enable_query_log
--let $restart_parameters=--datadir=$MYSQLTEST_VARDIR/some_directory
--source include/restart_mysqld.inc

--echo Check contents after restore
SELECT * FROM tinno;
SELECT * FROM tariatr;
SELECT * FROM tariant;

--echo Restart database in original data directory
--let $restart_parameters=
--source include/restart_mysqld.inc

--echo Clean up
DROP TABLE tinno;
DROP TABLE tariatr;
DROP TABLE tariant;
--rmdir $MYSQLTEST_VARDIR/some_directory
27 changes: 27 additions & 0 deletions mysql-test/main/grant_backup_server.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
CREATE USER user1@localhost IDENTIFIED BY '';
connect con1,localhost,user1;
BACKUP SERVER TO 'some_directory';
ERROR 42000: Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
disconnect con1;
connection default;
GRANT SELECT ON test.* TO user1@localhost;
connect con1,localhost,user1;
BACKUP SERVER TO 'some_directory';
ERROR 42000: Access denied; you need (at least one of) the RELOAD privilege(s) for this operation
disconnect con1;
connection default;
GRANT RELOAD ON test.* TO user1@localhost;
ERROR HY000: Incorrect usage of DB GRANT and GLOBAL PRIVILEGES
GRANT RELOAD ON *.* TO user1@localhost;
connect con1,localhost,user1;
BACKUP SERVER TO 'some_directory';
ERROR 42000: Access denied; you need (at least one of) the SELECT privilege(s) for this operation
disconnect con1;
connection default;
GRANT SELECT ON *.* TO user1@localhost;
connect con1,localhost,user1;
BACKUP SERVER TO '$datadir/some_directory';
ERROR HY000: Incorrect arguments to BACKUP SERVER TO
disconnect con1;
connection default;
DROP USER user1@localhost;
29 changes: 29 additions & 0 deletions mysql-test/main/grant_backup_server.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--source include/not_embedded.inc
CREATE USER user1@localhost IDENTIFIED BY '';
--connect con1,localhost,user1
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
BACKUP SERVER TO 'some_directory';
--disconnect con1
--connection default
GRANT SELECT ON test.* TO user1@localhost;
--connect con1,localhost,user1
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
BACKUP SERVER TO 'some_directory';
--disconnect con1
--connection default
--error ER_WRONG_USAGE
GRANT RELOAD ON test.* TO user1@localhost;
GRANT RELOAD ON *.* TO user1@localhost;
--connect con1,localhost,user1
--error ER_SPECIFIC_ACCESS_DENIED_ERROR
BACKUP SERVER TO 'some_directory';
--disconnect con1
--connection default
GRANT SELECT ON *.* TO user1@localhost;
--connect con1,localhost,user1
--let $datadir=`select @@datadir`
--error ER_WRONG_ARGUMENTS
evalp BACKUP SERVER TO '$datadir/some_directory';
--disconnect con1
--connection default
DROP USER user1@localhost;
2 changes: 1 addition & 1 deletion mysql-test/main/mysqld--help.result
Original file line number Diff line number Diff line change
Expand Up @@ -2053,7 +2053,7 @@ performance-schema-max-socket-classes 10
performance-schema-max-socket-instances -1
performance-schema-max-sql-text-length 1024
performance-schema-max-stage-classes 170
performance-schema-max-statement-classes 227
performance-schema-max-statement-classes 228
performance-schema-max-statement-stack 10
performance-schema-max-table-handles -1
performance-schema-max-table-instances -1
Expand Down
1 change: 1 addition & 0 deletions mysql-test/mariadb-test-run.pl
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ END
main-
archive-
atomic-
backup-
binlog-
binlog_encryption-
binlog_in_engine-
Expand Down
16 changes: 16 additions & 0 deletions mysql-test/suite/backup/backup_innodb,debug.rdiff
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--- backup_innodb.result
+++ backup_innodb,debug.result
@@ -10,7 +10,13 @@
BEGIN;
DELETE FROM t;
connect backup,localhost,root;
+SET DEBUG_SYNC='innodb_backup_start SIGNAL start WAIT_FOR resume';
BACKUP SERVER TO 'target_directory';
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR start';
+INSERT INTO t(a) SELECT * FROM seq_1_to_30000;
+SET DEBUG_SYNC='now SIGNAL resume';
+connection backup;
disconnect backup;
connection default;
ROLLBACK;
4 changes: 4 additions & 0 deletions mysql-test/suite/backup/backup_innodb.combinations
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[archived]
innodb_log_archive=ON
[circular]
innodb_log_archive=OFF
30 changes: 30 additions & 0 deletions mysql-test/suite/backup/backup_innodb.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
CREATE TABLE t(a INT PRIMARY KEY, b CHAR(255) DEFAULT '' NOT NULL, INDEX(b))
ENGINE=INNODB;
BEGIN;
INSERT INTO t SET a=1;
BACKUP SERVER TO '$target_directory';
ROLLBACK;
SELECT * FROM t;
a b
1
BEGIN;
DELETE FROM t;
connect backup,localhost,root;
BACKUP SERVER TO 'target_directory';
disconnect backup;
connection default;
ROLLBACK;
SELECT * FROM t;
a b
1
DELETE FROM t;
# restart: --defaults-file=MYSQLTEST_VARDIR/some_directory/backup.cnf --datadir=MYSQLTEST_VARDIR/some_directory
SELECT * FROM t;
a b
1
DELETE FROM t;
ERROR HY000: Table 't' is read only
# restart
SELECT * FROM t;
a b
DROP TABLE t;
Loading