Commit 0c5d1342 authored by Sachin's avatar Sachin Committed by Andrei

MDEV-11675 Lag Free Alter On Slave

This commit implements two phase binloggable ALTER.
When a new

      @@session.binlog_alter_two_phase = YES

ALTER query gets logged in two parts, the START ALTER and the COMMIT
or ROLLBACK ALTER. START Alter is written in binlog as soon as
necessary locks have been acquired for the table. The timing is
such that any concurrent DML:s that update the same table are either
committed, thus logged into binary log having done work on the old
version of the table, or will be queued for execution on its new
version.

The "COMPLETE" COMMIT or ROLLBACK ALTER are written at the very point
of a normal "single-piece" ALTER that is after the most of
the query work is done. When its result is positive COMMIT ALTER is
written, otherwise ROLLBACK ALTER is written with specific error
happened after START ALTER phase.
Replication of two-phase binloggable ALTER is
cross-version safe. Specifically the OLD slave merely does not
recognized the start alter part, still being able to process and
memorize its gtid.

Two phase logged ALTER is read from binlog by mysqlbinlog to produce
BINLOG 'string', where 'string' contains base64 encoded
Query_log_event containing either the start part of ALTER, or a
completion part. The Query details can be displayed with `-v` flag,
similarly to ROW format events.  Notice, mysqlbinlog output containing
parts of two-phase binloggable ALTER is processable correctly only by
binlog_alter_two_phase server.

@@log_warnings > 2 can reveal details of binlogging and slave side
processing of the ALTER parts.

The current commit also carries fixes to the following list of
reported bugs:
MDEV-27511, MDEV-27471, MDEV-27349, MDEV-27628, MDEV-27528.

Thanks to all people involved into early discussion of the feature
including Kristian Nielsen, those who helped to design, implement and
test: Sergei Golubchik, Andrei Elkin who took the burden of the
implemenation completion, Sujatha Sivakumar, Brandon
Nesterenko, Alice Sherepa, Ramesh Sivaraman, Jan Lindstrom.
parent c64e507f
...@@ -3536,7 +3536,6 @@ int main(int argc, char** argv) ...@@ -3536,7 +3536,6 @@ int main(int argc, char** argv)
"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n" "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n" "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n"); "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;\n"); fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;\n");
if (is_gtid_filtering_enabled()) if (is_gtid_filtering_enabled())
......
# ==== Purpose ====
#
# A lighter version of show_binlog_event.inc, with the same purpose
# to execute SHOW BINLOG EVENTS and mask non-deterministic output.
#
#
# Parameters:
#
# $binlog_file
# Filename for the 'IN' clause of SHOW BINLOG EVENTS. If none
# given, no argument is given to SHOW BINLOG EVENTS, meaning that
# it uses the first binlog. If you set this to "LAST", it prints
# the last binlog (according to SHOW MASTER STATUS).
#
# $binlog_start
# Position for the 'FROM' clause of SHOW BINLOG EVENTS. If none
# given, starts right after the Binlog_checkpoint_log_even.
#
# $regexp_replace
# A user's custom addon to standard preexisting list.
#
if ($binlog_start) if ($binlog_start)
{ {
--let $_binlog_start=$binlog_start --let $_binlog_start=$binlog_start
...@@ -13,5 +35,5 @@ if ($binlog_file) ...@@ -13,5 +35,5 @@ if ($binlog_file)
--let $_from_binlog_start=from $_binlog_start --let $_from_binlog_start=from $_binlog_start
--replace_result "$_from_binlog_start" "from <binlog_start>" $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_result "$_from_binlog_start" "from <binlog_start>" $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--replace_column 2 # 5 # --replace_column 2 # 5 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /file_id=[0-9]+/file_id=#/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /file_id=[0-9]+/file_id=#/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ $replace_regexp
--eval show binlog events $_in_binlog_file from $_binlog_start --eval show binlog events $_in_binlog_file from $_binlog_start
...@@ -107,6 +107,8 @@ let $script= ...@@ -107,6 +107,8 @@ let $script=
s{block_len=[0-9]+}{block_len=#}; s{block_len=[0-9]+}{block_len=#};
s{Server ver:.*DOLLAR}{SERVER_VERSION, BINLOG_VERSION}; s{Server ver:.*DOLLAR}{SERVER_VERSION, BINLOG_VERSION};
s{GTID [0-9]+-[0-9]+-[0-9]+}{GTID #-#-#}; s{GTID [0-9]+-[0-9]+-[0-9]+}{GTID #-#-#};
s{COMMIT ALTER id=[0-9]+}{COMMIT ALTER id=#};
s{ROLLBACK ALTER id=[0-9]+}{ROLLBACK ALTER id=#};
s{\[([0-9]-[0-9]-[0-9]+,?)+\]}{[#-#-#]}; s{\[([0-9]-[0-9]-[0-9]+,?)+\]}{[#-#-#]};
s{cid=[0-9]+}{cid=#}; s{cid=[0-9]+}{cid=#};
s{SQL_LOAD-[a-z,0-9,-]*.[a-z]*}{SQL_LOAD-<SERVER UUID>-<MASTER server-id>-<file-id>.<extension>}; s{SQL_LOAD-[a-z,0-9,-]*.[a-z]*}{SQL_LOAD-<SERVER UUID>-<MASTER server-id>-<file-id>.<extension>};
......
...@@ -42,6 +42,10 @@ The following specify which files/extra groups are read (specified before remain ...@@ -42,6 +42,10 @@ The following specify which files/extra groups are read (specified before remain
full' errors. No longer needed, as the server now handles full' errors. No longer needed, as the server now handles
this automatically. this automatically.
--bind-address=name IP address to bind to. --bind-address=name IP address to bind to.
--binlog-alter-two-phase=name
When set, split ALTER at binary logging into 2
statements: START ALTER and COMMIT/ROLLBACK ALTER. One
of: No, Yes
--binlog-annotate-row-events --binlog-annotate-row-events
Tells the master to annotate RBR events with the Tells the master to annotate RBR events with the
statement that caused these events statement that caused these events
...@@ -1476,6 +1480,7 @@ automatic-sp-privileges TRUE ...@@ -1476,6 +1480,7 @@ automatic-sp-privileges TRUE
back-log 80 back-log 80
big-tables FALSE big-tables FALSE
bind-address (No default value) bind-address (No default value)
binlog-alter-two-phase No
binlog-annotate-row-events TRUE binlog-annotate-row-events TRUE
binlog-cache-size 32768 binlog-cache-size 32768
binlog-checksum CRC32 binlog-checksum CRC32
......
set global binlog_alter_two_phase=YES;
set binlog_alter_two_phase=YES;
RESET MASTER;
create table myt (a int) engine=InnoDB;
alter table myt add column (b int);
FLUSH LOGS;
# Exec MYSQL_BINLOG --base64-output=decode-rows -v MYSQLD_DATADIR/BINLOG_FILENAME > MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
Verbose statements from : master-bin.000001
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
stmt
### alter table myt add column (b int)
### alter table myt add column (b int)
drop table raw_binlog_rows;
drop table myt;
set global binlog_alter_two_phase=No;
#
# Test verifies replay of binary logs which contain
# SA/RA/CA works fine.
# Generate a binary log with alter events and use mysqlbinlog tool to
# generate a sql file for replay. Source it on an clean master and
# verify the correctness. Use the latest binlog and repeat the same
# process mentioned above and observe replay works fine.
#
set global binlog_alter_two_phase=YES;
set binlog_alter_two_phase=YES;
create table t1 (f1 int primary key) engine=InnoDB;
create table t2 (f1 int primary key, constraint c1 foreign key (f1) references t1(f1)) engine=innodb;
alter table t2 add constraint c1 foreign key (f1) references t1(f1);
ERROR HY000: Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update")
drop table t2, t1;
select @@gtid_binlog_state;
@@gtid_binlog_state
0-1-5
FLUSH LOGS;
# reset the binlog
RESET MASTER;
# execute the binlog
SELECT @@gtid_binlog_state;
@@gtid_binlog_state
0-1-5
FLUSH LOGS;
# Replay 1: One more time to simulate S->S case
RESET MASTER;
# execute the binlog
SELECT @@gtid_binlog_state;
@@gtid_binlog_state
0-1-5
FLUSH LOGS;
# Replay 2: One more time to simulate S->S case
RESET MASTER;
# execute the binlog
SELECT @@gtid_binlog_state;
@@gtid_binlog_state
0-1-5
# clean up
RESET MASTER;
set global binlog_alter_two_phase=No;;
#
# Purpose:
#
# This test ensures that mysqlbinlog prints a comment when two-phase alter
# is enabled which shows the original alter query issued.
#
#
# References:
# MENT-662: Finalize MDEV-11675 "Lag Free Alter On Slave"
#
# Just row format for faster testing
--source include/have_binlog_format_row.inc
--source include/have_innodb.inc
#---
# Setup
#---
--let $binlog_alter_two_phase= `select @@binlog_alter_two_phase`
set global binlog_alter_two_phase=YES;
set binlog_alter_two_phase=YES;
RESET MASTER;
create table myt (a int) engine=InnoDB;
#---
# Issue ALTER
#---
alter table myt add column (b int);
#---
# Check binlog output
#---
FLUSH LOGS;
--disable_query_log
--let $MYSQLD_DATADIR= `select @@datadir`
--let $BINLOG_FILENAME= query_get_value(SHOW BINARY LOGS, Log_name, 1)
--echo # Exec MYSQL_BINLOG --base64-output=decode-rows -v MYSQLD_DATADIR/BINLOG_FILENAME > MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
--exec $MYSQL_BINLOG --base64-output=decode-rows -v $MYSQLD_DATADIR/$BINLOG_FILENAME > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
create table raw_binlog_rows (txt varchar(1000));
--eval load data local infile '$MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql' into table raw_binlog_rows columns terminated by '\n'
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_verbose.sql
--enable_query_log
--echo Verbose statements from : $BINLOG_FILENAME
# Output --verbose lines, with extra Windows CR's trimmed
select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%';
#---
# Cleanup
#---
drop table raw_binlog_rows;
drop table myt;
--eval set global binlog_alter_two_phase=$binlog_alter_two_phase
#
# MENT-662: Lag Free Alter On Slave
#
--echo #
--echo # Test verifies replay of binary logs which contain
--echo # SA/RA/CA works fine.
--echo # Generate a binary log with alter events and use mysqlbinlog tool to
--echo # generate a sql file for replay. Source it on an clean master and
--echo # verify the correctness. Use the latest binlog and repeat the same
--echo # process mentioned above and observe replay works fine.
--echo #
--source include/have_log_bin.inc
--source include/have_innodb.inc
--source include/have_binlog_format_statement.inc
--let $binlog_alter_two_phase= `select @@binlog_alter_two_phase`
set global binlog_alter_two_phase=YES;
set binlog_alter_two_phase=YES;
create table t1 (f1 int primary key) engine=InnoDB;
create table t2 (f1 int primary key, constraint c1 foreign key (f1) references t1(f1)) engine=innodb;
--error ER_CANT_CREATE_TABLE
alter table t2 add constraint c1 foreign key (f1) references t1(f1);
drop table t2, t1;
select @@gtid_binlog_state;
FLUSH LOGS;
let MYSQLD_DATADIR= `select @@datadir;`;
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/slave_1.sql
--echo # reset the binlog
RESET MASTER;
--echo # execute the binlog
--exec $MYSQL --port=$MASTER_MYPORT --host=127.0.0.1 -e "source $MYSQLTEST_VARDIR/tmp/slave_1.sql"
SELECT @@gtid_binlog_state;
FLUSH LOGS;
--echo # Replay 1: One more time to simulate S->S case
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/slave_2.sql
RESET MASTER;
--echo # execute the binlog
--exec $MYSQL --port=$MASTER_MYPORT --host=127.0.0.1 -e "source $MYSQLTEST_VARDIR/tmp/slave_2.sql"
SELECT @@gtid_binlog_state;
FLUSH LOGS;
--echo # Replay 2: One more time to simulate S->S case
--exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/slave_3.sql
RESET MASTER;
--echo # execute the binlog
--exec $MYSQL --port=$MASTER_MYPORT --host=127.0.0.1 -e "source $MYSQLTEST_VARDIR/tmp/slave_3.sql"
SELECT @@gtid_binlog_state;
--echo # clean up
remove_file $MYSQLTEST_VARDIR/tmp/slave_1.sql;
remove_file $MYSQLTEST_VARDIR/tmp/slave_2.sql;
remove_file $MYSQLTEST_VARDIR/tmp/slave_3.sql;
RESET MASTER;
--eval set global binlog_alter_two_phase=$binlog_alter_two_phase;
...@@ -18,6 +18,12 @@ SELECT COUNT(*) = 3 FROM t1; ...@@ -18,6 +18,12 @@ SELECT COUNT(*) = 3 FROM t1;
COUNT(*) = 3 COUNT(*) = 3
1 1
connection node_3; connection node_3;
SET @@session.binlog_alter_two_phase = 1;
ALTER TABLE t1 ADD COLUMN f2 INT;
INSERT INTO t1 VALUES (4,1);
connection node_1;
connection node_2;
connection node_3;
DROP TABLE t1; DROP TABLE t1;
connection node_2; connection node_2;
STOP SLAVE; STOP SLAVE;
......
...@@ -37,9 +37,25 @@ INSERT INTO t1 VALUES (3); ...@@ -37,9 +37,25 @@ INSERT INTO t1 VALUES (3);
--connection node_2 --connection node_2
SELECT COUNT(*) = 3 FROM t1; SELECT COUNT(*) = 3 FROM t1;
--connection node_3
SET @@session.binlog_alter_two_phase = 1;
ALTER TABLE t1 ADD COLUMN f2 INT;
INSERT INTO t1 VALUES (4,1);
--connection node_1
--let $count = 4
--let $table = t1
--source include/wait_until_rows_count.inc
--connection node_2
--let $count = 4
--let $table = t1
--source include/wait_until_rows_count.inc
--connection node_3 --connection node_3
DROP TABLE t1; DROP TABLE t1;
--connection node_2 --connection node_2
--let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'; --let $wait_condition = SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1';
--source include/wait_condition.inc --source include/wait_condition.inc
......
#
# Run start alter basic tests (CA/RA with given engine)
# Params:-
# $engine
# $sync_slave
# master_node and slave_node connection should be defined
--echo # $engine
--connection master_node
--eval create table t1(a int, b int) engine=$engine;
insert into t1 values(1,1);
insert into t1 values(2,2);
--echo # Normal Alter
alter table t1 add column c int;
show create table t1;
--echo # Failed Alter
insert into t1 values(1,1, NULL);
--error ER_DUP_ENTRY
alter table t1 change a a int unique;
set @@session.binlog_alter_two_phase = 0;
alter table t1 change a a int;
set @@session.binlog_alter_two_phase = 1;
alter table t1 change a a int;
show create table t1;
# The following restriction should be removed post MDEV-26005 fix.
# TODO MDEV-26130 , should be removed after fixing
#if ($engine != 'aria')
#{
#--eval create temporary table tmp_tbl(a int, b int) engine=$engine;
#insert into tmp_tbl values(1,1);
#insert into tmp_tbl values(2,2);
#--echo # Normal Alter
#alter table tmp_tbl add column c int;
#--echo # Failed Alter
#insert into tmp_tbl values(1,1, NULL);
#--error ER_DUP_ENTRY
#alter table tmp_tbl change a a int unique ;
#show create table tmp_tbl;
#}
if ($sync_slave)
{
--source include/save_master_gtid.inc
--connection slave_node
--source include/sync_with_master_gtid.inc
show create table t1;
}
--connection master_node
drop table t1;
#if ($engine != 'aria')
#{
#drop temporary table tmp_tbl;
#}
if ($sync_slave)
{
--source include/save_master_gtid.inc
--connection slave_node
--source include/sync_with_master_gtid.inc
}
#
# ==== Purpose ====
#
# Run concurrent split alter on given storage engine
# With concurrent 10 connections
#
# ==== Usage ====
#
# --let $alter_engine= Engine Name (myisam , innodb ...)
# --let $alter_algorithm= ...
# --let $alter_online = [][ONLINE]
# --let $domain_1=
# --let $domain_2=
# --let $M_port= //Master port
# --let $S_port= //Slave port
# --let $sync_slave= // 0/1 whether to sync slave with master or not
#
--connection master_node
set global debug_dbug="+d,start_alter_delay_master";
--let $i= 1
while($i < 11)
{
if($i == 1 && $domain_1)
{
--eval set gtid_domain_id= $domain_1;
}
if($i == 6 && $domain_2)
{
--eval set gtid_domain_id= $domain_2;
}
--eval create table t$i( a int primary key, b int) engine=$alter_engine
--eval insert into t$i values(1,1),(2,2)
--inc $i
}
if ($sync_slave)
{
--echo # Sync slave
--source include/save_master_gtid.inc
--connection slave_node
--source include/sync_with_master_gtid.inc
--connection master_node
}
--let $i= 1
while($i < 21)
{
if($i == 1 || $i == 11)
{
if($domain_1)
{
--eval set global gtid_domain_id= $domain_1;
}
}
if($i == 6 || $i == 16)
{
if($domain_2)
{
--eval set global gtid_domain_id= $domain_2;
}
}
connect(con$i,127.0.0.1,root,,$db_name, $M_port);
--inc $i
}
--let $i= 1
while($i < 11)
{
--connection con$i
--send_eval alter $alter_online table t$i add column c int, force, algorithm=$alter_algorithm
--inc $i
}
--connection master_node
set DEBUG_SYNC= "now signal alter_cont";
--let $i= 1
while($i < 11)
{
--connection con$i
--reap
--inc $i
}
--connection master_node
set DEBUG_SYNC= 'RESET';
if ($sync_slave)
{
--echo # Sync slave
--source include/save_master_gtid.inc
--connection slave_node
--source include/sync_with_master_gtid.inc
--connection master_node
}
--echo # Concurrent DML
--let $i= 1
while($i < 11)
{
--connection con$i
--send_eval alter table t$i add column d int, force, algorithm=$alter_algorithm
--inc $i
}
if ($alter_algorithm == "inplace")
{
--sleep 1
--let $i= 11
--let $j= 1
while($i < 21)
{
--connection con$i
--send_eval insert into t$j values(5,5,5);
--inc $i
--inc $j
}
--let $i= 11
while($i < 21)
{
--connection con$i
--reap
--inc $i
}
if ($sync_slave)
{
--echo # Sync slave
--source include/save_master_gtid.inc
--connection slave_node
--source include/sync_with_master_gtid.inc
--connection master_node
}
}
--connection master_node
set DEBUG_SYNC= "now signal alter_cont";
--let $i= 1
while($i < 11)
{
--connection con$i
--reap
--inc $i
}
--connection master_node
set DEBUG_SYNC= 'RESET';
if ($sync_slave)
{
--echo # Sync slave
--source include/save_master_gtid.inc
--connection slave_node
--source include/sync_with_master_gtid.inc
--connection master_node
}
--echo # Rollback tests
--let $i= 1
while($i < 11)
{
--connection con$i
--eval insert into t$i values(3,2,1,1)
--send_eval alter table t$i change b b int unique, force, algorithm=$alter_algorithm
--inc $i
}
--connection master_node
set DEBUG_SYNC= "now signal alter_cont";
--let $i= 1
while ($i < 11)
{
--connection con$i
--error ER_DUP_ENTRY
--reap
--inc $i
}
--connection master_node
set DEBUG_SYNC= 'RESET';
if ($sync_slave)
{
--echo # Sync slave
--source include/save_master_gtid.inc
--connection slave_node
--source include/sync_with_master_gtid.inc
--connection master_node
}
if ($sync_slave)
{
--enable_query_log
--echo # diff_table of master and slave , we will do only in the case when
--echo # sync_slave is on
--let $i= 1
while($i < 11)
{
--let $diff_tables= master_node:t$i, slave_node:t$i
source include/diff_tables.inc;
--inc $i
}
--disable_query_log
}
--connection master_node
drop table t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
if ($sync_slave)
{
--echo # Sync slave
--source include/save_master_gtid.inc
--connection slave_node
--source include/sync_with_master_gtid.inc
--connection master_node
}
--let $i= 1
while ($i < 21)
{
--disconnect con$i
--inc $i
}
--connection master_node
SET GLOBAL debug_dbug= "";
#
# ==== Purpose ====
#
# Run concurrent split alter on different storage engine and with sync to given
# master
#
# ==== Usage ====
# --let $domain_1=
# --let $domain_2=
# --let $M_port= //Master port
# --let $S_port= //Slave port
# --let $sync_slave=
# --let $db_name=
#
connect(master_node,127.0.0.1,root,,$db_name, $M_port);
if (!$sync_slave)
{
--eval set gtid_domain_id= $domain_1;
}
connect(slave_node,127.0.0.1,root,,test, $S_port);
if (!$sync_slave)
{
--eval set gtid_domain_id= $domain_2;
}
--let $engine=myisam
--source include/start_alter_basic.inc
--let $engine=innodb
--source include/start_alter_basic.inc
--let $engine=aria
--source include/start_alter_basic.inc
--disable_query_log
--disable_warnings
--connection master_node
--echo # concurrent alter Myisam
--let $alter_engine=myisam
--let $alter_algorithm=copy
--source include/start_alter_concurrent.inc
--connection master_node
--echo # concurrent alter Aria
--let $alter_engine=aria
--let $alter_algorithm=copy
--source include/start_alter_concurrent.inc
--connection master_node
--echo # concurrent alter Innodb copy
--let $alter_engine=innodb
--let $alter_algorithm=copy
--source include/start_alter_concurrent.inc
--connection master_node
--echo # concurrent alter Innodb Inplace
--let $alter_engine=innodb
--let $alter_algorithm=inplace
--source include/start_alter_concurrent.inc
--disconnect master_node
--disconnect slave_node
--enable_warnings
--enable_query_log
This diff is collapsed.
#
# Test verifies that "ROLLBACK ALTER" is written to binary log upon
#ALTER command execution failure.
#
include/master-slave.inc
[connection master]
connection master;
set global binlog_alter_two_phase=YES;
set binlog_alter_two_phase=YES;
create table t1 (f1 int primary key) engine=InnoDB;
create table t2 (f1 int primary key,
constraint c1 foreign key (f1) references t1(f1),
constraint c1 foreign key (f1) references t1(f1)) engine=InnoDB;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
create table t2 (f1 int primary key,
constraint c1 foreign key (f1) references t1(f1)) engine=innodb;
alter table t2 add constraint c1 foreign key (f1) references t1(f1);
ERROR HY000: Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update")
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (f1 int primary key) engine=InnoDB
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t2 (f1 int primary key,
constraint c1 foreign key (f1) references t1(f1)) engine=innodb
master-bin.000001 # Gtid # # GTID #-#-# START ALTER
master-bin.000001 # Query # # use `test`; alter table t2 add constraint c1 foreign key (f1) references t1(f1)
master-bin.000001 # Gtid # # GTID #-#-# ROLLBACK ALTER id=#
master-bin.000001 # Query # # use `test`; alter table t2 add constraint c1 foreign key (f1) references t1(f1)
set foreign_key_checks = 0;
alter table t2 add constraint c1 foreign key (f1) references t1(f1);
ERROR HY000: Duplicate FOREIGN KEY constraint name 'test/c1'
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t1 (f1 int primary key) engine=InnoDB
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t2 (f1 int primary key,
constraint c1 foreign key (f1) references t1(f1)) engine=innodb
master-bin.000001 # Gtid # # GTID #-#-# START ALTER
master-bin.000001 # Query # # use `test`; alter table t2 add constraint c1 foreign key (f1) references t1(f1)
master-bin.000001 # Gtid # # GTID #-#-# ROLLBACK ALTER id=#
master-bin.000001 # Query # # use `test`; alter table t2 add constraint c1 foreign key (f1) references t1(f1)
master-bin.000001 # Gtid # # GTID #-#-# START ALTER
master-bin.000001 # Query # # use `test`; set foreign_key_checks=1; alter table t2 add constraint c1 foreign key (f1) references t1(f1)
master-bin.000001 # Gtid # # GTID #-#-# ROLLBACK ALTER id=#
master-bin.000001 # Query # # use `test`; set foreign_key_checks=1; alter table t2 add constraint c1 foreign key (f1) references t1(f1)
connection slave;
connection master;
drop table t2, t1;
connection slave;
connection master;
set global binlog_alter_two_phase=No;;
include/rpl_end.inc
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
include/master-slave.inc
[connection master]
connection master;
set global binlog_alter_two_phase=true;
connection slave;
stop slave;
SET global slave_parallel_threads=2;
set global slave_parallel_mode=optimistic;
start slave;
connection master;
CREATE TABLE t1 (i int primary key) ENGINE = InnoDB;
connection master1;
ALTER TABLE t1 DROP PRIMARY KEY;
ALTER TABLE t1 ADD UNIQUE KEY ui (i);
ALTER TABLE t1 ADD PRIMARY KEY (i);
connection slave;
connection master;
drop table t1;
CREATE TABLE t1 (a int)engine=innodb;
ALTER TABLE t1 add column b int, LOCK=EXCLUSIVE;
drop table t1;
CREATE TABLE t1 (pk int)engine=innodb;
ALTER TABLE t1 DROP FOREIGN KEY y, LOCK=EXCLUSIVE;
ERROR 42000: Can't DROP FOREIGN KEY `y`; check that it exists
drop table t1;
connection slave;
connection master;
set global binlog_alter_two_phase=false;
connection slave;
include/stop_slave.inc
SET global slave_parallel_threads=0;
include/start_slave.inc
include/rpl_end.inc
include/rpl_init.inc [topology=1->2->3->4]
connection server_3;
set global gtid_strict_mode=1;
include/stop_slave.inc
SET GLOBAL slave_parallel_threads=10;
set global slave_parallel_mode=optimistic;
change master to master_use_gtid=slave_pos;
include/start_slave.inc
connection server_1;
set global binlog_alter_two_phase=YES;
set binlog_alter_two_phase=YES;
connect master_node,127.0.0.1,root,,$db_name, $SERVER_MYPORT_1;
connect slave_node,127.0.0.1,root,,test, $SERVER_MYPORT_2;
# innodb
connection master_node;
create table t1(a int, b int) engine=innodb;;
insert into t1 values(1,1);
insert into t1 values(2,2);
# Normal Alter
alter table t1 add column c int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
# Failed Alter
insert into t1 values(1,1, NULL);
alter table t1 change a a int unique;
ERROR 23000: Duplicate entry '1' for key 'a'
set @@session.binlog_alter_two_phase = 0;
alter table t1 change a a int;
set @@session.binlog_alter_two_phase = 1;
alter table t1 change a a int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
include/save_master_gtid.inc
connection slave_node;
include/sync_with_master_gtid.inc
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
connection master_node;
drop table t1;
include/save_master_gtid.inc
connection slave_node;
include/sync_with_master_gtid.inc
disconnect master_node;
disconnect slave_node;
connection server_1;
set global binlog_alter_two_phase=No;;
include/rpl_sync.inc
connection server_2;
select domain_id, seq_no from mysql.gtid_slave_pos order by seq_no desc limit 1;
domain_id seq_no
0 12
connection server_3;
select domain_id, seq_no from mysql.gtid_slave_pos order by seq_no desc limit 1;
domain_id seq_no
0 12
include/stop_slave.inc
set global slave_parallel_threads = 0;;
set global slave_parallel_mode = optimistic;;
set global gtid_strict_mode = 0;;
include/start_slave.inc
select @@slave_parallel_threads;
@@slave_parallel_threads
0
connection server_4;
select domain_id, seq_no from mysql.gtid_slave_pos order by seq_no desc limit 1;
domain_id seq_no
0 12
include/rpl_end.inc
include/master-slave.inc
[connection master]
connection slave;
include/stop_slave.inc
SET @@global.slave_parallel_threads=4;
SET @@global.slave_parallel_mode=optimistic;
CHANGE MASTER TO master_use_gtid=slave_pos;
SET @@global.debug_dbug="+d,at_write_start_alter";
include/start_slave.inc
connection master;
SET @@session.binlog_alter_two_phase=true;
CREATE TABLE t1 (a INT) ENGINE=innodb;
SET @@session.alter_algorithm='INSTANT';
SET @@session.gtid_domain_id=11;
ALTER TABLE t1 ADD COLUMN b int;
# START Alter having exclusive lock is waiting for the signal
connection slave;
# FTWRL is sent first to wait for SA
connection slave1;
FLUSH TABLES WITH READ LOCK;
# SA completes
connection slave;
set DEBUG_SYNC= "now signal alter_cont";
connection slave1;
connection slave;
# Release CA
connection slave1;
UNLOCK TABLES;
connection master;
connection slave;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT) ENGINE=innodb
slave-bin.000001 # Gtid # # GTID #-#-# START ALTER
slave-bin.000001 # Query # # use `test`; ALTER TABLE t1 ADD COLUMN b int
slave-bin.000001 # Gtid # # GTID #-#-# COMMIT ALTER id=#
slave-bin.000001 # Query # # use `test`; ALTER TABLE t1 ADD COLUMN b int
connection master;
DROP TABLE t1;
connection slave;
# cleanup
connection slave;
set DEBUG_SYNC = RESET;
include/stop_slave.inc
set global slave_parallel_threads = 0;
set global slave_parallel_mode = optimistic;
set @@global.debug_dbug = "";
include/start_slave.inc
include/rpl_end.inc
include/master-slave.inc
[connection master]
connection master;
set binlog_alter_two_phase=true;
CREATE OR REPLACE TABLE tab (
a int PRIMARY KEY,
b varchar(50),
c varchar(50)
) CHARACTER SET=latin1 engine=innodb;
SET SESSION alter_algorithm='INSTANT';
ALTER TABLE tab MODIFY COLUMN b varchar(100);
SET SESSION alter_algorithm='NOCOPY';
ALTER TABLE tab MODIFY COLUMN c varchar(100);
SHOW CREATE TABLE tab;
Table Create Table
tab CREATE TABLE `tab` (
`a` int(11) NOT NULL,
`b` varchar(100) DEFAULT NULL,
`c` varchar(100) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE tab (
a int PRIMARY KEY,
b varchar(50),
c varchar(50)
) CHARACTER SET=latin1 engine=innodb
master-bin.000001 # Gtid # # GTID #-#-# START ALTER
master-bin.000001 # Query # # use `test`; ALTER TABLE tab MODIFY COLUMN b varchar(100)
master-bin.000001 # Gtid # # GTID #-#-# COMMIT ALTER id=#
master-bin.000001 # Query # # use `test`; ALTER TABLE tab MODIFY COLUMN b varchar(100)
master-bin.000001 # Gtid # # GTID #-#-# START ALTER
master-bin.000001 # Query # # use `test`; ALTER TABLE tab MODIFY COLUMN c varchar(100)
master-bin.000001 # Gtid # # GTID #-#-# COMMIT ALTER id=#
master-bin.000001 # Query # # use `test`; ALTER TABLE tab MODIFY COLUMN c varchar(100)
connection slave;
SHOW CREATE TABLE tab;
Table Create Table
tab CREATE TABLE `tab` (
`a` int(11) NOT NULL,
`b` varchar(100) DEFAULT NULL,
`c` varchar(100) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; CREATE OR REPLACE TABLE tab (
a int PRIMARY KEY,
b varchar(50),
c varchar(50)
) CHARACTER SET=latin1 engine=innodb
slave-bin.000001 # Gtid # # GTID #-#-# START ALTER
slave-bin.000001 # Query # # use `test`; ALTER TABLE tab MODIFY COLUMN b varchar(100)
slave-bin.000001 # Gtid # # GTID #-#-# COMMIT ALTER id=#
slave-bin.000001 # Query # # use `test`; ALTER TABLE tab MODIFY COLUMN b varchar(100)
slave-bin.000001 # Gtid # # GTID #-#-# START ALTER
slave-bin.000001 # Query # # use `test`; ALTER TABLE tab MODIFY COLUMN c varchar(100)
slave-bin.000001 # Gtid # # GTID #-#-# COMMIT ALTER id=#
slave-bin.000001 # Query # # use `test`; ALTER TABLE tab MODIFY COLUMN c varchar(100)
connection master;
DROP TABLE tab;
connection slave;
include/rpl_end.inc
include/master-slave.inc
[connection master]
connection master;
set global binlog_alter_two_phase=true;
connection slave;
include/stop_slave.inc
change master to master_use_gtid= current_pos;
set global gtid_strict_mode=1;
# Legacy Master Slave
connect master_node,127.0.0.1,root,,$db_name, $M_port;
set gtid_domain_id= 0;;
connect slave_node,127.0.0.1,root,,test, $S_port;
set gtid_domain_id= 0;;
# myisam
connection master_node;
create table t1(a int, b int) engine=myisam;;
insert into t1 values(1,1);
insert into t1 values(2,2);
# Normal Alter
alter table t1 add column c int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
# Failed Alter
insert into t1 values(1,1, NULL);
alter table t1 change a a int unique;
ERROR 23000: Duplicate entry '1' for key 'a'
set @@session.binlog_alter_two_phase = 0;
alter table t1 change a a int;
set @@session.binlog_alter_two_phase = 1;
alter table t1 change a a int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
connection master_node;
drop table t1;
# innodb
connection master_node;
create table t1(a int, b int) engine=innodb;;
insert into t1 values(1,1);
insert into t1 values(2,2);
# Normal Alter
alter table t1 add column c int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
# Failed Alter
insert into t1 values(1,1, NULL);
alter table t1 change a a int unique;
ERROR 23000: Duplicate entry '1' for key 'a'
set @@session.binlog_alter_two_phase = 0;
alter table t1 change a a int;
set @@session.binlog_alter_two_phase = 1;
alter table t1 change a a int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
connection master_node;
drop table t1;
# aria
connection master_node;
create table t1(a int, b int) engine=aria;;
insert into t1 values(1,1);
insert into t1 values(2,2);
# Normal Alter
alter table t1 add column c int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
# Failed Alter
insert into t1 values(1,1, NULL);
alter table t1 change a a int unique;
ERROR 23000: Duplicate entry '1' for key 'a'
set @@session.binlog_alter_two_phase = 0;
alter table t1 change a a int;
set @@session.binlog_alter_two_phase = 1;
alter table t1 change a a int;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` int(11) DEFAULT NULL
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=1
connection master_node;
drop table t1;
# concurrent alter Myisam
# Concurrent DML
# Rollback tests
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
# concurrent alter Aria
# Concurrent DML
# Rollback tests
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
# concurrent alter Innodb copy
# Concurrent DML
# Rollback tests
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
# concurrent alter Innodb Inplace
# Concurrent DML
# Rollback tests
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
ERROR 23000: Duplicate entry '2' for key 'b'
connection master;
select @@gtid_binlog_state;
@@gtid_binlog_state
0-1-410
RESET master;
connection slave;
select @@gtid_binlog_state;
@@gtid_binlog_state
0-1-410
set global gtid_strict_mode=0;
include/start_slave.inc
connection master;
set global binlog_alter_two_phase=false;
include/rpl_end.inc
This diff is collapsed.
include/master-slave.inc
[connection master]
connection master;
set binlog_alter_two_phase=YES;
connection master;
CREATE TABLE t1 (i int) engine=innodb;
CREATE TABLE t2 (i int) engine=innodb;
ALTER TABLE t1 DROP CONSTRAINT IF EXISTS y;
Warnings:
Note 1091 Can't DROP CONSTRAINT `y`; check that it exists
OPTIMIZE TABLE t2;
Table Op Msg_type Msg_text
test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
test.t2 optimize status OK
connection slave;
connection master;
drop table t1,t2;
include/rpl_end.inc
This diff is collapsed.
include/master-slave.inc
[connection master]
connection master;
CREATE TABLE t1 (a1 int, d1 int DEFAULT 0);
INSERT INTO t1 VALUES (1,1) ;
SET binlog_alter_two_phase=YES;
ALTER TABLE t1 WAIT 9 RENAME COLUMN a1 TO a2;
SET binlog_alter_two_phase=NO;
ALTER TABLE t1 ALTER COLUMN d1 DROP DEFAULT;
connection slave;
connection master;
drop table t1;
connection slave;
include/rpl_end.inc
include/master-slave.inc
[connection master]
connection slave;
SET @old_debug_slave= @@global.debug;
stop slave;
SET GLOBAL slave_parallel_threads=4;
set global slave_parallel_mode=optimistic;
set global gtid_strict_mode=1;
start slave;
connection master;
call mtr.add_suppression("ALTER query started at .+ could not be completed");
SET @old_debug_master= @@global.debug;
set binlog_alter_two_phase=true;
create table t3( a int primary key, b int) engine=innodb;
connection master;
connection slave;
include/stop_slave.inc
connection master;
SET SESSION debug_dbug="d,start_alter_kill_after_binlog";
alter table t3 add column d int;
ERROR HY000: Lost connection to server during query
include/rpl_reconnect.inc
set binlog_alter_two_phase= true;
alter table t3 add column d int;
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid # # BEGIN GTID #-#-#
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'ALTER query started at .+ could not be completed' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query # # COMMIT
master-bin.000001 # Gtid # # GTID #-#-#
master-bin.000001 # Query # # use `test`; create table t3( a int primary key, b int) engine=innodb
master-bin.000001 # Gtid # # GTID #-#-# START ALTER
master-bin.000001 # Query # # use `test`; alter table t3 add column d int
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Gtid # # GTID #-#-# START ALTER
master-bin.000002 # Query # # use `test`; alter table t3 add column d int
master-bin.000002 # Gtid # # GTID #-#-# COMMIT ALTER id=#
master-bin.000002 # Query # # use `test`; alter table t3 add column d int
connection slave;
include/start_slave.inc
connection master;
connection slave;
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid # # BEGIN GTID #-#-#
slave-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'ALTER query started at .+ could not be completed' COLLATE 'latin1_swedish_ci'))
slave-bin.000001 # Query # # COMMIT
slave-bin.000001 # Gtid # # GTID #-#-#
slave-bin.000001 # Query # # use `test`; create table t3( a int primary key, b int) engine=innodb
slave-bin.000001 # Gtid # # GTID #-#-# START ALTER
slave-bin.000001 # Query # # use `test`; alter table t3 add column d int
slave-bin.000001 # Gtid # # GTID #-#-# START ALTER
slave-bin.000001 # Query # # use `test`; alter table t3 add column d int
slave-bin.000001 # Gtid # # GTID #-#-# COMMIT ALTER id=#
slave-bin.000001 # Query # # use `test`; alter table t3 add column d int
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` int(11) NOT NULL,
`b` int(11) DEFAULT NULL,
`d` int(11) DEFAULT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
connection master;
SET GLOBAL debug_dbug= @old_debug_master;
drop table t3;
set global binlog_alter_two_phase = No;;
connection slave;
SET GLOBAL debug_dbug= @old_debug_slave;
stop slave;
set global slave_parallel_threads = 0;;
set global slave_parallel_mode = optimistic;;
set global gtid_strict_mode = 0;;
start slave;
connection master;
include/rpl_end.inc
include/master-slave.inc
[connection master]
connection slave;
SET @old_debug_slave= @@global.debug;
include/stop_slave.inc
SET GLOBAL slave_parallel_threads=4;
set global slave_parallel_mode=optimistic;
set global gtid_strict_mode=1;
set global debug_dbug="+d,rpl_slave_stop_CA_before_binlog";
include/start_slave.inc
connection master;
SET @old_debug_master= @@global.debug;
set global debug_dbug="+d,start_alter_delay_master";
set global binlog_alter_two_phase=true;
create table t1( a int primary key, b int) engine=myisam;
create table t2( a int primary key, b int) engine=myisam;
connect con1,localhost,root,,;
alter table t1 add column c int;;
connection master;
# Get into binlog first and wait
# master gtid state is 0-1-3
connect con2,localhost,root,,;
alter table t2 add column c int;;
connection master;
# Get into binlog next and wait as well
# master gtid state is 0-1-4
set DEBUG_SYNC= "now signal alter_cont";
connection con1;
connection con2;
create table t3( a int primary key, b int) engine=innodb;
# master gtid state is 0-1-7
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Gtid_list 1 # []
master-bin.000001 # Binlog_checkpoint 1 # master-bin.000001
master-bin.000001 # Gtid 1 # GTID #-#-#
master-bin.000001 # Query 1 # use `test`; create table t1( a int primary key, b int) engine=myisam
master-bin.000001 # Gtid 1 # GTID #-#-#
master-bin.000001 # Query 1 # use `test`; create table t2( a int primary key, b int) engine=myisam
master-bin.000001 # Gtid 1 # GTID #-#-# START ALTER
master-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
master-bin.000001 # Gtid 1 # GTID #-#-# START ALTER
master-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
master-bin.000001 # Gtid 1 # GTID #-#-# COMMIT ALTER id=<seq_no>
master-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
master-bin.000001 # Gtid 1 # GTID #-#-# COMMIT ALTER id=<seq_no>
master-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
master-bin.000001 # Gtid 1 # GTID #-#-#
master-bin.000001 # Query 1 # use `test`; create table t3( a int primary key, b int) engine=innodb
# Stop Slave
# As master binlog is SA SA CA CA
# let's stop at first CA processing (in process_commit_alter)
connection slave;
include/sync_with_master_gtid.inc
connect extra_slave,127.0.0.1,root,,test,$SLAVE_MYPORT;
stop slave;;
connection slave;
connection extra_slave;
SET GLOBAL debug_dbug= @old_debug_slave;
connection slave;
include/wait_for_slave_sql_to_stop.inc
# The list of events after the slave has stopped must have just one CA:
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid_list 2 # []
slave-bin.000001 # Binlog_checkpoint 2 # slave-bin.000001
slave-bin.000001 # Gtid 1 # GTID #-#-#
slave-bin.000001 # Query 1 # use `test`; create table t1( a int primary key, b int) engine=myisam
slave-bin.000001 # Gtid 1 # GTID #-#-#
slave-bin.000001 # Query 1 # use `test`; create table t2( a int primary key, b int) engine=myisam
slave-bin.000001 # Gtid 1 # GTID #-#-# START ALTER
slave-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
slave-bin.000001 # Gtid 1 # GTID #-#-# START ALTER
slave-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
slave-bin.000001 # Gtid 1 # GTID #-#-# COMMIT ALTER id=<seq_no>
slave-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
select domain_id, seq_no from mysql.gtid_slave_pos order by seq_no desc limit 1;
domain_id seq_no
0 5
include/start_slave.inc
connection master;
connection slave;
# Everything from the master binlog must have been applied now:
select domain_id, seq_no from mysql.gtid_slave_pos order by seq_no desc limit 1;
domain_id seq_no
0 7
# slave gtid state is 0-1-7
# The list of events after the slave has synchronized must have both CA:
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
slave-bin.000001 # Gtid_list 2 # []
slave-bin.000001 # Binlog_checkpoint 2 # slave-bin.000001
slave-bin.000001 # Gtid 1 # GTID #-#-#
slave-bin.000001 # Query 1 # use `test`; create table t1( a int primary key, b int) engine=myisam
slave-bin.000001 # Gtid 1 # GTID #-#-#
slave-bin.000001 # Query 1 # use `test`; create table t2( a int primary key, b int) engine=myisam
slave-bin.000001 # Gtid 1 # GTID #-#-# START ALTER
slave-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
slave-bin.000001 # Gtid 1 # GTID #-#-# START ALTER
slave-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
slave-bin.000001 # Gtid 1 # GTID #-#-# COMMIT ALTER id=<seq_no>
slave-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
slave-bin.000001 # Gtid 1 # GTID #-#-# COMMIT ALTER id=<seq_no>
slave-bin.000001 # Query 1 # use `test`; alter table <t> add column c int
slave-bin.000001 # Gtid 1 # GTID #-#-#
slave-bin.000001 # Query 1 # use `test`; create table t3( a int primary key, b int) engine=innodb
connection master;
drop table t1,t2,t3;
set global binlog_alter_two_phase = No;;
SET GLOBAL debug_dbug= @old_debug_master;
set DEBUG_SYNC= 'RESET';
connection slave;
stop slave;
set global slave_parallel_threads = 0;;
set global slave_parallel_mode = optimistic;;
set global gtid_strict_mode = 0;;
set DEBUG_SYNC= 'RESET';
start slave;
include/rpl_end.inc
#
# MENT-662: Lag Free Alter On Slave
#
--echo #
--echo # Test verifies that "ROLLBACK ALTER" is written to binary log upon
--echo #ALTER command execution failure.
--echo #
--source include/have_innodb.inc
--source include/master-slave.inc
--connection master
--let $binlog_alter_two_phase= `select @@binlog_alter_two_phase`
set global binlog_alter_two_phase=YES;
set binlog_alter_two_phase=YES;
create table t1 (f1 int primary key) engine=InnoDB;
--error ER_CANT_CREATE_TABLE
create table t2 (f1 int primary key,
constraint c1 foreign key (f1) references t1(f1),
constraint c1 foreign key (f1) references t1(f1)) engine=InnoDB;
create table t2 (f1 int primary key,
constraint c1 foreign key (f1) references t1(f1)) engine=innodb;
--error ER_CANT_CREATE_TABLE
alter table t2 add constraint c1 foreign key (f1) references t1(f1);
--source include/show_binlog_events.inc
set foreign_key_checks = 0;
--error ER_DUP_CONSTRAINT_NAME
alter table t2 add constraint c1 foreign key (f1) references t1(f1);
--source include/show_binlog_events.inc
--sync_slave_with_master
--connection master
drop table t2, t1;
--sync_slave_with_master
--connection master
--eval set global binlog_alter_two_phase=$binlog_alter_two_phase;
--source include/rpl_end.inc
#
# Start Alter with Legacy Replication
#
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/master-slave.inc
--connection master
--let $binlog_alter_two_phase= `select @@binlog_alter_two_phase`
set global binlog_alter_two_phase=YES;
set binlog_alter_two_phase=YES;
--connection slave
--let $gtid_strict_mode= `select @@gtid_strict_mode`
set global gtid_strict_mode=1;
--echo # Legacy Master Slave
--let $domain_1=0
--let $domain_2=0
--let $M_port= $MASTER_MYPORT
--let $S_port= $SLAVE_MYPORT
--let $sync_slave=1
--source include/start_alter_include.inc
--connection master
--source include/save_master_gtid.inc
--connection slave
--source include/sync_with_master_gtid.inc
--eval set global gtid_strict_mode = $gtid_strict_mode;
--connection master
--eval set global binlog_alter_two_phase=$binlog_alter_two_phase;
--source include/rpl_end.inc
#
# Start Alter with Parallel Replication
# 1 domain id
# |Concurrent alters| < |Parallel workers on slave|
# |x| denotes number of entities it encloses
#
--source include/have_innodb.inc
--source include/have_debug.inc
--source include/master-slave.inc
--connection master
--let $binlog_alter_two_phase= `select @@binlog_alter_two_phase`
set global binlog_alter_two_phase=Yes;
set binlog_alter_two_phase=Yes;
--connection slave
--let $gtid_strict_mode= `select @@gtid_strict_mode`
--let $slave_parallel_threads= `select @@slave_parallel_threads`
--let $slave_parallel_mode= `select @@slave_parallel_mode`
set global gtid_strict_mode=1;
--connection slave
--source include/stop_slave.inc
SET GLOBAL slave_parallel_threads=10;
set global slave_parallel_mode=optimistic;
change master to master_use_gtid=slave_pos;
--source include/start_slave.inc
--echo # Parallel Slave
--connection master
--let $master_server= "master"
--let $domain_1=0
--let $domain_2=0
--let $M_port= $MASTER_MYPORT
--let $S_port= $SLAVE_MYPORT
--let $sync_slave=1
--source include/start_alter_include.inc
--connection master
--source include/save_master_gtid.inc
--connection slave
--source include/sync_with_master_gtid.inc
--echo # cleanup
--source include/stop_slave.inc
--eval set global slave_parallel_threads = $slave_parallel_threads;
--eval set global slave_parallel_mode = $slave_parallel_mode;
--eval set global gtid_strict_mode = $gtid_strict_mode;
set global gtid_domain_id= 0;
--source include/start_slave.inc
--connection master
--eval set global binlog_alter_two_phase=$binlog_alter_two_phase;
--source include/rpl_end.inc
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
!include ../my.cnf
[mysqld.1]
log-bin
log-slave-updates
[mysqld.2]
log-bin
log-slave-updates
[mysqld.3]
log-bin
log-slave-updates
[ENV]
SERVER_MYPORT_1= @mysqld.1.port
SERVER_MYPORT_2= @mysqld.2.port
SERVER_MYPORT_3= @mysqld.3.port
This diff is collapsed.
!include ../my.cnf
[mysqld.1]
log-bin
log-slave-updates
[mysqld.2]
log-bin
log-slave-updates
[mysqld.3]
log-bin
log-slave-updates
[ENV]
SERVER_MYPORT_1= @mysqld.1.port
SERVER_MYPORT_2= @mysqld.2.port
SERVER_MYPORT_3= @mysqld.3.port
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -1266,5 +1266,8 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list); ...@@ -1266,5 +1266,8 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list);
int binlog_commit(THD *thd, bool all, bool is_ro_1pc= false); int binlog_commit(THD *thd, bool all, bool is_ro_1pc= false);
int binlog_commit_by_xid(handlerton *hton, XID *xid); int binlog_commit_by_xid(handlerton *hton, XID *xid);
int binlog_rollback_by_xid(handlerton *hton, XID *xid); int binlog_rollback_by_xid(handlerton *hton, XID *xid);
bool write_bin_log_start_alter(THD *thd, bool& partial_alter,
uint64 start_alter_id, bool log_if_exists);
#endif /* LOG_H */ #endif /* LOG_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment