Skip to content

Commit

Permalink
Support changing OS thread priorities
Browse files Browse the repository at this point in the history
Summary:
Support changing priorities of threads associated with user connections.

This change enables 3 ways to change thread priories:
1. **Change current thread priority** : `set thread_priority=<priority_value>`.
2. **Set default priority for all new threads** :  `set global thread_priority=<priority_value>`.
3. **Change any thread priority** : `set global thread_priority_str=<os-thread-id>:<priority_value>`.

- Priority values take a range of -20 to 19 (the same as nice).
- Non-default priority threads are not leaked into the thread cache: Threads which have non-zero priority will be reset to 0 priority at the end of the connection. The threads will be terminated in the case where such priority-reset is not possible.

Automation will mostly make use of the 1st scenario to change the current connection/thread's priority before starting work, say a backup or a large scan.

- Added a new session variable `thread_priority`.
- Renamed `thread_nice_value` var to `thread_priority_str`.
- a new information_schema table, `thread_priorities` to track the priority of all the threads.

`thread_priority` sysvar:
- takes an integer value, in the range similar to nice.
- If this is set at the session level, the current thread's priority is modified.
- If this is set at the global level, all **new** threads will inherit the modified priority.

`thread_priority_str` sysvar:
- input string format: <os-thread-id>:<priority-value>

INFORMATION_SCHEMA.THREAD_PRIORITIES schema:
```
mysql> describe information_schema.threads;
+------------------+---------------------+------+-----+---------+-------+
| Field            | Type                | Null | Key | Default | Extra |
+------------------+---------------------+------+-----+---------+-------+
| ID               | bigint(21) unsigned | NO   |     | 0       |       |
| SYSTEM_THREAD_ID | bigint(21) unsigned | NO   |     | 0       |       |
| PRIORITY         | bigint(5)           | NO   |     | 0       |       |
+------------------+---------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
```
- ID is the connection id as seen in `show processlist`.
- SYSTEM_THREAD_ID is the unix thread id as seen in `ps`.
- PRIORITY is the thread priority (nice value).

Notable changes:
- CAP_SYS_NICE capability is acquired before changing the thread priority, and dropped after the action is done.
- libcap library is a dependency for this change.
- setuid changed to setresuid.

Reviewed By: mzait

Differential Revision: D22046019

fbshipit-source-id: 372586a058f
  • Loading branch information
sagar0 authored and facebook-github-bot committed Jul 30, 2020
1 parent 7fdfd32 commit f912b38
Show file tree
Hide file tree
Showing 29 changed files with 1,070 additions and 101 deletions.
2 changes: 2 additions & 0 deletions config.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
#cmakedefine HAVE_SYS_UTIME_H 1
#cmakedefine HAVE_SYS_WAIT_H 1
#cmakedefine HAVE_SYS_PARAM_H 1
#cmakedefine HAVE_SYS_CAPABILITY_H 1

/* Libraries */
#cmakedefine HAVE_LIBPTHREAD 1
Expand All @@ -116,6 +117,7 @@
#cmakedefine HAVE_LIBRESOLV 1
/* Does "struct timespec" have a "sec" and "nsec" field? */
#cmakedefine HAVE_TIMESPEC_TS_SEC 1
#cmakedefine HAVE_LIBCAP 1

/* Readline */
#cmakedefine HAVE_HIST_ENTRY 1
Expand Down
6 changes: 5 additions & 1 deletion configure.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,13 @@ IF(UNIX)
ENDIF()
MY_SEARCH_LIBS(backtrace execinfo LIBEXECINFO)
MY_SEARCH_LIBS(timer_create rt LIBRT)
MY_SEARCH_LIBS(cap_get_proc cap LIBCAP)

FIND_PACKAGE(Threads)

SET(CMAKE_REQUIRED_LIBRARIES
${LIBM} ${LIBNSL} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${LIBDL}
${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBEXECINFO}
${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBEXECINFO} ${LIBCAP}
)
# Need explicit pthread for gcc -fsanitize=address
IF(CMAKE_USE_PTHREADS_INIT AND CMAKE_C_FLAGS MATCHES "-fsanitize=")
Expand Down Expand Up @@ -429,6 +430,9 @@ CHECK_INCLUDE_FILES(sys/event.h HAVE_SYS_EVENT_H)
CHECK_INCLUDE_FILES(sys/queue.h HAVE_SYS_QUEUE_H)
CHECK_SYMBOL_EXISTS (TAILQ_FOREACH "sys/queue.h" HAVE_TAILQFOREACH)

# For LIBCAP
CHECK_INCLUDE_FILES (sys/capability.h HAVE_SYS_CAPABILITY_H)

IF(HAVE_SYS_STREAM_H)
# Needs sys/stream.h on Solaris
CHECK_INCLUDE_FILES ("sys/stream.h;sys/ptem.h" HAVE_SYS_PTEM_H)
Expand Down
2 changes: 1 addition & 1 deletion libmysqld/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ ENDIF()
SET(LIBS
dbug strings regex mysys mysys_ssl vio
${ZLIB_LIBRARY} ${SSL_LIBRARIES}
${LIBWRAP} ${LIBCRYPT} ${LIBDL}
${LIBWRAP} ${LIBCRYPT} ${LIBDL} ${LIBCAP}
${MYSQLD_STATIC_PLUGIN_LIBS}
sql_embedded
)
Expand Down
3 changes: 3 additions & 0 deletions mysql-test/include/as_root.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if (!$MYSQL_TEST_ROOT){
skip Run as root;
}
2 changes: 2 additions & 0 deletions mysql-test/r/information_schema-big.result
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ COLUMN_STATISTICS TABLE_SCHEMA
DATABASE_APPLIED_HLC DATABASE_NAME
ADMISSION_CONTROL_QUEUE SCHEMA_NAME
SQL_FINDINGS SQL_ID
THREAD_PRIORITIES ID
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
INNER JOIN
Expand Down Expand Up @@ -155,3 +156,4 @@ COLUMN_STATISTICS TABLE_SCHEMA
DATABASE_APPLIED_HLC DATABASE_NAME
ADMISSION_CONTROL_QUEUE SCHEMA_NAME
SQL_FINDINGS SQL_ID
THREAD_PRIORITIES ID
10 changes: 9 additions & 1 deletion mysql-test/r/information_schema.result
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ COLUMN_STATISTICS
DATABASE_APPLIED_HLC
ADMISSION_CONTROL_QUEUE
SQL_FINDINGS
THREAD_PRIORITIES
columns_priv
db
event
Expand Down Expand Up @@ -155,6 +156,7 @@ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
TABLE_STATISTICS TABLE_STATISTICS
TRIGGERS TRIGGERS
THREAD_PRIORITIES THREAD_PRIORITIES
tables_priv tables_priv
time_zone time_zone
time_zone_leap_second time_zone_leap_second
Expand All @@ -177,6 +179,7 @@ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
TABLE_STATISTICS TABLE_STATISTICS
TRIGGERS TRIGGERS
THREAD_PRIORITIES THREAD_PRIORITIES
tables_priv tables_priv
time_zone time_zone
time_zone_leap_second time_zone_leap_second
Expand All @@ -199,6 +202,7 @@ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TABLE_PRIVILEGES TABLE_PRIVILEGES
TABLE_STATISTICS TABLE_STATISTICS
TRIGGERS TRIGGERS
THREAD_PRIORITIES THREAD_PRIORITIES
tables_priv tables_priv
time_zone time_zone
time_zone_leap_second time_zone_leap_second
Expand Down Expand Up @@ -694,6 +698,7 @@ TABLE_CONSTRAINTS
TABLE_PRIVILEGES
TABLE_STATISTICS
TRIGGERS
THREAD_PRIORITIES
create database information_schema;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
use information_schema;
Expand All @@ -706,6 +711,7 @@ TABLE_CONSTRAINTS SYSTEM VIEW
TABLE_PRIVILEGES SYSTEM VIEW
TABLE_STATISTICS SYSTEM VIEW
TRIGGERS SYSTEM VIEW
THREAD_PRIORITIES SYSTEM VIEW
create table t1(a int);
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
use test;
Expand All @@ -721,6 +727,7 @@ TABLE_CONSTRAINTS
TABLE_PRIVILEGES
TABLE_STATISTICS
TRIGGERS
THREAD_PRIORITIES
select table_name from tables where table_name='user';
table_name
user
Expand Down Expand Up @@ -957,7 +964,7 @@ table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest')
AND table_name not like 'ndb%' AND table_name not like 'innodb_%' AND table_name not like 'rocksdb_%'
GROUP BY TABLE_SCHEMA;
table_schema count(*)
information_schema 58
information_schema 59
mysql 27
create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row
Expand Down Expand Up @@ -1448,6 +1455,7 @@ TABLESPACES information_schema.TABLESPACES 1
TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1
TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
TABLE_STATISTICS information_schema.TABLE_STATISTICS 1
THREAD_PRIORITIES information_schema.THREAD_PRIORITIES 1
TRANSACTION_LIST information_schema.TRANSACTION_LIST 1
TRIGGERS information_schema.TRIGGERS 1
USER_LATENCY_HISTOGRAMS information_schema.USER_LATENCY_HISTOGRAMS 1
Expand Down
2 changes: 2 additions & 0 deletions mysql-test/r/information_schema_db.result
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ COLUMN_STATISTICS
DATABASE_APPLIED_HLC
ADMISSION_CONTROL_QUEUE
SQL_FINDINGS
THREAD_PRIORITIES
show tables from INFORMATION_SCHEMA like 'T%';
Tables_in_information_schema (T%)
TRANSACTION_LIST
Expand All @@ -72,6 +73,7 @@ TABLE_CONSTRAINTS
TABLE_PRIVILEGES
TABLE_STATISTICS
TRIGGERS
THREAD_PRIORITIES
create database `inf%`;
create database mbase;
use `inf%`;
Expand Down
14 changes: 10 additions & 4 deletions mysql-test/r/mysqld--help-notwin-profiling.result
Original file line number Diff line number Diff line change
Expand Up @@ -2079,9 +2079,14 @@ The following options may be given as the first argument:
--thread-handling=name
Define threads usage for handling queries, one of
one-thread-per-connection, no-threads, loaded-dynamically
--thread-nice-value[=name]
Input format is threadId:niceValue nice value range is
-20 to 19
--thread-priority=# Set the priority of a thread. Changes the priority of the
current thread if set at the session level. Changes the
priority of all new threads if set at the global level.
The values are in the range -20 to 19, similar to nice.
--thread-priority-str[=name]
Set the priority of a thread. The input format is
OSthreadId:PriValue. The priority values are in the range
-20 to 19, similar to nice.
--thread-stack=# The stack size for each thread
--time-format=name The TIME format (ignored)
--timed-mutexes Specify whether to time mutexes. Deprecated, has no
Expand Down Expand Up @@ -2785,7 +2790,8 @@ table-open-cache-instances 8
tc-heuristic-recover COMMIT
thread-cache-size 9
thread-handling one-thread-per-connection
thread-nice-value
thread-priority 0
thread-priority-str
thread-stack 327680
time-format %H:%i:%s
timed-mutexes FALSE
Expand Down
14 changes: 10 additions & 4 deletions mysql-test/r/mysqld--help-notwin.result
Original file line number Diff line number Diff line change
Expand Up @@ -2077,9 +2077,14 @@ The following options may be given as the first argument:
--thread-handling=name
Define threads usage for handling queries, one of
one-thread-per-connection, no-threads, loaded-dynamically
--thread-nice-value[=name]
Input format is threadId:niceValue nice value range is
-20 to 19
--thread-priority=# Set the priority of a thread. Changes the priority of the
current thread if set at the session level. Changes the
priority of all new threads if set at the global level.
The values are in the range -20 to 19, similar to nice.
--thread-priority-str[=name]
Set the priority of a thread. The input format is
OSthreadId:PriValue. The priority values are in the range
-20 to 19, similar to nice.
--thread-stack=# The stack size for each thread
--time-format=name The TIME format (ignored)
--timed-mutexes Specify whether to time mutexes. Deprecated, has no
Expand Down Expand Up @@ -2782,7 +2787,8 @@ table-open-cache-instances 8
tc-heuristic-recover COMMIT
thread-cache-size 9
thread-handling one-thread-per-connection
thread-nice-value
thread-priority 0
thread-priority-str
thread-stack 327680
time-format %H:%i:%s
timed-mutexes FALSE
Expand Down
2 changes: 2 additions & 0 deletions mysql-test/r/mysqlshow.result
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ DROP TABLE t1, t2;
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
| TABLE_STATISTICS |
| THREAD_PRIORITIES |
| TRANSACTION_LIST |
| TRIGGERS |
| USER_LATENCY_HISTOGRAMS |
Expand Down Expand Up @@ -270,6 +271,7 @@ DROP TABLE t1, t2;
| TABLE_CONSTRAINTS |
| TABLE_PRIVILEGES |
| TABLE_STATISTICS |
| THREAD_PRIORITIES |
| TRANSACTION_LIST |
| TRIGGERS |
| USER_LATENCY_HISTOGRAMS |
Expand Down
Loading

0 comments on commit f912b38

Please sign in to comment.