summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Nielsen <knielsen@knielsen-hq.org>2015-05-11 11:55:58 +0200
committerKristian Nielsen <knielsen@knielsen-hq.org>2015-05-11 12:43:38 +0200
commit8bedb638d7078c007b58bea4196c3749028192b4 (patch)
tree510740c7ce604ce5b96d88bf5b2a38b7d8550a6c
parentecfc3de57ee6a498b30ca8f59fdb952ab38f5698 (diff)
downloadmariadb-git-8bedb638d7078c007b58bea4196c3749028192b4.tar.gz
MDEV-8113: Parallel slave: slave hangs on ALTER TABLE (or other DDL) as the first event after slave start
In optimistic parallel replication, it is not safe to try to run a following transaction in parallel with a DDL statement, and there is code to prevent this. However, the code was missing the case where the DDL is the very first event after slave start. In this case, following transactions could run in parallel with the DDL, which can cause the slave to hang or even corrupt slave in unlucky cases.
-rw-r--r--mysql-test/suite/rpl/r/rpl_parallel_optimistic.result41
-rw-r--r--mysql-test/suite/rpl/t/rpl_parallel_optimistic.test27
-rw-r--r--sql/rpl_parallel.cc5
3 files changed, 73 insertions, 0 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result b/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result
index 7593b490894..fc8a5edc997 100644
--- a/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result
+++ b/mysql-test/suite/rpl/r/rpl_parallel_optimistic.result
@@ -455,6 +455,47 @@ a b
include/stop_slave.inc
SET GLOBAL debug_dbug= @old_debug;
include/start_slave.inc
+*** MDEV-8113: ALTER TABLE causes slave hang in optimistic parallel replication ***
+include/stop_slave.inc
+ALTER TABLE t2 ADD c INT;
+INSERT INTO t2 (a,b) VALUES (50, 0);
+INSERT INTO t2 (a,b) VALUES (51, 1);
+INSERT INTO t2 (a,b) VALUES (52, 2);
+INSERT INTO t2 (a,b) VALUES (53, 3);
+INSERT INTO t2 (a,b) VALUES (54, 4);
+INSERT INTO t2 (a,b) VALUES (55, 5);
+INSERT INTO t2 (a,b) VALUES (56, 6);
+INSERT INTO t2 (a,b) VALUES (57, 7);
+INSERT INTO t2 (a,b) VALUES (58, 8);
+INSERT INTO t2 (a,b) VALUES (59, 9);
+ALTER TABLE t2 DROP COLUMN c;
+SELECT * FROM t2 WHERE a >= 50 ORDER BY a;
+a b
+50 0
+51 1
+52 2
+53 3
+54 4
+55 5
+56 6
+57 7
+58 8
+59 9
+include/save_master_gtid.inc
+include/start_slave.inc
+include/sync_with_master_gtid.inc
+SELECT * FROM t2 WHERE a >= 50 ORDER BY a;
+a b
+50 0
+51 1
+52 2
+53 3
+54 4
+55 5
+56 6
+57 7
+58 8
+59 9
include/stop_slave.inc
SET GLOBAL slave_parallel_mode=@old_parallel_mode;
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test
index e7d4f18f8a5..93dfe4d5e7c 100644
--- a/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test
+++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic.test
@@ -429,6 +429,33 @@ SET GLOBAL debug_dbug= @old_debug;
--source include/start_slave.inc
+--echo *** MDEV-8113: ALTER TABLE causes slave hang in optimistic parallel replication ***
+
+--connection server_2
+--source include/stop_slave.inc
+
+--connection server_1
+ALTER TABLE t2 ADD c INT;
+INSERT INTO t2 (a,b) VALUES (50, 0);
+INSERT INTO t2 (a,b) VALUES (51, 1);
+INSERT INTO t2 (a,b) VALUES (52, 2);
+INSERT INTO t2 (a,b) VALUES (53, 3);
+INSERT INTO t2 (a,b) VALUES (54, 4);
+INSERT INTO t2 (a,b) VALUES (55, 5);
+INSERT INTO t2 (a,b) VALUES (56, 6);
+INSERT INTO t2 (a,b) VALUES (57, 7);
+INSERT INTO t2 (a,b) VALUES (58, 8);
+INSERT INTO t2 (a,b) VALUES (59, 9);
+ALTER TABLE t2 DROP COLUMN c;
+SELECT * FROM t2 WHERE a >= 50 ORDER BY a;
+--source include/save_master_gtid.inc
+
+--connection server_2
+--source include/start_slave.inc
+--source include/sync_with_master_gtid.inc
+SELECT * FROM t2 WHERE a >= 50 ORDER BY a;
+
+
# Clean up.
--connection server_2
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index d046caf0540..9a1786cee5d 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -2299,6 +2299,11 @@ rpl_parallel::do_event(rpl_group_info *serial_rgi, Log_event *ev,
}
gco->flags= flags;
}
+ else
+ {
+ if (gtid_flags & Gtid_log_event::FL_DDL)
+ force_switch_flag= group_commit_orderer::FORCE_SWITCH;
+ }
rgi->speculation= speculation;
if (gtid_flags & Gtid_log_event::FL_GROUP_COMMIT_ID)