Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FB8-59: Database admission control #969

Closed
Closed
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
115 changes: 115 additions & 0 deletions mysql-test/r/admission_control.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
create database test_db;
create user 'test_user'@'localhost';
grant all on test_db.* to 'test_user'@'localhost';
grant all on test.* to 'test_user'@'localhost';
use test_db;
set @start_max_running_queries= @@global.max_running_queries;
set @start_max_waiting_queries= @@global.max_waiting_queries;
set @@global.max_running_queries=10;
set @@global.max_waiting_queries=5;
create table t1(a int) engine=InnoDB;
lock table t1 write;
Threads waiting for admission will have appropriate state set in processlist.
Super user is exempted from admission control checks.
select * from t1;
a
set @@global.admission_control_filter = 'USE';
select @@global.admission_control_filter;
@@global.admission_control_filter
USE
Maximum waiting queries reached. So this would hit an error.
use test_db;
select * from t1||||
ERROR HY000: Maximum waiting queries 5 reached for database `test_db`
Maximum waiting queries reached. So this would hit an error.
use test;
create table t1_test(aaa int);
insert into t1_test values (1);
select aaa from t1_test;
drop table t1_test;
use test_db;
select * from t1||||
aaa
1
ERROR HY000: Maximum waiting queries 5 reached for database `test_db`
use test_db;
select * from t1;
ERROR HY000: Maximum waiting queries 5 reached for database `test_db`
set @@global.admission_control_filter = '';
select @@global.admission_control_filter;
@@global.admission_control_filter

Check status variables
aborted_queries = 3
running_queries = 10
waiting_queries = 5
Filled up queues on one db doesn't affect queries on other db.
use test;
set @@global.max_waiting_queries=6;
Kill a thread that is waiting for admission.
select count(*) from t1;
kill ID;
use test_db;
unlock tables;
Verify the waiting queries received wakeup signal.
select count(*) from t1;
count(*)
15
set @save_admission_control_by_trx = @@global.admission_control_by_trx;
select @save_admission_control_by_trx;
@save_admission_control_by_trx
0
set @@global.max_running_queries=5;
set @@global.max_waiting_queries=10;
# By default, open transaction has no effect on running queries
select count(*) from t1;
count(*)
15
# Test: open transactions will take slots in running queries,
# and will not be blocked
set @@global.admission_control_filter = 'BEGIN,COMMIT,ROLLBACK';
select @@global.admission_control_filter;
@@global.admission_control_filter
BEGIN,COMMIT,ROLLBACK
set @@global.admission_control_by_trx = true;
SELECT @@global.admission_control_by_trx;
@@global.admission_control_by_trx
1
Open transaction is able to continue running queries
connection con_max_wait;
New queries will be rejected (waiting queue is full)
select * from t1;
ERROR HY000: Maximum waiting queries 10 reached for database `test_db`
New transactions will be rejected (waiting queue is full)
begin;
select * from t1;
ERROR HY000: Maximum waiting queries 10 reached for database `test_db`
aborted_queries will increase by 2
Committing a transaction will free up the running query slots
The waiting queries will be unblocked
Check status variables
include/assert.inc [DB Admission control waiting queries should be zero]
include/assert.inc [DB Admission control running queries should be zero]
include/assert.inc [DB Admission control aborted queries should be five]
set @@global.admission_control_by_trx = @save_admission_control_by_trx;
select @@global.admission_control_by_trx;
@@global.admission_control_by_trx
0
set @@global.admission_control_filter = '';
select @@global.admission_control_filter;
@@global.admission_control_filter

# End of open transaction test
reset global.max_running_queries and global.max_waiting_queries
set @@global.max_running_queries=10;
set @@global.max_waiting_queries=5;
Run parallel load and drop the database.
set @@global.max_waiting_queries=0;
Cleanup.
Verify there are no waiting threads.
select count(*) from information_schema.processlist where state='waiting for admission';
count(*)
0
set @@global.max_running_queries=@start_max_running_queries;
set @@global.max_waiting_queries=@start_max_waiting_queries;
drop user test_user@localhost;
93 changes: 93 additions & 0 deletions mysql-test/r/admission_control_hang.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
create database test_db;
create user test_user@localhost;
grant all on test_db.* to test_user@localhost;
set @start_max_running_queries = @@global.max_running_queries;
set @@global.max_running_queries = 4;
set @start_innodb_lock_wait_timeout = @@global.innodb_lock_wait_timeout;
set @@global.innodb_lock_wait_timeout = 10000;
set @start_admission_control_filter = @@global.admission_control_filter;
set @@global.admission_control_filter = 'COMMIT';
create table t1 (a int) engine=innodb;
insert into t1 values(1);
begin;
update t1 set a=2 where a=1;
update t1 set a=2 where a=1;
update t1 set a=2 where a=1;
update t1 set a=2 where a=1;
update t1 set a=2 where a=1;
set @@global.admission_control_filter = 'USE';
select @@global.admission_control_filter;
@@global.admission_control_filter
USE
use test;
use test_db;
set @@global.admission_control_filter = 'ALTER,BEGIN,COMMIT,CREATE,DELETE,DROP,INSERT,LOAD,SELECT,SET,REPLACE,TRUNCATE,UPDATE,SHOW,ROLLBACK';
select @@global.admission_control_filter;
@@global.admission_control_filter
ALTER,BEGIN,COMMIT,CREATE,DELETE,DROP,INSERT,LOAD,SELECT,SET,REPLACE,ROLLBACK,TRUNCATE,UPDATE,SHOW
create table t2(a int) engine=innodb;
begin;
insert into t2 values(1);
update t2 set a=2 where a=1;
commit;
SHOW TABLES LIKE 't2';
Tables_in_test_db (t2)
t2
begin;
alter table t2 rename t3;
select * from t3;
a
2
delete from t3;
set @val = 1;
truncate table t3;
rollback;
drop table t3;
set @save_admission_control_by_trx = @@global.admission_control_by_trx;
select @save_admission_control_by_trx;
@save_admission_control_by_trx
0
# Turn on admission_control_by_trx
set @@global.admission_control_by_trx = true;
SELECT @@global.admission_control_by_trx;
@@global.admission_control_by_trx
1
create table t2(a int) engine=innodb;
begin;
insert into t2 values(1);
update t2 set a=2 where a=1;
commit;
SHOW TABLES LIKE 't2';
Tables_in_test_db (t2)
t2
begin;
alter table t2 rename t3;
select * from t3;
a
2
delete from t3;
set @val = 1;
truncate table t3;
rollback;
drop table t3;
set @@global.admission_control_filter = default;
select @@global.admission_control_filter;
@@global.admission_control_filter

select count(*) from t1;
count(*)
1
set @@global.admission_control_by_trx = @save_admission_control_by_trx;
select @@global.admission_control_by_trx;
@@global.admission_control_by_trx
0
set @@global.admission_control_filter = 'COMMIT';
select @@global.admission_control_filter;
@@global.admission_control_filter
COMMIT
commit;
set @@global.max_running_queries = @start_max_running_queries;
set @@global.innodb_lock_wait_timeout = @start_innodb_lock_wait_timeout;
set @@global.admission_control_filter = @start_admission_control_filter;
drop database test_db;
drop user test_user@localhost;
8 changes: 8 additions & 0 deletions mysql-test/r/admission_control_multi_query.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
create database test_db;
create user test_user@localhost;
grant all on test_db.* to test_user@localhost;
grant all on test.* to test_user@localhost;
use test_db;
create table t1 (a int primary key, b int) engine=InnoDB;
drop database test_db;
drop user test_user@localhost;
5 changes: 5 additions & 0 deletions mysql-test/r/admission_control_stress.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Test setup.
Generate load. Toggle max_running_queries and randomly kill a query.
Cleanup
set global max_connections = @start_max_connections;
set global max_running_queries = @start_max_running_queries;
3 changes: 3 additions & 0 deletions mysql-test/r/information_schema_cs.result
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,9 @@ mysql user 0 0
show status where variable_name like "%database%";
Variable_name Value
Com_show_databases 3
Database_admission_control_aborted_queries 0
Database_admission_control_running_queries 0
Database_admission_control_waiting_queries 0
show variables where variable_name like "skip_show_databas";
Variable_name Value
show global status like "Threads_running";
Expand Down
17 changes: 17 additions & 0 deletions mysql-test/r/mysqld--help-notwin.result
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ The following options may be given as the first argument:
values *, ::, 0.0.0.0 are not allowed.
--admin-port=# Port number to use for service connection, built-in
default (33062)
--admission-control-by-trx
Allow open transactions to go through admission control
--admission-control-filter=name
Commands that are skipped in admission control checks.
The legal values are: ALTER, BEGIN, COMMIT, CREATE,
DELETE, DROP, INSERT, LOAD, SELECT, SET, REPLACE,
ROLLBACK, TRUNCATE, UPDATE, SHOW and empty string
--allow-noncurrent-db-rw=name
Switch to allow/deny reads and writes to a table not in
the current database.
Expand Down Expand Up @@ -622,6 +629,9 @@ The following options may be given as the first argument:
If non-zero: relay log will be rotated automatically when
the size exceeds this value; if zero: when the size
exceeds max_binlog_size
--max-running-queries=#
The maximum number of running queries allowed for a
database. If this value is 0, no such limits are applied.
--max-seeks-for-key=#
Limit assumed max number of seeks when looking up rows
based on a key
Expand All @@ -633,6 +643,9 @@ The following options may be given as the first argument:
--max-user-connections=#
The maximum number of active connections for a single
user (0 = no limit)
--max-waiting-queries=#
The maximum number of waiting queries allowed for a
database.If this value is 0, no such limits are applied.
--max-write-lock-count=#
After this many write locks, allow some read locks to run
in between
Expand Down Expand Up @@ -1414,6 +1427,8 @@ abort-slave-event-count 0
activate-all-roles-on-login FALSE
admin-address (No default value)
admin-port 33062
admission-control-by-trx FALSE
admission-control-filter
allow-noncurrent-db-rw ON
allow-suspicious-udfs FALSE
auto-increment-increment 1
Expand Down Expand Up @@ -1576,10 +1591,12 @@ max-nonsuper-connections 0
max-points-in-geometry 65536
max-prepared-stmt-count 16382
max-relay-log-size 0
max-running-queries 0
max-seeks-for-key 18446744073709551615
max-sort-length 1024
max-sp-recursion-depth 0
max-user-connections 0
max-waiting-queries 0
max-write-lock-count 18446744073709551615
memlock FALSE
min-examined-row-limit 0
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/suite/perfschema/r/dml_setup_instruments.result
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ where name like 'Wait/Synch/Rwlock/sql/%'
and name not in ('wait/synch/rwlock/sql/CRYPTO_dynlock_value::lock')
order by name limit 10;
NAME ENABLED TIMED PROPERTIES VOLATILITY DOCUMENTATION
wait/synch/rwlock/sql/AC::rwlock YES YES 0 NULL
wait/synch/rwlock/sql/Binlog_relay_IO_delegate::lock YES YES singleton 0 NULL
wait/synch/rwlock/sql/Binlog_storage_delegate::lock YES YES singleton 0 NULL
wait/synch/rwlock/sql/Binlog_transmit_delegate::lock YES YES singleton 0 NULL
Expand All @@ -28,7 +29,6 @@ wait/synch/rwlock/sql/channel_to_filter_lock YES YES 0 NULL
wait/synch/rwlock/sql/gtid_commit_rollback YES YES singleton 0 NULL
wait/synch/rwlock/sql/gtid_mode_lock YES YES singleton 0 NULL
wait/synch/rwlock/sql/gtid_retrieved YES YES singleton 0 NULL
wait/synch/rwlock/sql/LOCK_sys_init_connect YES YES singleton 0 NULL
select * from performance_schema.setup_instruments
where name like 'Wait/Synch/Cond/sql/%'
and name not in (
Expand Down
8 changes: 8 additions & 0 deletions mysql-test/suite/sys_vars/r/all_vars.result
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ left join t1 on variable_name=test_name where test_name is null ORDER BY variabl
There should be *no* variables listed below:
activate_all_roles_on_login
activate_all_roles_on_login
admission_control_by_trx
admission_control_by_trx
admission_control_filter
admission_control_filter
cte_max_recursion_depth
cte_max_recursion_depth
default_collation_for_utf8mb4
Expand All @@ -35,6 +39,10 @@ log_global_var_changes
log_global_var_changes
mandatory_roles
mandatory_roles
max_running_queries
max_running_queries
max_waiting_queries
max_waiting_queries
password_require_current
password_require_current
regexp_stack_limit
Expand Down
Loading