Skip to content

Commit

Permalink
MDEV-15935 Adding global/session system var redirect_url
Browse files Browse the repository at this point in the history
Adding a global/session var `redirect_url' of string type. The initial
value is empty. Can be supplied in mysqld with --redirect-url or set
in --init-connect. A valid redirect_url should be of the format

{mysql,mariadb}://host[:port]

where <host> is an arbitrary string not containing colons, and <port>
is a number between 0 and 65535 inclusive.

The variable will be used by the server to notify clients that they
should connect to another server, specified by the value of the
variable, if not empty.

The notification is done by the inclusion of the variable in
session_track_system_variable.
  • Loading branch information
mariadb-YuchenPei committed Oct 26, 2023
1 parent 6151bde commit 5af70de
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 16 deletions.
5 changes: 4 additions & 1 deletion mysql-test/main/mysqld--help.result
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,8 @@ The following specify which files/extra groups are read (specified before remain
--read-rnd-buffer-size=#
When reading rows in sorted order after a sort, the rows
are read through this buffer to avoid a disk seeks
--redirect-url=name URL of another server to redirect clients to. Empty
string means no redirection
--relay-log=name The location and name to use for relay logs.
--relay-log-index=name
The location and name to use for the file that keeps a
Expand Down Expand Up @@ -1838,6 +1840,7 @@ read-binlog-speed-limit 0
read-buffer-size 131072
read-only FALSE
read-rnd-buffer-size 262144
redirect-url
relay-log (No default value)
relay-log-index (No default value)
relay-log-info-file relay-log.info
Expand Down Expand Up @@ -1869,7 +1872,7 @@ secure-timestamp NO
server-id 1
session-track-schema TRUE
session-track-state-change FALSE
session-track-system-variables autocommit,character_set_client,character_set_connection,character_set_results,time_zone
session-track-system-variables autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone
session-track-transaction-info OFF
show-slave-auth-info FALSE
silent-startup FALSE
Expand Down
13 changes: 13 additions & 0 deletions mysql-test/suite/sys_vars/r/mdev_32254.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#
# MDEV-32254 Server crashes when adding records to table after setting redirect_url with empty variable
#
set @old_redirect_url=@@global.redirect_url;
set global redirect_url=@empty_value;
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'NULL'
CREATE TABLE t (c1 INT) ENGINE=INNODB;
INSERT INTO t VALUES (1),(1);
drop table t;
set global redirect_url=@old_redirect_url;
#
# end of test mdev_32254
#
81 changes: 81 additions & 0 deletions mysql-test/suite/sys_vars/r/redirect.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#
# MDEV-15935 Connection Redirection Mechanism in MariaDB Client/Server Protocol
#
connect con,localhost,anyone_but_root;
select @@redirect_url;
@@redirect_url
mysql://foobar
connection default;
set @old_global_redirect_url=@@global.redirect_url;
set @old_session_redirect_url=@@session.redirect_url;
set @old_session_track_system_variables=@@session_track_system_variables;
set session_track_system_variables="";
select @@global.redirect_url;
@@global.redirect_url

set global redirect_url=default;
select @@global.redirect_url;
@@global.redirect_url

set global redirect_url="mariadb.org";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mariadb.org'
set global redirect_url="https://mariadb.org";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'https://mariadb.org'
set global redirect_url="mysql://mariadb.org:";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mysql://mariadb.org:'
set global redirect_url="mysql://mariadb.org:hello";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mysql://mariadb.org:hello'
set global redirect_url="mysql://";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mysql://'
set global redirect_url="mysql://mariadb.org";
select @@global.redirect_url;
@@global.redirect_url
mysql://mariadb.org
set global redirect_url="mysql://mariadb.org:12a";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mysql://mariadb.org:12a'
set global redirect_url="mysql://mariadb.org:66666";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mysql://mariadb.org:66666'
set global redirect_url="mysql://mariadb.org:12345";
select @@global.redirect_url;
@@global.redirect_url
mysql://mariadb.org:12345
set global redirect_url="maria";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'maria'
set global redirect_url="mariadb://mariadb.org:";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mariadb://mariadb.org:'
set global redirect_url="mariadb://mariadb.org:hello";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mariadb://mariadb.org:hello'
set global redirect_url="mariadb://";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mariadb://'
set global redirect_url="mariadb://mariadb.org";
select @@global.redirect_url;
@@global.redirect_url
mariadb://mariadb.org
set global redirect_url="mariadb://mariadb.org:12a";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mariadb://mariadb.org:12a'
set global redirect_url="mariadb://mariadb.org:66666";
ERROR 42000: Variable 'redirect_url' can't be set to the value of 'mariadb://mariadb.org:66666'
set global redirect_url="mariadb://mariadb.org:12345";
select @@global.redirect_url;
@@global.redirect_url
mariadb://mariadb.org:12345
select @@session.redirect_url;
@@session.redirect_url

set session redirect_url=default;
select @@session.redirect_url;
@@session.redirect_url
mariadb://mariadb.org:12345
set session redirect_url="mysql://localhost";
select @@session.redirect_url;
@@session.redirect_url
mysql://localhost
select @@global.redirect_url;
@@global.redirect_url
mariadb://mariadb.org:12345
set global redirect_url=@old_global_redirect_url;
set session redirect_url=@old_session_redirect_url;
set session session_track_system_variables=@old_session_track_system_variables;
#
# end of test MDEV-15935
#
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@
# Global - default
SELECT @@global.session_track_system_variables;
@@global.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone
# Session - default
SELECT @@session.session_track_system_variables;
@@session.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone

# via INFORMATION_SCHEMA.GLOBAL_VARIABLES
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'session_track_system_variables' ORDER BY VARIABLE_NAME;
VARIABLE_NAME VARIABLE_VALUE
SESSION_TRACK_SYSTEM_VARIABLES autocommit,character_set_client,character_set_connection,character_set_results,time_zone
SESSION_TRACK_SYSTEM_VARIABLES autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone
# via INFORMATION_SCHEMA.SESSION_VARIABLES
SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE 'session_track_system_variables' ORDER BY VARIABLE_NAME;
VARIABLE_NAME VARIABLE_VALUE
SESSION_TRACK_SYSTEM_VARIABLES autocommit,character_set_client,character_set_connection,character_set_results,time_zone
SESSION_TRACK_SYSTEM_VARIABLES autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone
SET @global_saved_tmp = @@global.session_track_system_variables;

# Altering global variable's value
Expand All @@ -28,7 +28,7 @@ SELECT @@global.session_track_system_variables;
autocommit
SELECT @@session.session_track_system_variables;
@@session.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone

# Altering session variable's value
SET @@session.session_track_system_variables='autocommit';
Expand Down Expand Up @@ -66,25 +66,25 @@ SET @@session.session_track_system_variables = DEFAULT;

SELECT @@global.session_track_system_variables;
@@global.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone
SELECT @@session.session_track_system_variables;
@@session.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone

# Variables' values in a new session (con2).
connect con2,"127.0.0.1",root,,test,$MASTER_MYPORT,;
SELECT @@global.session_track_system_variables;
@@global.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone
SELECT @@session.session_track_system_variables;
@@session.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone

# Altering session should not affect global.
SET @@session.session_track_system_variables = 'sql_mode';
SELECT @@global.session_track_system_variables;
@@global.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone
SELECT @@session.session_track_system_variables;
@@session.session_track_system_variables
sql_mode
Expand All @@ -98,7 +98,7 @@ SELECT @@global.session_track_system_variables;
sql_mode
SELECT @@session.session_track_system_variables;
@@session.session_track_system_variables
autocommit,character_set_client,character_set_connection,character_set_results,time_zone
autocommit,character_set_client,character_set_connection,character_set_results,redirect_url,time_zone

# Switching to the default connection.
connection default;
Expand Down
10 changes: 10 additions & 0 deletions mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
Original file line number Diff line number Diff line change
Expand Up @@ -3412,6 +3412,16 @@ NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME REDIRECT_URL
VARIABLE_SCOPE SESSION
VARIABLE_TYPE VARCHAR
VARIABLE_COMMENT URL of another server to redirect clients to. Empty string means no redirection
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
ENUM_VALUE_LIST NULL
READ_ONLY NO
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME RELAY_LOG
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE VARCHAR
Expand Down
17 changes: 17 additions & 0 deletions mysql-test/suite/sys_vars/t/mdev_32254.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--echo #
--echo # MDEV-32254 Server crashes when adding records to table after setting redirect_url with empty variable
--echo #
--source include/have_innodb.inc
# redirect_url is undefined in embedded.
--source include/not_embedded.inc
set @old_redirect_url=@@global.redirect_url;
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url=@empty_value;
CREATE TABLE t (c1 INT) ENGINE=INNODB;
INSERT INTO t VALUES (1),(1);
drop table t;
set global redirect_url=@old_redirect_url;

--echo #
--echo # end of test mdev_32254
--echo #
1 change: 1 addition & 0 deletions mysql-test/suite/sys_vars/t/redirect.opt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--init-connect="set redirect_url='mysql://foobar'"
74 changes: 74 additions & 0 deletions mysql-test/suite/sys_vars/t/redirect.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
--echo #
--echo # MDEV-15935 Connection Redirection Mechanism in MariaDB Client/Server Protocol
--echo #
# redirect_url is undefined in embedded.
--source include/not_embedded.inc

# We need to connect as a non super user for the init-connect to take
# effect
--source include/add_anonymous_users.inc
connect (con,localhost,anyone_but_root);
select @@redirect_url;

connection default;
--source include/delete_anonymous_users.inc
set @old_global_redirect_url=@@global.redirect_url;
set @old_session_redirect_url=@@session.redirect_url;
set @old_session_track_system_variables=@@session_track_system_variables;
set session_track_system_variables="";

select @@global.redirect_url;
set global redirect_url=default;
select @@global.redirect_url;
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mariadb.org";
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="https://mariadb.org";

--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mysql://mariadb.org:";
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mysql://mariadb.org:hello";
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mysql://";
set global redirect_url="mysql://mariadb.org";
select @@global.redirect_url;
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mysql://mariadb.org:12a";
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mysql://mariadb.org:66666";
set global redirect_url="mysql://mariadb.org:12345";
select @@global.redirect_url;

--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="maria";
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mariadb://mariadb.org:";
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mariadb://mariadb.org:hello";
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mariadb://";
set global redirect_url="mariadb://mariadb.org";
select @@global.redirect_url;
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mariadb://mariadb.org:12a";
--error ER_WRONG_VALUE_FOR_VAR
set global redirect_url="mariadb://mariadb.org:66666";
set global redirect_url="mariadb://mariadb.org:12345";
select @@global.redirect_url;

select @@session.redirect_url;
# Test that session default is global value
set session redirect_url=default;
select @@session.redirect_url;
set session redirect_url="mysql://localhost";
select @@session.redirect_url;
select @@global.redirect_url;

set global redirect_url=@old_global_redirect_url;
set session redirect_url=@old_session_redirect_url;
set session session_track_system_variables=@old_session_track_system_variables;

--echo #
--echo # end of test MDEV-15935
--echo #
1 change: 1 addition & 0 deletions sql/sql_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,7 @@ typedef struct system_variables

Time_zone *time_zone;
char *session_track_system_variables;
char *redirect_url;

/* Some wsrep variables */
ulonglong wsrep_trx_fragment_size;
Expand Down
9 changes: 9 additions & 0 deletions sql/sql_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3278,6 +3278,8 @@ void plugin_thdvar_init(THD *thd)
/* This and all other variable cleanups are here for COM_CHANGE_USER :( */
#ifndef EMBEDDED_LIBRARY
thd->session_tracker.sysvars.deinit(thd);
my_free(thd->variables.redirect_url);
thd->variables.redirect_url= 0;
#endif
my_free((char*) thd->variables.default_master_connection.str);
thd->variables.default_master_connection.str= 0;
Expand Down Expand Up @@ -3311,7 +3313,12 @@ void plugin_thdvar_init(THD *thd)
MYF(MY_WME | MY_THREAD_SPECIFIC));
#ifndef EMBEDDED_LIBRARY
thd->session_tracker.sysvars.init(thd);
thd->variables.redirect_url=
my_strdup(key_memory_Sys_var_charptr_value,
global_system_variables.redirect_url,
MYF(MY_WME | MY_THREAD_SPECIFIC));
#endif

DBUG_VOID_RETURN;
}

Expand Down Expand Up @@ -3379,6 +3386,8 @@ void plugin_thdvar_cleanup(THD *thd)

#ifndef EMBEDDED_LIBRARY
thd->session_tracker.sysvars.deinit(thd);
my_free(thd->variables.redirect_url);
thd->variables.redirect_url= 0;
#endif
my_free((char*) thd->variables.default_master_connection.str);
thd->variables.default_master_connection.str= 0;
Expand Down

0 comments on commit 5af70de

Please sign in to comment.