Skip to content

Commit

Permalink
Per-user session variable default values
Browse files Browse the repository at this point in the history
Summary:
This diff introduces per-user session variable default values. This is for MyRocks and MySQL production debugging. A new global variable 'per-user-session-var-default-val' with type of string is introduced, it defines the default values of multiple session variables for multiple users, e.g.

--per-user-session-var-default-val="user1:user2:user3:tx_isolation=read-committed,gap_lock_raise_error=0,user4:user5:big_tables=1,auto_increment_increment=12345,long_query_time=123.45"

In this example, the default values of session variables tx_isolation and gap_lock_raise_error for user1, user2, and user3 are defined, the default values of session variables big_tables, auto_increment_increment, and long_query_time for user4 and user 5 are defined. When these users connect to server, the corresponding session variables will be set with these values so that these users don't have to execute SET command to set these session variables before executing queries. The cost of an extra round trip is saved.
(1) This global variable is dynamic so it can be set at runtime.
(2) Sys-vars have many types. The per-user session variables supported types are enum/bool/int/uint/double, which are the most common types for session variables. Other types like string(charptr)/proxy_user/external_user/key_cache/plugin/struct etc are *not* supported.
(3) The users won't be validated when per-user-session-var-default-val is set since users can be changed any time after the global is set
(4) The session variables will be validated when per-user-session-var-default-val is set. Invalid command line value will cause server fail to start. Invalid value in SET command will fail the command.

Test Plan:
New tests added:
  sys_vars.per_user_session_var_default_val_basic.test
  sys_vars.per_user_session_var_default_val_null.test
  sys_vars.per_user_session_var_default_val_empty.test
  sys_vars.per_user_session_var_default_val.test
  sys_vars.per_user_session_var_default_validation.test

Reviewers: santoshb, jkedgar

Reviewed By: jkedgar

Subscribers: webscalesql-eng

Differential Revision: https://reviews.facebook.net/D55791
  • Loading branch information
pengtfb committed Apr 4, 2016
1 parent c5a7b3b commit fda980c
Show file tree
Hide file tree
Showing 24 changed files with 3,554 additions and 8 deletions.
7 changes: 7 additions & 0 deletions include/my_getopt.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ extern my_bool my_getopt_print_errors;
extern my_bool my_getopt_skip_unknown;
extern my_error_reporter my_getopt_error_reporter;

extern my_bool my_get_bool_argument(const struct my_option *opts,
const char *argument,
int *error);
extern longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
extern ulonglong getopt_ull(char *, const struct my_option *, int *);
extern double getopt_double(char *arg, const struct my_option *optp, int *err);

extern int handle_options (int *argc, char ***argv,
const struct my_option *longopts, my_get_one_option);
extern int handle_options_with_logging (int *argc, char ***argv,
Expand Down
3 changes: 3 additions & 0 deletions mysql-test/r/mysqld--help-notwin-profiling.result
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,8 @@ The following options may be given as the first argument:
The rate of sampling replayed events on slave to
determine the peak replication lag over some period.
--peak-lag-time=# The time frame peak lag is measured within, in seconds.
--per-user-session-var-default-val[=name]
Per user session variable default value
--performance-schema
Enable the performance schema.
(Defaults to on; use --skip-performance-schema to disable.)
Expand Down Expand Up @@ -1684,6 +1686,7 @@ optimizer-trace-offset -1
part-scan-max 10
peak-lag-sample-rate 100
peak-lag-time 60
per-user-session-var-default-val (No default value)
performance-schema TRUE
performance-schema-accounts-size -1
performance-schema-consumer-events-stages-current FALSE
Expand Down
3 changes: 3 additions & 0 deletions mysql-test/r/mysqld--help-notwin.result
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,8 @@ The following options may be given as the first argument:
The rate of sampling replayed events on slave to
determine the peak replication lag over some period.
--peak-lag-time=# The time frame peak lag is measured within, in seconds.
--per-user-session-var-default-val[=name]
Per user session variable default value
--performance-schema
Enable the performance schema.
(Defaults to on; use --skip-performance-schema to disable.)
Expand Down Expand Up @@ -1682,6 +1684,7 @@ optimizer-trace-offset -1
part-scan-max 10
peak-lag-sample-rate 100
peak-lag-time 60
per-user-session-var-default-val (No default value)
performance-schema TRUE
performance-schema-accounts-size -1
performance-schema-consumer-events-stages-current FALSE
Expand Down
2,354 changes: 2,354 additions & 0 deletions mysql-test/suite/sys_vars/r/per_user_session_var_default_val.result

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
SET @original_val = @@global.per_user_session_var_default_val;
SELECT @original_val;
@original_val
NULL
SELECT @@GLOBAL.per_user_session_var_default_val = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='per_user_session_var_default_val';
@@GLOBAL.per_user_session_var_default_val = VARIABLE_VALUE
NULL
SELECT @@SESSION.per_user_session_var_default_val;
ERROR HY000: Variable 'per_user_session_var_default_val' is a GLOBAL variable
SET SESSION per_user_session_var_default_val = "";
ERROR HY000: Variable 'per_user_session_var_default_val' is a GLOBAL variable and should be set with SET GLOBAL
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val
NULL
## default value is NULL
SET GLOBAL per_user_session_var_default_val = DEFAULT;
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val
NULL
## NULL is a valid value
SET GLOBAL per_user_session_var_default_val = NULL;
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val
NULL
## "" is a valid value
SET GLOBAL per_user_session_var_default_val = "";
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val

SET @@global.per_user_session_var_default_val = @original_val;
SELECT @@global.per_user_session_var_default_val;
@@global.per_user_session_var_default_val
NULL
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# empty string is a valid value
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# default value is NULL ptr
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val
NULL
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
flush privileges;
create user usr1@localhost;
grant all privileges on *.* to admin1@localhost identified by password '' with grant option;
flush user_resources;
SET @original_val = @@global.per_user_session_var_default_val;
SELECT @original_val;
@original_val
NULL
## default value is NULL
SET GLOBAL per_user_session_var_default_val = DEFAULT;
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val
NULL
## NULL is a valid value
SET GLOBAL per_user_session_var_default_val = NULL;
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val
NULL
## "" is a valid value
SET GLOBAL per_user_session_var_default_val = "";
SELECT @@GLOBAL.per_user_session_var_default_val;
@@GLOBAL.per_user_session_var_default_val

##
## Invalid values. SET command will fail
##
SET GLOBAL per_user_session_var_default_val = " ";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of ' '
SET GLOBAL per_user_session_var_default_val = " ";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of ' '
SET GLOBAL per_user_session_var_default_val = ":";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of ':'
SET GLOBAL per_user_session_var_default_val = "=";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of '='
SET GLOBAL per_user_session_var_default_val = ",";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of ','
SET GLOBAL per_user_session_var_default_val = ";";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of ';'
SET GLOBAL per_user_session_var_default_val = "\"";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of '"'
SET GLOBAL per_user_session_var_default_val = "'";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of '''
SET GLOBAL per_user_session_var_default_val = "\\";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of '\'
SET GLOBAL per_user_session_var_default_val = "/";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of '/'
SET GLOBAL per_user_session_var_default_val = "u";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u'
SET GLOBAL per_user_session_var_default_val = "gap_lock_raise_error=0";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'gap_lock_raise_error=0'
SET GLOBAL per_user_session_var_default_val = "gap_lock_raise_error=0,u2:gap_lock_raise_error=1";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'gap_lock_raise_error=0,u2:gap_lock_raise_error=1'
SET GLOBAL per_user_session_var_default_val = " u";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of ' u'
SET GLOBAL per_user_session_var_default_val = "u ";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u '
SET GLOBAL per_user_session_var_default_val = "u :";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u :'
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error'
SET GLOBAL per_user_session_var_default_val = "u: ";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u: '
SET GLOBAL per_user_session_var_default_val = " u:gap_lock_raise_error";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of ' u:gap_lock_raise_error'
SET GLOBAL per_user_session_var_default_val = "u:v:";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:v:'
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error=";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error='
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error=0:";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error=0:'
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error=0=";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error=0='
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error=0=1";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error=0=1'
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error=0,u:gap_lock_write_log=0";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error=0,u:gap_lock_write_log=0'
SET GLOBAL per_user_session_var_default_val = "u:= 0";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:= 0'
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error= 0";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error= 0'
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error= ";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error= '
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error=0,";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error=0,'
SET GLOBAL per_user_session_var_default_val = "u:gap_lock_raise_error=0;";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u:gap_lock_raise_error=0;'
SET GLOBAL per_user_session_var_default_val = "u1:u2:gap_lock_raise_error=0,gap_lock_write_log=0,,u3:big_tables=1";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:u2:gap_lock_raise_error=0,gap_lock_write_log=0,,u3:big_tables=1'
SET GLOBAL per_user_session_var_default_val = "u1::u2:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=1";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1::u2:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=1'
SET GLOBAL per_user_session_var_default_val = "u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=1 ";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=1 '
SET GLOBAL per_user_session_var_default_val = "u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=1,";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=1,'
SET GLOBAL per_user_session_var_default_val = "u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=1'";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=1''
SET GLOBAL per_user_session_var_default_val = "u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables='1'";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables='1''
SET GLOBAL per_user_session_var_default_val = "u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables=\"1\"";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:gap_lock_raise_error=0,gap_lock_write_log=0,u3:big_tables="1"'
SET GLOBAL per_user_session_var_default_val = "u1:time_zone=\'+10:00\'";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:time_zone='+10:00''
## Syntax error
SET GLOBAL per_user_session_var_default_val = "u1:optimizer_switch=index_merge=on";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:optimizer_switch=index_merge=on'
## Unsupported type 'flagset'
SET GLOBAL per_user_session_var_default_val = "u1:optimizer_switch=xyz";
ERROR 42000: Variable 'per_user_session_var_default_val' can't be set to the value of 'u1:optimizer_switch=xyz'
##
## root privilege is required to set session variable binglog_format
## root privilege will be granted to usr1 temporarily to get this done
##
SET GLOBAL per_user_session_var_default_val = "usr1:binlog_format=MIXED";
SELECT @@GLOBAL.binlog_format, @@SESSION.binlog_format;
@@GLOBAL.binlog_format @@SESSION.binlog_format
STATEMENT MIXED
SET GLOBAL per_user_session_var_default_val = "usr1:binlog_format=ROW";
SELECT @@GLOBAL.binlog_format, @@SESSION.binlog_format;
@@GLOBAL.binlog_format @@SESSION.binlog_format
STATEMENT ROW
SET GLOBAL per_user_session_var_default_val = "admin1:binlog_format=MIXED";
SELECT @@GLOBAL.binlog_format, @@SESSION.binlog_format;
@@GLOBAL.binlog_format @@SESSION.binlog_format
STATEMENT MIXED
SET GLOBAL per_user_session_var_default_val = "admin1:binlog_format=ROW";
SELECT @@GLOBAL.binlog_format, @@SESSION.binlog_format;
@@GLOBAL.binlog_format @@SESSION.binlog_format
STATEMENT ROW
drop user usr1@localhost;
drop user admin1@localhost;
SET @@global.per_user_session_var_default_val = @original_val;
SELECT @@global.per_user_session_var_default_val;
@@global.per_user_session_var_default_val
NULL
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
--echo ## create connection batch $i
let $j=1;
while ($j<=5) {
connect (con_tao_$i$j,localhost,tao$j,,);
connect (con_tao_ssl_$i$j,localhost,tao$j,,,,,SSL);
inc $j;
}
connect (con_root_$i,localhost,root,,);
connect (con_root_ssl_$i,localhost,root,,,,,SSL);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--per-user-session-var-default-val="tao2:tao3:root:tx_isolation=read-committed,gap_lock_raise_error=0,gap_lock_write_log=0,big_tables=1,tao1:bulk_insert_buffer_size=16M,gap_lock_raise_error=0,gap_lock_write_log=0,auto_increment_increment=12345,long_query_time=123.45"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--per-user-session-var-default-val="tao2:tao3:root:tx_isolation=read-committed,gap_lock_raise_error=0,gap_lock_write_log=0,big_tables=1,tao1:bulk_insert_buffer_size=16M,gap_lock_raise_error=0,gap_lock_write_log=0,auto_increment_increment=12345,long_query_time=123.45"
121 changes: 121 additions & 0 deletions mysql-test/suite/sys_vars/t/per_user_session_var_default_val.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
--source include/load_sysvars.inc

# Wait for all the connections from previous tests except
# the default one to be completedly disconnected
let $count_sessions= 1;
--source include/wait_until_count_sessions.inc

flush privileges;

--source include/master-slave.inc
connection master;

let $original_val = query_get_value(select @@GLOBAL.per_user_session_var_default_val as val, val, 1);
--echo $original_val
SELECT @@GLOBAL.per_user_session_var_default_val;

--echo ## create non-super users tao1, tao2, and tao3
create user tao1@localhost;
create user tao2@localhost;
create user tao3@localhost;

--echo ## create super users tao4 and tao5
grant all privileges on *.* to tao4@localhost identified by password '' with grant option;
grant all privileges on *.* to tao5@localhost identified by password '' with grant option;

flush user_resources;

let $i=1;
--echo ## ($i) Initial non-empty value
--source per_user_session_var_conn_create.inc

inc $i;
--echo ## ($i) DEFAULT value
SET GLOBAL per_user_session_var_default_val = DEFAULT;
SELECT @@GLOBAL.per_user_session_var_default_val;
--source per_user_session_var_conn_create.inc

inc $i;
--echo ## ($i) Non-empty value
SET GLOBAL per_user_session_var_default_val="tao1:tao2:tao3:tao4:tx_isolation=serializable,big_tables=1,auto_increment_increment=12345,long_query_time=123.45,bulk_insert_buffer_size=1G,tao5:root:binlog_format=row";
SELECT @@GLOBAL.per_user_session_var_default_val;
--source per_user_session_var_conn_create.inc

inc $i;
--echo ## ($i) NULL value
SET GLOBAL per_user_session_var_default_val = NULL;
SELECT @@GLOBAL.per_user_session_var_default_val;
--source per_user_session_var_conn_create.inc

inc $i;
--echo ## ($i) Non-empty value
SET GLOBAL per_user_session_var_default_val="tao1:tx_isolation=READ-UNCOMMITTED,tao2:tao3:gap_lock_raise_error=FALSE,root:gap_lock_write_log=off,tao4:big_tables=1,auto_increment_increment=12345,long_query_time=123.45,tao5:binlog_format=MIXED,bulk_insert_buffer_size=32M";
SELECT @@GLOBAL.per_user_session_var_default_val;
--source per_user_session_var_conn_create.inc

inc $i;
--echo ## ($i) Empty value
SET GLOBAL per_user_session_var_default_val = "";
SELECT @@GLOBAL.per_user_session_var_default_val;
--source per_user_session_var_conn_create.inc

inc $i;
--echo ## ($i) Restored initial non-empty value
eval SET @@global.per_user_session_var_default_val = "$original_val";
SELECT @@global.per_user_session_var_default_val;
--source per_user_session_var_conn_create.inc

--echo ##
--echo ## Session variables of all the connnections
--echo ##

let $k=1;
while ($k<=$i) {
--echo ##
--echo ## ($k) Connection batch $k
--echo ##

let $j=1;
while ($j<=5) {
--echo ##
--echo ## Connection con_tao_$k$j for user tao$j
--echo ##
connection con_tao_$k$j;
--source per_user_session_var_print.inc
disconnect con_tao_$k$j;

--echo ##
--echo ## SSL connection con_tao_ssl_$k$j for user tao$j
--echo ##
connection con_tao_ssl_$k$j;
--source per_user_session_var_print.inc
disconnect con_tao_ssl_$k$j;

inc $j;
}
--echo ##
--echo ## Connection con_root_$k for user root
--echo ##
connection con_root_$k;
--source per_user_session_var_print.inc
disconnect con_root_$k;

--echo ##
--echo ## SSL connection con_root_ssl_$k for user root
--echo ##
connection con_root_ssl_$k;
--source per_user_session_var_print.inc
disconnect con_root_ssl_$k;

inc $k;
}

connection default;

drop user tao1@localhost;
drop user tao2@localhost;
drop user tao3@localhost;
drop user tao4@localhost;
drop user tao5@localhost;

--source include/rpl_end.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--source include/load_sysvars.inc

SET @original_val = @@global.per_user_session_var_default_val;
SELECT @original_val;

SELECT @@GLOBAL.per_user_session_var_default_val = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE VARIABLE_NAME='per_user_session_var_default_val';

--error ER_INCORRECT_GLOBAL_LOCAL_VAR
SELECT @@SESSION.per_user_session_var_default_val;

--error ER_GLOBAL_VARIABLE
SET SESSION per_user_session_var_default_val = "";

SELECT @@GLOBAL.per_user_session_var_default_val;

--echo ## default value is NULL
SET GLOBAL per_user_session_var_default_val = DEFAULT;
SELECT @@GLOBAL.per_user_session_var_default_val;

--echo ## NULL is a valid value
SET GLOBAL per_user_session_var_default_val = NULL;
SELECT @@GLOBAL.per_user_session_var_default_val;

--echo ## "" is a valid value
SET GLOBAL per_user_session_var_default_val = "";
SELECT @@GLOBAL.per_user_session_var_default_val;

SET @@global.per_user_session_var_default_val = @original_val;
SELECT @@global.per_user_session_var_default_val;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--per-user-session-var-default-val=""
Loading

0 comments on commit fda980c

Please sign in to comment.