mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-03 20:36:16 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			363 lines
		
	
	
	
		
			9.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			363 lines
		
	
	
	
		
			9.7 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
#
 | 
						|
# Test KILL and KILL QUERY statements.
 | 
						|
#
 | 
						|
# Killing a connection in an embedded server does not work like in a normal
 | 
						|
# server, if it is waiting for a new statement. In an embedded server, the
 | 
						|
# connection does not read() from a socket, but returns control to the
 | 
						|
# application. 'mysqltest' does not handle the kill request.
 | 
						|
#
 | 
						|
 | 
						|
-- source include/not_embedded.inc
 | 
						|
-- source include/have_debug_sync.inc
 | 
						|
-- source include/have_innodb.inc
 | 
						|
set local sql_mode="";
 | 
						|
set global sql_mode="";
 | 
						|
 | 
						|
delimiter |;
 | 
						|
# Helper function used to repeatedly kill a session.
 | 
						|
CREATE FUNCTION MY_KILL(tid INT) RETURNS INT
 | 
						|
BEGIN
 | 
						|
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
 | 
						|
  KILL tid;
 | 
						|
  RETURN (SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = tid);
 | 
						|
END|
 | 
						|
delimiter ;|
 | 
						|
 | 
						|
connect con1, localhost, root;
 | 
						|
connect con2, localhost, root;
 | 
						|
 | 
						|
# Save id of con1
 | 
						|
connection con1;
 | 
						|
--disable_reconnect
 | 
						|
let $ID= `SELECT @id := CONNECTION_ID()`;
 | 
						|
connection con2;
 | 
						|
let $ignore= `SELECT @id := $ID`;
 | 
						|
connection con1;
 | 
						|
# Signal when this connection is terminating.
 | 
						|
SET DEBUG_SYNC= 'thread_end SIGNAL con1_end';
 | 
						|
# See if we can kill read().
 | 
						|
# Run into read() immediately after hitting 'before_do_command_net_read'.
 | 
						|
SET DEBUG_SYNC= 'before_do_command_net_read SIGNAL con1_read';
 | 
						|
 | 
						|
# Kill con1
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC='now WAIT_FOR con1_read';
 | 
						|
# At this point we have no way to figure out, when con1 is blocked in
 | 
						|
# reading from the socket. Sending KILL to early would not terminate
 | 
						|
# con1. So we repeat KILL until con1 terminates.
 | 
						|
let $wait_condition= SELECT MY_KILL(@id);
 | 
						|
--source include/wait_condition.inc
 | 
						|
# If KILL missed the read(), sync point wait will time out.
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR con1_end';
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
 | 
						|
connection con1;
 | 
						|
--error 1053,2006,2013,5014
 | 
						|
SELECT 1;
 | 
						|
 | 
						|
--enable_reconnect
 | 
						|
# this should work, and we should have a new connection_id()
 | 
						|
SELECT 1;
 | 
						|
let $ignore= `SELECT @id := $ID`;
 | 
						|
SELECT @id != CONNECTION_ID();
 | 
						|
 | 
						|
#make sure the server is still alive
 | 
						|
connection con2;
 | 
						|
SELECT 4;
 | 
						|
connection default;
 | 
						|
 | 
						|
--error ER_SUBQUERIES_NOT_SUPPORTED
 | 
						|
KILL (SELECT COUNT(*) FROM mysql.user);
 | 
						|
 | 
						|
connection con1;
 | 
						|
let $ID= `SELECT @id := CONNECTION_ID()`;
 | 
						|
connection con2;
 | 
						|
let $ignore= `SELECT @id := $ID`;
 | 
						|
connection con1;
 | 
						|
disable_reconnect;
 | 
						|
# Signal when this connection is terminating.
 | 
						|
SET DEBUG_SYNC= 'thread_end SIGNAL con1_end';
 | 
						|
# See if we can kill the sync point itself.
 | 
						|
# Wait in 'before_do_command_net_read' until killed.
 | 
						|
# It doesn't wait for a signal 'kill' but for to be killed.
 | 
						|
# The signal name doesn't matter here.
 | 
						|
SET DEBUG_SYNC= 'before_do_command_net_read SIGNAL con1_read WAIT_FOR kill';
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR con1_read';
 | 
						|
# Repeat KILL until con1 terminates.
 | 
						|
let $wait_condition= SELECT MY_KILL(@id);
 | 
						|
--source include/wait_condition.inc
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR con1_end';
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
 | 
						|
connection con1;
 | 
						|
--error 1053,2006,2013,5014
 | 
						|
SELECT 1;
 | 
						|
enable_reconnect;
 | 
						|
SELECT 1;
 | 
						|
let $ignore= `SELECT @id := $ID`;
 | 
						|
SELECT @id != CONNECTION_ID();
 | 
						|
connection con2;
 | 
						|
SELECT 4;
 | 
						|
connection default;
 | 
						|
 | 
						|
#
 | 
						|
# BUG#14851: killing long running subquery processed via a temporary table.
 | 
						|
#
 | 
						|
 | 
						|
CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT);
 | 
						|
CREATE TABLE t2 (id INT UNSIGNED NOT NULL);
 | 
						|
 | 
						|
INSERT INTO t1 VALUES
 | 
						|
(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0),
 | 
						|
(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0),
 | 
						|
(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0),
 | 
						|
(0),(0),(0),(0),(0),(0),(0),(0), (0),(0),(0),(0),(0),(0),(0),(0);
 | 
						|
INSERT t1 SELECT 0 FROM t1 AS a1, t1 AS a2 LIMIT 4032;
 | 
						|
 | 
						|
INSERT INTO t2 SELECT id FROM t1;
 | 
						|
 | 
						|
connection con1;
 | 
						|
let $ID= `SELECT @id := CONNECTION_ID()`;
 | 
						|
connection con2;
 | 
						|
let $ignore= `SELECT @id := $ID`;
 | 
						|
 | 
						|
connection con1;
 | 
						|
SET DEBUG_SYNC= 'thread_end SIGNAL con1_end';
 | 
						|
SET DEBUG_SYNC= 'before_acos_function SIGNAL in_sync';
 | 
						|
# This is a very long running query. If this test start failing,
 | 
						|
# it may be necessary to change to an even longer query.
 | 
						|
send SELECT id FROM t1 WHERE id IN
 | 
						|
       (SELECT DISTINCT a.id FROM t2 a, t2 b, t2 c, t2 d
 | 
						|
          GROUP BY ACOS(1/a.id), b.id, c.id, d.id
 | 
						|
          HAVING a.id BETWEEN 10 AND 20);
 | 
						|
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
 | 
						|
KILL @id;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR con1_end';
 | 
						|
 | 
						|
connection con1;
 | 
						|
--error 1317,1053,2006,2013,5014
 | 
						|
reap;
 | 
						|
SELECT 1;
 | 
						|
 | 
						|
connection default;
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
DROP TABLE t1, t2;
 | 
						|
 | 
						|
#
 | 
						|
# Test of blocking of sending ERROR after OK or EOF
 | 
						|
#
 | 
						|
connection con1;
 | 
						|
let $ID= `SELECT @id := CONNECTION_ID()`;
 | 
						|
connection con2;
 | 
						|
let $ignore= `SELECT @id := $ID`;
 | 
						|
connection con1;
 | 
						|
SET DEBUG_SYNC= 'before_acos_function SIGNAL in_sync WAIT_FOR kill';
 | 
						|
send SELECT ACOS(0);
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
 | 
						|
KILL QUERY @id;
 | 
						|
connection con1;
 | 
						|
reap;
 | 
						|
SELECT 1;
 | 
						|
SELECT @id = CONNECTION_ID();
 | 
						|
connection default;
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
 | 
						|
#
 | 
						|
# Bug#27563: Stored functions and triggers wasn't throwing an error when killed.
 | 
						|
#
 | 
						|
CREATE TABLE t1 (f1 INT);
 | 
						|
delimiter |;
 | 
						|
CREATE FUNCTION bug27563() RETURNS INT(11)
 | 
						|
DETERMINISTIC
 | 
						|
BEGIN
 | 
						|
  DECLARE CONTINUE HANDLER FOR SQLSTATE '70100' SET @a:= 'killed';
 | 
						|
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @a:= 'exception';
 | 
						|
  SET DEBUG_SYNC= 'now SIGNAL in_sync WAIT_FOR kill';
 | 
						|
  RETURN 1;
 | 
						|
END|
 | 
						|
delimiter ;|
 | 
						|
# Test stored functions
 | 
						|
# Test INSERT
 | 
						|
connection con1;
 | 
						|
let $ID= `SELECT @id := CONNECTION_ID()`;
 | 
						|
connection con2;
 | 
						|
let $ignore= `SELECT @id := $ID`;
 | 
						|
connection con1;
 | 
						|
send INSERT INTO t1 VALUES (bug27563());
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
 | 
						|
KILL QUERY @id;
 | 
						|
connection con1;
 | 
						|
--error 1317
 | 
						|
reap;
 | 
						|
SELECT * FROM t1;
 | 
						|
connection default;
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
 | 
						|
# Test UPDATE
 | 
						|
INSERT INTO t1 VALUES(0);
 | 
						|
connection con1;
 | 
						|
send UPDATE t1 SET f1= bug27563();
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
 | 
						|
KILL QUERY @id;
 | 
						|
connection con1;
 | 
						|
--error 1317
 | 
						|
reap;
 | 
						|
SELECT * FROM t1;
 | 
						|
connection default;
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
 | 
						|
# Test DELETE
 | 
						|
INSERT INTO t1 VALUES(1);
 | 
						|
connection con1;
 | 
						|
send DELETE FROM t1 WHERE bug27563() IS NULL;
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
 | 
						|
KILL QUERY @id;
 | 
						|
connection con1;
 | 
						|
--error 1317
 | 
						|
reap;
 | 
						|
SELECT * FROM t1;
 | 
						|
connection default;
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
 | 
						|
# Test SELECT
 | 
						|
connection con1;
 | 
						|
send SELECT * FROM t1 WHERE f1= bug27563();
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
 | 
						|
KILL QUERY @id;
 | 
						|
connection con1;
 | 
						|
--error 1317
 | 
						|
reap;
 | 
						|
SELECT * FROM t1;
 | 
						|
connection default;
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
DROP FUNCTION bug27563;
 | 
						|
 | 
						|
# Test TRIGGERS
 | 
						|
CREATE TABLE t2 (f2 INT);
 | 
						|
delimiter |;
 | 
						|
CREATE TRIGGER trg27563 BEFORE INSERT ON t1 FOR EACH ROW
 | 
						|
BEGIN
 | 
						|
  DECLARE CONTINUE HANDLER FOR SQLSTATE '70100' SET @a:= 'killed';
 | 
						|
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @a:= 'exception';
 | 
						|
  INSERT INTO t2 VALUES(0);
 | 
						|
  SET DEBUG_SYNC= 'now SIGNAL in_sync WAIT_FOR kill';
 | 
						|
  INSERT INTO t2 VALUES(1);
 | 
						|
END|
 | 
						|
delimiter ;|
 | 
						|
connection con1;
 | 
						|
send INSERT INTO t1 VALUES(2),(3);
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
 | 
						|
KILL QUERY @id;
 | 
						|
connection con1;
 | 
						|
--error 1317
 | 
						|
reap;
 | 
						|
SELECT * FROM t1;
 | 
						|
SELECT * FROM t2;
 | 
						|
connection default;
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
DROP TABLE t1, t2;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # Bug#19723: kill of active connection yields different error code
 | 
						|
--echo # depending on platform.
 | 
						|
--echo #
 | 
						|
 | 
						|
--connection con1
 | 
						|
let $ID= `SELECT @id := CONNECTION_ID()`;
 | 
						|
SET DEBUG_SYNC= 'thread_end SIGNAL con1_end';
 | 
						|
--disable_reconnect
 | 
						|
--error ER_CONNECTION_KILLED
 | 
						|
KILL @id;
 | 
						|
 | 
						|
connection con2;
 | 
						|
SET DEBUG_SYNC= 'now WAIT_FOR con1_end';
 | 
						|
connection con1;
 | 
						|
--echo # ER_SERVER_SHUTDOWN, CR_SERVER_GONE_ERROR, CR_SERVER_LOST,
 | 
						|
--echo # depending on the timing of close of the connection socket
 | 
						|
--error 1053,2006,2013,5014
 | 
						|
SELECT 1;
 | 
						|
--enable_reconnect
 | 
						|
SELECT 1;
 | 
						|
let $ignore= `SELECT @id := $ID`;
 | 
						|
SELECT @id != CONNECTION_ID();
 | 
						|
connection default;
 | 
						|
 | 
						|
SET DEBUG_SYNC = 'RESET';
 | 
						|
DROP FUNCTION MY_KILL;
 | 
						|
 | 
						|
set global sql_mode=default;
 | 
						|
disconnect con1;
 | 
						|
disconnect con2;
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # MDEV-29368 Assertion `trx->mysql_thd == thd' failed in innobase_kill_query from process_timers/timer_handler and use-after-poison in innobase_kill_query
 | 
						|
--echo #
 | 
						|
connect foo,localhost,root;
 | 
						|
let $id=`select connection_id()`;
 | 
						|
create table t1 (a int) engine=innodb;
 | 
						|
insert t1 values (1);
 | 
						|
set debug_sync='THD_cleanup_after_set_killed SIGNAL go0 WAIT_FOR go1';
 | 
						|
set debug_sync='innobase_connection_closed SIGNAL go2 WAIT_FOR go3';
 | 
						|
disconnect foo;
 | 
						|
 | 
						|
connection default;
 | 
						|
set debug_sync='now WAIT_FOR go0';
 | 
						|
set debug_sync='found_killee SIGNAL go1 WAIT_FOR go2';
 | 
						|
evalp kill $id;
 | 
						|
--disable_cursor_protocol
 | 
						|
select variable_value into @threads_cached from information_schema.global_status where variable_name='threads_cached';
 | 
						|
--enable_cursor_protocol
 | 
						|
set debug_sync='now SIGNAL go3';
 | 
						|
if (`select @@thread_handling != 'pool-of-threads'`) {
 | 
						|
  # cannot check that a thread was added to thread pool on windows, but the test works there w/o the wait
 | 
						|
  let wait_condition= select variable_value>@threads_cached from information_schema.global_status where variable_name='threads_cached';
 | 
						|
  source include/wait_condition.inc;
 | 
						|
}
 | 
						|
drop table t1;
 | 
						|
set debug_sync='reset';
 | 
						|
 | 
						|
 | 
						|
--echo #
 | 
						|
--echo # MDEV-33285 - Assertion `m_table' failed in ha_perfschema::rnd_end on
 | 
						|
--echo #              CHECKSUM TABLE
 | 
						|
--echo #
 | 
						|
let $id= `select connection_id()`;
 | 
						|
CREATE TABLE t1 (a INT);
 | 
						|
INSERT INTO t1 VALUES(1);
 | 
						|
SET debug_sync='mysql_checksum_table_after_calculate_checksum SIGNAL parked WAIT_FOR go';
 | 
						|
send CHECKSUM TABLE t1;
 | 
						|
 | 
						|
connect con1, localhost, root;
 | 
						|
connection con1;
 | 
						|
SET debug_sync='now WAIT_FOR parked';
 | 
						|
replace_result $id id;
 | 
						|
eval KILL QUERY $id;
 | 
						|
SET debug_sync='now SIGNAL go';
 | 
						|
connection default;
 | 
						|
error ER_QUERY_INTERRUPTED;
 | 
						|
reap;
 | 
						|
 | 
						|
SET debug_sync='RESET';
 | 
						|
SET debug_sync='mysql_checksum_table_before_calculate_checksum SIGNAL parked WAIT_FOR go';
 | 
						|
send CHECKSUM TABLE t1;
 | 
						|
connection con1;
 | 
						|
SET debug_sync='now WAIT_FOR parked';
 | 
						|
replace_result $id id;
 | 
						|
eval KILL QUERY $id;
 | 
						|
SET debug_sync='now SIGNAL go';
 | 
						|
 | 
						|
connection default;
 | 
						|
error ER_QUERY_INTERRUPTED;
 | 
						|
reap;
 | 
						|
DROP TABLE t1;
 | 
						|
disconnect con1;
 | 
						|
SET debug_sync='RESET';
 |