Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.

Commit 3d88554

Browse files
lthHerman Lee
authored andcommitted
Support multiple admission control queues per-shard
Summary: This adds multiple queues within a shard so that we can separate out different workloads on a shard. This is controlled by a session variable admission_control_queue, which can be set to a number from 0-9. This can also be set via a connection/query attribute with the key as "admission_control_queue". In order of precedence, we first check query attributes, then connection attributes, then session variable. By default, the session variable contains value 0, so that is the default queue. Initially, I was planning to have named queues. However, it turns out that 5.6 does not support strings as session variables, so I used integers instead. This might be something we could do in 8.0 instead. To control priority, we assign weights to each of the queues and this is controlled by a session variable admission_control_weights which is a comma separated list of weights. The nth number in the list specifies the weight of the nth queue. Not all 10 weights have to be specified, in which case they get a default weight of 1. The intuition behind weight is such that roughly (weight of queue) / (sum of all weights) of the running pool is allocated for that queue. A new information schema table `admission_control_queue` was added to track stats on a per-queue basis. This also fixes an existing bug where depending on the scheduling, two thread exiting admission control can signal the same thread at the front of the queue because it hasn't had the opportunity to dequeue itself yet. This means that we're leaking slots, since we rely on threads exiting admission control always signal a new thread. This is done by having the exiting thread do the dequeue instead of waiting for the owning thread to do it. Reference patch: 4138f36 413f6d6 c2855ab Differential Revision: D22983748
1 parent 035d22b commit 3d88554

28 files changed

Lines changed: 1131 additions & 84 deletions

‎client/mysqltest.cc‎

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,9 @@ enum enum_commands {
543543
Q_QUERY_ATTRS_ADD,
544544
Q_QUERY_ATTRS_DELETE,
545545
Q_QUERY_ATTRS_RESET,
546+
Q_CONN_ATTRS_ADD,
547+
Q_CONN_ATTRS_DELETE,
548+
Q_CONN_ATTRS_RESET,
546549
Q_ENABLE_CLIENT_INTERACTIVE,
547550
Q_DUMP_TIMED_OUT_CONNECTION_SOCKET_BUFFER,
548551
Q_UNKNOWN, /* Unknown command. */
@@ -581,7 +584,8 @@ const char *command_names[] = {
581584
"send_shutdown", "shutdown_server", "result_format", "move_file",
582585
"remove_files_wildcard", "copy_files_wildcard", "send_eval", "output",
583586
"reset_connection", "query_attributes", "query_attrs_add",
584-
"query_attrs_delete", "query_attrs_reset", "enable_client_interactive",
587+
"query_attrs_delete", "query_attrs_reset", "conn_attrs_add",
588+
"conn_attrs_delete", "conn_attrs_reset", "enable_client_interactive",
585589
"dump_timed_out_connection_socket_buffer",
586590

587591
nullptr};
@@ -7464,6 +7468,44 @@ void do_query_attrs_delete(struct st_command *command) {
74647468
DBUG_VOID_RETURN;
74657469
}
74667470

7471+
void do_conn_attrs_add(struct st_command *command) {
7472+
int error;
7473+
static DYNAMIC_STRING key;
7474+
static DYNAMIC_STRING value;
7475+
const struct command_arg conn_attrs_args[] = {
7476+
{"key", ARG_STRING, true, &key, "Key for connection attributes"},
7477+
{"value", ARG_STRING, true, &value, "Value for connection attributes"}};
7478+
DBUG_ENTER("do_conn_attrs_add");
7479+
7480+
check_command_args(command, command->first_argument, conn_attrs_args,
7481+
sizeof(conn_attrs_args) / sizeof(struct command_arg), ' ');
7482+
7483+
error = mysql_options4(&cur_con->mysql, MYSQL_OPT_CONNECT_ATTR_ADD, key.str,
7484+
value.str);
7485+
handle_command_error(command, error);
7486+
dynstr_free(&key);
7487+
dynstr_free(&value);
7488+
DBUG_VOID_RETURN;
7489+
}
7490+
7491+
void do_conn_attrs_delete(struct st_command *command) {
7492+
int error;
7493+
static DYNAMIC_STRING key;
7494+
const struct command_arg conn_attrs_args[] = {
7495+
{"key", ARG_STRING, true, &key, "Key for connection attributes"},
7496+
};
7497+
DBUG_ENTER("do_conn_attrs_delete");
7498+
7499+
check_command_args(command, command->first_argument, conn_attrs_args,
7500+
sizeof(conn_attrs_args) / sizeof(struct command_arg), ' ');
7501+
7502+
error =
7503+
mysql_options(&cur_con->mysql, MYSQL_OPT_CONNECT_ATTR_DELETE, key.str);
7504+
handle_command_error(command, error);
7505+
dynstr_free(&key);
7506+
DBUG_VOID_RETURN;
7507+
}
7508+
74677509
bool match_delimiter(int c, const char *delim, size_t length) {
74687510
uint i;
74697511
char tmp[MAX_DELIMITER_LENGTH];
@@ -10463,6 +10505,15 @@ int main(int argc, char **argv) {
1046310505
case Q_QUERY_ATTRS_RESET:
1046410506
mysql_options(&cur_con->mysql, MYSQL_OPT_QUERY_ATTR_RESET, 0);
1046510507
break;
10508+
case Q_CONN_ATTRS_ADD:
10509+
do_conn_attrs_add(command);
10510+
break;
10511+
case Q_CONN_ATTRS_DELETE:
10512+
do_conn_attrs_delete(command);
10513+
break;
10514+
case Q_CONN_ATTRS_RESET:
10515+
mysql_options(&cur_con->mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
10516+
break;
1046610517

1046710518
case Q_ENABLE_CLIENT_INTERACTIVE:
1046810519
enable_client_interactive = true;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
create database test_db;
2+
create user test_user@localhost identified with 'mysql_native_password' BY '';
3+
grant all on test_db.* to test_user@localhost;
4+
grant all on test.* to test_user@localhost;
5+
use test_db;
6+
create table t1 (a int primary key, b int) engine=InnoDB;
7+
drop database test_db;
8+
drop user test_user@localhost;
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
create database test_db;
2+
create user test_user@localhost;
3+
grant all on test_db.* to test_user@localhost;
4+
grant all on test.* to test_user@localhost;
5+
use test_db;
6+
set @save_max_running_queries = @@max_running_queries;
7+
set @save_max_waiting_queries = @@max_waiting_queries;
8+
set @save_admission_control_weights = @@admission_control_weights;
9+
set global max_running_queries = 5;
10+
set global max_waiting_queries = 2000;
11+
#
12+
# Test admission_control_queue variable works
13+
#
14+
select GET_LOCK('lock1', -1);
15+
GET_LOCK('lock1', -1)
16+
1
17+
select GET_LOCK('lock1', -1);
18+
select * from information_schema.admission_control_queue;
19+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
20+
test_db 0 0 1 0 0
21+
select RELEASE_LOCK('lock1');
22+
RELEASE_LOCK('lock1')
23+
1
24+
select * from information_schema.admission_control_queue;
25+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
26+
GET_LOCK('lock1', -1)
27+
1
28+
#
29+
# Test connection attribute overrides
30+
#
31+
select GET_LOCK('lock1', -1);
32+
GET_LOCK('lock1', -1)
33+
1
34+
use test_db;
35+
select GET_LOCK('lock1', -1);
36+
select * from information_schema.admission_control_queue;
37+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
38+
test_db 1 0 1 0 0
39+
select RELEASE_LOCK('lock1');
40+
RELEASE_LOCK('lock1')
41+
1
42+
select * from information_schema.admission_control_queue;
43+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
44+
GET_LOCK('lock1', -1)
45+
1
46+
#
47+
# Test connection and query attribute overrides
48+
#
49+
select GET_LOCK('lock1', -1);
50+
GET_LOCK('lock1', -1)
51+
1
52+
use test_db;
53+
select GET_LOCK('lock1', -1);
54+
select * from information_schema.admission_control_queue;
55+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
56+
test_db 2 0 1 0 0
57+
select RELEASE_LOCK('lock1');
58+
RELEASE_LOCK('lock1')
59+
1
60+
select * from information_schema.admission_control_queue;
61+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
62+
GET_LOCK('lock1', -1)
63+
1
64+
#
65+
# Test weights (2,3) on queue 1,2
66+
#
67+
set global admission_control_weights = "1,2,3";
68+
select GET_LOCK('lock1', -1);
69+
GET_LOCK('lock1', -1)
70+
1
71+
select GET_LOCK('lock2', -1);
72+
GET_LOCK('lock2', -1)
73+
1
74+
# Set up 5 running queries
75+
select GET_LOCK('lock1', -1);
76+
select GET_LOCK('lock1', -1);
77+
select GET_LOCK('lock1', -1);
78+
select GET_LOCK('lock1', -1);
79+
select GET_LOCK('lock1', -1);
80+
select * from information_schema.admission_control_queue;
81+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
82+
test_db 0 0 5 0 0
83+
# Set up 5 waiting queries each for queue 1 and 2
84+
select GET_LOCK('lock2', -1);
85+
select GET_LOCK('lock2', -1);
86+
select GET_LOCK('lock2', -1);
87+
select GET_LOCK('lock2', -1);
88+
select GET_LOCK('lock2', -1);
89+
select GET_LOCK('lock2', -1);
90+
select GET_LOCK('lock2', -1);
91+
select GET_LOCK('lock2', -1);
92+
select GET_LOCK('lock2', -1);
93+
select GET_LOCK('lock2', -1);
94+
# Check that 10 queries are waiting
95+
select * from information_schema.admission_control_queue;
96+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
97+
test_db 0 0 5 0 0
98+
test_db 1 5 0 0 0
99+
test_db 2 5 0 0 0
100+
select RELEASE_LOCK('lock1');
101+
RELEASE_LOCK('lock1')
102+
1
103+
# Check that 5 of the 10 queries are now scheduled with 2-3 ratio.
104+
select * from information_schema.admission_control_queue;
105+
SCHEMA_NAME QUEUE_ID WAITING_QUERIES RUNNING_QUERIES ABORTED_QUERIES TIMEOUT_QUERIES
106+
test_db 1 3 2 0 0
107+
test_db 2 2 3 0 0
108+
# Cleanup
109+
select RELEASE_LOCK('lock2');
110+
RELEASE_LOCK('lock2')
111+
1
112+
set global max_running_queries = @save_max_running_queries;
113+
set global max_waiting_queries = @save_max_waiting_queries;
114+
set global admission_control_weights = @save_admission_control_weights;
115+
drop database test_db;
116+
drop user test_user@localhost;

‎mysql-test/r/dd_is_compatibility_ci.result‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ WHERE table_schema LIKE 'information_schema'
154154
SELECT * FROM v1;
155155
table_name
156156
ADMINISTRABLE_ROLE_AUTHORIZATIONS
157+
ADMISSION_CONTROL_QUEUE
157158
APPLICABLE_ROLES
158159
AUTHINFO
159160
CHARACTER_SETS

‎mysql-test/r/dd_is_compatibility_cs.result‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ WHERE table_schema LIKE 'information_schema'
154154
SELECT * FROM v1;
155155
table_name
156156
ADMINISTRABLE_ROLE_AUTHORIZATIONS
157+
ADMISSION_CONTROL_QUEUE
157158
APPLICABLE_ROLES
158159
AUTHINFO
159160
CHARACTER_SETS

‎mysql-test/r/information_schema_ci.result‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ table_name COLLATE utf8_general_ci not like 'innodb_%';
6262
select * from v1;
6363
c
6464
ADMINISTRABLE_ROLE_AUTHORIZATIONS
65+
ADMISSION_CONTROL_QUEUE
6566
APPLICABLE_ROLES
6667
AUTHINFO
6768
CHARACTER_SETS
@@ -643,7 +644,7 @@ where table_schema='information_schema'
643644
order by table_name collate utf8_general_ci limit 2;
644645
TABLE_NAME TABLE_TYPE ENGINE
645646
ADMINISTRABLE_ROLE_AUTHORIZATIONS SYSTEM VIEW NULL
646-
APPLICABLE_ROLES SYSTEM VIEW NULL
647+
ADMISSION_CONTROL_QUEUE SYSTEM VIEW NULL
647648
show tables from information_schema like "T%";
648649
Tables_in_information_schema (T%)
649650
TABLES
@@ -907,7 +908,7 @@ AND table_name COLLATE utf8_general_ci not like 'innodb_%'
907908
AND table_name COLLATE utf8_general_ci not like 'rocksdb_%'
908909
GROUP BY TABLE_SCHEMA;
909910
TABLE_SCHEMA count(*)
910-
information_schema 53
911+
information_schema 54
911912
mysql 35
912913
create table t1 (i int, j int);
913914
create trigger trg1 before insert on t1 for each row
@@ -1360,6 +1361,7 @@ and t.table_name not like 'INNODB_%'
13601361
group by t.table_name order by num1, t.table_name COLLATE utf8_general_ci;
13611362
TABLE_NAME group_concat(t.table_schema, '.', t.table_name) num1
13621363
ADMINISTRABLE_ROLE_AUTHORIZATIONS information_schema.ADMINISTRABLE_ROLE_AUTHORIZATIONS 1
1364+
ADMISSION_CONTROL_QUEUE information_schema.ADMISSION_CONTROL_QUEUE 1
13631365
APPLICABLE_ROLES information_schema.APPLICABLE_ROLES 1
13641366
AUTHINFO information_schema.AUTHINFO 1
13651367
CHARACTER_SETS information_schema.CHARACTER_SETS 1
@@ -2494,6 +2496,7 @@ AND t.table_name NOT LIKE 'ndb%'
24942496
c1.column_name COLLATE utf8_general_ci;
24952497
TABLE_NAME COLUMN_NAME
24962498
ADMINISTRABLE_ROLE_AUTHORIZATIONS USER
2499+
ADMISSION_CONTROL_QUEUE SCHEMA_NAME
24972500
APPLICABLE_ROLES USER
24982501
AUTHINFO ID
24992502
CHARACTER_SETS CHARACTER_SET_NAME
@@ -2567,6 +2570,7 @@ AND t.table_name NOT LIKE 'ndb%'
25672570
c1.column_name COLLATE utf8_general_ci;
25682571
TABLE_NAME COLUMN_NAME
25692572
ADMINISTRABLE_ROLE_AUTHORIZATIONS USER
2573+
ADMISSION_CONTROL_QUEUE SCHEMA_NAME
25702574
APPLICABLE_ROLES USER
25712575
AUTHINFO ID
25722576
CHARACTER_SETS CHARACTER_SET_NAME

‎mysql-test/r/information_schema_cs.result‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ table_name COLLATE utf8_general_ci not like 'innodb_%';
6262
select * from v1;
6363
c
6464
ADMINISTRABLE_ROLE_AUTHORIZATIONS
65+
ADMISSION_CONTROL_QUEUE
6566
APPLICABLE_ROLES
6667
AUTHINFO
6768
CHARACTER_SETS
@@ -643,7 +644,7 @@ where table_schema='information_schema'
643644
order by table_name collate utf8_general_ci limit 2;
644645
TABLE_NAME TABLE_TYPE ENGINE
645646
ADMINISTRABLE_ROLE_AUTHORIZATIONS SYSTEM VIEW NULL
646-
APPLICABLE_ROLES SYSTEM VIEW NULL
647+
ADMISSION_CONTROL_QUEUE SYSTEM VIEW NULL
647648
show tables from information_schema like "T%";
648649
Tables_in_information_schema (T%)
649650
TABLES
@@ -907,7 +908,7 @@ AND table_name COLLATE utf8_general_ci not like 'innodb_%'
907908
AND table_name COLLATE utf8_general_ci not like 'rocksdb_%'
908909
GROUP BY TABLE_SCHEMA;
909910
TABLE_SCHEMA count(*)
910-
information_schema 53
911+
information_schema 54
911912
mysql 35
912913
create table t1 (i int, j int);
913914
create trigger trg1 before insert on t1 for each row
@@ -1360,6 +1361,7 @@ and t.table_name not like 'INNODB_%'
13601361
group by t.table_name order by num1, t.table_name COLLATE utf8_general_ci;
13611362
TABLE_NAME group_concat(t.table_schema, '.', t.table_name) num1
13621363
ADMINISTRABLE_ROLE_AUTHORIZATIONS information_schema.ADMINISTRABLE_ROLE_AUTHORIZATIONS 1
1364+
ADMISSION_CONTROL_QUEUE information_schema.ADMISSION_CONTROL_QUEUE 1
13631365
APPLICABLE_ROLES information_schema.APPLICABLE_ROLES 1
13641366
AUTHINFO information_schema.AUTHINFO 1
13651367
CHARACTER_SETS information_schema.CHARACTER_SETS 1
@@ -2494,6 +2496,7 @@ AND t.table_name NOT LIKE 'ndb%'
24942496
c1.column_name COLLATE utf8_general_ci;
24952497
TABLE_NAME COLUMN_NAME
24962498
ADMINISTRABLE_ROLE_AUTHORIZATIONS USER
2499+
ADMISSION_CONTROL_QUEUE SCHEMA_NAME
24972500
APPLICABLE_ROLES USER
24982501
AUTHINFO ID
24992502
CHARACTER_SETS CHARACTER_SET_NAME
@@ -2567,6 +2570,7 @@ AND t.table_name NOT LIKE 'ndb%'
25672570
c1.column_name COLLATE utf8_general_ci;
25682571
TABLE_NAME COLUMN_NAME
25692572
ADMINISTRABLE_ROLE_AUTHORIZATIONS USER
2573+
ADMISSION_CONTROL_QUEUE SCHEMA_NAME
25702574
APPLICABLE_ROLES USER
25712575
AUTHINFO ID
25722576
CHARACTER_SETS CHARACTER_SET_NAME

‎mysql-test/r/mysqld--help-notwin.result‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,19 @@ The following options may be given as the first argument:
4848
The legal values are: ALTER, BEGIN, COMMIT, CREATE,
4949
DELETE, DROP, INSERT, LOAD, SELECT, SET, REPLACE,
5050
ROLLBACK, TRUNCATE, UPDATE, SHOW and empty string
51+
--admission-control-queue[=#]
52+
Determines which queue this request goes to during
53+
admission control. Allowed values are 0-9, since only 10
54+
queues are available.
5155
--admission-control-queue-timeout[=#]
5256
Number of milliseconds to wait on admission control
5357
queue. 0 means immediate timeout. -1 means infinite
5458
timeout.
59+
--admission-control-weights[=name]
60+
Determines the weight of each queue as a comma-separated
61+
list of integers, where the nth number is the nth queue's
62+
weight. The queue weight to total weight ratio determines
63+
what fraction of the running pool a queue can use.
5564
--allow-noncurrent-db-rw=name
5665
Switch to allow/deny reads and writes to a table not in
5766
the current database.
@@ -2512,7 +2521,9 @@ admin-ssl-key (No default value)
25122521
admin-tls-ciphersuites (No default value)
25132522
admission-control-by-trx FALSE
25142523
admission-control-filter
2524+
admission-control-queue 0
25152525
admission-control-queue-timeout -1
2526+
admission-control-weights (No default value)
25162527
allow-noncurrent-db-rw ON
25172528
allow-suspicious-udfs FALSE
25182529
apply-log (No default value)

‎mysql-test/r/mysqlshow_ci.result‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Database: information_schema
8080
| Tables |
8181
+---------------------------------------+
8282
| ADMINISTRABLE_ROLE_AUTHORIZATIONS |
83+
| ADMISSION_CONTROL_QUEUE |
8384
| APPLICABLE_ROLES |
8485
| AUTHINFO |
8586
| CHARACTER_SETS |
@@ -184,6 +185,7 @@ Database: INFORMATION_SCHEMA
184185
| Tables |
185186
+---------------------------------------+
186187
| ADMINISTRABLE_ROLE_AUTHORIZATIONS |
188+
| ADMISSION_CONTROL_QUEUE |
187189
| APPLICABLE_ROLES |
188190
| AUTHINFO |
189191
| CHARACTER_SETS |

‎mysql-test/r/mysqlshow_cs.result‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Database: information_schema
8080
| Tables |
8181
+---------------------------------------+
8282
| ADMINISTRABLE_ROLE_AUTHORIZATIONS |
83+
| ADMISSION_CONTROL_QUEUE |
8384
| APPLICABLE_ROLES |
8485
| AUTHINFO |
8586
| CHARACTER_SETS |
@@ -185,6 +186,7 @@ Database: INFORMATION_SCHEMA
185186
| Tables |
186187
+---------------------------------------+
187188
| ADMINISTRABLE_ROLE_AUTHORIZATIONS |
189+
| ADMISSION_CONTROL_QUEUE |
188190
| APPLICABLE_ROLES |
189191
| AUTHINFO |
190192
| CHARACTER_SETS |

0 commit comments

Comments
 (0)