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.
This commit is contained in:
parent
45f6262f54
commit
8f21a31669
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user