mariadb/mysql-test/t/rpl_killed_ddl.test
He Zhenxing 9530126822 BUG#37145 Killing a statement doing DDL may log binlog event with error code 1053
When the thread executing a DDL was killed after finished its
execution but before writing the binlog event, the error code in
the binlog event could be set wrongly to ER_SERVER_SHUTDOWN or
ER_QUERY_INTERRUPTED.

This patch fixed the problem by ignoring the kill status when
constructing the event for DDL statements.

This patch also included the following changes in order to
provide the test case.

 1) modified mysqltest to support variable for connection command

 2) modified mysql-test-run.pl, add new variable MYSQL_SLAVE to
    run mysql client against the slave mysqld.
2009-03-27 13:19:50 +08:00

271 lines
6.4 KiB
Text

# ==== Purpose ====
#
# This test check if DDL statements are correctly binlogged when the
# thread is killed
#
# ==== Method ====
#
# Start a DDL query and kill it, check if the error code of the binlog
# event is correct.
#
# DDL statements tested:
# CREATE/ALTER/RENAME/DROP DATABASE
# CREATE/ALTER/DROP FUNCTION
# CREATE/ALTER/DROP PROCEDURE
# CREATE/ALTER/RENAME/DROP TABLE
# CREATE/DROP TRIGGER
# CREATE/ALTER/DROP VIEW
#
# ==== Bugs =====
#
source include/have_debug.inc;
source include/master-slave.inc;
# Use the DBUG_SYNC_POINT to make sure the thread running the DDL is
# waiting before creating the query log event
let $debug_lock= "debug_lock.before_query_log_event";
######## INITIALIZATION ########
disable_warnings;
DROP DATABASE IF EXISTS d1;
DROP DATABASE IF EXISTS d2;
DROP DATABASE IF EXISTS d3;
DROP DATABASE IF EXISTS d4;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP FUNCTION IF EXISTS f3;
DROP FUNCTION IF EXISTS f4;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
DROP TABLE IF EXISTS t4;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP PROCEDURE IF EXISTS p3;
DROP PROCEDURE IF EXISTS p4;
DROP TRIGGER IF EXISTS tr1;
DROP TRIGGER IF EXISTS tr2;
DROP TRIGGER IF EXISTS tr3;
DROP TRIGGER IF EXISTS tr4;
enable_warnings;
CREATE DATABASE d1;
CREATE FUNCTION f1 () RETURNS INT DETERMINISTIC
RETURN 1;
DELIMITER //;
CREATE PROCEDURE p1 (OUT rows INT)
BEGIN
SELECT COUNT(*) INTO rows FROM t1;
END;
//
DELIMITER ;//
CREATE TABLE t1 (a int);
CREATE TABLE t3 (a int);
DELIMITER //;
CREATE TRIGGER tr1 BEFORE INSERT ON t1
FOR EACH ROW BEGIN
DELETE FROM t4 WHERE a=NEW.a;
END;
//
DELIMITER ;//
CREATE INDEX i1 ON t1 (a);
CREATE VIEW v1 AS SELECT a FROM t1 WHERE a < 100;
sync_slave_with_master;
connection master1;
let $connection_name= master1;
let $connection_id= `SELECT CONNECTION_ID()`;
connection master;
echo [on master];
# This will block the execution of a statement at the DBUG_SYNC_POINT
# with given lock name
if (`SELECT '$debug_lock' != ''`)
{
disable_query_log;
disable_result_log;
eval SELECT IS_FREE_LOCK($debug_lock);
eval SELECT GET_LOCK($debug_lock, 10);
eval SELECT IS_FREE_LOCK($debug_lock);
enable_query_log;
enable_result_log;
}
######## START TEST ########
connection master1;
echo [on master1];
disable_warnings;
######## DATABASE ########
let $diff_statement= SHOW DATABASES LIKE 'd%';
send CREATE DATABASE d2;
source include/kill_query_and_diff_master_slave.inc;
send ALTER DATABASE d1
DEFAULT CHARACTER SET = 'utf8';
source include/kill_query_and_diff_master_slave.inc;
send DROP DATABASE d1;
source include/kill_query_and_diff_master_slave.inc;
send DROP DATABASE d2;
source include/kill_query_and_diff_master_slave.inc;
######## FUNCTION ########
let $diff_statement= SHOW FUNCTION STATUS LIKE 'f%';
send CREATE FUNCTION f2 () RETURNS INT DETERMINISTIC
RETURN 1;
source include/kill_query_and_diff_master_slave.inc;
send ALTER FUNCTION f1 SQL SECURITY INVOKER;
source include/kill_query_and_diff_master_slave.inc;
# function f1 probably does not exist because the ALTER query was
# killed
send DROP FUNCTION IF EXISTS f1;
source include/kill_query_and_diff_master_slave.inc;
# function f2 probably does not exist because the CREATE query was
# killed
send DROP FUNCTION IF EXISTS f2;
source include/kill_query_and_diff_master_slave.inc;
######## PROCEDURE ########
let $diff_statement= SHOW PROCEDURE STATUS LIKE 'p%';
DELIMITER //;
send CREATE PROCEDURE p2 (OUT rows INT)
BEGIN
SELECT COUNT(*) INTO rows FROM t2;
END;
//
DELIMITER ;//
source include/kill_query_and_diff_master_slave.inc;
send ALTER PROCEDURE p1 SQL SECURITY INVOKER COMMENT 'return rows of table t1';
source include/kill_query_and_diff_master_slave.inc;
send DROP PROCEDURE IF EXISTS p1;
source include/kill_query_and_diff_master_slave.inc;
send DROP PROCEDURE IF EXISTS p2;
source include/kill_query_and_diff_master_slave.inc;
######## TABLE ########
let $diff_statement= SHOW TABLES LIKE 't%';
send CREATE TABLE t2 (b int);
source include/kill_query_and_diff_master_slave.inc;
send ALTER TABLE t1 ADD (d int);
source include/kill_query_and_diff_master_slave.inc;
send RENAME TABLE t3 TO t4;
source include/kill_query_and_diff_master_slave.inc;
######## INDEX ########
let $diff_statement= SHOW INDEX FROM t1;
send CREATE INDEX i2 on t1 (a);
source include/kill_query_and_diff_master_slave.inc;
send DROP INDEX i1 on t1;
source include/kill_query_and_diff_master_slave.inc;
######## TRIGGER ########
let $diff_statement= SHOW TRIGGERS LIKE 'v%';
DELIMITER //;
send CREATE TRIGGER tr2 BEFORE INSERT ON t4
FOR EACH ROW BEGIN
DELETE FROM t1 WHERE a=NEW.a;
END;
//
DELIMITER ;//
source include/kill_query_and_diff_master_slave.inc;
send DROP TRIGGER tr1;
source include/kill_query_and_diff_master_slave.inc;
send DROP TRIGGER IF EXISTS tr2;
source include/kill_query_and_diff_master_slave.inc;
######## VIEW ########
let $diff_statement= SHOW TABLES LIKE 'v%';
send CREATE VIEW v2 AS SELECT a FROM t1 WHERE a > 100;
source include/kill_query_and_diff_master_slave.inc;
send DROP VIEW v1;
source include/kill_query_and_diff_master_slave.inc;
send DROP VIEW IF EXISTS v2;
source include/kill_query_and_diff_master_slave.inc;
######## DROP TABLE ########
# Because of BUG#43529, we cannot use the DBUG_SYNC_POINT for DROP
# TABLE statements on 5.0
connection master;
disable_query_log;
disable_result_log;
eval SELECT RELEASE_LOCK($debug_lock);
enable_result_log;
enable_query_log;
let $debug_lock=;
connection master1;
let $diff_statement= SHOW TABLES LIKE 't%';
send DROP TABLE t1;
source include/kill_query_and_diff_master_slave.inc;
send DROP TABLE IF EXISTS t2;
source include/kill_query_and_diff_master_slave.inc;
######## CLEAN UP ########
# The DROP statements above are killed during the process, so they
# does not make sure the objects are dropped.
disable_warnings;
DROP DATABASE IF EXISTS d1;
DROP DATABASE IF EXISTS d2;
DROP DATABASE IF EXISTS d3;
DROP DATABASE IF EXISTS d4;
DROP FUNCTION IF EXISTS f1;
DROP FUNCTION IF EXISTS f2;
DROP FUNCTION IF EXISTS f3;
DROP FUNCTION IF EXISTS f4;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
DROP TABLE IF EXISTS t4;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP PROCEDURE IF EXISTS p3;
DROP PROCEDURE IF EXISTS p4;
enable_warnings;