summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Nielsen <knielsen@knielsen-hq.org>2014-07-10 13:55:53 +0200
committerKristian Nielsen <knielsen@knielsen-hq.org>2014-07-10 13:55:53 +0200
commit8f21a3166908d71b5828d50bfce65b480508c6c1 (patch)
treec4aff2031f1402155445fb5cf4e5e29c5dcb1774
parent45f6262f54c5d1ef535c0529c399a7352b5fdea4 (diff)
downloadmariadb-git-8f21a3166908d71b5828d50bfce65b480508c6c1.tar.gz
MDEV-6435: Assertion `m_status == DA_ERROR' failed in Diagnostics_area::sql_errno() with parallel replication
When a MyISAM query is killed midway, the query is logged to the binlog marked with the error. The slave does not attempt to run the query, but aborts with a suitable error message in the error log for the DBA to act on. In this case, the parallel replication code would check the sql_errno() code, even no my_error() had been set. In debug builds, this causes an assertion. Fixed the code to check that we actually have an error set before querying for an error code.
-rw-r--r--mysql-test/suite/rpl/r/rpl_parallel.result28
-rw-r--r--mysql-test/suite/rpl/t/rpl_parallel.test50
-rw-r--r--sql/rpl_parallel.cc5
-rw-r--r--sql/sp_head.cc2
4 files changed, 82 insertions, 3 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_parallel.result b/mysql-test/suite/rpl/r/rpl_parallel.result
index 70ac0b579f3..1c686e44a25 100644
--- a/mysql-test/suite/rpl/r/rpl_parallel.result
+++ b/mysql-test/suite/rpl/r/rpl_parallel.result
@@ -819,11 +819,37 @@ test_check
OK
test_check
OK
+*** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error ***
+CREATE TABLE t6 (a INT) ENGINE=MyISAM;
+CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1;
+SET @old_format= @@binlog_format;
+SET binlog_format= statement;
+SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont';
+INSERT INTO t6 VALUES (1), (2), (3);
+SET debug_sync='now WAIT_FOR ready';
+KILL QUERY CONID;
+SET debug_sync='now SIGNAL cont';
+ERROR 70100: Query execution was interrupted
+SET binlog_format= @old_format;
+SET debug_sync='RESET';
+SET debug_sync='RESET';
+include/wait_for_slave_sql_error.inc [errno=1317]
+STOP SLAVE IO_THREAD;
+SET GLOBAL gtid_slave_pos= 'AFTER_ERROR_GTID_POS';
+include/start_slave.inc
+INSERT INTO t6 VALUES (4);
+SELECT * FROM t6 ORDER BY a;
+a
+1
+4
+SELECT * FROM t6 ORDER BY a;
+a
+4
include/stop_slave.inc
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
include/start_slave.inc
SET DEBUG_SYNC= 'RESET';
DROP function foo;
-DROP TABLE t1,t2,t3,t4,t5;
+DROP TABLE t1,t2,t3,t4,t5,t6;
SET DEBUG_SYNC= 'RESET';
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_parallel.test b/mysql-test/suite/rpl/t/rpl_parallel.test
index 09111fb7461..0f679fa18ee 100644
--- a/mysql-test/suite/rpl/t/rpl_parallel.test
+++ b/mysql-test/suite/rpl/t/rpl_parallel.test
@@ -1292,6 +1292,54 @@ eval SELECT IF('$io_pos' = '$sql_pos', "OK", "Not ok, $io_pos <> $sql_pos") AS t
--enable_query_log
+--echo *** MDEV_6435: Incorrect error handling when query binlogged partially on master with "killed" error ***
+
+--connection server_1
+CREATE TABLE t6 (a INT) ENGINE=MyISAM;
+CREATE TRIGGER tr AFTER INSERT ON t6 FOR EACH ROW SET @a = 1;
+
+--connection con1
+SET @old_format= @@binlog_format;
+SET binlog_format= statement;
+--let $conid = `SELECT CONNECTION_ID()`
+SET debug_sync='sp_head_execute_before_loop SIGNAL ready WAIT_FOR cont';
+send INSERT INTO t6 VALUES (1), (2), (3);
+
+--connection server_1
+SET debug_sync='now WAIT_FOR ready';
+--replace_result $conid CONID
+eval KILL QUERY $conid;
+SET debug_sync='now SIGNAL cont';
+
+--connection con1
+--error ER_QUERY_INTERRUPTED
+--reap
+SET binlog_format= @old_format;
+SET debug_sync='RESET';
+--let $after_error_gtid_pos= `SELECT @@gtid_binlog_pos`
+
+--connection server_1
+SET debug_sync='RESET';
+
+
+--connection server_2
+--let $slave_sql_errno= 1317
+--source include/wait_for_slave_sql_error.inc
+STOP SLAVE IO_THREAD;
+--replace_result $after_error_gtid_pos AFTER_ERROR_GTID_POS
+eval SET GLOBAL gtid_slave_pos= '$after_error_gtid_pos';
+--source include/start_slave.inc
+
+--connection server_1
+INSERT INTO t6 VALUES (4);
+SELECT * FROM t6 ORDER BY a;
+--save_master_pos
+
+--connection server_2
+--sync_with_master
+SELECT * FROM t6 ORDER BY a;
+
+
--connection server_2
--source include/stop_slave.inc
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
@@ -1300,7 +1348,7 @@ SET DEBUG_SYNC= 'RESET';
--connection server_1
DROP function foo;
-DROP TABLE t1,t2,t3,t4,t5;
+DROP TABLE t1,t2,t3,t4,t5,t6;
SET DEBUG_SYNC= 'RESET';
--source include/rpl_end.inc
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 98753865568..0d23248539c 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -234,8 +234,11 @@ static void
convert_kill_to_deadlock_error(rpl_group_info *rgi)
{
THD *thd= rgi->thd;
- int err_code= thd->get_stmt_da()->sql_errno();
+ int err_code;
+ if (!thd->get_stmt_da()->is_error())
+ return;
+ err_code= thd->get_stmt_da()->sql_errno();
if ((err_code == ER_QUERY_INTERRUPTED || err_code == ER_CONNECTION_KILLED) &&
rgi->killed_for_retry)
{
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 8a9e8ddc816..73218b4fda8 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -43,6 +43,7 @@
#include "sql_base.h" // close_thread_tables
#include "transaction.h" // trans_commit_stmt
#include "sql_audit.h"
+#include "debug_sync.h"
/*
Sufficient max length of printed destinations and frame offsets (all uints).
@@ -1309,6 +1310,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
/* Discard the initial part of executing routines. */
thd->profiling.discard_current_query();
#endif
+ DEBUG_SYNC(thd, "sp_head_execute_before_loop");
do
{
sp_instr *i;