mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-33070 Thread pool starvation at oversubscribe
Allow one more worker at the oversubscribe threshold so a group only becomes oversubscribed after it exceeds the configured limit. Add a regression test that reproduces the starvation case in the generic thread pool and verifies queued work still drains. Signed-off-by: Varun Deep Saini <varun.23bcs10048@ms.sst.scaler.com>
This commit is contained in:
committed by
Georgi Kodinov
parent
52e9f3e7aa
commit
ad5ef77e18
7
mysql-test/main/mdev-33070.cnf
Normal file
7
mysql-test/main/mdev-33070.cnf
Normal file
@@ -0,0 +1,7 @@
|
||||
!include include/default_my.cnf
|
||||
|
||||
[mysqld.1]
|
||||
extra-port= @ENV.MASTER_EXTRA_PORT
|
||||
|
||||
[ENV]
|
||||
MASTER_EXTRA_PORT= @OPT.port
|
||||
1
mysql-test/main/mdev-33070.opt
Normal file
1
mysql-test/main/mdev-33070.opt
Normal file
@@ -0,0 +1 @@
|
||||
--thread-handling=pool-of-threads --loose-thread-pool-mode=generic --thread-pool-size=1 --thread-pool-max-threads=3 --thread-pool-oversubscribe=1 --thread-pool-stall-limit=10000 --thread-pool-dedicated-listener
|
||||
35
mysql-test/main/mdev-33070.result
Normal file
35
mysql-test/main/mdev-33070.result
Normal file
@@ -0,0 +1,35 @@
|
||||
# MDEV-33070 Thread pool starvation at oversubscribe threshold
|
||||
CREATE TABLE t1 (a INT);
|
||||
connect c1, localhost, root,,;
|
||||
connect c2, localhost, root,,;
|
||||
connect c3, localhost, root,,;
|
||||
connect extra_con, 127.0.0.1, root,,test,$MASTER_EXTRA_PORT,;
|
||||
connection c1;
|
||||
SELECT SLEEP(1000);
|
||||
connection extra_con;
|
||||
connection c2;
|
||||
SELECT SLEEP(1000);
|
||||
connection extra_con;
|
||||
connection c3;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
connection extra_con;
|
||||
KILL QUERY c1_id;
|
||||
SELECT COUNT(*) = 1 FROM t1;
|
||||
COUNT(*) = 1
|
||||
1
|
||||
connection c1;
|
||||
disconnect c1;
|
||||
connection extra_con;
|
||||
KILL QUERY c2_id;
|
||||
connection c2;
|
||||
disconnect c2;
|
||||
connection c3;
|
||||
disconnect c3;
|
||||
connection extra_con;
|
||||
SELECT COUNT(*) = 1 FROM t1;
|
||||
COUNT(*) = 1
|
||||
1
|
||||
disconnect extra_con;
|
||||
connection default;
|
||||
DROP TABLE t1;
|
||||
# End of MDEV-33070 tests
|
||||
83
mysql-test/main/mdev-33070.test
Normal file
83
mysql-test/main/mdev-33070.test
Normal file
@@ -0,0 +1,83 @@
|
||||
--source include/not_embedded.inc
|
||||
--source include/have_pool_of_threads.inc
|
||||
|
||||
--echo # MDEV-33070 Thread pool starvation at oversubscribe threshold
|
||||
|
||||
# The server is started with a single thread group, a dedicated listener,
|
||||
# one worker thread, and thread_pool_oversubscribe=1.
|
||||
#
|
||||
# c1 and c2 run long queries and occupy the one worker plus the one allowed
|
||||
# oversubscribe slot. c3 submits a trivial INSERT which the listener can only
|
||||
# enqueue, because it is sent only after both c1 and c2 are confirmed running.
|
||||
#
|
||||
# Before the fix, after c1 was killed the worker stayed at the oversubscribe
|
||||
# threshold and went to sleep instead of dequeuing c3. Because
|
||||
# thread_pool_dedicated_listener=ON, only the worker can drain the queue, so if
|
||||
# c3 is still pending while c1 and c2 run and completes only after c1 is
|
||||
# killed, then the worker resumed dequeuing.
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
|
||||
--connect (c1, localhost, root,,)
|
||||
--connect (c2, localhost, root,,)
|
||||
--connect (c3, localhost, root,,)
|
||||
--connect (extra_con, 127.0.0.1, root,,test,$MASTER_EXTRA_PORT,)
|
||||
|
||||
--connection c1
|
||||
--let $c1_id= `SELECT CONNECTION_ID()`
|
||||
--send SELECT SLEEP(1000)
|
||||
|
||||
--connection extra_con
|
||||
let $wait_condition=
|
||||
SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.PROCESSLIST
|
||||
WHERE STATE='User sleep' AND ID=$c1_id;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection c2
|
||||
--let $c2_id= `SELECT CONNECTION_ID()`
|
||||
--send SELECT SLEEP(1000)
|
||||
|
||||
--connection extra_con
|
||||
let $wait_condition=
|
||||
SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.PROCESSLIST
|
||||
WHERE STATE='User sleep' AND ID=$c2_id;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--connection c3
|
||||
--send INSERT INTO t1 VALUES (1)
|
||||
|
||||
--connection extra_con
|
||||
--replace_result $c1_id c1_id
|
||||
eval KILL QUERY $c1_id;
|
||||
|
||||
let $wait_timeout= 10;
|
||||
let $wait_condition=
|
||||
SELECT COUNT(*) = 1 FROM t1;
|
||||
--source include/wait_condition.inc
|
||||
SELECT COUNT(*) = 1 FROM t1;
|
||||
|
||||
--connection c1
|
||||
--error 0,ER_QUERY_INTERRUPTED,ER_STATEMENT_TIMEOUT
|
||||
--reap
|
||||
--disconnect c1
|
||||
|
||||
--connection extra_con
|
||||
--replace_result $c2_id c2_id
|
||||
eval KILL QUERY $c2_id;
|
||||
|
||||
--connection c2
|
||||
--error 0,ER_QUERY_INTERRUPTED
|
||||
--reap
|
||||
--disconnect c2
|
||||
|
||||
--connection c3
|
||||
--reap
|
||||
--disconnect c3
|
||||
|
||||
--connection extra_con
|
||||
SELECT COUNT(*) = 1 FROM t1;
|
||||
--disconnect extra_con
|
||||
|
||||
--connection default
|
||||
DROP TABLE t1;
|
||||
--echo # End of MDEV-33070 tests
|
||||
@@ -1139,7 +1139,7 @@ static void queue_put(thread_group_t *thread_group, TP_connection_generic *conne
|
||||
|
||||
static bool too_many_threads(thread_group_t *thread_group)
|
||||
{
|
||||
return (thread_group->active_thread_count >= 1+(int)threadpool_oversubscribe
|
||||
return (thread_group->active_thread_count > 1+(int)threadpool_oversubscribe
|
||||
&& !thread_group->stalled);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user