mariadb/mysql-test/main/partition_sync.test
Sergei Golubchik bead24b7f3 mariadb-test: wait on disconnect
Remove one of the major sources of race condiitons in mariadb-test.
Normally, mariadb_close() sends COM_QUIT to the server and immediately
disconnects. In mariadb-test it means the test can switch to another
connection and sends queries to the server before the server even
started parsing the COM_QUIT packet and these queries can see the
connection as fully active, as it didn't reach dispatch_command yet.

This is a major source of instability in tests and many - but not all,
still less than a half - tests employ workarounds. The correct one
is a pair count_sessions.inc/wait_until_count_sessions.inc.
Also very popular was wait_until_disconnected.inc, which was completely
useless, because it verifies that the connection is closed, and after
disconnect it always is, it didn't verify whether the server processed
COM_QUIT. Sadly the placebo was as widely used as the real thing.

Let's fix this by making mariadb-test `disconnect` command _to wait_ for
the server to confirm. This makes almost all workarounds redundant.

In some cases count_sessions.inc/wait_until_count_sessions.inc is still
needed, though, as only `disconnect` command is changed:

 * after external tools, like `exec $MYSQL`
 * after failed `connect` command
 * replication, after `STOP SLAVE`
 * Federated/CONNECT/SPIDER/etc after `DROP TABLE`

and also in some XA tests, because an XA transaction is dissociated from
the THD very late, after the server has closed the client connection.

Collateral cleanups: fix comments, remove some redundant statements:
 * DROP IF EXISTS if nothing is known to exist
 * DROP table/view before DROP DATABASE
 * REVOKE privileges before DROP USER
 etc
2025-07-16 09:14:33 +07:00

113 lines
2.6 KiB
Text

--source include/have_partition.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
--echo #
--echo # Bug #43867 ALTER TABLE on a partitioned table
--echo # causes unnecessary deadlocks
--echo #
CREATE TABLE t1 (a int) PARTITION BY RANGE (a)
(PARTITION p0 VALUES LESS THAN (1),
PARTITION p1 VALUES LESS THAN (2));
INSERT INTO t1 VALUES (0),(1);
connect(con1,localhost,root);
connection con1;
BEGIN;
SELECT * FROM t1;
connection default;
--error ER_PARTITION_DOES_NOT_EXIST
ALTER TABLE t1 DROP PARTITION p3;
connection con1;
--echo # This failed with deadlock and should not do so.
SELECT * FROM t1;
connection default;
disconnect con1;
DROP TABLE t1;
--echo #
--echo # Bug #46654 False deadlock on concurrent DML/DDL
--echo # with partitions, inconsistent behavior
--echo #
--disable_warnings
DROP TABLE IF EXISTS tbl_with_partitions;
--enable_warnings
CREATE TABLE tbl_with_partitions ( i INT )
PARTITION BY HASH(i);
INSERT INTO tbl_with_partitions VALUES (1);
connect(con2,localhost,root);
connect(con3,localhost,root);
connection con3;
LOCK TABLE tbl_with_partitions READ;
--echo # Access table with disabled autocommit
connection default;
SET AUTOCOMMIT = 0;
SELECT * FROM tbl_with_partitions;
--echo # Alter table, abort after prepare
connection con2;
set session debug_dbug="+d,abort_copy_table";
--error ER_LOCK_WAIT_TIMEOUT
ALTER TABLE tbl_with_partitions ADD COLUMN f INT;
--echo # Try accessing the table after Alter aborted.
--echo # This used to give ER_LOCK_DEADLOCK.
connection default;
SELECT * FROM tbl_with_partitions;
connection con3;
UNLOCK TABLES;
--echo # Cleanup
connection default;
disconnect con2;
disconnect con3;
DROP TABLE tbl_with_partitions;
--echo #
--echo # MDEV-15465 Server crash or ASAN heap-use-after-free in Item_func_match::cleanup
--echo # upon using FT search with partitioning.
--echo #
--connect (con1,localhost,root,,test)
CREATE OR REPLACE TABLE t1 (c CHAR(8)) ENGINE=MyISAM PARTITION BY KEY(c);
--connection default
set debug_sync= 'execute_command_after_close_tables SIGNAL opened WAIT_FOR go';
--send
DELETE FROM t1 WHERE MATCH(c) AGAINST ('foo' IN BOOLEAN MODE);
--connection con1
set debug_sync= 'now WAIT_FOR opened';
FLUSH TABLES;
set debug_sync= 'now SIGNAL go';
--connection default
--reap
set debug_sync= 'execute_command_after_close_tables SIGNAL opened WAIT_FOR go';
--send
SELECT * FROM t1 WHERE MATCH(c) AGAINST ('foo' IN BOOLEAN MODE);
--connection con1
set debug_sync= 'now WAIT_FOR opened';
FLUSH TABLES;
set debug_sync= 'now SIGNAL go';
# Cleanup
--disconnect con1
--connection default
--reap
DROP TABLE t1;
set debug_sync= 'RESET';