1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-09 08:01:34 +03:00
Files
mariadb/mysql-test/suite/rpl/r/rpl_mdev6386.result
Kristian Nielsen 370318f894 MDEV-6386: Assertion `thd->transaction.stmt.is_empty() || thd->in_sub_stmt || (thd->state_flags & Open_tables_state::BACKUPS_AVAIL)' fails with parallel replication
The direct cause of the assertion was missing error handling in
record_gtid(). If ha_commit_trans() fails for the statement commit, there was
missing code to catch the error and do ha_rollback_trans() in this case; this
caused close_thread_tables() to assert.

Normally, this error case is not hit, but in this case it was triggered due to
another bug: When a transaction T1 fails during parallel replication, the code
would signal following transactions that they could start to run without
properly marking the error condition. This caused subsequent transactions to
incorrectly start replicating, only to get an error later during their own
commit step. This was particularly serious if the subsequent transactions were
DDL or MyISAM updates, which cannot be rolled back and would leave replication
in an inconsistent state.

Fixed by 1) in case of error, only signal following transactions to continue
once the error has been properly marked and those transactions will know not
to start; and 2) implement proper error handling in record_gtid() in the case
that statement commit fails.
2014-06-27 13:34:29 +02:00

57 lines
1.2 KiB
Plaintext

include/master-slave.inc
[connection master]
ALTER TABLE mysql.gtid_slave_pos ENGINE = InnoDB;
FLUSH LOGS;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) Engine=InnoDB;
include/stop_slave.inc
SET sql_log_bin= 0;
INSERT INTO t1 VALUES (1, 2);
SET sql_log_bin= 1;
CHANGE MASTER TO master_use_gtid= current_pos;
Contents on slave before:
SELECT * FROM t1 ORDER BY a;
a b
1 2
SET @old_parallel= @@GLOBAL.slave_parallel_threads;
SET GLOBAL slave_parallel_threads=8;
CREATE TEMPORARY TABLE t2 LIKE t1;
INSERT INTO t2 VALUE (1, 1);
INSERT INTO t2 VALUE (2, 1);
INSERT INTO t2 VALUE (3, 1);
INSERT INTO t2 VALUE (4, 1);
INSERT INTO t2 VALUE (5, 1);
INSERT INTO t1 SELECT * FROM t2;
DROP TEMPORARY TABLE t2;
Contents on master:
SELECT * FROM t1 ORDER BY a;
a b
1 1
2 1
3 1
4 1
5 1
START SLAVE;
include/wait_for_slave_sql_error.inc [errno=1062]
STOP SLAVE IO_THREAD;
Contents on slave on slave error:
SELECT * FROM t1 ORDER BY a;
a b
1 2
SET sql_log_bin= 0;
DELETE FROM t1 WHERE a=1;
SET sql_log_bin= 1;
include/start_slave.inc
Contents on slave after:
SELECT * FROM t1 ORDER BY a;
a b
1 1
2 1
3 1
4 1
5 1
DROP TABLE t1;
include/stop_slave.inc
SET GLOBAL slave_parallel_threads= @old_parallel;
include/start_slave.inc
include/rpl_end.inc