Skip to content

Commit aa3bf9a

Browse files
MDEV-39492 Parallel Query: Study how to create worker threads
Introduces parallel_worker_threads variable to control the number of worker threads created by a parallel execution query. 2 new files, sql_parallel_workers.h sql_parallel_workers.cc which contain structures for the creation, management and deletion of parallel worker threads (pwt_ in the name). Main management class created in the stack in JOIN::exec, implemented for the top level select. Current parallel_worker_thread_func sleeps for 10 seconds, generates a warning, signals the main thread, sleeps 10 seconds, signals the main thread again, sets it's finished flag and cleans it's THD. The main thread loops through worker threads, looking for finished thread and cleans them up if they have finished. It then waits for a signal, then processes it's message queue. The thread management data is allocated on the stack in JOIN::exec. Everything else is allocated using my_malloc() and my_free(). Threads are registed in server_threads, so are visible in information_schema.processlist and the show processlist command. We check that a kill query on a parallel worker is passed onto it's manager and the query is properly aborted, and that a kill connection is handled properly in parallel_worker.test. Review input 1: cleanup earlier Do cleanup before we've finished sending the result to the client. This way, one can see the errors (and eventually warnings) marshalled back to the main thread and returned to the user: MariaDB [test]> set parallel_worker_threads=10; Query OK, 0 rows affected (0.001 sec) MariaDB [test]> select seq from seq_1_to_10; ERROR 4103 (HY000): Argument to the worker_busted_function() function does not belong to the range [0,1]
1 parent 1450236 commit aa3bf9a

19 files changed

Lines changed: 824 additions & 10 deletions

include/my_pthread.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,18 @@ typedef uint64 my_thread_id;
624624
*/
625625
#define MY_THREAD_ID_MAX UINT32_MAX
626626

627+
#ifdef _WIN32
628+
#define MAX_THREAD_NAME 256
629+
#elif defined(__linux__)
630+
#define MAX_THREAD_NAME 16
631+
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
632+
#define MAX_THREAD_NAME 19
633+
#include <pthread_np.h>
634+
#elif defined(__apple_build_version__)
635+
#include <sys/proc_info.h>
636+
#define MAX_THREAD_NAME MAXTHREADNAMESIZE
637+
#endif
638+
627639
extern void my_threadattr_global_init(void);
628640
extern my_bool my_thread_global_init(void);
629641
extern void my_thread_set_name(const char *);

libmysqld/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
7272
../sql/mf_iocache.cc ../sql/my_decimal.cc
7373
../sql/net_serv.cc ../sql/opt_range.cc
7474
../sql/opt_group_by_cardinality.cc
75+
../sql/sql_parallel_workers.cc
7576
../sql/opt_rewrite_date_cmp.cc
7677
../sql/opt_rewrite_remove_casefold.cc
7778
../sql/opt_sargable_left.cc

mysql-test/main/mysqld--help.result

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,9 @@ The following specify which files/extra groups are read (specified before remain
10121012
Cost of checking the row against the WHERE clause.
10131013
Increasing this will have the optimizer to prefer plans
10141014
with less row combinations
1015+
--parallel-worker-threads=#
1016+
Number of worker threads available for parallel query
1017+
execution. 0 means parallel execution is disabled
10151018
--path=name Comma-separated list of schema names that defines the
10161019
search order for stored routines
10171020
--performance-schema
@@ -2004,6 +2007,7 @@ optimizer-trace
20042007
optimizer-trace-max-mem-size 1048576
20052008
optimizer-use-condition-selectivity 4
20062009
optimizer-where-cost 0.032
2010+
parallel-worker-threads 0
20072011
path CURRENT_SCHEMA
20082012
performance-schema FALSE
20092013
performance-schema-accounts-size -1
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#
2+
# MDEV-39492 Parallel Query: Study how to create worker threads
3+
#
4+
connect killee, localhost, root, , ;
5+
# check that kill query on a parallel worker is passed to the manager
6+
connection killee;
7+
set session parallel_worker_threads=3;
8+
select seq from seq_1_to_2;;
9+
connection default;
10+
kill query ID;
11+
connection killee;
12+
ERROR 70100: Query execution was interrupted
13+
# reset connection, discard any generated errors
14+
disconnect killee;
15+
connect killee, localhost, root, , ;
16+
# check that kill on a parallel worker is passed to the manager
17+
# doing this last so we don't need to restart default connection
18+
set session parallel_worker_threads=3;
19+
select seq from seq_1_to_2;;
20+
connection default;
21+
kill ID;
22+
connection killee;
23+
Got one of the listed errors
24+
# generated error die with connection
25+
connection default;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#
2+
# Test KILL and KILL QUERY statements.
3+
#
4+
5+
-- source include/count_sessions.inc
6+
-- source include/not_embedded.inc
7+
# this will be used in the future -- source include/have_innodb.inc
8+
-- source include/have_sequence.inc
9+
10+
--disable_service_connection
11+
12+
--echo #
13+
--echo # MDEV-39492 Parallel Query: Study how to create worker threads
14+
--echo #
15+
16+
connect (killee, localhost, root, , );
17+
18+
--echo # check that kill query on a parallel worker is passed to the manager
19+
20+
connection killee;
21+
let $id= `select connection_id()`;
22+
set session parallel_worker_threads=3;
23+
--send select seq from seq_1_to_2;
24+
connection default;
25+
let $name= "%parallel worker $id";
26+
let $wait_condition= SELECT @kid:=ID from information_schema.processlist where info like $name limit 1;
27+
source include/wait_condition.inc;
28+
let $killID= `select @kid`;
29+
--replace_result $killID ID
30+
eval kill query $killID;
31+
connection killee;
32+
--error 1317
33+
--reap
34+
35+
--echo # reset connection, discard any generated errors
36+
disconnect killee;
37+
connect (killee, localhost, root, , );
38+
39+
--echo # check that kill on a parallel worker is passed to the manager
40+
--echo # doing this last so we don't need to restart default connection
41+
42+
let $id= `select connection_id()`;
43+
set session parallel_worker_threads=3;
44+
--send select seq from seq_1_to_2;
45+
connection default;
46+
let $name= "%parallel worker $id";
47+
let $wait_condition= SELECT @kid:=ID from information_schema.processlist where info like $name limit 1;
48+
source include/wait_condition.inc;
49+
let $killID= `select @kid`;
50+
--replace_result $killID ID
51+
eval kill $killID;
52+
connection killee;
53+
--error 1317,2013
54+
--reap
55+
--echo # generated error die with connection
56+
57+
connection default;
58+
--source include/wait_until_count_sessions.inc

mysql-test/suite/perfschema/r/dml_setup_instruments.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ wait/synch/cond/sql/COND_gtid_ignore_duplicates YES YES
4949
wait/synch/cond/sql/COND_manager YES YES
5050
wait/synch/cond/sql/COND_parallel_entry YES YES
5151
wait/synch/cond/sql/COND_prepare_ordered YES YES
52+
wait/synch/cond/sql/COND_pwt_new_message YES YES
5253
wait/synch/cond/sql/COND_queue_state YES YES
53-
wait/synch/cond/sql/COND_rpl_thread YES YES
5454
select * from performance_schema.setup_instruments
5555
where name='Wait';
5656
select * from performance_schema.setup_instruments

mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2992,6 +2992,16 @@ NUMERIC_BLOCK_SIZE NULL
29922992
ENUM_VALUE_LIST NULL
29932993
READ_ONLY NO
29942994
COMMAND_LINE_ARGUMENT REQUIRED
2995+
VARIABLE_NAME PARALLEL_WORKER_THREADS
2996+
VARIABLE_SCOPE SESSION
2997+
VARIABLE_TYPE BIGINT UNSIGNED
2998+
VARIABLE_COMMENT Number of worker threads available for parallel query execution. 0 means parallel execution is disabled
2999+
NUMERIC_MIN_VALUE 0
3000+
NUMERIC_MAX_VALUE 100
3001+
NUMERIC_BLOCK_SIZE 1
3002+
ENUM_VALUE_LIST NULL
3003+
READ_ONLY NO
3004+
COMMAND_LINE_ARGUMENT REQUIRED
29953005
VARIABLE_NAME PATH
29963006
VARIABLE_SCOPE SESSION
29973007
VARIABLE_TYPE VARCHAR

mysys/my_thread_name.cc

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@
2020
#include <stdio.h>
2121

2222
#ifdef _WIN32
23-
#define MAX_THREAD_NAME 256
2423
typedef HRESULT (*func_SetThreadDescription)(HANDLE,PCWSTR);
25-
#elif defined(__linux__)
26-
#define MAX_THREAD_NAME 16
27-
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
28-
#include <pthread_np.h>
2924
#endif
3025

3126
#if defined(HAVE_PSI_THREAD_INTERFACE) && !defined DBUG_OFF

sql/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ SET (SQL_SOURCE
115115
../sql-common/client_plugin.c
116116
opt_range.cc vector_mhnsw.cc
117117
opt_group_by_cardinality.cc
118+
sql_parallel_workers.cc
118119
opt_rewrite_date_cmp.cc
119120
opt_rewrite_remove_casefold.cc
120121
opt_sargable_left.cc

sql/mysqld.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9911,6 +9911,7 @@ PSI_stage_info stage_starting= { 0, "starting", 0};
99119911
PSI_stage_info stage_waiting_for_flush= { 0, "Waiting for non trans tables to be flushed", 0};
99129912
PSI_stage_info stage_waiting_for_ddl= { 0, "Waiting for DDLs", 0};
99139913
PSI_stage_info stage_waiting_for_reset_master= { 0, "Waiting for a running RESET MASTER to complete", 0};
9914+
PSI_stage_info stage_reading_data_from_parallel_worker= { 0, "Reading data from parallel worker", 0};
99149915

99159916
#ifdef WITH_WSREP
99169917
// Additional Galera thread states
@@ -10003,6 +10004,10 @@ PSI_memory_key key_memory_user_var_entry_value;
1000310004
PSI_memory_key key_memory_String_value;
1000410005
PSI_memory_key key_memory_WSREP;
1000510006
PSI_memory_key key_memory_trace_ddl_info;
10007+
PSI_memory_key key_memory_pwt_queued_event;
10008+
PSI_memory_key key_memory_pwt_error_message;
10009+
PSI_memory_key key_memory_pwt_workers;
10010+
PSI_memory_key key_memory_pwt_db;
1000610011

1000710012
#ifdef HAVE_PSI_INTERFACE
1000810013

@@ -10256,6 +10261,9 @@ static PSI_memory_info all_server_memory[]=
1025610261
{ &key_memory_trace_ddl_info, "TRACE_DDL_INFO", 0}
1025710262
};
1025810263

10264+
10265+
extern void pwt_init_psi_keys(void);
10266+
1025910267
/**
1026010268
Initialise all the performance schema instrumentation points
1026110269
used by the server.
@@ -10342,6 +10350,7 @@ void init_server_psi_keys(void)
1034210350
stmt_info_rpl.m_flags= PSI_FLAG_MUTABLE;
1034310351
mysql_statement_register(category, &stmt_info_rpl, 1);
1034410352
#endif
10353+
pwt_init_psi_keys();
1034510354
}
1034610355

1034710356
#endif /* HAVE_PSI_INTERFACE */

0 commit comments

Comments
 (0)