mariadb/mysql-test/suite/mariabackup/slave_provision_nolock.test
2023-12-02 01:02:50 +01:00

170 lines
5 KiB
Text

--source include/have_innodb.inc
--source include/have_log_bin.inc
call mtr.add_suppression("Can't init tc log");
call mtr.add_suppression("Aborting");
# Test provisioning a slave from an existing server, using mariabackup --no-lock
# and the binlog position recovered from InnoDB redo log.
# Update the InnoDB system tablespace to simulate a pre-10.3.5
# position in TRX_SYS. There was a bug that the wrong position could
# be recovered if the old filename in TRX_SYS compares newer than the
# newer filenames stored in rseg headers.
let MYSQLD_DATADIR=`select @@datadir`;
let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
--source include/shutdown_mysqld.inc
--perl
use strict;
use warnings;
use Fcntl qw(:DEFAULT :seek);
do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
my $ps = $ENV{INNODB_PAGE_SIZE};
sysopen IBD_FILE, "$ENV{MYSQLD_DATADIR}/ibdata1", O_RDWR
or die "Cannot open ibdata1: $!\n";
# Read the TRX_SYS page.
my $page;
sysseek(IBD_FILE, $ps * 5, SEEK_SET)
or die "Cannot seek ibdata1: $!\n";
sysread(IBD_FILE, $page, $ps)
or die "Cannot read ibdata1: $!\n";
# Put in an old binlog position that will compare larger than master-bin.000001
my $old_name= '~~~-bin.999999' . chr(0);
my $old_off= 0xffff0000;
my $old_magic= 873422344;
my $binlog_offset= $ps - 1000 + 38;
substr($page, $binlog_offset, 4)= pack('N', $old_magic);
substr($page, $binlog_offset + 4, 4)= pack('N', ($old_off >> 32));
substr($page, $binlog_offset + 8, 4)= pack('N', ($old_off & 0xffffffff));
substr($page, $binlog_offset + 12, length($old_name))= $old_name;
# Write back the modified page.
my $full_crc32= get_full_crc32(\*IBD_FILE);
$page= fix_page_crc($page, $full_crc32);
sysseek(IBD_FILE, $ps * 5, SEEK_SET)
or die "Cannot seek ibdata1: $!\n";
syswrite(IBD_FILE, $page, $ps) == $ps
or die "Cannot write ibdata1: $!\n";
close IBD_FILE;
EOF
--source include/start_mysqld.inc
let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
RESET MASTER;
CREATE TABLE t1(a varchar(60) PRIMARY KEY, b VARCHAR(60)) ENGINE INNODB;
INSERT INTO t1 VALUES(1, NULL);
CREATE TABLE t2 (val INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (0);
--disable_query_log
--delimiter //
CREATE PROCEDURE gen_load()
MODIFIES SQL DATA
BEGIN
DECLARE i INT;
DECLARE flag TYPE OF t2.val;
SET i = 0;
load_loop: LOOP
SELECT val INTO flag FROM t2;
IF NOT (flag=0) THEN
LEAVE load_loop;
END IF;
START TRANSACTION;
INSERT INTO t1 VALUES (CONCAT("AbAdCaFe", LPAD(i, 6, "0")), @@SESSION.last_gtid);
COMMIT;
SET i = i + 1;
END LOOP;
END
//
--delimiter ;
--enable_query_log
connect (con1,localhost,root,,);
--echo *** Start a background load...
send CALL gen_load();
--connection default
--echo *** Doing backup...
--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir --no-lock
--echo *** Doing prepare...
--exec $XTRABACKUP --prepare --binlog-info=1 --target-dir=$basedir
--echo *** Stop the background load...
UPDATE t2 SET val=1;
--connection con1
reap;
--connection default
disconnect con1;
--let $count_master= `SELECT COUNT(*) FROM t1`
--echo *** Provision a new slave from the backup
--connect (server2,127.0.0.1,root,,,$SERVER_MYPORT_2)
--let $datadir_2= `SELECT @@datadir`
--echo *** Stopping provisioned server
--source include/shutdown_mysqld.inc
--echo *** Removing old datadir for provisioned server
--rmdir $datadir_2
--echo *** Provision new server from backup
--exec $XTRABACKUP --copy-back --datadir=$datadir_2 --target-dir=$basedir
# --no-lock backup might leave prepared xa transactions. rollback them.
--error 1
--exec $MYSQLD_LAST_CMD --tc-heuristic-recover=ROLLBACK
--source include/start_mysqld.inc
--echo *** Configure slave position from xtrabackup_binlog_pos_innodb
CREATE TABLE t3 (file VARCHAR(255), pos INT) ENGINE=InnoDB;
--replace_result $basedir BASEDIR
--disable_warnings
eval LOAD DATA LOCAL INFILE "$basedir/xtrabackup_binlog_pos_innodb"
INTO TABLE t3 FIELDS ESCAPED BY '' (file, pos);
--enable_warnings
# Remove leading ./ from filename (leading .\ on windows).
--let provision_master_file= `SELECT REGEXP_REPLACE(file, "^[.].", "") FROM t3`
--let provision_master_pos= `SELECT pos FROM t3`
--replace_result $SERVER_MYPORT_1 PORT $provision_master_file MASTER_FILE $provision_master_pos MASTER_POS
eval CHANGE MASTER TO
master_port=$SERVER_MYPORT_1, master_host='127.0.0.1', master_user='root',
master_log_file= "$provision_master_file",
master_log_pos= $provision_master_pos;
START SLAVE;
--connection default
--save_master_pos
--connection server2
--sync_with_master
--let $count_slave= `SELECT COUNT(*) FROM t1`
if ($count_master != $count_slave) {
--echo *** ERROR: Table on master has $count_master rows, but table on provisioned slave has $count_slave rows
--die Row difference on provisioned slave.
}
# Cleanup
--connection server2
STOP SLAVE;
RESET SLAVE ALL;
DROP PROCEDURE gen_load;
DROP TABLE t1, t2, t3;
--connection default
DROP PROCEDURE gen_load;
DROP TABLE t1, t2;
rmdir $basedir;