Skip to content

Commit e956bb2

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 e956bb2

File tree

2 files changed

+126
-9
lines changed

2 files changed

+126
-9
lines changed

docs/_static/thread-pool-diagram.png

782 KB
Loading

docs/threadpool.md

Lines changed: 126 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,38 @@ The default method, called one-thread-per-connection, creates a new thread for e
88

99
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.
1010

11+
12+
## How thread pool works
13+
14+
### Simplified Overview of the Thread Pool
15+
16+
A thread pool allows MySQL to manage many client connections with greater
17+
efficiency. Rather than launching a new thread for each connection, which is a resource-intensive approach, the server initializes a fixed set of reusable threads in advance.
18+
19+
Here's the basic process:
20+
21+
* When a client connects, the server assigns the connection to a specific thread
22+
group.
23+
24+
* Each thread group includes a listener responsible for detecting new queries.
25+
26+
* Queries from clients enter one of two queues: high-priority or low-priority.
27+
28+
* Worker threads within the group retrieve queries from these queues for
29+
execution.
30+
31+
* Queries associated with active transactions and unused high-priority tickets
32+
are directed to the high-priority queue.
33+
34+
* All other queries enter the low-priority queue and wait for an available
35+
worker.
36+
37+
This approach avoids the overhead associated with excessive thread creation and
38+
maintains server responsiveness, even during periods of high connection volume.
39+
40+
41+
<img src="../_static/thread-pool-diagram.png" alt="Thread pool diagram" width="250" />
42+
1143
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:
1244

1345
1. The thread pool starts with a set number of thread groups.
@@ -56,23 +88,73 @@ Starting with 8.0.14, Percona Server for MySQL uses the upstream implementation
5688

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

59-
## Priority connection scheduling
91+
## Thread pool priority queues
92+
93+
The thread pool limits the number of concurrently running queries to improve
94+
performance under high load. Even when concurrency is constrained, the number
95+
of open transactions can remain high. The thread pool manages these connections
96+
using priority queues.
6097

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.
98+
When a new connection starts a transaction, the thread pool evaluates whether
99+
to place it in the high-priority queue. It does so if both of the following
100+
conditions are true:
62101

63-
The thread pool adds the connection to the high-priority queue and decrements the ticket if the connection has the following attributes:
102+
- The connection has an open transaction.
103+
- The connection has a non-zero number of high-priority tickets, as defined by
104+
the `thread_pool_high_prio_tickets` variable.
64105

65-
* Has an open transaction
106+
Each time the thread pool schedules work, it checks the high-priority queue
107+
first. If that queue is empty, it pulls from the low-priority queue. This
108+
behavior ensures that transactions already in progress receive preferential
109+
treatment.
66110

67-
* Has a non-zero number of high-priority tickets
111+
If `thread_pool_high_prio_tickets` is set to `0`, all connections go to the
112+
low-priority queue. If the value is greater than `0`, each new connection
113+
receives that number of high-priority tickets. The thread pool decrements a
114+
ticket each time it prioritizes a connection.
68115

69-
Otherwise, the variable adds the connection to the low-priority queue with the initial value.
116+
## Configuring `thread_pool_high_prio_mode`
70117

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.
118+
The `thread_pool_high_prio_mode` variable controls how the thread pool assigns
119+
priority to connections, and accepts the following values:
120+
121+
* `transactions`: Prioritizes statements that are part of an open transaction
122+
(default).
123+
124+
* `statements`: Prioritizes all statements from a connection with available
125+
high-priority tickets.
126+
127+
* `none`: Disables high-priority scheduling. All connections go to the
128+
low-priority queue.
129+
130+
131+
132+
### Static configuration
133+
134+
To set the variable persistently, add the following to your `my.cnf` file:
135+
136+
```ini
137+
[mysqld]
138+
thread_pool_high_prio_mode = transactions
139+
```
140+
141+
### Dynamic configuration
142+
143+
You can also change this setting at runtime without restarting:
144+
145+
```
146+
mysql> SET GLOBAL thread_pool_high_prio_mode = 'transactions';
147+
```
148+
149+
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:
150+
151+
* Restart the server, or
152+
153+
* Have connected clients disconnect and reconnect manually.
154+
155+
This dynamic adjustment enables fine-tuning thread scheduling behavior in production systems without downtime.
72156

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.
74157

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
76158

77159
## Low-priority queue throttling
78160

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

124206
### `thread_pool_high_prio_mode`
125207

208+
---
209+
### `thread_pool_high_prio_mode`
210+
211+
| Option | Description |
212+
| -------------- | --------------------------------------------------------------------------- |
213+
| Command-line: | Yes |
214+
| Config file: | Yes |
215+
| Scope: | Global |
216+
| Dynamic: | Yes |
217+
| Data type: | Enumeration (`transactions`, `statements`, `none`) |
218+
| Default value: | `transactions` |
219+
220+
Controls how the thread pool schedules high-priority work. When set to
221+
`transactions`, only statements within an open transaction are eligible for
222+
high-priority execution. The `statements` option prioritizes all statements
223+
from connections that still have unused high-priority tickets. Setting this
224+
variable to `none` disables high-priority queueing entirely.
225+
226+
Changes take effect immediately for new connections. Existing sessions must
227+
reconnect to adopt the new behavior.
228+
229+
126230
This variable provides more fine-grained control over high-priority scheduling globally or per connection.
127231

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

249353
This status variable shows the number of threads in the pool.
250354

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

0 commit comments

Comments
 (0)