Skip to content

Commit

Permalink
MDEV-17749 Kill during LOCK TABLE ; ALTER TABLE causes assert
Browse files Browse the repository at this point in the history
The problem was that when LOCK TABLES where unwinded as part of
a killed connection, unlink_all_closed_tables() did not like that
there was uncommited transactions.
Fixed by doing a rollback of any open transaction in this particular case.
  • Loading branch information
montywi committed May 26, 2021
1 parent 1864a8e commit aa284e0
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
36 changes: 36 additions & 0 deletions mysql-test/main/lock_kill.result
@@ -0,0 +1,36 @@
#
# MDEV-17749 Kill during LOCK TABLE ; ALTER TABLE causes assert
#
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
connect con1,localhost,root,,test;
LOCK TABLE t1 WRITE;
ALTER TABLE t1 ADD COLUMN b INT;
connection default;
Killing connection
connection con1;
connection default;
disconnect con1;
DROP TABLE t1;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
connect con1,localhost,root,,test;
LOCK TABLE t1 WRITE, t2 WRITE;
ALTER TABLE t1 ADD COLUMN b INT;
connection default;
Killing connection
connection con1;
connection default;
disconnect con1;
DROP TABLE t1, t2;
CREATE TABLE t1 (id int(11)) ENGINE=InnoDB;
LOCK TABLES t1 WRITE;
SET max_statement_time= 0.0001;
CREATE TRIGGER tr16 AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO t1 VALUES (1);
SET max_statement_time= default;
DROP TRIGGER IF EXISTS trg16;
Warnings:
Note 1360 Trigger does not exist
DROP TABLE t1;
#
# End of 10.3 tests
#
59 changes: 59 additions & 0 deletions mysql-test/main/lock_kill.test
@@ -0,0 +1,59 @@
--source include/have_innodb.inc

# This test file is for testing killing of queries that are under LOCK TABLES

--echo #
--echo # MDEV-17749 Kill during LOCK TABLE ; ALTER TABLE causes assert
--echo #

CREATE TABLE t1 (a INT) ENGINE=InnoDB;
--connect (con1,localhost,root,,test)
LOCK TABLE t1 WRITE;
--let $conid= `SELECT CONNECTION_ID()`
--send ALTER TABLE t1 ADD COLUMN b INT
--connection default
--disable_query_log
--echo Killing connection
eval KILL $conid;
--enable_query_log
--connection con1
--error 0,2013
reap;
--connection default
--disconnect con1
DROP TABLE t1;

CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
--connect (con1,localhost,root,,test)
LOCK TABLE t1 WRITE, t2 WRITE;
--let $conid= `SELECT CONNECTION_ID()`
--send ALTER TABLE t1 ADD COLUMN b INT
--connection default
--disable_query_log
--echo Killing connection
eval KILL $conid;
--enable_query_log
--connection con1
--error 0,2013
reap;
--connection default
--disconnect con1
DROP TABLE t1, t2;

# Similar test for CREATE TRIGGER, which also failed

CREATE TABLE t1 (id int(11)) ENGINE=InnoDB;
LOCK TABLES t1 WRITE;
SET max_statement_time= 0.0001;
--error 0,1969
--disable_warnings
CREATE TRIGGER tr16 AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO t1 VALUES (1);
--enable_warnings
SET max_statement_time= default;
DROP TRIGGER IF EXISTS trg16;
DROP TABLE t1;

--echo #
--echo # End of 10.3 tests
--echo #
10 changes: 10 additions & 0 deletions sql/sql_base.cc
Expand Up @@ -2469,7 +2469,17 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count)

/* If no tables left, do an automatic UNLOCK TABLES */
if (thd->lock && thd->lock->table_count == 0)
{
/*
We have to rollback any open transactions here.
This is required in the case where the server has been killed
but some transations are still open (as part of locked tables).
If we don't do this, we will get an assert in unlock_locked_tables().
*/
ha_rollback_trans(thd, FALSE);
ha_rollback_trans(thd, TRUE);
unlock_locked_tables(thd);
}
}


Expand Down

0 comments on commit aa284e0

Please sign in to comment.