mirror of
https://github.com/MariaDB/server.git
synced 2025-08-13 05:51:32 +02:00

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
118 lines
3.4 KiB
Text
118 lines
3.4 KiB
Text
# Tests of synchronization of stored procedure execution.
|
|
#
|
|
# Bug #30977 Concurrent statement using stored function and
|
|
# DROP FUNCTION breaks SBR
|
|
#
|
|
# A stored routine could change after dispatch_command()
|
|
# but before a MDL lock is taken. This must be noticed and the
|
|
# sp cache flushed so the correct version can be loaded.
|
|
#
|
|
connect con2, localhost, root;
|
|
connection default;
|
|
CREATE FUNCTION f1() RETURNS INT RETURN 1;
|
|
# Get f1 cached
|
|
SELECT f1();
|
|
f1()
|
|
1
|
|
# Then start executing it again...
|
|
SET DEBUG_SYNC= 'before_execute_sql_command SIGNAL before WAIT_FOR changed';
|
|
# Sending:
|
|
SELECT f1();
|
|
connection con2;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR before';
|
|
# ... but before f1 is locked, change it.
|
|
DROP FUNCTION f1;
|
|
CREATE FUNCTION f1() RETURNS INT RETURN 2;
|
|
SET DEBUG_SYNC= 'now SIGNAL changed';
|
|
# We should now get '2' and not '1'.
|
|
connection default;
|
|
# Reaping: SELECT f1()
|
|
f1()
|
|
2
|
|
disconnect con2;
|
|
DROP FUNCTION f1;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
#
|
|
# Field translation items must be cleared in case of back-offs
|
|
# for queries that use Information Schema tables. Otherwise
|
|
# memory allocated in fix_fields() for views may end up referring
|
|
# to freed memory.
|
|
#
|
|
DROP FUNCTION IF EXISTS f1;
|
|
connect con2, localhost, root;
|
|
connect con3, localhost, root;
|
|
connection default;
|
|
CREATE FUNCTION f1() RETURNS INT RETURN 0;
|
|
connection con2;
|
|
SET DEBUG_SYNC= 'after_wait_locked_pname SIGNAL locked WAIT_FOR issued';
|
|
# con2 will now have an x-lock on f1
|
|
# Sending:
|
|
ALTER FUNCTION f1 COMMENT 'comment';
|
|
connection default;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR locked';
|
|
# This query will block due to the x-lock on f1 and back-off
|
|
SHOW OPEN TABLES WHERE f1()=0;
|
|
connection con3;
|
|
# Check that the IS query is blocked before releasing the x-lock
|
|
SET DEBUG_SYNC= 'now SIGNAL issued';
|
|
connection default;
|
|
# Reaping: ALTER FUNCTION f1 COMMENT 'comment'
|
|
DROP FUNCTION f1;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
disconnect con2;
|
|
disconnect con3;
|
|
#
|
|
# Bug #48246 assert in close_thread_table
|
|
#
|
|
CREATE TABLE t0 (b INTEGER);
|
|
CREATE TABLE t1 (a INTEGER);
|
|
CREATE FUNCTION f1(b INTEGER) RETURNS INTEGER RETURN 1;
|
|
CREATE PROCEDURE p1() SELECT COUNT(f1(a)) FROM t1, t0;
|
|
INSERT INTO t0 VALUES(1);
|
|
INSERT INTO t1 VALUES(1), (2);
|
|
connect con2, localhost, root;
|
|
CALL p1();
|
|
COUNT(f1(a))
|
|
2
|
|
SET DEBUG_SYNC= 'after_open_table_mdl_shared SIGNAL locked_t1 WAIT_FOR go_for_t0';
|
|
# This call used to cause an assertion. MDL deadlock with upcoming
|
|
# LOCK TABLES statement will cause back-off and retry.
|
|
# A variable indicating if a prelocking list exists, used to be not
|
|
# reset properly causing an eventual assert.
|
|
# Sending:
|
|
CALL p1();
|
|
connection default;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR locked_t1';
|
|
# Issue LOCK TABLES statement which will enter in MDL deadlock
|
|
# with CALL statement and as result will cause it to perform
|
|
# back-off and retry.
|
|
SET DEBUG_SYNC= 'mdl_acquire_lock_wait SIGNAL go_for_t0';
|
|
LOCK TABLES t0 WRITE, t1 WRITE;
|
|
UNLOCK TABLES;
|
|
connection con2;
|
|
# Reaping: CALL p1()
|
|
COUNT(f1(a))
|
|
2
|
|
connection default;
|
|
disconnect con2;
|
|
DROP PROCEDURE p1;
|
|
DROP FUNCTION f1;
|
|
DROP TABLES t0, t1;
|
|
#
|
|
# test for bug#11756013
|
|
#
|
|
DROP SCHEMA IF EXISTS s1;
|
|
CREATE SCHEMA s1;
|
|
CREATE PROCEDURE s1.p1() BEGIN END;
|
|
connect con3, localhost, root;
|
|
SET DEBUG_SYNC='before_db_dir_check SIGNAL check_db WAIT_FOR dropped_schema';
|
|
CALL s1.p1;
|
|
connection default;
|
|
SET DEBUG_SYNC='now WAIT_FOR check_db';
|
|
DROP SCHEMA s1;
|
|
SET DEBUG_SYNC='now SIGNAL dropped_schema';
|
|
connection con3;
|
|
ERROR 42000: Unknown database 's1'
|
|
connection default;
|
|
disconnect con3;
|
|
SET DEBUG_SYNC = 'RESET';
|