Skip to content

Commit e6b49f6

Browse files
committed
PS-10071 [DOCS] - update Threadpool to add implementation 8.0
new file: docs/_static/thread-pool-diagram.png modified: docs/threadpool.md
1 parent ab05d24 commit e6b49f6

File tree

2 files changed

+204
-13
lines changed

2 files changed

+204
-13
lines changed

docs/_static/thread-pool-diagram.png

782 KB
Loading

docs/threadpool.md

Lines changed: 204 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,118 @@
11
# Thread pool
22

3-
Thread pooling can improve performance and scalability for MySQL databases. This technique reuses a fixed number of threads to handle multiple client connections and execute statements. It reduces the overhead of creating and destroying threads and avoids the contention and context switching that can occur when there are too many threads.
3+
## Introduction
4+
5+
Thread pooling improves performance and scalability for MySQL-compatible databases by
6+
reusing a fixed number of pre-created threads to manage multiple client
7+
sessions. This design reduces resource overhead, lowers contention, and avoids
8+
context switching bottlenecks during high concurrency.
9+
10+
The default MySQL method creates one thread per client connection. This approach
11+
works efficiently under moderate connection loads. As the number of active
12+
connections increases, especially beyond 20,000, system overhead becomes
13+
significant and throughput decreases.
14+
15+
Percona Server for MySQL includes an integrated thread pool that replaces the
16+
default model. The thread pool manages connections more efficiently by queuing
17+
work and reusing threads, especially in OLTP environments with many short-lived
18+
queries.
19+
20+
## Core concepts and usage examples
21+
22+
### Fixed pool of threads
23+
24+
The server initializes a defined number of threads at startup and reuses them
25+
to process incoming queries.
26+
27+
28+
```ini
29+
[mysqld]
30+
thread_handling = pool-of-threads
31+
```
32+
This setting activates the thread pool model.
33+
34+
### Thread groups
35+
36+
The thread pool organizes threads into groups. Each group contains a listener thread, a set of worker threads, and handles a portion of the client connections.
37+
38+
39+
```ini
40+
[mysqld]
41+
thread_pool_size = 8
42+
```
43+
44+
This configuration spreads work across eight thread groups.
45+
46+
### Priority queues
47+
48+
Each thread group maintains a high-priority queue and a low-priority queue. New queries are added to one of the two based on ticket availability and transaction state. The thread pool always checks the high-priority queue first.
49+
50+
```mysql
51+
mysql> SHOW STATUS LIKE 'Threadpool%';
52+
```
53+
54+
This command displays queue lengths and thread statistics.
55+
56+
### High-priority ticketing
57+
58+
Each connection begins with a set number of high-priority tickets. These tickets allow prioritization for a limited number of queries. One ticket is used every time the thread pool promotes a query to the high-priority queue.
59+
60+
```ini
61+
[mysqld]
62+
thread_pool_high_prio_tickets = 5
63+
```
64+
65+
This assigns five tickets to each new connection.
66+
67+
68+
### High-priority modes
69+
70+
The `thread_pool_high_prio_mode` setting controls how the thread pool schedules queries using tickets.
71+
72+
```mysql
73+
mysql> SET GLOBAL thread_pool_high_prio_mode = 'transactions';
74+
```
75+
76+
This setting limits prioritization to queries within open transactions.
77+
78+
79+
### Adaptive scheduling
80+
81+
The server assigns new connections to thread groups using a round-robin method. This approach balances workload evenly and prevents any group from becoming a bottleneck.
82+
83+
84+
Connection 1 goes to Group 1
85+
86+
Connection 2 goes to Group 2
87+
88+
Connection 3 goes to Group 3
89+
90+
Connection 4 goes to Group 4
91+
92+
Connection 5 returns to Group 1
93+
94+
<img src="../_static/thread-pool-diagram.png" alt="Thread pool diagram" width="250" />
95+
96+
### Configuration and monitoring
97+
98+
Administrators can fine-tune thread pool behavior by adjusting dynamic and static variables.
99+
100+
```ini
101+
[mysqld]
102+
thread_pool_stall_limit = 100
103+
```
104+
105+
This value, in milliseconds, limits how long a task can stall before being redistributed.
106+
107+
```mysql
108+
mysql> SHOW ENGINE THREAD_POOL STATUS;
109+
```
110+
111+
This command returns information about thread usage and group activity.
112+
4113

5-
If you have fewer than 20,000 connections, using the thread pool does not provide significant benefits. It’s better to keep thread pooling disabled and use the default method.
6114

7-
The default method, called one-thread-per-connection, creates a new thread for each client that connects to the MySQL server. This thread manages all queries and responses for that connection until it’s closed. This approach works well for a moderate number of connections, but it can become inefficient as the number of connections increases.
8115

9-
MySQL supports thread pooling through the thread pool plugin, which replaces the default one-thread-per-connection model. When a statement arrives, the thread group either begins executing it immediately or queues it for later execution in a round-robin fashion. The high-priority queue consists of several thread groups, each managing client connections. Each thread group has a listener thread that listens for incoming statements from the connections assigned to the group. The thread pool exposes several system variables that can be used to configure its operation, such as thread_pool_size, thread_pool_algorithm, thread_pool_stall_limit, and others.
10116

11117
The thread pool plugin consists of several thread groups, each of which manages a set of client connections. As connections are established, the thread pool assigns them to thread groups using the round-robin method. This method assigns threads fairly and efficiently. Here's how it works:
12118

@@ -56,23 +162,73 @@ Starting with 8.0.14, Percona Server for MySQL uses the upstream implementation
56162

57163
Implemented in 8.0.12-1: We ported the `Thread Pool` feature from Percona Server for MySQL 5.7.
58164

59-
## Priority connection scheduling
165+
## Thread pool priority queues
166+
167+
The thread pool limits the number of concurrently running queries to improve
168+
performance under high load. Even when concurrency is constrained, the number
169+
of open transactions can remain high. The thread pool manages these connections
170+
using priority queues.
171+
172+
When a new connection starts a transaction, the thread pool evaluates whether
173+
to place it in the high-priority queue. It does so if both of the following
174+
conditions are true:
175+
176+
- The connection has an open transaction.
177+
- The connection has a non-zero number of high-priority tickets, as defined by
178+
the `thread_pool_high_prio_tickets` variable.
60179

61-
The thread pool limits the number of concurrently running queries. The number of open transactions may remain high. Connections with already-started transactions are added to the end of the queue. A high number of open transactions has implications for the currently running queries. The [thread_pool_high_prio_tickets](#thread_pool_high_prio_tickets) variable controls the high-priority queue policy and assigns tickets to each new connection.
180+
Each time the thread pool schedules work, it checks the high-priority queue
181+
first. If that queue is empty, it pulls from the low-priority queue. This
182+
behavior ensures that transactions already in progress receive preferential
183+
treatment.
62184

63-
The thread pool adds the connection to the high-priority queue and decrements the ticket if the connection has the following attributes:
185+
If `thread_pool_high_prio_tickets` is set to `0`, all connections go to the
186+
low-priority queue. If the value is greater than `0`, each new connection
187+
receives that number of high-priority tickets. The thread pool decrements a
188+
ticket each time it prioritizes a connection.
64189

65-
* Has an open transaction
190+
## Configuring `thread_pool_high_prio_mode`
66191

67-
* Has a non-zero number of high-priority tickets
192+
The `thread_pool_high_prio_mode` variable controls how the thread pool assigns
193+
priority to connections, and accepts the following values:
68194

69-
Otherwise, the variable adds the connection to the low-priority queue with the initial value.
195+
* `transactions`: Prioritizes statements that are part of an open transaction
196+
(default).
197+
198+
* `statements`: Prioritizes all statements from a connection with available
199+
high-priority tickets.
200+
201+
* `none`: Disables high-priority scheduling. All connections go to the
202+
low-priority queue.
203+
70204

71-
Each time, the thread pool checks the high-priority queue for the next connection. When the high-priority queue is empty, the thread pool picks connections from the low-priority queue. The default behavior is to put events from already started transactions into the high-priority queue.
72205

73-
If the value equals `0`, all connections are put into the low-priority queue. If the value exceeds zero, each connection could be put into a high-priority queue.
206+
### Static configuration
207+
208+
To set the variable persistently, add the following to your `my.cnf` file:
209+
210+
```ini
211+
[mysqld]
212+
thread_pool_high_prio_mode = transactions
213+
```
214+
215+
### Dynamic configuration
216+
217+
You can also change this setting at runtime without restarting:
218+
219+
```
220+
mysql> SET GLOBAL thread_pool_high_prio_mode = 'transactions';
221+
```
222+
223+
This change takes effect immediately for new connections only. Existing client sessions continue to operate under the previously active mode. To ensure all clients reflect the new behavior, either:
224+
225+
* Restart the server, or
226+
227+
* Have connected clients disconnect and reconnect manually.
228+
229+
This dynamic adjustment enables fine-tuning thread scheduling behavior in production systems without downtime.
230+
74231

75-
The [thread_pool_high_prio_mode](#thread_pool_high_prio_mode) variable prioritizes all statements for a connection or assigns connections to the low-priority queue. To implement this new [thread_pool_high_prio_mode](#thread_pool_high_prio_mode) variable
76232

77233
## Low-priority queue throttling
78234

@@ -123,6 +279,28 @@ This variable can limit the time an idle thread should wait before exiting.
123279

124280
### `thread_pool_high_prio_mode`
125281

282+
---
283+
### `thread_pool_high_prio_mode`
284+
285+
| Option | Description |
286+
| -------------- | --------------------------------------------------------------------------- |
287+
| Command-line: | Yes |
288+
| Config file: | Yes |
289+
| Scope: | Global |
290+
| Dynamic: | Yes |
291+
| Data type: | Enumeration (`transactions`, `statements`, `none`) |
292+
| Default value: | `transactions` |
293+
294+
Controls how the thread pool schedules high-priority work. When set to
295+
`transactions`, only statements within an open transaction are eligible for
296+
high-priority execution. The `statements` option prioritizes all statements
297+
from connections that still have unused high-priority tickets. Setting this
298+
variable to `none` disables high-priority queueing entirely.
299+
300+
Changes take effect immediately for new connections. Existing sessions must
301+
reconnect to adopt the new behavior.
302+
303+
126304
This variable provides more fine-grained control over high-priority scheduling globally or per connection.
127305

128306
The following values are allowed:
@@ -248,3 +426,16 @@ This status variable shows the number of idle threads in the pool.
248426

249427
This status variable shows the number of threads in the pool.
250428

429+
### Limitations and recommendations
430+
431+
| Limitation | Description | Recommendation |
432+
|----------------------------------|-----------------------------------------------------------------------------|------------------------------------------------------------------------------|
433+
| Limited benefit at low loads | Thread pool offers marginal gains below ~512–1000 connections. | Use default threading for small workloads. Evaluate before enabling. |
434+
| No effect on existing sessions | Dynamic changes only affect new connections. | Prompt clients to reconnect or plan for a rolling restart. |
435+
| Long-running query contention | Extended queries block worker threads, reducing throughput. | Isolate long-running queries to separate servers or use query timeouts. |
436+
| Thread starvation risk | High-priority queues may crowd out low-priority connections. | Monitor queue activity; balance ticket settings and connection patterns. |
437+
| Complexity in tuning | Poor variable configuration can degrade performance. | Test settings in staging; tune iteratively based on observed behavior. |
438+
| Limited monitoring | Native tools offer minimal queue and saturation visibility. | Integrate with monitoring systems (e.g., PMM, Prometheus) for better insight. |
439+
| Static design | Not a plugin; cannot be toggled dynamically. | Decide at deployment; changes require a configuration update and restart. |
440+
441+

0 commit comments

Comments
 (0)