Skip to content

Commit

Permalink
Add a variable for appending a custom message to server read_only error
Browse files Browse the repository at this point in the history
Summary:
Proposing a way to set a custom message in the `--read-only (super)` error.
Note: the variable can only be set when server is in read-only (super) state.

p.s. I am hesitant to add a mutex for the variable, so we will get a snapshot
of the current pointer of the variable (const char*) when printing the error.

Squash with https://reviews.facebook.net/D61383

Test Plan: Added tests.

Reviewers: santoshb

Reviewed By: santoshb

Subscribers: webscalesql-eng, ebergen

Differential Revision: https://reviews.facebook.net/D61713
  • Loading branch information
tianx committed Aug 10, 2016
1 parent 424ce1f commit 9f00827
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 0 deletions.
1 change: 1 addition & 0 deletions mysql-test/r/bug58669.result
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ user1@localhost
SHOW VARIABLES LIKE "read_only%";
Variable_name Value
read_only ON
read_only_error_msg_extra
read_only_slave ON
INSERT INTO db1.t1 VALUES (1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
Expand Down
4 changes: 4 additions & 0 deletions mysql-test/r/mysqld--help-notwin-profiling.result
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,9 @@ The following options may be given as the first argument:
--read-only Make all non-temporary tables read-only, with the
exception for replication (slave) threads and users with
the SUPER privilege
--read-only-error-msg-extra[=name]
Set this variable to print out extra error information,
which will be appended to read_only error messages.
--read-only-slave Blocks disabling read_only if the server is a slave. This
is helpful in asserting that read_only is never disabled
on a slave. Slave with read_only=0 may generate new GTID
Expand Down Expand Up @@ -1796,6 +1799,7 @@ range-alloc-block-size 4096
rbr-idempotent-tables (No default value)
read-buffer-size 131072
read-only FALSE
read-only-error-msg-extra
read-only-slave TRUE
read-rnd-buffer-size 262144
relay-log (No default value)
Expand Down
4 changes: 4 additions & 0 deletions mysql-test/r/mysqld--help-notwin.result
Original file line number Diff line number Diff line change
Expand Up @@ -870,6 +870,9 @@ The following options may be given as the first argument:
--read-only Make all non-temporary tables read-only, with the
exception for replication (slave) threads and users with
the SUPER privilege
--read-only-error-msg-extra[=name]
Set this variable to print out extra error information,
which will be appended to read_only error messages.
--read-only-slave Blocks disabling read_only if the server is a slave. This
is helpful in asserting that read_only is never disabled
on a slave. Slave with read_only=0 may generate new GTID
Expand Down Expand Up @@ -1793,6 +1796,7 @@ range-alloc-block-size 4096
rbr-idempotent-tables (No default value)
read-buffer-size 131072
read-only FALSE
read-only-error-msg-extra
read-only-slave TRUE
read-rnd-buffer-size 262144
relay-log (No default value)
Expand Down
6 changes: 6 additions & 0 deletions mysql-test/suite/rpl/r/rpl_read_only.result
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,12 @@ insert into t1 values(1006);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement. Current master_host: 127.0.0.1, master_port: MASTER_PORT
insert into t2 values(2006);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement. Current master_host: 127.0.0.1, master_port: MASTER_PORT
set global read_only_error_msg_extra = "This is a custom message";
insert into t1 values(1006);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement. Current master_host: 127.0.0.1, master_port: MASTER_PORT. This is a custom message
insert into t2 values(2006);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement. Current master_host: 127.0.0.1, master_port: MASTER_PORT. This is a custom message
set global read_only_error_msg_extra = default;
drop user test;
drop table t1;
drop table t2;
Expand Down
13 changes: 13 additions & 0 deletions mysql-test/suite/rpl/t/rpl_read_only.test
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ create user test;

connect (master2,127.0.0.1,test,,test,$MASTER_MYPORT,);
connect (slave2,127.0.0.1,test,,test,$SLAVE_MYPORT,);
connect (slave2_root,127.0.0.1,root,,test,$SLAVE_MYPORT,);

connection master1;

Expand Down Expand Up @@ -119,6 +120,18 @@ insert into t1 values(1006);
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_OPTION_PREVENTS_STATEMENT_EXTRA_INFO
insert into t2 values(2006);
# set extra info for the error message
connection slave2_root;
set global read_only_error_msg_extra = "This is a custom message";
connection slave2;
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_OPTION_PREVENTS_STATEMENT_EXTRA_INFO
insert into t1 values(1006);
--replace_result $MASTER_MYPORT MASTER_PORT
--error ER_OPTION_PREVENTS_STATEMENT_EXTRA_INFO
insert into t2 values(2006);
connection slave2_root;
set global read_only_error_msg_extra = default;

# Verify read_only cannot be disabled on slave
connection slave;
Expand Down
20 changes: 20 additions & 0 deletions mysql-test/suite/sys_vars/r/read_only_error_msg_extra_basic.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
set @@global.read_only_error_msg_extra='Not in read_only';
ERROR HY000: The system variable read_only_error_msg_extra can only be set in read-only (super) status.
set global read_only = true;
set @@global.read_only_error_msg_extra = default;
select @@global.read_only_error_msg_extra;
@@global.read_only_error_msg_extra

set @saved_read_only_error_msg_extra = @@global.read_only_error_msg_extra;
set @@global.read_only_error_msg_extra='This is a custom message';
set global super_read_only = true;
set @@global.read_only_error_msg_extra='This is another custom message';
set @@global.read_only_error_msg_extra=1;
ERROR 42000: Incorrect argument type to variable 'read_only_error_msg_extra'
select @@session.read_only_error_msg_extra;
ERROR HY000: Variable 'read_only_error_msg_extra' is a GLOBAL variable
set @@session.read_only_error_msg_extra='This is a custom message';
ERROR HY000: Variable 'read_only_error_msg_extra' is a GLOBAL variable and should be set with SET GLOBAL
set global read_only_error_msg_extra = @saved_read_only_error_msg_extra;
set global super_read_only = false;
set global read_only = false;
28 changes: 28 additions & 0 deletions mysql-test/suite/sys_vars/t/read_only_error_msg_extra_basic.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--source include/not_embedded.inc

# Cannot set the value if server is not in read_only
--error ER_VARIABLE_NOT_SETTABLE_WITHOUT_READ_ONLY
set @@global.read_only_error_msg_extra='Not in read_only';

set global read_only = true;
set @@global.read_only_error_msg_extra = default;
select @@global.read_only_error_msg_extra;
set @saved_read_only_error_msg_extra = @@global.read_only_error_msg_extra;

set @@global.read_only_error_msg_extra='This is a custom message';

set global super_read_only = true;
set @@global.read_only_error_msg_extra='This is another custom message';

--error ER_WRONG_TYPE_FOR_VAR
set @@global.read_only_error_msg_extra=1;

--error ER_INCORRECT_GLOBAL_LOCAL_VAR
select @@session.read_only_error_msg_extra;
--error ER_GLOBAL_VARIABLE
set @@session.read_only_error_msg_extra='This is a custom message';

set global read_only_error_msg_extra = @saved_read_only_error_msg_extra;

set global super_read_only = false;
set global read_only = false;
1 change: 1 addition & 0 deletions sql/mysqld.cc
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ my_bool block_create_myisam = FALSE;
my_bool block_create_memory = FALSE;
my_bool block_create_no_primary_key = FALSE;
my_bool read_only= 0, opt_readonly= 0;
char* opt_read_only_error_msg_extra;
my_bool super_read_only = 0, opt_super_readonly = 0;
my_bool use_temp_pool, relay_log_purge;
my_bool relay_log_recovery;
Expand Down
1 change: 1 addition & 0 deletions sql/mysqld.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ extern ulong slave_run_triggers_for_rbr;
extern ulonglong slave_type_conversions_options;
extern ulonglong admission_control_filter;
extern my_bool read_only, opt_readonly, super_read_only, opt_super_readonly;
extern char* opt_read_only_error_msg_extra;
extern my_bool send_error_before_closing_timed_out_connection;
extern my_bool allow_document_type;
extern my_bool block_create_myisam;
Expand Down
3 changes: 3 additions & 0 deletions sql/share/errmsg-utf8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7229,6 +7229,9 @@ ER_CONNECTION_TIMEOUT

ER_OPTION_PREVENTS_STATEMENT_EXTRA_INFO
eng "The MySQL server is running with the %s option so it cannot execute this statement. %s"

ER_VARIABLE_NOT_SETTABLE_WITHOUT_READ_ONLY
eng "The system variable %.200s can only be set in read-only (super) status."
#
# End of 5.6 error messages.
#
6 changes: 6 additions & 0 deletions sql/sql_parse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9920,6 +9920,12 @@ int get_active_master_info(std::string *str_ptr)
*str_ptr += active_mi->host;
*str_ptr += ", master_port: ";
*str_ptr += std::to_string(active_mi->port);
const char *extra_str = opt_read_only_error_msg_extra;
if (extra_str && extra_str[0])
{
*str_ptr += ". ";
*str_ptr += extra_str;
}
return ER_OPTION_PREVENTS_STATEMENT_EXTRA_INFO;
}
#endif
Expand Down
20 changes: 20 additions & 0 deletions sql/sys_vars.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5505,3 +5505,23 @@ static Sys_var_uint Sys_select_into_file_fsync_timeout(
"SELECT INTO OUTFILE",
SESSION_VAR(select_into_file_fsync_timeout), CMD_LINE(OPT_ARG),
VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));

static bool check_read_only_error_msg_extra(
sys_var *self, THD *thd, set_var *var)
{
if (!opt_readonly && !opt_super_readonly)
{
my_error(ER_VARIABLE_NOT_SETTABLE_WITHOUT_READ_ONLY,
MYF(0),
var->var->name.str);
return true;
}
return false;
}
static Sys_var_charptr Sys_read_only_error_msg_extra(
"read_only_error_msg_extra",
"Set this variable to print out extra error information, "
"which will be appended to read_only error messages.",
GLOBAL_VAR(opt_read_only_error_msg_extra), CMD_LINE(OPT_ARG),
IN_SYSTEM_CHARSET, DEFAULT(""), NO_MUTEX_GUARD, NOT_IN_BINLOG,
ON_CHECK(check_read_only_error_msg_extra));

0 comments on commit 9f00827

Please sign in to comment.