Skip to content

Commit

Permalink
MDEV-14401: Stored procedure that declares a handler that catches ER_…
Browse files Browse the repository at this point in the history
…LOCK_DEADLOCK error causes thd->is_error() assertion

This was missing bug fix from MySQL wsrep i.e. Galera.
Problem was that if stored procedure declares a handler that
catches deadlock error, then the error may have been
cleared in method sp_rcontext::handle_sql_condition().
Use wsrep_conflict_state correctly to determine is the
error already sent to client.

Add test case for both this bug and MDEV-12837: WSREP: BF
lock wait long. Test requires both fixes to pass.
  • Loading branch information
Jan Lindström committed Dec 7, 2017
1 parent da3a3a6 commit ba576c5
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 12 deletions.
23 changes: 23 additions & 0 deletions mysql-test/suite/galera/r/galera_bf_lock_wait.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2;
ALTER TABLE t1 add primary key(a);
CREATE PROCEDURE p1()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback;
WHILE 1 DO
start transaction;
update t1 set b=connection_id() where a=1;
commit;
END WHILE;
END|
connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1;
call p1;
connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1;
call p1;
connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2;
call p1;
connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2;
call p1;
connection default;
checking error log for 'BF lock wait long' message for 10 times every 10 seconds ...
drop table t1;
drop procedure p1;
52 changes: 52 additions & 0 deletions mysql-test/suite/galera/t/galera_bf_lock_wait.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
--source include/galera_cluster.inc
--source include/big_test.inc

CREATE TABLE t1 ENGINE=InnoDB select 1 as a, 1 as b union select 2, 2;
ALTER TABLE t1 add primary key(a);

DELIMITER |;

CREATE PROCEDURE p1()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION rollback;
WHILE 1 DO
start transaction;
update t1 set b=connection_id() where a=1;
commit;
END WHILE;
END|


DELIMITER ;|

--connect node_1_p1, 127.0.0.1, root, , test, $NODE_MYPORT_1
send call p1;
--connect node_1_p2, 127.0.0.1, root, , test, $NODE_MYPORT_1
send call p1;
--connect node_2_p1, 127.0.0.1, root, , test, $NODE_MYPORT_2
send call p1;
--connect node_2_p2, 127.0.0.1, root, , test, $NODE_MYPORT_2
send call p1;

connection default;
let $counter=10;
let $sleep_period=10;

echo checking error log for 'BF lock wait long' message for $counter times every $sleep_period seconds ...;
while($counter > 0)
{
--disable_query_log
--disable_result_log
eval do sleep($sleep_period);
--enable_query_log
--enable_result_log

# use error 0,1 instead if want test to continue
--error 1
exec grep 'BF lock wait long' $MYSQLTEST_VARDIR/log/mysqld.*.err;
dec $counter;
}

drop table t1;
drop procedure p1;

33 changes: 21 additions & 12 deletions sql/sql_parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5563,14 +5563,19 @@ mysql_execute_command(THD *thd)
thd->print_aborted_warning(3, "RELEASE");
}
#ifdef WITH_WSREP
if (WSREP(thd) && (thd->wsrep_conflict_state != NO_CONFLICT &&
thd->wsrep_conflict_state != REPLAYING))
{
DBUG_ASSERT(thd->is_error()); // the error is already issued
if (WSREP(thd)) {

if (thd->wsrep_conflict_state == NO_CONFLICT ||
thd->wsrep_conflict_state == REPLAYING)
{
my_ok(thd);
}
} else {
#endif /* WITH_WSREP */
my_ok(thd);
#ifdef WITH_WSREP
}
else
#endif /* WITH_WSREP */
my_ok(thd);
break;
}
case SQLCOM_ROLLBACK:
Expand Down Expand Up @@ -5607,13 +5612,16 @@ mysql_execute_command(THD *thd)
if (tx_release)
thd->set_killed(KILL_CONNECTION);
#ifdef WITH_WSREP
if (WSREP(thd) && thd->wsrep_conflict_state != NO_CONFLICT)
{
DBUG_ASSERT(thd->is_error()); // the error is already issued
if (WSREP(thd)) {
if (thd->wsrep_conflict_state == NO_CONFLICT) {
my_ok(thd);
}
} else {
#endif /* WITH_WSREP */
my_ok(thd);
#ifdef WITH_WSREP
}
else
#endif /* WITH_WSREP */
my_ok(thd);
break;
}
case SQLCOM_RELEASE_SAVEPOINT:
Expand Down Expand Up @@ -6237,8 +6245,9 @@ mysql_execute_command(THD *thd)
if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
trans_rollback_stmt(thd);
#ifdef WITH_WSREP
else if (thd->spcont &&
if (thd->spcont &&
(thd->wsrep_conflict_state == MUST_ABORT ||
thd->wsrep_conflict_state == ABORTED ||
thd->wsrep_conflict_state == CERT_FAILURE))
{
/*
Expand Down

0 comments on commit ba576c5

Please sign in to comment.