Skip to content
/ server Public
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions mysql-test/main/mdev-33070.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
!include include/default_my.cnf

[mysqld.1]
extra-port= @ENV.MASTER_EXTRA_PORT

[ENV]
MASTER_EXTRA_PORT= @OPT.port
1 change: 1 addition & 0 deletions mysql-test/main/mdev-33070.opt
Original file line number Diff line number Diff line change
@@ -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
41 changes: 41 additions & 0 deletions mysql-test/main/mdev-33070.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 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;
SELECT SLEEP(1);
SLEEP(1)
0
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
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
85 changes: 85 additions & 0 deletions mysql-test/main/mdev-33070.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
--source include/have_pool_of_threads.inc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we customarily start with a heading stating the MDEV.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test needs a good explanation.

To be honest, I don't quite understand, why we need thread_pool_max_threads=3, and 6 connections to prove that patch is working.

Would it work if we were more economic perhaps?
Say thread_pool_max_threads=2, oversubscribe=0, thread_pool_dedicated_listener=ON,
so we have one dedicated listener (so we can still enqueue new requests, into the queue), a single worker (making for 2 threads overall). And check that after killing a running query the queue is still drained by that single worker (i.e single worker won't switch to wait, because "too many threads" were active). Will this work and prove that the patch is correct? (I see that it is correct, but test case is not very obvious).

In any case, write the comments of how test case showing that the fix is working.


--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.
#
# 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
SELECT SLEEP(1);
SELECT COUNT(*) = 0 FROM t1;

--replace_result $c1_id c1_id
eval KILL QUERY $c1_id;

let $wait_timeout= 2;
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
2 changes: 1 addition & 1 deletion sql/threadpool_generic.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1140,7 +1140,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);
}

Expand Down