From 1864d9596d9531427f1d63f86ada9e0cb21b51db Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 28 Sep 2012 02:06:56 +0300 Subject: [PATCH 1/6] Implementation of Multi-source replication (MDEV:253) Documentation of the feature can be found at: http://kb.askmonty.org/en/multi-source-replication/ This code is based on code from Taobao, developed by Plinux BUILD/SETUP.sh: Added -Wno-invalid-offsetof to get rid of warning of offsetof() on C++ class (safe in the contex we use it) client/mysqltest.cc: Added support for error names starting with 'W' Added connection_name support to --sync_with_master cmake/maintainer.cmake: Added -Wno-invalid-offsetof to get rid of warning of offsetof() on C++ class (safe in the contex we use it) mysql-test/r/mysqltest.result: Updated results mysql-test/r/parser.result: Updated results mysql-test/suite/multi_source/my.cnf: Setup of multi-master tests mysql-test/suite/multi_source/simple.result: Simple basic test of multi-source functionality mysql-test/suite/multi_source/simple.test: Simple basic test of multi-source functionality mysql-test/suite/multi_source/syntax.result: Test of multi-source syntax mysql-test/suite/multi_source/syntax.test: Test of multi-source syntax mysql-test/suite/rpl/r/rpl_rotate_logs.result: Updated results because of new error messages mysql-test/t/parser.test: Updated test as master_pos_wait() now takes more arguments than before sql/event_scheduler.cc: No reason to initialize slave_thread (it's guaranteed to be zero here) sql/item_create.cc: Added connection_name argument to master_pos_wait() Simplified code sql/item_func.cc: Added connection_name argument to master_pos_wait() sql/item_func.h: Added connection_name argument to master_pos_wait() sql/log.cc: Added tag "Master 'connection_name'" to slave errors that has a connection name. sql/mysqld.cc: Added variable mysqld_server_initialized so that other functions can test if server is fully initialized. Free all slave data in one place (fewer ifdef's) Removed not needed call to close_active_mi() Initialize slaves() later in startup to ensure that everthing is really initialized when slaves start. Made status variable slave_running multi-source safe sql/mysqld.h: Added mysqld_server_initialized sql/rpl_mi.cc: Store connection name and cmp_connection_name (only used for show full slave status) in Master_info Added code for Master_info_index, which handles storage of multi-master information Don't write the empty "" connection_name to multi-master.info file. This is handled by the original code. sql/rpl_mi.h: Added connection_name and Master_info_index sql/rpl_rli.cc: Added connection_name to relay log files. sql/rpl_rli.h: Fixed type of slave_skip_counter as we now access it directly in sys_vars.cc, so it must be uint sql/share/errmsg-utf8.txt: Added new error messages needed for multi-source Added multi-source name to error ER_MASTER_INFO and WARN_NO_MASTER_INFO sql/slave.cc: Moved things a bit around to make it easier to handle error conditions. Create a global master_info_index and add the "" connection to it Ensure that new Master_info doesn't fail. Don't call terminate_slave_threads(active_mi..) on end_slave() as this is now done automaticly when deleting master_info_index. Delete not needed function close_active_mi(). One can achive same thing by calling end_slave(). Added support for SHOW FULL SLAVE STATUS (show status for all master connections with connection_name as first column) sql/slave.h: Added new prototypes sql/sql_base.cc: More DBUG_PRINT sql/sql_class.cc: Reset thd->connection_name and thd-->default_master_connection sql/sql_class.h: Added thd->connection_name and thd-->default_master_connection Added slave_skip_count to variables to make changing the @@sql_slave_skip_count variable thread safe sql/sql_const.h: Added MAX_CONNECTION_NAME sql/sql_lex.cc: Reset 'lex->verbose' (to simplify some sql_yacc.yy code) sql/sql_lex.h: Added connection_name sql/sql_parse.cc: Added support for connection_name to all SLAVE commands. - Instead of using active_mi, we now get the current Master_info from master_info_index. - Create new replication threads with CHANGE MASTER - Added support for show_all_master_info() sql/sql_reload.cc: Made reset/full slave use master_info_index->get_master_info() instead of active_mi. If one uses 'RESET SLAVE "connection_name" all' the connection is removed from master_info_index. sql/sql_repl.cc: sql_slave_skip_counter is moved to thd->variables to make it thread safe and fix some bugs with it Add connection name to relay log files. Added connection name to errors. Added some logging for multi-master if log_warnings > 1 stop_slave(): - Don't check if thd is set. It's guaranteed to always be set. change_master(): - Check for duplicate connection names in change_master() - Check for wrong arguments first in file (to simplify error handling) - Register new connections in master_info_index sql/sql_yacc.yy: Added optional connection_name to a all relevant master/slave commands sql/strfunc.cc: my_global.h shoud always be included first. sql/sys_vars.cc: Added variable default_master_connection Made variable sql_slave_skip_counter multi-source safe sql/sys_vars.h: Added Sys_var_session_lexstring (needed for default_master_connection) Added Sys_var_multi_source_uint (needed for sql_slave_skip_counter). --- BUILD/SETUP.sh | 2 +- client/mysqltest.cc | 42 +- cmake/maintainer.cmake | 2 +- mysql-test/r/mysqltest.result | 2 +- mysql-test/r/parser.result | 2 +- mysql-test/suite/multi_source/my.cnf | 22 + mysql-test/suite/multi_source/simple.result | 64 +++ mysql-test/suite/multi_source/simple.test | 38 ++ .../suite/multi_source/skip_counter.result | 81 +++ .../suite/multi_source/skip_counter.test | 126 +++++ mysql-test/suite/multi_source/syntax.result | 89 ++++ mysql-test/suite/multi_source/syntax.test | 77 +++ mysql-test/suite/rpl/r/rpl_rotate_logs.result | 4 +- mysql-test/t/parser.test | 2 +- sql/event_scheduler.cc | 1 - sql/item_create.cc | 23 +- sql/item_func.cc | 34 +- sql/item_func.h | 3 + sql/log.cc | 21 +- sql/mysqld.cc | 68 +-- sql/mysqld.h | 2 +- sql/rpl_mi.cc | 472 +++++++++++++++++- sql/rpl_mi.h | 51 +- sql/rpl_rli.cc | 22 +- sql/rpl_rli.h | 3 +- sql/share/errmsg-utf8.txt | 19 +- sql/slave.cc | 199 ++++++-- sql/slave.h | 9 +- sql/sql_base.cc | 5 + sql/sql_class.cc | 10 + sql/sql_class.h | 10 + sql/sql_const.h | 1 + sql/sql_lex.cc | 1 + sql/sql_lex.h | 1 + sql/sql_parse.cc | 107 ++-- sql/sql_reload.cc | 17 +- sql/sql_repl.cc | 127 +++-- sql/sql_yacc.yy | 53 +- sql/strfunc.cc | 1 + sql/sys_vars.cc | 112 +++-- sql/sys_vars.h | 142 ++++++ 41 files changed, 1833 insertions(+), 234 deletions(-) create mode 100644 mysql-test/suite/multi_source/my.cnf create mode 100644 mysql-test/suite/multi_source/simple.result create mode 100644 mysql-test/suite/multi_source/simple.test create mode 100644 mysql-test/suite/multi_source/skip_counter.result create mode 100644 mysql-test/suite/multi_source/skip_counter.test create mode 100644 mysql-test/suite/multi_source/syntax.result create mode 100644 mysql-test/suite/multi_source/syntax.test diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index de3cb4890a9..5154f64b98f 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -139,7 +139,7 @@ else # C warnings c_warnings="$warnings" # C++ warnings - cxx_warnings="$warnings -Wno-unused-parameter" + cxx_warnings="$warnings -Wno-unused-parameter -Wno-invalid-offsetof" # cxx_warnings="$cxx_warnings -Woverloaded-virtual -Wsign-promo" cxx_warnings="$cxx_warnings -Wnon-virtual-dtor" debug_extra_cflags="-O0 -g3 -gdwarf-2" diff --git a/client/mysqltest.cc b/client/mysqltest.cc index bb89db4b231..f824d53ed1b 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -253,6 +253,8 @@ static void init_re(void); static int match_re(my_regex_t *, char *); static void free_re(void); +static char *get_string(char **to_ptr, char **from_ptr, + struct st_command *command); static int replace(DYNAMIC_STRING *ds_str, const char *search_str, ulong search_len, const char *replace_str, ulong replace_len); @@ -4580,7 +4582,8 @@ void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused))) } -void do_sync_with_master2(struct st_command *command, long offset) +void do_sync_with_master2(struct st_command *command, long offset, + const char *connection_name) { MYSQL_RES *res; MYSQL_ROW row; @@ -4591,8 +4594,9 @@ void do_sync_with_master2(struct st_command *command, long offset) if (!master_pos.file[0]) die("Calling 'sync_with_master' without calling 'save_master_pos'"); - sprintf(query_buf, "select master_pos_wait('%s', %ld, %d)", - master_pos.file, master_pos.pos + offset, timeout); + sprintf(query_buf, "select master_pos_wait('%s', %ld, %d, '%s')", + master_pos.file, master_pos.pos + offset, timeout, + connection_name); if (mysql_query(mysql, query_buf)) die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql), @@ -4652,16 +4656,32 @@ void do_sync_with_master(struct st_command *command) long offset= 0; char *p= command->first_argument; const char *offset_start= p; + char *start, *buff= 0; + start= (char*) ""; + if (*offset_start) { for (; my_isdigit(charset_info, *p); p++) offset = offset * 10 + *p - '0'; - if(*p && !my_isspace(charset_info, *p)) + if (*p && !my_isspace(charset_info, *p) && *p != ',') die("Invalid integer argument \"%s\"", offset_start); + + while (*p && my_isspace(charset_info, *p)) + p++; + if (*p == ',') + { + p++; + while (*p && my_isspace(charset_info, *p)) + p++; + start= buff= (char*)my_malloc(strlen(p)+1,MYF(MY_WME | MY_FAE)); + get_string(&buff, &p, command); + } command->last_argument= p; } - do_sync_with_master2(command, offset); + do_sync_with_master2(command, offset, start); + if (buff) + my_free(start); return; } @@ -5286,7 +5306,7 @@ void do_get_errcodes(struct st_command *command) { die("The sqlstate definition must start with an uppercase S"); } - else if (*p == 'E') + else if (*p == 'E' || *p == 'W') { /* Error name string */ @@ -5295,9 +5315,9 @@ void do_get_errcodes(struct st_command *command) to->type= ERR_ERRNO; DBUG_PRINT("info", ("ERR_ERRNO: %d", to->code.errnum)); } - else if (*p == 'e') + else if (*p == 'e' || *p == 'w') { - die("The error name definition must start with an uppercase E"); + die("The error name definition must start with an uppercase E or W"); } else { @@ -5360,8 +5380,8 @@ void do_get_errcodes(struct st_command *command) If string is a '$variable', return the value of the variable. */ -char *get_string(char **to_ptr, char **from_ptr, - struct st_command *command) +static char *get_string(char **to_ptr, char **from_ptr, + struct st_command *command) { char c, sep; char *to= *to_ptr, *from= *from_ptr, *start=to; @@ -9288,7 +9308,7 @@ int main(int argc, char **argv) select_connection(command); else select_connection_name("slave"); - do_sync_with_master2(command, 0); + do_sync_with_master2(command, 0, ""); break; } case Q_COMMENT: diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake index a70226e2b6e..d52405e8bcc 100644 --- a/cmake/maintainer.cmake +++ b/cmake/maintainer.cmake @@ -18,7 +18,7 @@ INCLUDE(CheckCCompilerFlag) # Setup GCC (GNU C compiler) warning options. MACRO(SET_MYSQL_MAINTAINER_GNU_C_OPTIONS) SET(MY_MAINTAINER_WARNINGS - "-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -DFORCE_INIT_OF_VARS") + "-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Wno-invalid-offsetof -DFORCE_INIT_OF_VARS") CHECK_C_COMPILER_FLAG("-Wno-missing-field-initializers" HAVE_NO_MISSING_FIELD_INITIALIZERS) diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index fdb3029059f..d08ffd96a04 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -232,7 +232,7 @@ mysqltest: At line 2: Spurious text after `query` expression mysqltest: At line 1: Missing argument(s) to 'error' mysqltest: At line 1: Missing argument(s) to 'error' mysqltest: At line 1: The sqlstate definition must start with an uppercase S -mysqltest: At line 1: The error name definition must start with an uppercase E +mysqltest: At line 1: The error name definition must start with an uppercase E or W mysqltest: At line 1: Invalid argument to error: '9eeeee' - the errno may only consist of digits[0-9] mysqltest: At line 1: Invalid argument to error: '1sssss' - the errno may only consist of digits[0-9] mysqltest: At line 1: The sqlstate must be exactly 5 chars long diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 10700d0ba73..54378f16d49 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -441,7 +441,7 @@ select master_pos_wait(); ERROR 42000: Incorrect parameter count in the call to native function 'master_pos_wait' select master_pos_wait(1); ERROR 42000: Incorrect parameter count in the call to native function 'master_pos_wait' -select master_pos_wait(1, 2, 3, 4); +select master_pos_wait(1, 2, 3, 4, 5); ERROR 42000: Incorrect parameter count in the call to native function 'master_pos_wait' select rand(1, 2, 3); ERROR 42000: Incorrect parameter count in the call to native function 'rand' diff --git a/mysql-test/suite/multi_source/my.cnf b/mysql-test/suite/multi_source/my.cnf new file mode 100644 index 00000000000..dd57fd2199f --- /dev/null +++ b/mysql-test/suite/multi_source/my.cnf @@ -0,0 +1,22 @@ +# cat t/multisource1.cnf +!include include/default_mysqld.cnf +!include include/default_client.cnf + +[mysqld.1] +server-id=1 +log-bin=master-bin + +[mysqld.2] +server-id=2 +log-bin=master-bin + +[mysqld.3] +server-id=3 + +[ENV] +SERVER_MYPORT_1= @mysqld.1.port +SERVER_MYSOCK_1= @mysqld.1.socket +SERVER_MYPORT_2= @mysqld.2.port +SERVER_MYSOCK_2= @mysqld.2.socket +SERVER_MYPORT_3= @mysqld.3.port +SERVER_MYSOCK_3= @mysqld.3.socket diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result new file mode 100644 index 00000000000..7448e0a0113 --- /dev/null +++ b/mysql-test/suite/multi_source/simple.result @@ -0,0 +1,64 @@ +change master 'slave1' to master_port=MYPORT_1, master_host='127.0.0.1', master_user='root'; +change master 'slave2' to master_port=MYPORT_2, master_host='127.0.0.1', master_user='root'; +start slave 'slave1'; +start slave 'slave2'; +show full slave status; +Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id +slave1 Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 mysqld-relay-bin-slave1.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 1 +slave2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 +stop slave 'slave1'; +show slave 'slave1' status; +Slave_IO_State +Master_Host 127.0.0.1 +Master_User root +Master_Port MYPORT_1 +Connect_Retry 60 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos 286 +Relay_Log_File mysqld-relay-bin-slave1.000002 +Relay_Log_Pos 572 +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running No +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos 286 +Relay_Log_Space 875 +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master NULL +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 0 +Last_SQL_Error +Replicate_Ignore_Server_Ids +Master_Server_Id 1 +reset slave 'slave1'; +show full slave status; +Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id +slave1 127.0.0.1 root MYPORT_1 60 4 mysqld-relay-bin-slave1.000001 4 No No 0 0 0 265 None 0 No NULL No 0 0 1 +slave2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 +reset slave 'slave1' all; +show full slave status; +Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id +slave2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 +stop slave 'slave2'; +show full slave status; +Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id +slave2 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 No No 0 0 286 875 None 0 No NULL No 0 0 2 +reset slave 'slave2' all; diff --git a/mysql-test/suite/multi_source/simple.test b/mysql-test/suite/multi_source/simple.test new file mode 100644 index 00000000000..97696c6e75f --- /dev/null +++ b/mysql-test/suite/multi_source/simple.test @@ -0,0 +1,38 @@ +# +# Simple multi-master test +# + +--connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3) + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +eval change master 'slave1' to master_port=$SERVER_MYPORT_1, master_host='127.0.0.1', master_user='root'; +--replace_result $SERVER_MYPORT_2 MYPORT_2 +eval change master 'slave2' to master_port=$SERVER_MYPORT_2, master_host='127.0.0.1', master_user='root'; +start slave 'slave1'; +start slave 'slave2'; +--sleep 5 + +--replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 +show full slave status; + +stop slave 'slave1'; + +--replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 +query_vertical show slave 'slave1' status; + +reset slave 'slave1'; +--replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 +show full slave status; + +reset slave 'slave1' all; +--replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 +show full slave status; + +stop slave 'slave2'; +--replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 +show full slave status; + +# +# clean up +# +reset slave 'slave2' all; diff --git a/mysql-test/suite/multi_source/skip_counter.result b/mysql-test/suite/multi_source/skip_counter.result new file mode 100644 index 00000000000..1fb1c255d80 --- /dev/null +++ b/mysql-test/suite/multi_source/skip_counter.result @@ -0,0 +1,81 @@ +connect master1,127.0.0.1,root,,,$SERVER_MYPORT_1; +drop database if exists db; +create database db; +create table db.t1 (i int) engine=MyISAM; +connect master2,127.0.0.1,root,,,$SERVER_MYPORT_2; +drop database if exists db; +create database db; +create table db.t2 (i int) engine=MyISAM; +connect slave,127.0.0.1,root,,,$SERVER_MYPORT_3; +change master 'master1' to +master_port=MYPORT_1, +master_host='127.0.0.1', +master_user='root'; +start slave 'master1'; +set default_master_connection = 'master1'; +include/wait_for_slave_to_start.inc +set default_master_connection = 'master2'; +change master 'master2' to +master_port=MYPORT_2, +master_host='127.0.0.1', +master_user='root'; +set global sql_slave_skip_counter = 2; +select @@global.sql_slave_skip_counter; +@@global.sql_slave_skip_counter +2 +select @@session.sql_slave_skip_counter; +@@session.sql_slave_skip_counter +2 +set session sql_slave_skip_counter = 3; +select @@global.sql_slave_skip_counter; +@@global.sql_slave_skip_counter +3 +select @@session.sql_slave_skip_counter; +@@session.sql_slave_skip_counter +3 +set global sql_slave_skip_counter= default; +select @@global.sql_slave_skip_counter; +@@global.sql_slave_skip_counter +0 +select @@session.sql_slave_skip_counter; +@@session.sql_slave_skip_counter +0 +set global sql_slave_skip_counter= 3; +set default_master_connection = 'master1'; +select @@session.sql_slave_skip_counter; +@@session.sql_slave_skip_counter +0 +set default_master_connection = 'qqq'; +select @@session.sql_slave_skip_counter; +@@session.sql_slave_skip_counter +0 +Warnings: +Warning 1617 There is no master connection 'qqq' +set default_master_connection = 'master2'; +select @@session.sql_slave_skip_counter; +@@session.sql_slave_skip_counter +3 +start slave 'master2'; +include/wait_for_slave_to_start.inc +set default_master_connection = ''; +connection master2; +connection slave; +show tables in db; +Tables_in_db +t1 +t2 +drop database db; +set default_master_connection = 'master1'; +stop slave; +include/wait_for_slave_to_stop.inc +set default_master_connection = 'master2'; +stop slave; +include/wait_for_slave_to_stop.inc +set global sql_slave_skip_counter = 0; +disconnect slave; +connection master1; +drop database db; +disconnect master1; +connection master2; +drop database db; +disconnect master2; diff --git a/mysql-test/suite/multi_source/skip_counter.test b/mysql-test/suite/multi_source/skip_counter.test new file mode 100644 index 00000000000..fe5df69097a --- /dev/null +++ b/mysql-test/suite/multi_source/skip_counter.test @@ -0,0 +1,126 @@ +# +# Test of sql_slave_skip_counter +# + +--enable_connect_log + +# Create a schema and a table i +# on the 1st master + +--connect (master1,127.0.0.1,root,,,$SERVER_MYPORT_1) + +--disable_warnings +drop database if exists db; +--enable_warnings +create database db; +create table db.t1 (i int) engine=MyISAM; +--save_master_pos + + +# Create the same schema and another table +# on the 2nd master + +--connect (master2,127.0.0.1,root,,,$SERVER_MYPORT_2) + +--disable_warnings +drop database if exists db; +--enable_warnings +create database db; +create table db.t2 (i int) engine=MyISAM; + +--connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3) +--disable_connect_log + +# Start replication from the first master + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +eval change master 'master1' to +master_port=$SERVER_MYPORT_1, +master_host='127.0.0.1', +master_user='root'; + +start slave 'master1'; +set default_master_connection = 'master1'; +--source include/wait_for_slave_to_start.inc +--sync_with_master 0,'master1' + +# Start replication from the second master + +set default_master_connection = 'master2'; + +--replace_result $SERVER_MYPORT_2 MYPORT_2 +eval change master 'master2' to +master_port=$SERVER_MYPORT_2, +master_host='127.0.0.1', +master_user='root'; + +# the schema creation will be replicated from the 1st master, +# so we want to skip it in the second replication connection. + +# Normally it should have been 2 events, but +# currently Binlog_checkpoint also counts. Maybe we'll need +# to modify the test later + +--let $skip_counter_saved = `select @@global.sql_slave_skip_counter` +set global sql_slave_skip_counter = 2; +select @@global.sql_slave_skip_counter; +select @@session.sql_slave_skip_counter; +set session sql_slave_skip_counter = 3; +select @@global.sql_slave_skip_counter; +select @@session.sql_slave_skip_counter; +set global sql_slave_skip_counter= default; +select @@global.sql_slave_skip_counter; +select @@session.sql_slave_skip_counter; +set global sql_slave_skip_counter= 3; +set default_master_connection = 'master1'; +select @@session.sql_slave_skip_counter; +set default_master_connection = 'qqq'; +select @@session.sql_slave_skip_counter; +set default_master_connection = 'master2'; +select @@session.sql_slave_skip_counter; + +start slave 'master2'; +--source include/wait_for_slave_to_start.inc +set default_master_connection = ''; + +--enable_connect_log + +--connection master2 +--save_master_pos + +--connection slave + +--disable_connect_log +--sync_with_master 0,'master2' + +# If the skip_counter worked as expected, we should +# get here (replication shouldn't have broken) +# and should see both tables here +# (drop database which came from master2 shoudn't have been executed +# so t1 should still exist) + +show tables in db; + +# Cleanup + +drop database db; +set default_master_connection = 'master1'; +stop slave; + +--source include/wait_for_slave_to_stop.inc +set default_master_connection = 'master2'; +stop slave; + +--source include/wait_for_slave_to_stop.inc +--eval set global sql_slave_skip_counter = $skip_counter_saved + +--enable_connect_log +--disconnect slave + +--connection master1 +drop database db; +--disconnect master1 + +--connection master2 +drop database db; +--disconnect master2 diff --git a/mysql-test/suite/multi_source/syntax.result b/mysql-test/suite/multi_source/syntax.result new file mode 100644 index 00000000000..23ea4d9fd3d --- /dev/null +++ b/mysql-test/suite/multi_source/syntax.result @@ -0,0 +1,89 @@ +include/master-slave.inc +[connection master] +show slave status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id +show slave '' status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id +show full slave status; +Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id +# +# Check error handling +# +show slave 'qqq' status; +ERROR HY000: There is no master connection 'qqq' +show slave 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' status; +ERROR HY000: There is no master connection 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' +show slave 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' status; +ERROR HY000: Incorrect arguments to MASTER_CONNECTION_NAME +change master 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' to master_host='dummy'; +ERROR HY000: Incorrect arguments to MASTER_CONNECTION_NAME +start slave 'qqq'; +ERROR HY000: There is no master connection 'qqq' +stop slave 'qqq'; +ERROR HY000: There is no master connection 'qqq' +slave 'qqq' start; +ERROR HY000: There is no master connection 'qqq' +slave 'qqq' stop; +ERROR HY000: There is no master connection 'qqq' +flush slave 'qqq'; +ERROR HY000: There is no master connection 'qqq' +reset slave 'qqq'; +ERROR HY000: There is no master connection 'qqq' +select master_pos_wait('master-bin.999999',0,2,'qqq'); +master_pos_wait('master-bin.999999',0,2,'qqq') +NULL +Warnings: +Warning 1617 There is no master connection 'qqq' +select master_pos_wait('master-bin.999999',0,2,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'); +master_pos_wait('master-bin.999999',0,2,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc') +NULL +Warnings: +Warning 1210 Incorrect arguments to MASTER_CONNECTION_NAME +# +# checking usage of default_master_connection; +# +select @@default_master_connection; +@@default_master_connection + +select @@global.default_master_connection; +ERROR HY000: Variable 'default_master_connection' is a SESSION variable +set @@global.default_master_connection='qqq'; +ERROR HY000: Variable 'default_master_connection' is a SESSION variable and can't be used with SET GLOBAL +set @@default_master_connection='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'; +ERROR 42000: Variable 'default_master_connection' can't be set to the value of 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' +select @@default_master_connection; +@@default_master_connection + +set @@default_master_connection='qqq'; +select @@default_master_connection; +@@default_master_connection +qqq +show variables like "default_master_connection"; +Variable_name Value +default_master_connection qqq +show slave status; +ERROR HY000: There is no master connection 'qqq' +select master_pos_wait('master-bin.999999',0,2); +master_pos_wait('master-bin.999999',0,2) +NULL +Warnings: +Warning 1617 There is no master connection 'qqq' +set @@default_master_connection=''; +select master_pos_wait('master-bin.999999',0,2); +master_pos_wait('master-bin.999999',0,2) +-1 +set @@default_master_connection=''; +# +# checking variables +# +show status like "Slave_running"; +Variable_name Value +Slave_running ON +set @@default_master_connection='qqq'; +show status like "Slave_running"; +Variable_name Value +Slave_running OFF +Warnings: +Warning 1617 There is no master connection 'qqq' +set @@default_master_connection=''; +include/rpl_end.inc diff --git a/mysql-test/suite/multi_source/syntax.test b/mysql-test/suite/multi_source/syntax.test new file mode 100644 index 00000000000..af793fe6100 --- /dev/null +++ b/mysql-test/suite/multi_source/syntax.test @@ -0,0 +1,77 @@ +# Test multi master syntax +source include/master-slave.inc; + +# Check syntax of multi source replication + +show slave status; +show slave '' status; +show full slave status; + +--echo # +--echo # Check error handling +--echo # + +--error WARN_NO_MASTER_INFO +show slave 'qqq' status; +--error WARN_NO_MASTER_INFO +show slave 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' status; +--error ER_WRONG_ARGUMENTS +show slave 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' status; +--error ER_WRONG_ARGUMENTS +change master 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc' to master_host='dummy'; + +--error WARN_NO_MASTER_INFO +start slave 'qqq'; +--error WARN_NO_MASTER_INFO +stop slave 'qqq'; +--error WARN_NO_MASTER_INFO +slave 'qqq' start; +--error WARN_NO_MASTER_INFO +slave 'qqq' stop; +--error WARN_NO_MASTER_INFO +flush slave 'qqq'; +--error WARN_NO_MASTER_INFO +reset slave 'qqq'; + +select master_pos_wait('master-bin.999999',0,2,'qqq'); +select master_pos_wait('master-bin.999999',0,2,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'); + +save_master_pos; +connection slave; +sync_with_master 0,''; +sync_with_master 0 ,''; +sync_with_master 0, ''; + +--echo # +--echo # checking usage of default_master_connection; +--echo # +select @@default_master_connection; + +--error 1238 +select @@global.default_master_connection; +--error 1228 +set @@global.default_master_connection='qqq'; +--error 1231 +set @@default_master_connection='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc'; +select @@default_master_connection; +set @@default_master_connection='qqq'; +select @@default_master_connection; +show variables like "default_master_connection"; + +--error WARN_NO_MASTER_INFO +show slave status; +select master_pos_wait('master-bin.999999',0,2); +set @@default_master_connection=''; +select master_pos_wait('master-bin.999999',0,2); + +set @@default_master_connection=''; + +--echo # +--echo # checking variables +--echo # +show status like "Slave_running"; +set @@default_master_connection='qqq'; +show status like "Slave_running"; +set @@default_master_connection=''; + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_rotate_logs.result b/mysql-test/suite/rpl/r/rpl_rotate_logs.result index f10e30c698d..783c02b961c 100644 --- a/mysql-test/suite/rpl/r/rpl_rotate_logs.result +++ b/mysql-test/suite/rpl/r/rpl_rotate_logs.result @@ -2,9 +2,9 @@ CALL mtr.add_suppression("Unsafe statement written to the binary log using state start slave; Got one of the listed errors start slave; -ERROR HY000: Could not initialize master info structure; more error messages can be found in the MariaDB error log +ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; -ERROR HY000: Could not initialize master info structure; more error messages can be found in the MariaDB error log +ERROR HY000: Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log reset slave; change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; reset master; diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index d477843b22b..2c8cfafb90a 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -553,7 +553,7 @@ select master_pos_wait(); -- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT select master_pos_wait(1); -- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT -select master_pos_wait(1, 2, 3, 4); +select master_pos_wait(1, 2, 3, 4, 5); -- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT select rand(1, 2, 3); diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index b41c9e2cda0..f107914f738 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -190,7 +190,6 @@ pre_init_event_thread(THD* thd) my_net_init(&thd->net, NULL); thd->security_ctx->set_user((char*)"event_scheduler"); thd->net.read_timeout= slave_net_timeout; - thd->slave_thread= 0; thd->variables.option_bits|= OPTION_AUTO_IS_NULL; thd->client_capabilities|= CLIENT_MULTI_RESULTS; mysql_mutex_lock(&LOCK_thread_count); diff --git a/sql/item_create.cc b/sql/item_create.cc index 96837a8f262..87e90ed4f8b 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -4393,27 +4393,36 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name, if (item_list != NULL) arg_count= item_list->elements; + if (arg_count < 2 || arg_count >4) + { + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str); + return func; + } + + thd->lex->safe_to_cache_query= 0; + + Item *param_1= item_list->pop(); + Item *param_2= item_list->pop(); switch (arg_count) { case 2: { - Item *param_1= item_list->pop(); - Item *param_2= item_list->pop(); func= new (thd->mem_root) Item_master_pos_wait(param_1, param_2); - thd->lex->safe_to_cache_query= 0; break; } case 3: { - Item *param_1= item_list->pop(); - Item *param_2= item_list->pop(); Item *param_3= item_list->pop(); func= new (thd->mem_root) Item_master_pos_wait(param_1, param_2, param_3); thd->lex->safe_to_cache_query= 0; break; } - default: + case 4: { - my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str); + Item *param_3= item_list->pop(); + Item *param_4= item_list->pop(); + func= new (thd->mem_root) Item_master_pos_wait(param_1, param_2, param_3, + param_4); + thd->lex->safe_to_cache_query= 0; break; } } diff --git a/sql/item_func.cc b/sql/item_func.cc index 441eb37d701..5db91cd4231 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3866,13 +3866,45 @@ longlong Item_master_pos_wait::val_int() #ifdef HAVE_REPLICATION longlong pos = (ulong)args[1]->val_int(); longlong timeout = (arg_count==3) ? args[2]->val_int() : 0 ; - if ((event_count = active_mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2) + String connection_name_buff; + LEX_STRING connection_name; + Master_info *mi; + if (arg_count == 4) + { + String *con; + if (!(con= args[3]->val_str(&connection_name_buff))) + goto err; + + connection_name.str= (char*) con->ptr(); + connection_name.length= con->length(); + if (check_master_connection_name(&connection_name)) + { + my_error(ER_WRONG_ARGUMENTS, MYF(ME_JUST_WARNING), + "MASTER_CONNECTION_NAME"); + goto err; + } + } + else + connection_name= thd->variables.default_master_connection; + + if (!(mi= master_info_index->get_master_info(&connection_name, + MYSQL_ERROR::WARN_LEVEL_WARN))) + goto err; + if ((event_count = mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2) { null_value = 1; event_count=0; } #endif return event_count; + +#ifdef HAVE_REPLICATION +err: + { + null_value = 1; + return 0; + } +#endif } diff --git a/sql/item_func.h b/sql/item_func.h index 586444e0e4e..07b246b3ccd 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -496,6 +496,8 @@ public: { collation.set_numeric(); fix_char_length(21); } Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { collation.set_numeric(); fix_char_length(21); } + Item_int_func(Item *a,Item *b,Item *c, Item *d) :Item_func(a,b,c,d) + { collation.set_numeric(); fix_char_length(21); } Item_int_func(List &list) :Item_func(list) { collation.set_numeric(); fix_char_length(21); } Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) @@ -1522,6 +1524,7 @@ class Item_master_pos_wait :public Item_int_func public: Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {} Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {} + Item_master_pos_wait(Item *a,Item *b, Item *c, Item *d) :Item_int_func(a,b,c,d) {} longlong val_int(); const char *func_name() const { return "master_pos_wait"; } void fix_length_and_dec() { max_length=21; maybe_null=1;} diff --git a/sql/log.cc b/sql/log.cc index e4db7b2eb0f..54340f94679 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -40,6 +40,7 @@ #include "rpl_rli.h" #include "sql_audit.h" #include "log_slow.h" +#include "mysqld.h" #include #include @@ -6980,16 +6981,33 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer, time_t skr; struct tm tm_tmp; struct tm *start; + THD *thd; + int tag_length= 0; + char tag[NAME_LEN]; DBUG_ENTER("print_buffer_to_file"); DBUG_PRINT("enter",("buffer: %s", buffer)); + if (mysqld_server_initialized && (thd= current_thd)) + { + if (thd->connection_name.length) + { + /* + Add tag for slaves so that the user can see from which connection + the error originates. + */ + tag_length= my_snprintf(tag, sizeof(tag), ER(ER_MASTER_LOG_PREFIX), + (int) thd->connection_name.length, + thd->connection_name.str); + } + } + mysql_mutex_lock(&LOCK_error_log); skr= my_time(0); localtime_r(&skr, &tm_tmp); start=&tm_tmp; - fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %.*s\n", + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %.*s%.*s\n", start->tm_year % 100, start->tm_mon+1, start->tm_mday, @@ -6998,6 +7016,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer, start->tm_sec, (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? "Warning" : "Note"), + tag_length, tag, (int) length, buffer); fflush(stderr); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 96ea789edd7..defd3a71b93 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -673,8 +673,7 @@ pthread_attr_t connection_attrib; mysql_mutex_t LOCK_server_started; mysql_cond_t COND_server_started; -int mysqld_server_started= 0; - +int mysqld_server_started=0, mysqld_server_initialized= 0; File_parser_dummy_hook file_parser_dummy_hook; /* replication parameters, if master_host is not NULL, we are a slave */ @@ -1761,7 +1760,12 @@ void clean_up(bool print_message) if (cleanup_done++) return; /* purecov: inspected */ - close_active_mi(); +#ifdef HAVE_REPLICATION + // We must call end_slave() as clean_up may have been called during startup + end_slave(); + if (use_slave_mask) + bitmap_free(&slave_error_mask); +#endif stop_handle_manager(); release_ddl_log(); @@ -1776,10 +1780,6 @@ void clean_up(bool print_message) injector::free_instance(); mysql_bin_log.cleanup(); -#ifdef HAVE_REPLICATION - if (use_slave_mask) - bitmap_free(&slave_error_mask); -#endif my_tz_free(); my_dboptions_cache_free(); #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -4626,6 +4626,7 @@ int mysqld_main(int argc, char **argv) } #endif + mysqld_server_started= mysqld_server_initialized= 0; orig_argc= argc; orig_argv= argv; my_getopt_use_args_separator= TRUE; @@ -4890,16 +4891,6 @@ int mysqld_main(int argc, char **argv) opt_skip_slave_start= 1; binlog_unsafe_map_init(); - /* - init_slave() must be called after the thread keys are created. - Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other - places) assume that active_mi != 0, so let's fail if it's 0 (out of - memory); a message has already been printed. - */ - if (init_slave() && !active_mi) - { - unireg_abort(1); - } #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE initialize_performance_schema_acl(opt_bootstrap); @@ -4917,9 +4908,17 @@ int mysqld_main(int argc, char **argv) execute_ddl_log_recovery(); + /* + We must have LOCK_open before LOCK_global_system_variables because + LOCK_open is hold while sql_plugin.c::intern_sys_var_ptr() is called. + */ + mysql_mutex_record_order(&LOCK_open, &LOCK_global_system_variables); + if (Events::init(opt_noacl || opt_bootstrap)) unireg_abort(1); + mysqld_server_initialized= 1; + if (opt_bootstrap) { select_thread_in_use= 0; // Allow 'kill' to work @@ -4932,21 +4931,27 @@ int mysqld_main(int argc, char **argv) exit(0); } } + + create_shutdown_thread(); + start_handle_manager(); + + /* + init_slave() must be called after the thread keys are created. + Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other + places) assume that active_mi != 0, so let's fail if it's 0 (out of + memory); a message has already been printed. + */ + if (init_slave() && !active_mi) + { + unireg_abort(1); + } + if (opt_init_file && *opt_init_file) { if (read_init_file(opt_init_file)) unireg_abort(1); } - /* - We must have LOCK_open before LOCK_global_system_variables because - LOCK_open is hold while sql_plugin.c::intern_sys_var_ptr() is called. - */ - mysql_mutex_record_order(&LOCK_open, &LOCK_global_system_variables); - - create_shutdown_thread(); - start_handle_manager(); - sql_print_information(ER_DEFAULT(ER_STARTUP),my_progname,server_version, ((unix_sock == INVALID_SOCKET) ? (char*) "" : mysqld_unix_port), @@ -6524,12 +6529,17 @@ static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff) static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff) { + Master_info *mi; var->type= SHOW_MY_BOOL; mysql_mutex_lock(&LOCK_active_mi); var->value= buff; - *((my_bool *)buff)= (my_bool) (active_mi && - active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT && - active_mi->rli.slave_running); + mi= master_info_index-> + get_master_info(&thd->variables.default_master_connection, + MYSQL_ERROR::WARN_LEVEL_WARN); + *((my_bool *)buff)= (my_bool) (mi && + mi->slave_running == + MYSQL_SLAVE_RUN_CONNECT && + mi->rli.slave_running); mysql_mutex_unlock(&LOCK_active_mi); return 0; } diff --git a/sql/mysqld.h b/sql/mysqld.h index 7a24b56dcb7..fd33ca0cf85 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -198,7 +198,7 @@ extern handlerton *myisam_hton; extern handlerton *heap_hton; extern const char *load_default_groups[]; extern struct my_option my_long_options[]; -extern int mysqld_server_started; +extern int mysqld_server_started, mysqld_server_initialized; extern "C" MYSQL_PLUGIN_IMPORT int orig_argc; extern "C" MYSQL_PLUGIN_IMPORT char **orig_argv; extern pthread_attr_t connection_attrib; diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 3c5a99121fa..3dc3e38f419 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -20,6 +20,7 @@ #include "unireg.h" // REQUIRED by other includes #include "rpl_mi.h" #include "slave.h" // SLAVE_MAX_HEARTBEAT_PERIOD +#include "strfunc.h" #ifdef HAVE_REPLICATION @@ -27,7 +28,8 @@ static void init_master_log_pos(Master_info* mi); -Master_info::Master_info(bool is_slave_recovery) +Master_info::Master_info(LEX_STRING *connection_name_arg, + bool is_slave_recovery) :Slave_reporting_capability("I/O"), ssl(0), ssl_verify_server_cert(1), fd(-1), io_thd(0), rli(is_slave_recovery), port(MYSQL_PORT), @@ -40,6 +42,21 @@ Master_info::Master_info(bool is_slave_recovery) ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0; ssl_cipher[0]= 0; ssl_key[0]= 0; + /* Store connection name and lower case connection name */ + connection_name.length= cmp_connection_name.length= + connection_name_arg->length; + if ((connection_name.str= (char*) my_malloc(connection_name_arg->length*2+2, + MYF(MY_WME)))) + { + cmp_connection_name.str= (connection_name.str + + connection_name_arg->length+1); + strmake(connection_name.str, connection_name_arg->str, + connection_name.length); + memcpy(cmp_connection_name.str, connection_name_arg->str, + connection_name.length+1); + my_casedn_str(system_charset_info, cmp_connection_name.str); + } + my_init_dynamic_array(&ignore_server_ids, sizeof(::server_id), 16, 16); bzero((char*) &file, sizeof(file)); mysql_mutex_init(key_master_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST); @@ -55,6 +72,7 @@ Master_info::Master_info(bool is_slave_recovery) Master_info::~Master_info() { + my_free(connection_name.str); delete_dynamic(&ignore_server_ids); mysql_mutex_destroy(&run_lock); mysql_mutex_destroy(&data_lock); @@ -407,7 +425,7 @@ file '%s')", fname); mi->master_log_name, (ulong) mi->master_log_pos)); - mi->rli.mi = mi; + mi->rli.mi= mi; if (init_relay_log_info(&mi->rli, slave_info_fname)) goto err; @@ -560,5 +578,455 @@ void end_master_info(Master_info* mi) DBUG_VOID_RETURN; } +/* Multi-Master By P.Linux */ +uchar *get_key_master_info(Master_info *mi, size_t *length, + my_bool not_used __attribute__((unused))) +{ + /* Return lower case name */ + *length= mi->cmp_connection_name.length; + return (uchar*) mi->cmp_connection_name.str; +} + +void free_key_master_info(Master_info *mi) +{ + DBUG_ENTER("free_key_master_info"); + terminate_slave_threads(mi,SLAVE_FORCE_ALL); + end_master_info(mi); + delete mi; + DBUG_VOID_RETURN; +} + +/** + Check if connection name for master_info is valid. + + It's valid if it's a valid system name, is less than + MAX_CONNECTION_NAME. + + @return + 0 ok + 1 error +*/ + +bool check_master_connection_name(LEX_STRING *name) +{ + if (name->length >= MAX_CONNECTION_NAME) + return 1; + return 0; +} + + +/** + Create a log file with a signed suffix. + + @param + res_file_name Store result here + length Length of res_file_name buffer + info_file Original file name (prefix) + separator Separator character + suffix Suffix + + @note + If suffix is an empty string, then we don't add any suffix. + This is to allow one to use this function also to generate old + file names without a prefix. +*/ + +void create_signed_file_name(char *res_file_name, uint length, + const char *info_file, + char separator, LEX_STRING *suffix) +{ + char buff[MAX_CONNECTION_NAME+1], res[MAX_CONNECTION_NAME+1], *p; + p= strmake(res_file_name, info_file, length); + if (suffix->length != 0 && p != info_file + length) + { + uint errors; + size_t res_length; + + *p++= separator; + /* Create null terminated string */ + strmake(buff, suffix->str, suffix->length); + /* Convert to lower case */ + my_casedn_str(system_charset_info, buff); + /* Convert to characters usable in a file name */ + res_length= strconvert(system_charset_info, buff, + &my_charset_filename, res, sizeof(res), &errors); + strmake(p, res, min(length - (p - res_file_name), res_length)); + } +} + + +Master_info_index::Master_info_index() +{ + index_file_name[0] = 0; + bzero((char*) &index_file, sizeof(index_file)); +} + +Master_info_index::~Master_info_index() +{ + /* This will close connection for all objects in the cache */ + my_hash_free(&master_info_hash); + end_io_cache(&index_file); + if (index_file.file > 0) + my_close(index_file.file, MYF(MY_WME)); +} + + +/* Load All Master_info from master.info.index File + * RETURN: + * 0 - All Success + * 1 - All Fail + * 2 - Some Success, Some Fail + */ + +bool Master_info_index::init_all_master_info() +{ + int thread_mask; + int err_num= 0, succ_num= 0; // The number of success read Master_info + char sign[MAX_CONNECTION_NAME]; + File index_file_nr; + size_t filename_length, dir_length; + DBUG_ENTER("init_all_master_info"); + + /* + Create the Master_info index file by prepending 'multi-' before + the master_info_file file name. + */ + fn_format(index_file_name, master_info_file, mysql_data_home, + "", MY_UNPACK_FILENAME); + filename_length= strlen(index_file_name) + 1; /* Count 0 byte */ + dir_length= dirname_length(index_file_name); + bmove_upp((uchar*) index_file_name + filename_length + 6, + (uchar*) index_file_name + filename_length, + filename_length - dir_length); + memcpy(index_file_name + dir_length, "multi-", 6); + + if ((index_file_nr= my_open(index_file_name, + O_RDWR | O_CREAT | O_BINARY , + MYF(MY_WME | ME_NOREFRESH))) < 0 || + my_sync(index_file_nr, MYF(MY_WME)) || + init_io_cache(&index_file, index_file_nr, + IO_SIZE, READ_CACHE, + my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)), + 0, MYF(MY_WME | MY_WAIT_IF_FULL))) + { + if (index_file_nr >= 0) + my_close(index_file_nr,MYF(0)); + + sql_print_error("Creation of Master_info index file '%s' failed", + index_file_name); + DBUG_RETURN(1); + } + + /* Initialize Master_info Hash Table */ + if (my_hash_init(&master_info_hash, system_charset_info, + MAX_REPLICATION_THREAD, 0, 0, + (my_hash_get_key) get_key_master_info, + (my_hash_free_key)free_key_master_info, HASH_UNIQUE)) + { + sql_print_error("Initializing Master_info hash table failed"); + DBUG_RETURN(1); + } + + reinit_io_cache(&index_file, READ_CACHE, 0L,0,0); + while (!init_strvar_from_file(sign, sizeof(sign), + &index_file, NULL)) + { + LEX_STRING connection_name; + Master_info *mi; + char buf_master_info_file[FN_REFLEN]; + char buf_relay_log_info_file[FN_REFLEN]; + + connection_name.str= sign; + connection_name.length= strlen(sign); + if (!(mi= new Master_info(&connection_name, relay_log_recovery)) || + mi->error()) + { + delete mi; + DBUG_RETURN(1); + } + + lock_slave_threads(mi); + init_thread_mask(&thread_mask,mi,0 /*not inverse*/); + + create_signed_file_name(buf_master_info_file, sizeof(buf_master_info_file), + master_info_file, '.', &connection_name); + create_signed_file_name(buf_relay_log_info_file, + sizeof(buf_relay_log_info_file), + relay_log_info_file, '.', &connection_name); + if (global_system_variables.log_warnings > 1) + sql_print_information("Reading Master_info: '%s' Relay_info:'%s'", + buf_master_info_file, buf_relay_log_info_file); + + if (init_master_info(mi, buf_master_info_file, buf_relay_log_info_file, + 0, thread_mask)) + { + err_num++; + sql_print_error("Initialized Master_info from '%s' failed", + buf_master_info_file); + if (!master_info_index->get_master_info(&connection_name, + MYSQL_ERROR::WARN_LEVEL_NOTE)) + { + /* Master_info is not in HASH; Add it */ + if (master_info_index->add_master_info(mi, FALSE)) + return 1; + succ_num++; + unlock_slave_threads(mi); + } + else + { + /* Master_info already in HASH */ + sql_print_error(ER(ER_CONNECTION_ALREADY_EXISTS), + (int) connection_name.length, connection_name.str); + unlock_slave_threads(mi); + delete mi; + } + continue; + } + else + { + /* Initialization of Master_info succeded. Add it to HASH */ + if (global_system_variables.log_warnings > 1) + sql_print_information("Initialized Master_info from '%s'", + buf_master_info_file); + if (master_info_index->get_master_info(&connection_name, + MYSQL_ERROR::WARN_LEVEL_NOTE)) + { + /* Master_info was already registered */ + sql_print_error(ER(ER_CONNECTION_ALREADY_EXISTS), + (int) connection_name.length, connection_name.str); + unlock_slave_threads(mi); + delete mi; + continue; + } + + /* Master_info was not registered; add it */ + if (master_info_index->add_master_info(mi, FALSE)) + return 1; + succ_num++; + unlock_slave_threads(mi); + + if (!opt_skip_slave_start) + { + if (start_slave_threads(1 /* need mutex */, + 0 /* no wait for start*/, + mi, + buf_master_info_file, + buf_relay_log_info_file, + SLAVE_IO | SLAVE_SQL)) + { + sql_print_error("Failed to create slave threads for connection %.*s", + (int) connection_name.length, + connection_name.str); + continue; + } + if (global_system_variables.log_warnings) + sql_print_information("Started replication for '%.*s'", + (int) connection_name.length, + connection_name.str); + } + } + } + + if (!err_num) // No Error on read Master_info + { + if (global_system_variables.log_warnings > 1) + sql_print_information("Reading of all Master_info entries succeded"); + DBUG_RETURN(0); + } + else if (succ_num) // Have some Error and some Success + { + sql_print_warning("Reading of some Master_info entries failed"); + DBUG_RETURN(2); + } + else // All failed + { + sql_print_error("Reading of all Master_info entries failed!"); + DBUG_RETURN(1); + } +} + + +/* Write new master.info to master.info.index File */ +bool Master_info_index::write_master_name_to_index_file(LEX_STRING *name, + bool do_sync) +{ + DBUG_ASSERT(my_b_inited(&index_file) != 0); + DBUG_ENTER("write_master_name_to_index_file"); + + /* Don't write default slave to master_info.index */ + if (name->length == 0) + DBUG_RETURN(0); + + reinit_io_cache(&index_file, WRITE_CACHE, + my_b_filelength(&index_file), 0, 0); + + if (my_b_write(&index_file, (uchar*) name->str, name->length) || + my_b_write(&index_file, (uchar*) "\n", 1) || + flush_io_cache(&index_file) || + (do_sync && my_sync(index_file.file, MYF(MY_WME)))) + { + sql_print_error("Write of new Master_info for '%.*s' to index file failed", + (int) name->length, name->str); + DBUG_RETURN(1); + } + + DBUG_RETURN(0); +} + + +/** + Get Master_info for a connection + + @param + connection_name Connection name + warning WARN_LEVEL_NOTE -> Don't print anything + WARN_LEVEL_WARN -> Issue warning if not exists + WARN_LEVEL_ERROR-> Issue error if not exists +*/ + +Master_info * +Master_info_index::get_master_info(LEX_STRING *connection_name, + MYSQL_ERROR::enum_warning_level warning) +{ + Master_info *mi; + char buff[MAX_CONNECTION_NAME+1], *res; + uint buff_length; + + /* Make name lower case for comparison */ + res= strmake(buff, connection_name->str, connection_name->length); + my_casedn_str(system_charset_info, buff); + buff_length= (size_t) (res-buff); + + mi= (Master_info*) my_hash_search(&master_info_hash, + (uchar*) buff, buff_length); + if (!mi && warning != MYSQL_ERROR::WARN_LEVEL_NOTE) + { + my_error(WARN_NO_MASTER_INFO, + MYF(warning == MYSQL_ERROR::WARN_LEVEL_WARN ? ME_JUST_WARNING : + 0), + (int) connection_name->length, + connection_name->str); + } + return mi; +} + + +/* Check Master_host & Master_port is duplicated or not */ +bool Master_info_index::check_duplicate_master_info(LEX_STRING *name_arg, + const char *host, + uint port) +{ + Master_info *mi; + + /* Get full host and port name */ + if ((mi= master_info_index->get_master_info(name_arg, + MYSQL_ERROR::WARN_LEVEL_NOTE))) + { + if (!host) + host= mi->host; + if (!port) + port= mi->port; + } + if (!host || !port) + return FALSE; // Not comparable yet + + for (uint i= 0; i < master_info_hash.records; ++i) + { + Master_info *tmp_mi; + tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i); + if (tmp_mi == mi) + continue; // Current connection + if (!strcasecmp(host, tmp_mi->host) && port == tmp_mi->port) + { + sql_print_error(ER(ER_CONNECTION_ALREADY_EXISTS), + (int) tmp_mi->connection_name.length, + tmp_mi->connection_name.str); + return TRUE; + } + } + return FALSE; +} + + +/* Add a Master_info class to Hash Table */ +bool Master_info_index::add_master_info(Master_info *mi, bool write_to_file) +{ + if (!my_hash_insert(&master_info_hash, (uchar*) mi)) + { + if (global_system_variables.log_warnings > 1) + sql_print_information("Added new Master_info '%.*s' to hash table", + (int) mi->connection_name.length, + mi->connection_name.str); + if (write_to_file) + return write_master_name_to_index_file(&mi->connection_name, 1); + return FALSE; + } + + /* Impossible error (EOM) ? */ + sql_print_error("Adding new entry '%.*s' to master_info failed", + (int) mi->connection_name.length, + mi->connection_name.str); + return TRUE; +} + + +/** + Remove a Master_info class From Hash Table + + TODO: Change this to use my_rename() to make the file name creation + atomic +*/ + +bool Master_info_index::remove_master_info(LEX_STRING *name) +{ + Master_info* mi; + DBUG_ENTER("remove_master_info"); + + if ((mi= get_master_info(name, MYSQL_ERROR::WARN_LEVEL_WARN))) + { + // Delete Master_info and rewrite others to file + if (!my_hash_delete(&master_info_hash, (uchar*) mi)) + { + File index_file_nr; + + // Close IO_CACHE and FILE handler fisrt + end_io_cache(&index_file); + my_close(index_file.file, MYF(MY_WME)); + + // Reopen File and truncate it + fn_format(index_file_name, master_info_file, mysql_data_home, + ".index", MY_UNPACK_FILENAME | MY_APPEND_EXT); + + if ((index_file_nr= my_open(index_file_name, + O_RDWR | O_CREAT | O_TRUNC | O_BINARY , + MYF(MY_WME))) < 0 || + init_io_cache(&index_file, index_file_nr, + IO_SIZE, WRITE_CACHE, + my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)), + 0, MYF(MY_WME | MY_WAIT_IF_FULL))) + { + int error= my_errno; + if (index_file_nr >= 0) + my_close(index_file_nr,MYF(0)); + + sql_print_error("Create of Master Info Index file '%s' failed with " + "error: %M", + index_file_name, error); + DBUG_RETURN(TRUE); + } + + // Rewrite Master_info.index + uint i; + for (i= 0; i< master_info_hash.records; ++i) + { + Master_info *tmp_mi; + tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i); + write_master_name_to_index_file(&tmp_mi->connection_name, 0); + } + my_sync(index_file_nr, MYF(MY_WME)); + } + } + DBUG_RETURN(FALSE); +} #endif /* HAVE_REPLICATION */ diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index a885576ef1c..6892ecdb9d1 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -59,16 +59,23 @@ typedef struct st_mysql MYSQL; class Master_info : public Slave_reporting_capability { public: - Master_info(bool is_slave_recovery); + Master_info(LEX_STRING *connection_name, bool is_slave_recovery); ~Master_info(); bool shall_ignore_server_id(ulong s_id); void clear_in_memory_info(bool all); + bool error() + { + /* If malloc() in initialization failed */ + return connection_name.str == 0; + } /* the variables below are needed because we can change masters on the fly */ - char master_log_name[FN_REFLEN]; + char master_log_name[FN_REFLEN+6]; /* Place for multi-*/ char host[HOSTNAME_LENGTH+1]; char user[USERNAME_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; + LEX_STRING connection_name; /* User supplied connection name */ + LEX_STRING cmp_connection_name; /* Connection name in lower case */ bool ssl; // enables use of SSL connection if true char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN]; char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN]; @@ -130,5 +137,45 @@ int flush_master_info(Master_info* mi, bool need_lock_relay_log); int change_master_server_id_cmp(ulong *id1, ulong *id2); +/* + Multi master are handled trough this struct. + Changes to this needs to be protected by LOCK_active_mi; +*/ + +class Master_info_index +{ +private: + IO_CACHE index_file; + char index_file_name[FN_REFLEN]; + +public: + Master_info_index(); + ~Master_info_index(); + + HASH master_info_hash; + + bool init_all_master_info(); + bool write_master_name_to_index_file(LEX_STRING *connection_name, + bool do_sync); + + bool check_duplicate_master_info(LEX_STRING *connection_name, + const char *host, uint port); + bool add_master_info(Master_info *mi, bool write_to_file); + bool remove_master_info(LEX_STRING *connection_name); + Master_info *get_master_info(LEX_STRING *connection_name, + MYSQL_ERROR::enum_warning_level warning); +}; + +bool check_master_connection_name(LEX_STRING *name); +void create_signed_file_name(char *res_file_name, uint length, + const char *info_file, + char separator, + LEX_STRING *suffix); + +uchar *get_key_master_info(Master_info *mi, size_t *length, + my_bool not_used __attribute__((unused))); +void free_key_master_info(Master_info *mi); + + #endif /* HAVE_REPLICATION */ #endif /* RPL_MI_H */ diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index a700aff0da9..442a9895f6b 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -206,19 +206,37 @@ a file name for --relay-log-index option", opt_relaylog_index_name); name_warning_sent= 1; } + /* For multimaster, add connection name to relay log filenames */ + Master_info* mi= rli->mi; + char buf_relay_logname[FN_REFLEN], buf_relaylog_index_name_buff[FN_REFLEN]; + char *buf_relaylog_index_name= opt_relaylog_index_name; + + create_signed_file_name(buf_relay_logname, sizeof(buf_relay_logname), + ln, '-', &mi->connection_name); + ln= buf_relay_logname; + + if (opt_relaylog_index_name) + { + buf_relaylog_index_name= buf_relaylog_index_name_buff; + create_signed_file_name(buf_relaylog_index_name_buff, + sizeof(buf_relaylog_index_name_buff), + opt_relaylog_index_name, '-', + &mi->connection_name); + } + rli->relay_log.is_relay_log= TRUE; /* note, that if open() fails, we'll still have index file open but a destructor will take care of that */ - if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE) || + if (rli->relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) || rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, (max_relay_log_size ? max_relay_log_size : max_binlog_size), 1, TRUE)) { mysql_mutex_unlock(&rli->data_lock); - sql_print_error("Failed in open_log() called from init_relay_log_info()"); + sql_print_error("Failed when trying to open logs for '%s' in init_relay_log_info(). Error: %M", ln, my_errno); DBUG_RETURN(1); } } diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index b989283deb4..eb808351a34 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -25,7 +25,6 @@ struct RPL_TABLE_LIST; class Master_info; -extern uint sql_slave_skip_counter; /**************************************************************************** @@ -230,7 +229,7 @@ public: skipping one or more events in the master log that have caused errors, and have been manually applied by DBA already. */ - volatile uint32 slave_skip_counter; + volatile uint slave_skip_counter; /* Must be uint */ volatile ulong abort_pos_wait; /* Incremented on change master */ volatile ulong slave_run_id; /* Incremented on slave start */ mysql_mutex_t log_space_lock; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 2e8b2231948..bb5506756e1 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -4310,11 +4310,11 @@ ER_BAD_SLAVE swe "Servern är inte konfigurerade som en replikationsslav. Ändra konfigurationsfilen eller gör CHANGE MASTER TO" ukr "Сервер не зконфігуровано як підлеглий, виправте це у файлі конфігурації або з CHANGE MASTER TO" ER_MASTER_INFO - eng "Could not initialize master info structure; more error messages can be found in the MariaDB error log" - fre "Impossible d'initialiser les structures d'information de maître, vous trouverez des messages d'erreur supplémentaires dans le journal des erreurs de MariaDB" - ger "Konnte Master-Info-Struktur nicht initialisieren. Weitere Fehlermeldungen können im MariaDB-Error-Log eingesehen werden" - serbian "Nisam mogao da inicijalizujem informacionu strukturu glavnog servera, proverite da li imam privilegije potrebne za pristup file-u 'master.info'" - swe "Kunde inte initialisera replikationsstrukturerna. See MariaDB fel fil för mera information" + eng "Could not initialize master info structure for '%.*s'; more error messages can be found in the MariaDB error log" + fre "Impossible d'initialiser les structures d'information de maître '%.*s', vous trouverez des messages d'erreur supplémentaires dans le journal des erreurs de MariaDB" + ger "Konnte Master-Info-Struktur '%.*s' nicht initialisieren. Weitere Fehlermeldungen können im MariaDB-Error-Log eingesehen werden" + serbian "Nisam mogao da inicijalizujem informacionu strukturu glavnog servera, proverite da li imam privilegije potrebne za pristup file-u 'master.info' '%.*s'" + swe "Kunde inte initialisera replikationsstrukturerna för '%.*s'. See MariaDB fel fil för mera information" ER_SLAVE_THREAD dan "Kunne ikke danne en slave-tråd; check systemressourcerne" nla "Kon slave thread niet aanmaken, controleer systeem resources" @@ -6156,8 +6156,8 @@ ER_DELAYED_NOT_SUPPORTED eng "DELAYED option not supported for table '%-.192s'" ger "Die DELAYED-Option wird für Tabelle '%-.192s' nicht unterstützt" WARN_NO_MASTER_INFO - eng "The master info structure does not exist" - ger "Die Master-Info-Struktur existiert nicht" + eng "There is no master connection '%.*s'" + ger "Die Master-Info-Struktur existiert nicht '%.*s'" WARN_OPTION_IGNORED eng "<%-.64s> option ignored" ger "Option <%-.64s> ignoriert" @@ -6588,3 +6588,8 @@ ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT ER_NO_SUCH_TABLE_IN_ENGINE 42S02 eng "Table '%-.192s.%-.192s' doesn't exist in engine" swe "Det finns ingen tabell som heter '%-.192s.%-.192s' i handlern" +ER_CONNECTION_ALREADY_EXISTS + eng "Connection '%.*s' already exists" +ER_MASTER_LOG_PREFIX + eng "Master '%.*s': " + diff --git a/sql/slave.cc b/sql/slave.cc index 7b7bddecd17..8254e90b369 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -71,8 +71,10 @@ char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE]; char* slave_load_tmpdir = 0; Master_info *active_mi= 0; +Master_info_index *master_info_index; my_bool replicate_same_server_id; ulonglong relay_log_space_limit = 0; +LEX_STRING default_master_connection_name= { (char*) "", 0 }; /* When slave thread exits, we need to remember the temporary tables so we @@ -144,7 +146,8 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev); static bool wait_for_relay_log_space(Relay_log_info* rli); static inline bool io_slave_killed(THD* thd,Master_info* mi); static inline bool sql_slave_killed(THD* thd,Relay_log_info* rli); -static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type); +static int init_slave_thread(THD* thd, Master_info *mi, + SLAVE_THD_TYPE thd_type); static void print_slave_skip_errors(void); static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi); static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi, @@ -159,6 +162,8 @@ static int terminate_slave_thread(THD *thd, volatile uint *slave_running, bool skip_lock); static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info); +static bool send_show_master_info_header(THD *thd, Master_info *mi, bool full); +static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full); /* Find out which replications threads are running @@ -263,15 +268,33 @@ int init_slave() So it's safer to take the lock. */ mysql_mutex_lock(&LOCK_active_mi); - /* - TODO: re-write this to interate through the list of files - for multi-master - */ - active_mi= new Master_info(relay_log_recovery); if (pthread_key_create(&RPL_MASTER_INFO, NULL)) goto err; + master_info_index= new Master_info_index; + if (!master_info_index || master_info_index->init_all_master_info()) + { + sql_print_error("Failed to initialize multi master structures"); + mysql_mutex_unlock(&LOCK_active_mi); + DBUG_RETURN(1); + } + if (!(active_mi= new Master_info(&default_master_connection_name, + relay_log_recovery)) || + active_mi->error()) + { + delete active_mi; + active_mi= 0; + goto err; + } + + if (master_info_index->add_master_info(active_mi, FALSE)) + { + delete active_mi; + active_mi= 0; + goto err; + } + /* If --slave-skip-errors=... was not used, the string value for the system variable has not been set up yet. Do it now. @@ -286,18 +309,11 @@ int init_slave() If master_host is specified, create the master_info file if it doesn't exists. */ - if (!active_mi) - { - sql_print_error("Failed to allocate memory for the master info structure"); - error= 1; - goto err; - } if (init_master_info(active_mi,master_info_file,relay_log_info_file, 1, (SLAVE_IO | SLAVE_SQL))) { sql_print_error("Failed to initialize the master info structure"); - error= 1; goto err; } @@ -313,14 +329,18 @@ int init_slave() SLAVE_IO | SLAVE_SQL)) { sql_print_error("Failed to create slave threads"); - error= 1; goto err; } } -err: +end: mysql_mutex_unlock(&LOCK_active_mi); DBUG_RETURN(error); + +err: + sql_print_error("Failed to allocate memory for the Master Info structure"); + error= 1; + goto end; } /* @@ -820,42 +840,19 @@ void end_slave() running presently. If a START SLAVE was in progress, the mutex lock below will make us wait until slave threads have started, and START SLAVE returns, then we terminate them here. + + We can also be called by cleanup(), which only happens if some + startup parameter to the server was wrong. */ mysql_mutex_lock(&LOCK_active_mi); - if (active_mi) - { - /* - TODO: replace the line below with - list_walk(&master_list, (list_walk_action)end_slave_on_walk,0); - once multi-master code is ready. - */ - terminate_slave_threads(active_mi,SLAVE_FORCE_ALL); - } + /* This will call terminate_slave_threads() on all connections */ + delete master_info_index; + master_info_index= 0; + active_mi= 0; mysql_mutex_unlock(&LOCK_active_mi); DBUG_VOID_RETURN; } -/** - Free all resources used by slave threads at time of executing shutdown. - The routine must be called after all possible users of @c active_mi - have left. - - SYNOPSIS - close_active_mi() - -*/ -void close_active_mi() -{ - mysql_mutex_lock(&LOCK_active_mi); - if (active_mi) - { - end_master_info(active_mi); - delete active_mi; - active_mi= 0; - } - mysql_mutex_unlock(&LOCK_active_mi); -} - static bool io_slave_killed(THD* thd, Master_info* mi) { DBUG_ENTER("io_slave_killed"); @@ -2022,12 +2019,28 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi, @retval FALSE success @retval TRUE failure */ -bool show_master_info(THD* thd, Master_info* mi) + +bool show_master_info(THD *thd, Master_info *mi, bool full) +{ + DBUG_ENTER("show_master_info"); + + if (send_show_master_info_header(thd, mi, full)) + DBUG_RETURN(TRUE); + if (send_show_master_info_data(thd, mi, full)) + DBUG_RETURN(TRUE); + my_eof(thd); + DBUG_RETURN(FALSE); +} + +static bool send_show_master_info_header(THD *thd, Master_info *mi, bool full) { - // TODO: fix this for multi-master List field_list; Protocol *protocol= thd->protocol; - DBUG_ENTER("show_master_info"); + DBUG_ENTER("show_master_info_header"); + + if (full) + field_list.push_back(new Item_empty_string("Connection_name", + MAX_CONNECTION_NAME)); field_list.push_back(new Item_empty_string("Slave_IO_State", 14)); @@ -2097,17 +2110,29 @@ bool show_master_info(THD* thd, Master_info* mi) if (protocol->send_result_set_metadata(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); +} + + +static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full) +{ + DBUG_ENTER("send_show_master_info_data"); if (mi->host[0]) { DBUG_PRINT("info",("host is set: '%s'", mi->host)); String *packet= &thd->packet; + Protocol *protocol= thd->protocol; + protocol->prepare_for_resend(); /* slave_running can be accessed without run_lock but not other non-volotile members like mi->io_thd, which is guarded by the mutex. */ + if (full) + protocol->store(mi->connection_name.str, mi->connection_name.length, + &my_charset_bin); mysql_mutex_lock(&mi->run_lock); protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin); mysql_mutex_unlock(&mi->run_lock); @@ -2250,6 +2275,65 @@ bool show_master_info(THD* thd, Master_info* mi) if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(), packet->length())) DBUG_RETURN(TRUE); } + DBUG_RETURN(FALSE); +} + + +/* Used to sort connections by name */ + +static int cmp_mi_by_name(const Master_info **arg1, + const Master_info **arg2) +{ + return my_strcasecmp(system_charset_info, (*arg1)->connection_name.str, + (*arg2)->connection_name.str); +} + + +/** + Execute a SHOW FULL SLAVE STATUS statement. + + @param thd Pointer to THD object for the client thread executing the + statement. + + Elements are sorted according to the original connection_name. + + @retval FALSE success + @retval TRUE failure +*/ + +bool show_all_master_info(THD* thd) +{ + uint i, elements; + Master_info **tmp; + DBUG_ENTER("show_master_info"); + + if (send_show_master_info_header(thd, active_mi, 1)) + DBUG_RETURN(TRUE); + + if (!(elements= master_info_index->master_info_hash.records)) + goto end; + + /* + Sort lines to get them into a predicted order + (needed for test cases and to not confuse users) + */ + if (!(tmp= (Master_info**) thd->alloc(sizeof(Master_info*) * elements))) + DBUG_RETURN(TRUE); + + for (i= 0; i < elements; i++) + { + tmp[i]= (Master_info *) my_hash_element(&master_info_index-> + master_info_hash, i); + } + my_qsort(tmp, elements, sizeof(Master_info*), (qsort_cmp) cmp_mi_by_name); + + for (i= 0; i < elements; i++) + { + if (send_show_master_info_data(thd, tmp[i], 1)) + DBUG_RETURN(TRUE); + } + +end: my_eof(thd); DBUG_RETURN(FALSE); } @@ -2303,7 +2387,8 @@ void set_slave_thread_default_charset(THD* thd, Relay_log_info const *rli) init_slave_thread() */ -static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) +static int init_slave_thread(THD* thd, Master_info *mi, + SLAVE_THD_TYPE thd_type) { DBUG_ENTER("init_slave_thread"); #if !defined(DBUG_OFF) @@ -2319,7 +2404,8 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) than the corresponding packet (query) sent from client to master. */ thd->variables.max_allowed_packet= slave_max_allowed_packet; - thd->slave_thread = 1; + thd->slave_thread= 1; + thd->connection_name= mi->connection_name; thd->enable_slow_log= opt_log_slow_slave_statements; thd->variables.log_slow_filter= global_system_variables.log_slow_filter; set_slave_thread_options(thd); @@ -2635,7 +2721,10 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli) int reason= ev->shall_skip(rli); if (reason == Log_event::EVENT_SKIP_COUNT) - sql_slave_skip_counter= --rli->slave_skip_counter; + { + DBUG_ASSERT(rli->slave_skip_counter > 0); + rli->slave_skip_counter--; + } mysql_mutex_unlock(&rli->data_lock); if (reason == Log_event::EVENT_SKIP_NOT) exec_res= ev->apply_event(rli); @@ -3058,7 +3147,7 @@ pthread_handler_t handle_slave_io(void *arg) pthread_detach_this_thread(); thd->thread_stack= (char*) &thd; // remember where our stack is mi->clear_error(); - if (init_slave_thread(thd, SLAVE_THD_IO)) + if (init_slave_thread(thd, mi, SLAVE_THD_IO)) { mysql_cond_broadcast(&mi->start_cond); sql_print_error("Failed during slave I/O thread initialization"); @@ -3457,7 +3546,8 @@ pthread_handler_t handle_slave_sql(void *arg) my_off_t UNINIT_VAR(saved_log_pos); my_off_t UNINIT_VAR(saved_master_log_pos); my_off_t saved_skip= 0; - Relay_log_info* rli = &((Master_info*)arg)->rli; + Master_info *mi= ((Master_info*)arg); + Relay_log_info* rli = &mi->rli; const char *errmsg; // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff @@ -3471,6 +3561,7 @@ pthread_handler_t handle_slave_sql(void *arg) thd->thread_stack = (char*)&thd; // remember where our stack is DBUG_ASSERT(rli->inited); + DBUG_ASSERT(rli->mi == mi); mysql_mutex_lock(&rli->run_lock); DBUG_ASSERT(!rli->slave_running); errmsg= 0; @@ -3485,7 +3576,7 @@ pthread_handler_t handle_slave_sql(void *arg) rli->slave_running = 1; pthread_detach_this_thread(); - if (init_slave_thread(thd, SLAVE_THD_SQL)) + if (init_slave_thread(thd, mi, SLAVE_THD_SQL)) { /* TODO: this is currently broken - slave start and change master diff --git a/sql/slave.h b/sql/slave.h index 6b4bcffe109..565f40b7236 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -45,9 +45,12 @@ #define MAX_SLAVE_ERROR 2000 +#define MAX_REPLICATION_THREAD 64 + // Forward declarations class Relay_log_info; class Master_info; +class Master_info_index; int init_intvar_from_file(int* var, IO_CACHE* f, int default_val); int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, @@ -197,7 +200,8 @@ int mysql_table_dump(THD* thd, const char* db, int fetch_master_table(THD* thd, const char* db_name, const char* table_name, Master_info* mi, MYSQL* mysql, bool overwrite); -bool show_master_info(THD* thd, Master_info* mi); +bool show_master_info(THD* thd, Master_info* mi, bool full); +bool show_all_master_info(THD* thd); bool show_binlog_info(THD* thd); bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report, bool (*pred)(const void *), const void *param); @@ -231,6 +235,9 @@ bool net_request_file(NET* net, const char* fname); extern bool volatile abort_loop; extern Master_info main_mi, *active_mi; /* active_mi for multi-master */ +extern Master_info *default_master_info; /* To replace active_mi */ +extern Master_info_index *master_info_index; +extern LEX_STRING default_master_connection_name; extern LIST master_list; extern my_bool replicate_same_server_id; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 85e9227c154..c098ba5be7c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -396,6 +396,7 @@ bool table_def_init(void) void table_def_start_shutdown(void) { + DBUG_ENTER("table_def_start_shutdown"); if (table_def_inited) { mysql_mutex_lock(&LOCK_open); @@ -410,6 +411,7 @@ void table_def_start_shutdown(void) /* Free all cached but unused TABLEs and TABLE_SHAREs. */ close_cached_tables(NULL, NULL, FALSE, LONG_TIMEOUT); } + DBUG_VOID_RETURN; } @@ -1086,6 +1088,9 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, mysql_mutex_unlock(&LOCK_open); + DBUG_PRINT("info", ("open table definitions: %d", + (int) table_def_cache.records)); + if (!wait_for_refresh) DBUG_RETURN(result); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f77ef114d2d..b0d262f7b6a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -799,6 +799,9 @@ THD::THD() progress.max_counter= 0; current_linfo = 0; slave_thread = 0; + connection_name.str= 0; + connection_name.length= 0; + bzero(&variables, sizeof(variables)); thread_id= 0; one_shot_set= 0; @@ -1166,7 +1169,14 @@ void THD::init(void) avoid temporary tables replication failure. */ variables.pseudo_thread_id= thread_id; + + variables.default_master_connection.str= default_master_connection_buff; + ::strmake(variables.default_master_connection.str, + global_system_variables.default_master_connection.str, + variables.default_master_connection.length); + mysql_mutex_unlock(&LOCK_global_system_variables); + server_status= SERVER_STATUS_AUTOCOMMIT; if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES; diff --git a/sql/sql_class.h b/sql/sql_class.h index 3aa0c5ae9c7..7f44a4b468a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -533,6 +533,11 @@ typedef struct system_variables thread the query is being run to replicate temp tables properly */ my_thread_id pseudo_thread_id; + /** + Place holder to store sql_slave_skip_counter in sys_var.cc during + update and show of variables. + */ + uint slave_skip_counter; my_bool low_priority_updates; my_bool query_cache_wlock_invalidate; @@ -557,6 +562,9 @@ typedef struct system_variables CHARSET_INFO *collation_database; CHARSET_INFO *collation_connection; + /* Names. These will be allocated in buffers in thd */ + LEX_STRING default_master_connection; + /* Error messages */ MY_LOCALE *lc_messages; /* Locale Support */ @@ -2192,6 +2200,8 @@ public: /* scramble - random string sent to client on handshake */ char scramble[SCRAMBLE_LENGTH+1]; + LEX_STRING connection_name; /* If slave */ + char default_master_connection_buff[MAX_CONNECTION_NAME+1]; bool slave_thread, one_shot_set; bool extra_port; /* If extra connection */ diff --git a/sql/sql_const.h b/sql/sql_const.h index cfbf077bd91..255a0162e93 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -38,6 +38,7 @@ #define MAX_REFLENGTH 4 /* Max length for record ref */ #endif #define MAX_HOSTNAME 61 /* len+1 in mysql.user */ +#define MAX_CONNECTION_NAME NAME_LEN #define MAX_MBWIDTH 3 /* Max multibyte sequence */ #define MAX_FIELD_CHARLENGTH 255 diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 240aeb223d4..0b8265e7028 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -503,6 +503,7 @@ void lex_start(THD *thd) lex->expr_allows_subselect= TRUE; lex->use_only_table_context= FALSE; lex->parse_vcol_expr= FALSE; + lex->verbose= 0; lex->name.str= 0; lex->name.length= 0; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 2f3214646de..7e92fe12dc3 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -286,6 +286,7 @@ struct LEX_MASTER_INFO char *host, *user, *password, *log_file_name; char *ssl_key, *ssl_cert, *ssl_ca, *ssl_capath, *ssl_cipher; char *relay_log_name; + LEX_STRING connection_name; ulonglong pos; ulong relay_log_pos; ulong server_id; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 175c2c1d672..114035bc16d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -82,6 +82,7 @@ #include #include #include "rpl_handler.h" +#include "rpl_mi.h" #include "sp_head.h" #include "sp.h" @@ -2343,10 +2344,41 @@ case SQLCOM_PREPARE: #ifdef HAVE_REPLICATION case SQLCOM_CHANGE_MASTER: { + LEX_MASTER_INFO *lex_mi= &thd->lex->mi; + Master_info *mi; + bool new_master= 0; + if (check_global_access(thd, SUPER_ACL)) goto error; mysql_mutex_lock(&LOCK_active_mi); - res = change_master(thd,active_mi); + + mi= master_info_index->get_master_info(&lex_mi->connection_name, + MYSQL_ERROR::WARN_LEVEL_NOTE); + + if (mi == NULL) + { + /* New replication created */ + mi= new Master_info(&lex_mi->connection_name, relay_log_recovery); + if (!mi || mi->error()) + { + delete mi; + res= 1; + mysql_mutex_unlock(&LOCK_active_mi); + break; + } + new_master= 1; + } + + res= change_master(thd, mi); + if (res && new_master) + { + /* + The new master was added by change_master(). Remove it as it didn't + work. + */ + master_info_index->remove_master_info(&lex_mi->connection_name); + } + mysql_mutex_unlock(&LOCK_active_mi); break; } @@ -2356,15 +2388,19 @@ case SQLCOM_PREPARE: if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL)) goto error; mysql_mutex_lock(&LOCK_active_mi); - if (active_mi != NULL) - { - res = show_master_info(thd, active_mi); - } + + if (lex->verbose) + res= show_all_master_info(thd); else { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO)); - my_ok(thd); + LEX_MASTER_INFO *lex_mi= &thd->lex->mi; + Master_info *mi; + mi= master_info_index->get_master_info(&lex_mi->connection_name, + MYSQL_ERROR::WARN_LEVEL_ERROR); + if (mi != NULL) + { + res= show_master_info(thd, mi, 0); + } } mysql_mutex_unlock(&LOCK_active_mi); break; @@ -2664,40 +2700,53 @@ end_with_restore_list: #ifdef HAVE_REPLICATION case SQLCOM_SLAVE_START: { + LEX_MASTER_INFO* lex_mi= &thd->lex->mi; + Master_info *mi; mysql_mutex_lock(&LOCK_active_mi); - start_slave(thd,active_mi,1 /* net report*/); + + if ((mi= (master_info_index-> + get_master_info(&lex_mi->connection_name, + MYSQL_ERROR::WARN_LEVEL_ERROR)))) + start_slave(thd, mi, 1 /* net report*/); mysql_mutex_unlock(&LOCK_active_mi); break; } case SQLCOM_SLAVE_STOP: - /* - If the client thread has locked tables, a deadlock is possible. - Assume that - - the client thread does LOCK TABLE t READ. - - then the master updates t. - - then the SQL slave thread wants to update t, - so it waits for the client thread because t is locked by it. + { + LEX_MASTER_INFO *lex_mi; + Master_info *mi; + /* + If the client thread has locked tables, a deadlock is possible. + Assume that + - the client thread does LOCK TABLE t READ. + - then the master updates t. + - then the SQL slave thread wants to update t, + so it waits for the client thread because t is locked by it. - then the client thread does SLAVE STOP. SLAVE STOP waits for the SQL slave thread to terminate its update t, which waits for the client thread because t is locked by it. - To prevent that, refuse SLAVE STOP if the - client thread has locked tables - */ - if (thd->locked_tables_mode || - thd->in_active_multi_stmt_transaction() || thd->global_read_lock.is_acquired()) - { - my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, - ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); - goto error; - } - { + To prevent that, refuse SLAVE STOP if the + client thread has locked tables + */ + if (thd->locked_tables_mode || + thd->in_active_multi_stmt_transaction() || + thd->global_read_lock.is_acquired()) + { + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); + goto error; + } + + lex_mi= &thd->lex->mi; mysql_mutex_lock(&LOCK_active_mi); - stop_slave(thd,active_mi,1/* net report*/); + if ((mi= (master_info_index-> + get_master_info(&lex_mi->connection_name, + MYSQL_ERROR::WARN_LEVEL_ERROR)))) + stop_slave(thd, mi, 1/* net report*/); mysql_mutex_unlock(&LOCK_active_mi); break; } #endif /* HAVE_REPLICATION */ - case SQLCOM_RENAME_TABLE: { if (execute_rename_table(thd, first_table, all_tables)) diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 914b9026014..fcb7d15f5ba 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -26,6 +26,7 @@ #include "sql_repl.h" // reset_master, reset_slave #include "rpl_mi.h" // Master_info::data_lock #include "debug_sync.h" +#include "rpl_mi.h" static void disable_checkpoints(THD *thd); @@ -314,13 +315,27 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, #ifdef HAVE_REPLICATION if (options & REFRESH_SLAVE) { + LEX_MASTER_INFO* lex_mi= &thd->lex->mi; + Master_info *mi; tmp_write_to_binlog= 0; mysql_mutex_lock(&LOCK_active_mi); - if (reset_slave(thd, active_mi)) + + if (!(mi= (master_info_index-> + get_master_info(&lex_mi->connection_name, + MYSQL_ERROR::WARN_LEVEL_ERROR)))) + { + result= 1; + } + else if (reset_slave(thd, mi)) { /* NOTE: my_error() has been already called by reset_slave(). */ result= 1; } + else if (mi->connection_name.length && thd->lex->reset_slave_info.all) + { + /* If not default connection and 'all' is used */ + master_info_index->remove_master_info(&mi->connection_name); + } mysql_mutex_unlock(&LOCK_active_mi); } #endif diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 079aab27101..99395738c66 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -34,14 +34,6 @@ my_bool opt_sporadic_binlog_dump_fail = 0; static int binlog_dump_count = 0; #endif -/** - a copy of active_mi->rli->slave_skip_counter, for showing in SHOW VARIABLES, - INFORMATION_SCHEMA.GLOBAL_VARIABLES and @@sql_slave_skip_counter without - taking all the mutexes needed to access active_mi->rli->slave_skip_counter - properly. -*/ -uint sql_slave_skip_counter; - extern TYPELIB binlog_checksum_typelib; /* @@ -1310,8 +1302,17 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) { int slave_errno= 0; int thread_mask; + char master_info_file_tmp[FN_REFLEN]; + char relay_log_info_file_tmp[FN_REFLEN]; DBUG_ENTER("start_slave"); + create_signed_file_name(master_info_file_tmp, + sizeof(master_info_file_tmp), + master_info_file, '.', &mi->connection_name); + create_signed_file_name(relay_log_info_file_tmp, + sizeof(relay_log_info_file_tmp), + relay_log_info_file, '.', &mi->connection_name); + if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0)) DBUG_RETURN(1); lock_slave_threads(mi); // this allows us to cleanly read slave_running @@ -1327,7 +1328,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) thread_mask&= thd->lex->slave_thd_opt; if (thread_mask) //some threads are stopped, start them { - if (init_master_info(mi,master_info_file,relay_log_info_file, 0, + if (init_master_info(mi,master_info_file_tmp,relay_log_info_file_tmp, 0, thread_mask)) slave_errno=ER_MASTER_INFO; else if (server_id_supplied && *mi->host) @@ -1401,10 +1402,11 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) if (!slave_errno) slave_errno = start_slave_threads(0 /*no mutex */, - 1 /* wait for start */, - mi, - master_info_file,relay_log_info_file, - thread_mask); + 1 /* wait for start */, + mi, + master_info_file_tmp, + relay_log_info_file_tmp, + thread_mask); } else slave_errno = ER_BAD_SLAVE; @@ -1421,7 +1423,9 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) if (slave_errno) { if (net_report) - my_message(slave_errno, ER(slave_errno), MYF(0)); + my_error(slave_errno, MYF(0), + (int) mi->connection_name.length, + mi->connection_name.str); DBUG_RETURN(1); } else if (net_report) @@ -1446,11 +1450,9 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) */ int stop_slave(THD* thd, Master_info* mi, bool net_report ) { - DBUG_ENTER("stop_slave"); - int slave_errno; - if (!thd) - thd = current_thd; + DBUG_ENTER("stop_slave"); + DBUG_PRINT("enter",("Connection: %s", mi->connection_name.str)); if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0)) DBUG_RETURN(1); @@ -1514,6 +1516,8 @@ int reset_slave(THD *thd, Master_info* mi) int thread_mask= 0, error= 0; uint sql_errno=ER_UNKNOWN_ERROR; const char* errmsg= "Unknown error occured while reseting slave"; + char master_info_file_tmp[FN_REFLEN]; + char relay_log_info_file_tmp[FN_REFLEN]; DBUG_ENTER("reset_slave"); lock_slave_threads(mi); @@ -1549,22 +1553,35 @@ int reset_slave(THD *thd, Master_info* mi) // close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 end_master_info(mi); + // and delete these two files - fn_format(fname, master_info_file, mysql_data_home, "", 4+32); + create_signed_file_name(master_info_file_tmp, + sizeof(master_info_file_tmp), + master_info_file, '.', &mi->connection_name); + create_signed_file_name(relay_log_info_file_tmp, + sizeof(relay_log_info_file_tmp), + relay_log_info_file, '.', &mi->connection_name); + + fn_format(fname, master_info_file_tmp, mysql_data_home, "", 4+32); if (mysql_file_stat(key_file_master_info, fname, &stat_area, MYF(0)) && mysql_file_delete(key_file_master_info, fname, MYF(MY_WME))) { error=1; goto err; } + else if (global_system_variables.log_warnings > 1) + sql_print_information("Deleted Master_info file '%s'.", fname); + // delete relay_log_info_file - fn_format(fname, relay_log_info_file, mysql_data_home, "", 4+32); + fn_format(fname, relay_log_info_file_tmp, mysql_data_home, "", 4+32); if (mysql_file_stat(key_file_relay_log_info, fname, &stat_area, MYF(0)) && mysql_file_delete(key_file_relay_log_info, fname, MYF(MY_WME))) { error=1; goto err; } + else if (global_system_variables.log_warnings > 1) + sql_print_information("Deleted Master_info file '%s'.", fname); RUN_HOOK(binlog_relay_io, after_reset_slave, (thd, mi)); err: @@ -1644,12 +1661,36 @@ bool change_master(THD* thd, Master_info* mi) char saved_host[HOSTNAME_LENGTH + 1]; uint saved_port; char saved_log_name[FN_REFLEN]; + char master_info_file_tmp[FN_REFLEN]; + char relay_log_info_file_tmp[FN_REFLEN]; my_off_t saved_log_pos; + LEX_MASTER_INFO* lex_mi= &thd->lex->mi; DBUG_ENTER("change_master"); + /* + We need to check if there is an empty master_host. Otherwise + change master succeeds, a master.info file is created containing + empty master_host string and when issuing: start slave; an error + is thrown stating that the server is not configured as slave. + (See BUG#28796). + */ + if (lex_mi->host && !*lex_mi->host) + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), "MASTER_HOST"); + DBUG_RETURN(TRUE); + } + if (master_info_index->check_duplicate_master_info(&lex_mi->connection_name, + lex_mi->host, + lex_mi->port)) + { + my_error(ER_MASTER_INFO, MYF(0), + (int) lex_mi->connection_name.length, + lex_mi->connection_name.str); + DBUG_RETURN(TRUE); + } + lock_slave_threads(mi); init_thread_mask(&thread_mask,mi,0 /*not inverse*/); - LEX_MASTER_INFO* lex_mi= &thd->lex->mi; if (thread_mask) // We refuse if any slave thread is running { my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); @@ -1658,24 +1699,40 @@ bool change_master(THD* thd, Master_info* mi) } thd_proc_info(thd, "Changing master"); - /* - We need to check if there is an empty master_host. Otherwise - change master succeeds, a master.info file is created containing - empty master_host string and when issuing: start slave; an error - is thrown stating that the server is not configured as slave. - (See BUG#28796). - */ - if(lex_mi->host && !*lex_mi->host) + + create_signed_file_name(master_info_file_tmp, + sizeof(master_info_file_tmp), + master_info_file, '.', &mi->connection_name); + create_signed_file_name(relay_log_info_file_tmp, + sizeof(relay_log_info_file_tmp), + relay_log_info_file, '.', &mi->connection_name); + + /* if new Master_info doesn't exists, add it */ + if (!master_info_index->get_master_info(&mi->connection_name, + MYSQL_ERROR::WARN_LEVEL_NOTE)) { - my_error(ER_WRONG_ARGUMENTS, MYF(0), "MASTER_HOST"); - unlock_slave_threads(mi); - DBUG_RETURN(TRUE); + if (master_info_index->add_master_info(mi, TRUE)) + { + my_error(ER_MASTER_INFO, MYF(0), + (int) lex_mi->connection_name.length, + lex_mi->connection_name.str); + ret= TRUE; + goto err; + } } - // TODO: see if needs re-write - if (init_master_info(mi, master_info_file, relay_log_info_file, 0, + if (global_system_variables.log_warnings > 1) + sql_print_information("Master: '%.*s' Master_info_file: '%s' " + "Relay_info_file: '%s'", + (int) mi->connection_name.length, + mi->connection_name.str, + master_info_file_tmp, relay_log_info_file_tmp); + + if (init_master_info(mi, master_info_file_tmp, relay_log_info_file_tmp, 0, thread_mask)) { - my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0)); + my_error(ER_MASTER_INFO, MYF(0), + (int) lex_mi->connection_name.length, + lex_mi->connection_name.str); ret= TRUE; goto err; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 555efaf366d..e1bcb48e541 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -65,6 +65,7 @@ #include #include "keycaches.h" #include "set_var.h" +#include "rpl_mi.h" /* this is to get the bison compilation windows warnings out */ #ifdef _MSC_VER @@ -1904,7 +1905,7 @@ help: /* change master */ change: - CHANGE MASTER_SYM TO_SYM + CHANGE MASTER_SYM optional_connection_name TO_SYM { Lex->sql_command = SQLCOM_CHANGE_MASTER; } @@ -2053,6 +2054,29 @@ master_file_def: } ; +optional_connection_name: + /* empty */ + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + lex->mi.connection_name= thd->variables.default_master_connection; + } + | connection_name; + ; + +connection_name: + TEXT_STRING_sys + { + Lex->mi.connection_name= $1; +#ifdef HAVE_REPLICATION + if (check_master_connection_name(&$1)) + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), "MASTER_CONNECTION_NAME"); + MYSQL_YYABORT; + } +#endif + } + /* create a table */ create: @@ -7074,7 +7098,7 @@ opt_to: */ slave: - START_SYM SLAVE slave_thread_opts + START_SYM SLAVE optional_connection_name slave_thread_opts { LEX *lex=Lex; lex->sql_command = SQLCOM_SLAVE_START; @@ -7083,14 +7107,14 @@ slave: } slave_until {} - | STOP_SYM SLAVE slave_thread_opts + | STOP_SYM SLAVE optional_connection_name slave_thread_opts { LEX *lex=Lex; lex->sql_command = SQLCOM_SLAVE_STOP; lex->type = 0; /* If you change this code don't forget to update SLAVE STOP too */ } - | SLAVE START_SYM slave_thread_opts + | SLAVE optional_connection_name START_SYM slave_thread_opts { LEX *lex=Lex; lex->sql_command = SQLCOM_SLAVE_START; @@ -7098,7 +7122,7 @@ slave: } slave_until {} - | SLAVE STOP_SYM slave_thread_opts + | SLAVE optional_connection_name STOP_SYM slave_thread_opts { LEX *lex=Lex; lex->sql_command = SQLCOM_SLAVE_STOP; @@ -11558,9 +11582,23 @@ show_param: { Lex->sql_command = SQLCOM_SHOW_MASTER_STAT; } - | SLAVE STATUS_SYM + | FULL SLAVE STATUS_SYM { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; + Lex->verbose= 1; + } + | SLAVE STATUS_SYM + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + lex->mi.connection_name= thd->variables.default_master_connection; + lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; + lex->verbose= 0; + } + | SLAVE connection_name STATUS_SYM + { + Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; + Lex->verbose= 0; } | CLIENT_STATS_SYM { @@ -11824,7 +11862,7 @@ flush_option: { Lex->type|= REFRESH_LOG; } | STATUS_SYM { Lex->type|= REFRESH_STATUS; } - | SLAVE + | SLAVE optional_connection_name { Lex->type|= REFRESH_SLAVE; Lex->reset_slave_info.all= false; @@ -11871,6 +11909,7 @@ reset_options: reset_option: SLAVE { Lex->type|= REFRESH_SLAVE; } + optional_connection_name slave_reset_options { } | MASTER_SYM { Lex->type|= REFRESH_MASTER; } | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;} diff --git a/sql/strfunc.cc b/sql/strfunc.cc index 0c0742b3805..9603ca30cfa 100644 --- a/sql/strfunc.cc +++ b/sql/strfunc.cc @@ -15,6 +15,7 @@ /* Some useful string utility functions used by the MySQL server */ +#include #include "sql_priv.h" #include "unireg.h" #include "strfunc.h" diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 4a003a89a7e..30cfe1a5680 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -796,6 +796,30 @@ static Sys_var_lexstring Sys_init_connect( DEFAULT(""), &PLock_sys_init_connect, NOT_IN_BINLOG, ON_CHECK(check_init_string)); +#ifdef HAVE_REPLICATION +static bool check_master_connection(sys_var *self, THD *thd, set_var *var) +{ + LEX_STRING tmp; + tmp.str= var->save_result.string_value.str; + tmp.length= var->save_result.string_value.length; + if (check_master_connection_name(&tmp)) + { + my_error(ER_WRONG_ARGUMENTS, MYF(ME_JUST_WARNING), + "DEFAULT_MASTER_CONNECTION"); + return true; + } + return false; +} + +static Sys_var_session_lexstring Sys_default_master_connection( + "default_master_connection", + "Master connection to use for all slave variables and slave commands", + SESSION_ONLY(default_master_connection), + NO_CMD_LINE, IN_SYSTEM_CHARSET, + DEFAULT(""), MAX_CONNECTION_NAME, ON_CHECK(check_master_connection), + ON_UPDATE(0)); +#endif + static Sys_var_charptr Sys_init_file( "init_file", "Read SQL commands from this file at startup", READ_ONLY GLOBAL_VAR(opt_init_file), @@ -3454,47 +3478,67 @@ static Sys_var_uint Sys_slave_net_timeout( NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(fix_slave_net_timeout)); -static bool check_slave_skip_counter(sys_var *self, THD *thd, set_var *var) + +/* + Access a multi_source variable + Return 0 + warning if it doesn't exist +*/ + +uint Sys_var_multi_source_uint:: +get_master_info_uint_value(THD *thd, ptrdiff_t offset) { - bool result= false; + Master_info *mi; + uint res= 0; // Default value mysql_mutex_lock(&LOCK_active_mi); - mysql_mutex_lock(&active_mi->rli.run_lock); - if (active_mi->rli.slave_running) + mi= master_info_index-> + get_master_info(&thd->variables.default_master_connection, + MYSQL_ERROR::WARN_LEVEL_WARN); + if (mi) { - my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); - result= true; + mysql_mutex_lock(&mi->rli.data_lock); + res= *((uint*) (((uchar*) mi) + master_info_offset)); + mysql_mutex_unlock(&mi->rli.data_lock); + } + mysql_mutex_unlock(&LOCK_active_mi); + return res; +} + + +static bool update_slave_skip_counter(sys_var *self, THD *thd, + enum_var_type type) +{ + bool result= true; + Master_info *mi; + mysql_mutex_lock(&LOCK_active_mi); + mi= master_info_index-> + get_master_info(&thd->variables.default_master_connection, + MYSQL_ERROR::WARN_LEVEL_ERROR); + if (mi) + { + mysql_mutex_lock(&mi->rli.run_lock); + if (mi->rli.slave_running) + my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); + else + { + result= false; // ok + mysql_mutex_lock(&mi->rli.data_lock); + /* The value was stored temporarly in thd */ + mi->rli.slave_skip_counter= thd->variables.slave_skip_counter; + mysql_mutex_unlock(&mi->rli.data_lock); + } + mysql_mutex_unlock(&mi->rli.run_lock); } - mysql_mutex_unlock(&active_mi->rli.run_lock); mysql_mutex_unlock(&LOCK_active_mi); return result; } -static bool fix_slave_skip_counter(sys_var *self, THD *thd, enum_var_type type) -{ - mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - mysql_mutex_lock(&active_mi->rli.run_lock); - /* - The following test should normally never be true as we test this - in the check function; To be safe against multiple - SQL_SLAVE_SKIP_COUNTER request, we do the check anyway - */ - if (!active_mi->rli.slave_running) - { - mysql_mutex_lock(&active_mi->rli.data_lock); - active_mi->rli.slave_skip_counter= sql_slave_skip_counter; - mysql_mutex_unlock(&active_mi->rli.data_lock); - } - mysql_mutex_unlock(&active_mi->rli.run_lock); - mysql_mutex_unlock(&LOCK_active_mi); - mysql_mutex_lock(&LOCK_global_system_variables); - return 0; -} -static Sys_var_uint Sys_slave_skip_counter( - "sql_slave_skip_counter", "sql_slave_skip_counter", - GLOBAL_VAR(sql_slave_skip_counter), NO_CMD_LINE, - VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_slave_skip_counter), - ON_UPDATE(fix_slave_skip_counter)); + +static Sys_var_multi_source_uint +Sys_slave_skip_counter("sql_slave_skip_counter", + "Skip the next N events from the master log", + SESSION_VAR(slave_skip_counter), + offsetof(Master_info, rli.slave_skip_counter), + VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1), + ON_UPDATE(update_slave_skip_counter)); static Sys_var_charptr Sys_slave_skip_errors( "slave_skip_errors", "Tells the slave thread to continue " diff --git a/sql/sys_vars.h b/sql/sys_vars.h index 21bebcd762c..6509ba6a5f4 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -633,6 +633,88 @@ public: } }; + +/* + A LEX_STRING stored only in thd->variables + Only to be used for small buffers +*/ + +class Sys_var_session_lexstring: public sys_var +{ + size_t max_length; +public: + Sys_var_session_lexstring(const char *name_arg, + const char *comment, int flag_args, + ptrdiff_t off, size_t size, CMD_LINE getopt, + enum charset_enum is_os_charset_arg, + const char *def_val, size_t max_length_arg, + on_check_function on_check_func=0, + on_update_function on_update_func=0) + : sys_var(&all_sys_vars, name_arg, comment, flag_args, off, getopt.id, + getopt.arg_type, SHOW_CHAR, (intptr)def_val, + 0, VARIABLE_NOT_IN_BINLOG, on_check_func, on_update_func, + 0, 0),max_length(max_length_arg) + { + option.var_type= GET_NO_ARG; + SYSVAR_ASSERT(scope() == ONLY_SESSION) + *const_cast(&show_val_type)= SHOW_LEX_STRING; + } + bool do_check(THD *thd, set_var *var) + { + char buff[STRING_BUFFER_USUAL_SIZE]; + String str(buff, sizeof(buff), system_charset_info), *res; + + if (!(res=var->value->val_str(&str))) + var->save_result.string_value.str= const_cast(""); + else + { + if (res->length() > max_length) + { + my_error(ER_WRONG_STRING_LENGTH, MYF(0), + res->ptr(), name.str, (int) max_length); + return true; + } + var->save_result.string_value.str= thd->strmake(res->ptr(), + res->length()); + var->save_result.string_value.length= res->length(); + } + return false; + } + bool session_update(THD *thd, set_var *var) + { + LEX_STRING *tmp= &session_var(thd, LEX_STRING); + tmp->length= var->save_result.string_value.length; + /* Store as \0 terminated string (just to be safe) */ + strmake(tmp->str, var->save_result.string_value.str, tmp->length); + return false; + } + bool global_update(THD *thd, set_var *var) + { + DBUG_ASSERT(FALSE); + return false; + } + void session_save_default(THD *thd, set_var *var) + { + char *ptr= (char*)(intptr)option.def_value; + var->save_result.string_value.str= ptr; + } + void global_save_default(THD *thd, set_var *var) + { + DBUG_ASSERT(FALSE); + } + uchar *session_value_ptr(THD *thd, LEX_STRING *base) + { + return (uchar*) &session_var(thd, LEX_STRING); + } + uchar *global_value_ptr(THD *thd, LEX_STRING *base) + { + DBUG_ASSERT(FALSE); + } + bool check_update_type(Item_result type) + { return type != STRING_RESULT; } +}; + + #ifndef DBUG_OFF /** @@session.dbug and @@global.dbug variables. @@ -1389,6 +1471,7 @@ public: }; #endif /* defined(ENABLED_DEBUG_SYNC) */ + /** The class for bit variables - a variant of boolean that stores the value in a bit. @@ -1862,6 +1945,65 @@ public: bool global_update(THD *thd, set_var *var); }; +/* + Class for handing multi-source replication variables + Variable values are store in Master_info, but to make it possible to + access variable without locks we also store it thd->variables. + These can be used as GLOBAL or SESSION, but both points to the same + variable. This is to make things compatible with MySQL 5.5 where variables + like sql_slave_skip_counter are GLOBAL. +*/ + +class Sys_var_multi_source_uint :public Sys_var_uint +{ + ptrdiff_t master_info_offset; +public: + Sys_var_multi_source_uint(const char *name_arg, + const char *comment, int flag_args, + ptrdiff_t off, size_t size, + ptrdiff_t master_info_offset_arg, + uint min_val, uint max_val, uint def_val, + uint block_size, + on_update_function on_update_func) + :Sys_var_uint(name_arg, comment, flag_args, off, size, + NO_CMD_LINE, min_val, max_val, def_val, block_size, + 0, VARIABLE_NOT_IN_BINLOG, 0, on_update_func), + master_info_offset(master_info_offset_arg) + { + /* No global storage of variables. Cause a crash if we try an update */ + option.value= (uchar**)1; + } + bool session_update(THD *thd, set_var *var) + { + session_var(thd, uint)= (uint) (var->save_result.ulonglong_value); + /* Value should be moved to multi_master in on_update_func */ + return false; + } + bool global_update(THD *thd, set_var *var) + { + return session_update(thd, var); + } + void session_save_default(THD *thd, set_var *var) + { + /* Use value given in variable declaration */ + global_save_default(thd, var); + } + uchar *session_value_ptr(THD *thd,LEX_STRING *base) + { + uint *tmp, res; + tmp= (uint*) (((uchar*)&(thd->variables)) + offset); + res= get_master_info_uint_value(thd, master_info_offset); + *tmp= res; + return (uchar*) tmp; + } + uchar *global_value_ptr(THD *thd, LEX_STRING *base) + { + return session_value_ptr(thd, base); + } + uint get_master_info_uint_value(THD *thd, ptrdiff_t offset); +}; + + /**************************************************************************** Used templates ****************************************************************************/ From 222883b0d66a3e4987b2f3d98023f677ea23642f Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 28 Sep 2012 03:45:05 +0300 Subject: [PATCH 2/6] Added multi-source support to show relaylog events --- sql/sql_repl.cc | 22 +++++++++++++++++++--- sql/sql_yacc.yy | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 99395738c66..036afb45a19 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -2022,6 +2022,7 @@ bool mysql_show_binlog_events(THD* thd) File file = -1; MYSQL_BIN_LOG *binary_log= NULL; int old_max_allowed_packet= thd->variables.max_allowed_packet; + Master_info *mi= 0; LOG_INFO linfo; DBUG_ENTER("mysql_show_binlog_events"); @@ -2051,10 +2052,15 @@ bool mysql_show_binlog_events(THD* thd) } else /* showing relay log contents */ { - if (!active_mi) + mysql_mutex_lock(&LOCK_active_mi); + if (!(mi= master_info_index-> + get_master_info(&thd->variables.default_master_connection, + MYSQL_ERROR::WARN_LEVEL_ERROR))) + { + mysql_mutex_unlock(&LOCK_active_mi); DBUG_RETURN(TRUE); - - binary_log= &(active_mi->rli.relay_log); + } + binary_log= &(mi->rli.relay_log); } if (binary_log->is_open()) @@ -2068,6 +2074,13 @@ bool mysql_show_binlog_events(THD* thd) mysql_mutex_t *log_lock = binary_log->get_log_lock(); Log_event* ev; + if (mi) + { + /* We can unlock the mutex as we have a lock on the file */ + mysql_mutex_unlock(&LOCK_active_mi); + mi= 0; + } + unit->set_limit(thd->lex->current_select); limit_start= unit->offset_limit_cnt; limit_end= unit->select_limit_cnt; @@ -2162,6 +2175,9 @@ bool mysql_show_binlog_events(THD* thd) mysql_mutex_unlock(log_lock); } + else if (mi) + mysql_mutex_unlock(&LOCK_active_mi); + // Check that linfo is still on the function scope. DEBUG_SYNC(thd, "after_show_binlog_events"); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e1bcb48e541..ab07a2010f0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11453,7 +11453,7 @@ show_param: LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS; } opt_limit_clause_init - | RELAYLOG_SYM EVENTS_SYM binlog_in binlog_from + | RELAYLOG_SYM optional_connection_name EVENTS_SYM binlog_in binlog_from { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_RELAYLOG_EVENTS; From 9b03041b27547e926145d8cc5c39bea659c45015 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Fri, 28 Sep 2012 09:28:40 +0400 Subject: [PATCH 3/6] Tests for Multi-source replication (MDEV-253) --- .../suite/multi_source/relaylog_events.result | 27 ++++++++ .../suite/multi_source/relaylog_events.test | 50 +++++++++++++++ .../suite/multi_source/reset_slave.result | 31 ++++++++++ .../suite/multi_source/reset_slave.test | 62 +++++++++++++++++++ mysql-test/suite/multi_source/simple.result | 5 ++ mysql-test/suite/multi_source/simple.test | 6 +- 6 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/multi_source/relaylog_events.result create mode 100644 mysql-test/suite/multi_source/relaylog_events.test create mode 100644 mysql-test/suite/multi_source/reset_slave.result create mode 100644 mysql-test/suite/multi_source/reset_slave.test diff --git a/mysql-test/suite/multi_source/relaylog_events.result b/mysql-test/suite/multi_source/relaylog_events.result new file mode 100644 index 00000000000..f93dff97718 --- /dev/null +++ b/mysql-test/suite/multi_source/relaylog_events.result @@ -0,0 +1,27 @@ +change master 'master1' to +master_port=MYPORT_1, +master_host='127.0.0.1', +master_user='root'; +start slave 'master1'; +set default_master_connection = 'master1'; +include/wait_for_slave_to_start.inc +drop table if exists t1; +create table t1 (i int) engine=MyISAM; +mysqld-relay-bin-master1.000001 +mysqld-relay-bin-master1.000002 +show relaylog events in 'mysqld-relay-bin-master1.000002'; +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-relay-bin-master1.000002 4 Format_desc 3 246 Server version +mysqld-relay-bin-master1.000002 246 Rotate 1 0 master-bin.000001;pos=4 +mysqld-relay-bin-master1.000002 290 Format_desc 1 246 Server version +mysqld-relay-bin-master1.000002 532 Binlog_checkpoint 1 286 master-bin.000001 +mysqld-relay-bin-master1.000002 572 Query 1 400 use `test`; DROP TABLE IF EXISTS `t1` /* generated by server */ +mysqld-relay-bin-master1.000002 686 Query 1 500 use `test`; create table t1 (i int) engine=MyISAM +show relaylog events; +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-relay-bin-master1.000001 4 Format_desc 3 246 Server version +mysqld-relay-bin-master1.000001 246 Rotate 3 304 mysqld-relay-bin-master1.000002;pos=4 +drop table t1; +stop slave; +include/wait_for_slave_to_stop.inc +reset master; diff --git a/mysql-test/suite/multi_source/relaylog_events.test b/mysql-test/suite/multi_source/relaylog_events.test new file mode 100644 index 00000000000..a9488d1373c --- /dev/null +++ b/mysql-test/suite/multi_source/relaylog_events.test @@ -0,0 +1,50 @@ +# +# Check that SHOW RELAYLOG EVENTS can be used +# for a named master connection +# + +--connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3) + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +eval change master 'master1' to +master_port=$SERVER_MYPORT_1, +master_host='127.0.0.1', +master_user='root'; + +start slave 'master1'; +set default_master_connection = 'master1'; +--source include/wait_for_slave_to_start.inc + +--connect (master1,127.0.0.1,root,,,$SERVER_MYPORT_1) +--disable_warnings +drop table if exists t1; +--enable_warnings +create table t1 (i int) engine=MyISAM; +--save_master_pos + +--connection slave +--sync_with_master 0,'master1' + +--let $datadir = `SELECT @@datadir` +--list_files $datadir mysqld-relay-bin-master1.* + +--replace_regex /Server ver:.*/Server version/ +show relaylog events in 'mysqld-relay-bin-master1.000002'; +--replace_regex /Server ver:.*/Server version/ +show relaylog events; + +--connection master1 +drop table t1; +--save_master_pos + +--connection slave +--sync_with_master 0,'master1' +stop slave; +--source include/wait_for_slave_to_stop.inc + +--disconnect slave + +--connection master1 +reset master; +--disconnect master1 + diff --git a/mysql-test/suite/multi_source/reset_slave.result b/mysql-test/suite/multi_source/reset_slave.result new file mode 100644 index 00000000000..0ae32e94166 --- /dev/null +++ b/mysql-test/suite/multi_source/reset_slave.result @@ -0,0 +1,31 @@ +change master 'master1' to +master_port=MYPORT_1, +master_host='127.0.0.1', +master_user='root'; +start slave 'master1'; +set default_master_connection = 'master1'; +include/wait_for_slave_to_start.inc +drop table if exists t1; +create table t1 (i int) engine=MyISAM; +insert into t1 values (1),(2); +stop slave 'master1'; +show slave 'master1' status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id + 127.0.0.1 root MYPORT_1 60 master-bin.000001 729 mysqld-relay-bin-master1.000002 1015 master-bin.000001 No No 0 0 729 1319 None 0 No NULL No 0 0 1 +mysqld-relay-bin-master1.000001 +mysqld-relay-bin-master1.000002 +mysqld-relay-bin.index-master1 +reset slave 'master1'; +show slave 'master1' status; +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id + 127.0.0.1 root MYPORT_1 60 4 mysqld-relay-bin-master1.000001 4 No No 0 0 0 265 None 0 No NULL No 0 0 1 +mysqld-relay-bin-master1.000001 +mysqld-relay-bin.index-master1 +reset slave 'master1' all; +show slave 'master1' status; +ERROR HY000: There is no master connection 'master1' +mysqld-relay-bin-master1.000001 +mysqld-relay-bin.index-master1 +drop table t1; +drop table t1; +reset master; diff --git a/mysql-test/suite/multi_source/reset_slave.test b/mysql-test/suite/multi_source/reset_slave.test new file mode 100644 index 00000000000..d3b9abb91ca --- /dev/null +++ b/mysql-test/suite/multi_source/reset_slave.test @@ -0,0 +1,62 @@ +#--enable_connect_log +--connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3) + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +eval change master 'master1' to +master_port=$SERVER_MYPORT_1, +master_host='127.0.0.1', +master_user='root'; + +start slave 'master1'; + +set default_master_connection = 'master1'; +--source include/wait_for_slave_to_start.inc + +--connect (master1,127.0.0.1,root,,,$SERVER_MYPORT_1) + +--disable_warnings +drop table if exists t1; +--enable_warnings + +create table t1 (i int) engine=MyISAM; +insert into t1 values (1),(2); + +--save_master_pos + +--connection slave + +--sync_with_master 0,'master1' +stop slave 'master1'; + +--wait_for_slave_to_stop + +--let $datadir = `SELECT @@datadir` + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +show slave 'master1' status; +--list_files $datadir mysqld* + +reset slave 'master1'; + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +show slave 'master1' status; +--list_files $datadir mysqld* + +reset slave 'master1' all; + +--error WARN_NO_MASTER_INFO +show slave 'master1' status; +--list_files $datadir mysqld* + +# Cleanup + +drop table t1; +--disconnect slave + +--connection master1 +drop table t1; +reset master; +--disconnect master1 + + + diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result index 7448e0a0113..aeb52d06bad 100644 --- a/mysql-test/suite/multi_source/simple.result +++ b/mysql-test/suite/multi_source/simple.result @@ -1,7 +1,12 @@ change master 'slave1' to master_port=MYPORT_1, master_host='127.0.0.1', master_user='root'; change master 'slave2' to master_port=MYPORT_2, master_host='127.0.0.1', master_user='root'; start slave 'slave1'; +set default_master_connection = 'slave1'; +include/wait_for_slave_to_start.inc +set default_master_connection = 'slave2'; start slave 'slave2'; +include/wait_for_slave_to_start.inc +set default_master_connection = ''; show full slave status; Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id slave1 Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 mysqld-relay-bin-slave1.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 1 diff --git a/mysql-test/suite/multi_source/simple.test b/mysql-test/suite/multi_source/simple.test index 97696c6e75f..8ebc1e9f0a6 100644 --- a/mysql-test/suite/multi_source/simple.test +++ b/mysql-test/suite/multi_source/simple.test @@ -9,8 +9,12 @@ eval change master 'slave1' to master_port=$SERVER_MYPORT_1, master_host='127.0. --replace_result $SERVER_MYPORT_2 MYPORT_2 eval change master 'slave2' to master_port=$SERVER_MYPORT_2, master_host='127.0.0.1', master_user='root'; start slave 'slave1'; +set default_master_connection = 'slave1'; +--source include/wait_for_slave_to_start.inc +set default_master_connection = 'slave2'; start slave 'slave2'; ---sleep 5 +--source include/wait_for_slave_to_start.inc +set default_master_connection = ''; --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 show full slave status; From 5a4b5869a039bd50ce5a040114ede77bbae58c80 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 28 Sep 2012 21:22:24 +0300 Subject: [PATCH 4/6] Fixed issues found by QA (Elena) - Added parameter to reset_logs() so that one can specify if new logs should be created. mysql-test/include/setup_fake_relay_log.inc: There is no orphan relay log files anymore mysql-test/mysql-test-run.pl: Added multi_source to test suite mysql-test/suite/multi_source/info_logs.result: New test mysql-test/suite/multi_source/info_logs.test: New test mysql-test/suite/multi_source/my.cnf: Added log-warnings to get more information to the log files mysql-test/suite/multi_source/relaylog_events.result: Added cleanup mysql-test/suite/multi_source/relaylog_events.test: Added cleanup mysql-test/suite/multi_source/reset_slave.result: Updated results after improved RESET SLAVE mysql-test/suite/multi_source/simple.result: Updated results after improved RESET SLAVE mysql-test/suite/multi_source/simple.test: Syncronize positions before show full slave status mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result: Updated results after improved RESET SLAVE (we now use less relay log files) mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result: Updated results after improved RESET SLAVE (we now use less relay log files) sql/log.cc: Added parameter to reset_logs() so that one can specify if new logs should be created. sql/log.h: Added parameter to reset_logs() sql/rpl_mi.cc: Create Master_info_index::index_file_names once at init More DBUG_PRINT Give error if Master_info_index::check_duplicate_master_info fails sql/rpl_rli.cc: If we do a full reset, don't create any new relay log files. sql/share/errmsg-utf8.txt: Improved error message if connection exists sql/sql_parse.cc: Fixed memory leak sql/sql_repl.cc: check_duplicate_master_info() now generates an error Added parameter to reset_logs() --- mysql-test/include/setup_fake_relay_log.inc | 4 - mysql-test/mysql-test-run.pl | 1 + .../suite/multi_source/info_logs.result | 115 +++++++++++++ mysql-test/suite/multi_source/info_logs.test | 160 ++++++++++++++++++ mysql-test/suite/multi_source/my.cnf | 3 + .../suite/multi_source/relaylog_events.result | 1 + .../suite/multi_source/relaylog_events.test | 2 + .../suite/multi_source/reset_slave.result | 6 +- mysql-test/suite/multi_source/simple.result | 2 +- mysql-test/suite/multi_source/simple.test | 13 ++ .../rpl/r/rpl_row_show_relaylog_events.result | 76 ++++----- .../r/rpl_stm_mix_show_relaylog_events.result | 70 ++++---- sql/log.cc | 8 +- sql/log.h | 2 +- sql/rpl_mi.cc | 53 +++--- sql/rpl_rli.cc | 35 ++-- sql/share/errmsg-utf8.txt | 3 +- sql/sql_parse.cc | 1 + sql/sql_repl.cc | 7 +- 19 files changed, 428 insertions(+), 134 deletions(-) create mode 100644 mysql-test/suite/multi_source/info_logs.result create mode 100644 mysql-test/suite/multi_source/info_logs.test diff --git a/mysql-test/include/setup_fake_relay_log.inc b/mysql-test/include/setup_fake_relay_log.inc index 4f1d4f6f162..a1964572427 100644 --- a/mysql-test/include/setup_fake_relay_log.inc +++ b/mysql-test/include/setup_fake_relay_log.inc @@ -74,7 +74,6 @@ let $_fake_relay_index= $_fake_datadir/$_fake_filename.index; let $_fake_relay_log_purge= `SELECT @@global.relay_log_purge`; RESET SLAVE; -let $_orphan_relay_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1); # Create relay log file. --copy_file $fake_relay_log $_fake_relay_log @@ -103,8 +102,5 @@ let $_orphan_relay_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1); # Setup replication from existing relay log. eval CHANGE MASTER TO MASTER_HOST='dummy.localdomain', RELAY_LOG_FILE='$_fake_filename-fake.000001', RELAY_LOG_POS=4; -# remove the orphan log file (became spurious) --- remove_file $_fake_datadir/$_orphan_relay_file - --let $include_filename= setup_fake_relay_log.inc --source include/end_include_file.inc diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 8c4013e1c24..768016d94aa 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -174,6 +174,7 @@ my $DEFAULT_SUITES= join(',', map { "$_-" } qw( heap innodb maria + multi_source optimizer_unfixed_bugs oqgraph parts diff --git a/mysql-test/suite/multi_source/info_logs.result b/mysql-test/suite/multi_source/info_logs.result new file mode 100644 index 00000000000..4947244068a --- /dev/null +++ b/mysql-test/suite/multi_source/info_logs.result @@ -0,0 +1,115 @@ +# +# List of files matching '*info*' pattern before starting any slaves +multi-master.info +# End of list +# +# Contents of multi-master.info +# EOF +# +change master 'master1' to +master_port=MYPORT_1, +master_host='127.0.0.1', +master_user='root'; +start slave 'master1'; +set default_master_connection = 'master1'; +include/wait_for_slave_to_start.inc +# +# List of files matching '*info*' pattern while 'master1' is running +master.info.master1 +multi-master.info +relay-log.info.master1 +# End of list +# +# Contents of multi-master.info +master1 +# EOF +# +change master 'master2' to +master_port=MYPORT_2, +master_host='127.0.0.1', +master_user='root'; +start slave 'master2'; +set default_master_connection = 'master2'; +include/wait_for_slave_to_start.inc +# +# List of files matching '*info*' pattern +# while 'master1' and 'master2' are running +master.info.master1 +master.info.master2 +multi-master.info +relay-log.info.master1 +relay-log.info.master2 +# End of list +# +# Contents of multi-master.info +master1 +master2 +# EOF +# +stop slave 'master1'; +set default_master_connection = 'master1'; +include/wait_for_slave_to_stop.inc +reset slave 'master1' all; +# +# List of files matching '*info*' pattern +# after 'master1' was completely reset, 'master2' still running +master.info.master2 +multi-master.info +relay-log.info.master2 +# End of list +# +# Contents of multi-master.info +master2 +# EOF +# +set default_master_connection = ''; +change master to +master_port=MYPORT_1, +master_host='127.0.0.1', +master_user='root'; +start slave; +include/wait_for_slave_to_start.inc +# +# List of files matching '*info*' pattern +# while 'master2' and '' are running +master.info +master.info.master2 +multi-master.info +relay-log.info +relay-log.info.master2 +# End of list +# +# Contents of multi-master.info +master2 +# EOF +# +show full slave status; +Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id + Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 mysqld-relay-bin.000002 572 master-bin.000001 Yes Yes 0 0 286 868 None 0 No 0 No 0 0 1 +master2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-master2.000002 572 master-bin.000001 Yes Yes 0 0 286 876 None 0 No 0 No 0 0 2 +show full slave status; +Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id + Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 mysqld-relay-bin.000004 532 master-bin.000001 Yes Yes 0 0 286 828 None 0 No 0 No 0 0 1 +master2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-master2.000004 532 master-bin.000001 Yes Yes 0 0 286 836 None 0 No 0 No 0 0 2 +# +# List of files matching '*info*' pattern +# after slave server restart +# while 'master2' and '' are running +master.info +master.info.master2 +multi-master.info +relay-log.info +relay-log.info.master2 +# End of list +# +# Contents of multi-master.info +master2 +# EOF +# +stop slave; +include/wait_for_slave_to_stop.inc +set default_master_connection = 'master2'; +stop slave; +include/wait_for_slave_to_stop.inc +reset slave all; +reset slave '' all; diff --git a/mysql-test/suite/multi_source/info_logs.test b/mysql-test/suite/multi_source/info_logs.test new file mode 100644 index 00000000000..40e1b481d2c --- /dev/null +++ b/mysql-test/suite/multi_source/info_logs.test @@ -0,0 +1,160 @@ +# +# Check log files with multi-source +# + +--connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3) + +--let $datadir = `SELECT @@datadir` + +# +# Check creation and updating of multi-source *info* logs +# + +--echo # +--echo # List of files matching '*info*' pattern before starting any slaves +--list_files $datadir *info* +--echo # End of list +--echo # +--echo # Contents of multi-master.info +--cat_file $datadir/multi-master.info +--echo # EOF +--echo # + +# Start replication from the first master + +--replace_result $SERVER_MYPORT_1 MYPORT_1 +eval change master 'master1' to +master_port=$SERVER_MYPORT_1, +master_host='127.0.0.1', +master_user='root'; + +start slave 'master1'; +set default_master_connection = 'master1'; +--source include/wait_for_slave_to_start.inc + +# Check the files + +--echo # +--echo # List of files matching '*info*' pattern while 'master1' is running +--list_files $datadir *info* +--echo # End of list +--echo # +--echo # Contents of multi-master.info +--cat_file $datadir/multi-master.info +--echo # EOF +--echo # + +# Start replication from the second master + +--replace_result $SERVER_MYPORT_2 MYPORT_2 +eval change master 'master2' to +master_port=$SERVER_MYPORT_2, +master_host='127.0.0.1', +master_user='root'; + +start slave 'master2'; +set default_master_connection = 'master2'; +--source include/wait_for_slave_to_start.inc + +# Check the files + +--echo # +--echo # List of files matching '*info*' pattern +--echo # while 'master1' and 'master2' are running +--list_files $datadir *info* +--echo # End of list +--echo # +--echo # Contents of multi-master.info +--cat_file $datadir/multi-master.info +--echo # EOF +--echo # + +# Remove master1 configuration + +stop slave 'master1'; +set default_master_connection = 'master1'; +--source include/wait_for_slave_to_stop.inc +reset slave 'master1' all; + +# Check the files + +--echo # +--echo # List of files matching '*info*' pattern +--echo # after 'master1' was completely reset, 'master2' still running +--list_files $datadir *info* +--echo # End of list +--echo # +--echo # Contents of multi-master.info +--cat_file $datadir/multi-master.info +--echo # EOF +--echo # + +# Start replication from the first master, +# now with the default empty name + +set default_master_connection = ''; +--replace_result $SERVER_MYPORT_1 MYPORT_1 +eval change master to +master_port=$SERVER_MYPORT_1, +master_host='127.0.0.1', +master_user='root'; + +start slave; +--source include/wait_for_slave_to_start.inc + +# Check the files + +--echo # +--echo # List of files matching '*info*' pattern +--echo # while 'master2' and '' are running +--list_files $datadir *info* +--echo # End of list +--echo # +--echo # Contents of multi-master.info +--cat_file $datadir/multi-master.info +--echo # EOF +--echo # + +--sleep 5 +--replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 +show full slave status; + +# Restart the slave server + +--enable_reconnect +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.3.expect +restart +EOF +--shutdown_server 60 +--source include/wait_until_connected_again.inc + +--replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 +show full slave status; + +# Check the files + +--echo # +--echo # List of files matching '*info*' pattern +--echo # after slave server restart +--echo # while 'master2' and '' are running +--list_files $datadir *info* +--echo # End of list +--echo # +--echo # Contents of multi-master.info +--cat_file $datadir/multi-master.info +--echo # EOF +--echo # + + +# Cleanup + +stop slave; +--source include/wait_for_slave_to_stop.inc + +set default_master_connection = 'master2'; +stop slave; +--source include/wait_for_slave_to_stop.inc +reset slave all; +reset slave '' all; + +--disconnect slave diff --git a/mysql-test/suite/multi_source/my.cnf b/mysql-test/suite/multi_source/my.cnf index dd57fd2199f..826967b52f9 100644 --- a/mysql-test/suite/multi_source/my.cnf +++ b/mysql-test/suite/multi_source/my.cnf @@ -5,13 +5,16 @@ [mysqld.1] server-id=1 log-bin=master-bin +log-warnings=2 [mysqld.2] server-id=2 log-bin=master-bin +log-warnings=2 [mysqld.3] server-id=3 +log-warnings=2 [ENV] SERVER_MYPORT_1= @mysqld.1.port diff --git a/mysql-test/suite/multi_source/relaylog_events.result b/mysql-test/suite/multi_source/relaylog_events.result index f93dff97718..a91ae82970b 100644 --- a/mysql-test/suite/multi_source/relaylog_events.result +++ b/mysql-test/suite/multi_source/relaylog_events.result @@ -24,4 +24,5 @@ mysqld-relay-bin-master1.000001 246 Rotate 3 304 mysqld-relay-bin-master1.000002 drop table t1; stop slave; include/wait_for_slave_to_stop.inc +reset slave 'master1' all; reset master; diff --git a/mysql-test/suite/multi_source/relaylog_events.test b/mysql-test/suite/multi_source/relaylog_events.test index a9488d1373c..b5bbf726316 100644 --- a/mysql-test/suite/multi_source/relaylog_events.test +++ b/mysql-test/suite/multi_source/relaylog_events.test @@ -42,6 +42,8 @@ drop table t1; stop slave; --source include/wait_for_slave_to_stop.inc +reset slave 'master1' all; + --disconnect slave --connection master1 diff --git a/mysql-test/suite/multi_source/reset_slave.result b/mysql-test/suite/multi_source/reset_slave.result index 0ae32e94166..a1256988bbf 100644 --- a/mysql-test/suite/multi_source/reset_slave.result +++ b/mysql-test/suite/multi_source/reset_slave.result @@ -18,14 +18,10 @@ mysqld-relay-bin.index-master1 reset slave 'master1'; show slave 'master1' status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id - 127.0.0.1 root MYPORT_1 60 4 mysqld-relay-bin-master1.000001 4 No No 0 0 0 265 None 0 No NULL No 0 0 1 -mysqld-relay-bin-master1.000001 -mysqld-relay-bin.index-master1 + 127.0.0.1 root MYPORT_1 60 4 1015 No No 0 0 0 1319 None 0 No NULL No 0 0 1 reset slave 'master1' all; show slave 'master1' status; ERROR HY000: There is no master connection 'master1' -mysqld-relay-bin-master1.000001 -mysqld-relay-bin.index-master1 drop table t1; drop table t1; reset master; diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result index aeb52d06bad..003622a1b46 100644 --- a/mysql-test/suite/multi_source/simple.result +++ b/mysql-test/suite/multi_source/simple.result @@ -56,7 +56,7 @@ Master_Server_Id 1 reset slave 'slave1'; show full slave status; Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id -slave1 127.0.0.1 root MYPORT_1 60 4 mysqld-relay-bin-slave1.000001 4 No No 0 0 0 265 None 0 No NULL No 0 0 1 +slave1 127.0.0.1 root MYPORT_1 60 4 572 No No 0 0 0 875 None 0 No NULL No 0 0 1 slave2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 reset slave 'slave1' all; show full slave status; diff --git a/mysql-test/suite/multi_source/simple.test b/mysql-test/suite/multi_source/simple.test index 8ebc1e9f0a6..2b4f06aa1fe 100644 --- a/mysql-test/suite/multi_source/simple.test +++ b/mysql-test/suite/multi_source/simple.test @@ -3,6 +3,9 @@ # --connect (slave,127.0.0.1,root,,,$SERVER_MYPORT_3) +--connect (master1,127.0.0.1,root,,,$SERVER_MYPORT_1) +--connect (master2,127.0.0.1,root,,,$SERVER_MYPORT_2) +--connection slave --replace_result $SERVER_MYPORT_1 MYPORT_1 eval change master 'slave1' to master_port=$SERVER_MYPORT_1, master_host='127.0.0.1', master_user='root'; @@ -16,6 +19,16 @@ start slave 'slave2'; --source include/wait_for_slave_to_start.inc set default_master_connection = ''; +# Ensure that all data is in the relay log +--connection master1 +--save_master_pos +--connection slave +--sync_with_master 0,'slave1' +--connection master2 +--save_master_pos +--connection slave +--sync_with_master 0,'slave2' + --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 show full slave status; diff --git a/mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result b/mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result index a6d691f420e..cd72b489e1a 100644 --- a/mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result +++ b/mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result @@ -90,38 +90,38 @@ slave-bin.000001 # Table_map # # table_id: # (test.t1) slave-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F slave-bin.000001 # Query # # COMMIT ******** [slave] SHOW RELAYLOG EVENTS IN ******** -show relaylog events in 'slave-relay-bin.000003' from ; +show relaylog events in 'slave-relay-bin.000002' from ; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000003 # Rotate # # master-bin.000001;pos=4 -slave-relay-bin.000003 # Format_desc # # SERVER_VERSION, BINLOG_VERSION -slave-relay-bin.000003 # Binlog_checkpoint # # master-bin.000001 -slave-relay-bin.000003 # Query # # use `test`; CREATE TABLE t1 (a INT) -slave-relay-bin.000003 # Query # # BEGIN -slave-relay-bin.000003 # Table_map # # table_id: # (test.t1) -slave-relay-bin.000003 # Write_rows # # table_id: # flags: STMT_END_F -slave-relay-bin.000003 # Query # # COMMIT -slave-relay-bin.000003 # Query # # BEGIN -slave-relay-bin.000003 # Table_map # # table_id: # (test.t1) -slave-relay-bin.000003 # Write_rows # # table_id: # flags: STMT_END_F -slave-relay-bin.000003 # Query # # COMMIT -slave-relay-bin.000003 # Query # # BEGIN -slave-relay-bin.000003 # Table_map # # table_id: # (test.t1) -slave-relay-bin.000003 # Write_rows # # table_id: # flags: STMT_END_F -slave-relay-bin.000003 # Query # # COMMIT +slave-relay-bin.000002 # Rotate # # master-bin.000001;pos=4 +slave-relay-bin.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +slave-relay-bin.000002 # Binlog_checkpoint # # master-bin.000001 +slave-relay-bin.000002 # Query # # use `test`; CREATE TABLE t1 (a INT) +slave-relay-bin.000002 # Query # # BEGIN +slave-relay-bin.000002 # Table_map # # table_id: # (test.t1) +slave-relay-bin.000002 # Write_rows # # table_id: # flags: STMT_END_F +slave-relay-bin.000002 # Query # # COMMIT +slave-relay-bin.000002 # Query # # BEGIN +slave-relay-bin.000002 # Table_map # # table_id: # (test.t1) +slave-relay-bin.000002 # Write_rows # # table_id: # flags: STMT_END_F +slave-relay-bin.000002 # Query # # COMMIT +slave-relay-bin.000002 # Query # # BEGIN +slave-relay-bin.000002 # Table_map # # table_id: # (test.t1) +slave-relay-bin.000002 # Write_rows # # table_id: # flags: STMT_END_F +slave-relay-bin.000002 # Query # # COMMIT ******** [slave] SHOW RELAYLOG EVENTS IN LIMIT 1 ******** -show relaylog events in 'slave-relay-bin.000003' from limit 1; +show relaylog events in 'slave-relay-bin.000002' from limit 1; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000003 # Rotate # # master-bin.000001;pos=4 +slave-relay-bin.000002 # Rotate # # master-bin.000001;pos=4 ******** [slave] SHOW RELAYLOG EVENTS IN LIMIT 1,3 ******** -show relaylog events in 'slave-relay-bin.000003' from limit 1,3; +show relaylog events in 'slave-relay-bin.000002' from limit 1,3; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000003 # Format_desc # # SERVER_VERSION, BINLOG_VERSION -slave-relay-bin.000003 # Binlog_checkpoint # # master-bin.000001 -slave-relay-bin.000003 # Query # # use `test`; CREATE TABLE t1 (a INT) +slave-relay-bin.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +slave-relay-bin.000002 # Binlog_checkpoint # # master-bin.000001 +slave-relay-bin.000002 # Query # # use `test`; CREATE TABLE t1 (a INT) ******** [slave] SHOW RELAYLOG EVENTS ******** show relaylog events from ; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000002 # Rotate # # slave-relay-bin.000003;pos=4 +slave-relay-bin.000001 # Rotate # # slave-relay-bin.000002;pos=4 FLUSH LOGS; FLUSH LOGS; DROP TABLE t1; @@ -186,26 +186,26 @@ slave-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F slave-bin.000001 # Query # # COMMIT slave-bin.000001 # Rotate # # slave-bin.000002;pos=4 ******** [slave] SHOW RELAYLOG EVENTS IN ******** -show relaylog events in 'slave-relay-bin.000006' from ; +show relaylog events in 'slave-relay-bin.000005' from ; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000006 # Rotate # # master-bin.000002;pos=4 -slave-relay-bin.000006 # Format_desc # # SERVER_VERSION, BINLOG_VERSION -slave-relay-bin.000006 # Binlog_checkpoint # # master-bin.000001 -slave-relay-bin.000006 # Binlog_checkpoint # # master-bin.000002 -slave-relay-bin.000006 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-relay-bin.000005 # Rotate # # master-bin.000002;pos=4 +slave-relay-bin.000005 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +slave-relay-bin.000005 # Binlog_checkpoint # # master-bin.000001 +slave-relay-bin.000005 # Binlog_checkpoint # # master-bin.000002 +slave-relay-bin.000005 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ ******** [slave] SHOW RELAYLOG EVENTS IN LIMIT 1 ******** -show relaylog events in 'slave-relay-bin.000006' from limit 1; +show relaylog events in 'slave-relay-bin.000005' from limit 1; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000006 # Rotate # # master-bin.000002;pos=4 +slave-relay-bin.000005 # Rotate # # master-bin.000002;pos=4 ******** [slave] SHOW RELAYLOG EVENTS IN LIMIT 1,3 ******** -show relaylog events in 'slave-relay-bin.000006' from limit 1,3; +show relaylog events in 'slave-relay-bin.000005' from limit 1,3; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000006 # Format_desc # # SERVER_VERSION, BINLOG_VERSION -slave-relay-bin.000006 # Binlog_checkpoint # # master-bin.000001 -slave-relay-bin.000006 # Binlog_checkpoint # # master-bin.000002 +slave-relay-bin.000005 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +slave-relay-bin.000005 # Binlog_checkpoint # # master-bin.000001 +slave-relay-bin.000005 # Binlog_checkpoint # # master-bin.000002 ******** [slave] SHOW RELAYLOG EVENTS ******** show relaylog events from ; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000005 # Rotate # # master-bin.000002;pos=4 -slave-relay-bin.000005 # Rotate # # slave-relay-bin.000006;pos=4 +slave-relay-bin.000004 # Rotate # # master-bin.000002;pos=4 +slave-relay-bin.000004 # Rotate # # slave-relay-bin.000005;pos=4 include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result b/mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result index 2c93a15a7b3..490c4998b5d 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result +++ b/mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result @@ -78,35 +78,35 @@ slave-bin.000001 # Query # # BEGIN slave-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (3) slave-bin.000001 # Query # # COMMIT ******** [slave] SHOW RELAYLOG EVENTS IN ******** -show relaylog events in 'slave-relay-bin.000003' from ; +show relaylog events in 'slave-relay-bin.000002' from ; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000003 # Rotate # # master-bin.000001;pos=4 -slave-relay-bin.000003 # Format_desc # # SERVER_VERSION, BINLOG_VERSION -slave-relay-bin.000003 # Binlog_checkpoint # # master-bin.000001 -slave-relay-bin.000003 # Query # # use `test`; CREATE TABLE t1 (a INT) -slave-relay-bin.000003 # Query # # BEGIN -slave-relay-bin.000003 # Query # # use `test`; INSERT INTO t1 VALUES (1) -slave-relay-bin.000003 # Query # # COMMIT -slave-relay-bin.000003 # Query # # BEGIN -slave-relay-bin.000003 # Query # # use `test`; INSERT INTO t1 VALUES (2) -slave-relay-bin.000003 # Query # # COMMIT -slave-relay-bin.000003 # Query # # BEGIN -slave-relay-bin.000003 # Query # # use `test`; INSERT INTO t1 VALUES (3) -slave-relay-bin.000003 # Query # # COMMIT +slave-relay-bin.000002 # Rotate # # master-bin.000001;pos=4 +slave-relay-bin.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +slave-relay-bin.000002 # Binlog_checkpoint # # master-bin.000001 +slave-relay-bin.000002 # Query # # use `test`; CREATE TABLE t1 (a INT) +slave-relay-bin.000002 # Query # # BEGIN +slave-relay-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (1) +slave-relay-bin.000002 # Query # # COMMIT +slave-relay-bin.000002 # Query # # BEGIN +slave-relay-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (2) +slave-relay-bin.000002 # Query # # COMMIT +slave-relay-bin.000002 # Query # # BEGIN +slave-relay-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES (3) +slave-relay-bin.000002 # Query # # COMMIT ******** [slave] SHOW RELAYLOG EVENTS IN LIMIT 1 ******** -show relaylog events in 'slave-relay-bin.000003' from limit 1; +show relaylog events in 'slave-relay-bin.000002' from limit 1; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000003 # Rotate # # master-bin.000001;pos=4 +slave-relay-bin.000002 # Rotate # # master-bin.000001;pos=4 ******** [slave] SHOW RELAYLOG EVENTS IN LIMIT 1,3 ******** -show relaylog events in 'slave-relay-bin.000003' from limit 1,3; +show relaylog events in 'slave-relay-bin.000002' from limit 1,3; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000003 # Format_desc # # SERVER_VERSION, BINLOG_VERSION -slave-relay-bin.000003 # Binlog_checkpoint # # master-bin.000001 -slave-relay-bin.000003 # Query # # use `test`; CREATE TABLE t1 (a INT) +slave-relay-bin.000002 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +slave-relay-bin.000002 # Binlog_checkpoint # # master-bin.000001 +slave-relay-bin.000002 # Query # # use `test`; CREATE TABLE t1 (a INT) ******** [slave] SHOW RELAYLOG EVENTS ******** show relaylog events from ; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000002 # Rotate # # slave-relay-bin.000003;pos=4 +slave-relay-bin.000001 # Rotate # # slave-relay-bin.000002;pos=4 FLUSH LOGS; FLUSH LOGS; DROP TABLE t1; @@ -165,26 +165,26 @@ slave-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (3) slave-bin.000001 # Query # # COMMIT slave-bin.000001 # Rotate # # slave-bin.000002;pos=4 ******** [slave] SHOW RELAYLOG EVENTS IN ******** -show relaylog events in 'slave-relay-bin.000006' from ; +show relaylog events in 'slave-relay-bin.000005' from ; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000006 # Rotate # # master-bin.000002;pos=4 -slave-relay-bin.000006 # Format_desc # # SERVER_VERSION, BINLOG_VERSION -slave-relay-bin.000006 # Binlog_checkpoint # # master-bin.000001 -slave-relay-bin.000006 # Binlog_checkpoint # # master-bin.000002 -slave-relay-bin.000006 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ +slave-relay-bin.000005 # Rotate # # master-bin.000002;pos=4 +slave-relay-bin.000005 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +slave-relay-bin.000005 # Binlog_checkpoint # # master-bin.000001 +slave-relay-bin.000005 # Binlog_checkpoint # # master-bin.000002 +slave-relay-bin.000005 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ ******** [slave] SHOW RELAYLOG EVENTS IN LIMIT 1 ******** -show relaylog events in 'slave-relay-bin.000006' from limit 1; +show relaylog events in 'slave-relay-bin.000005' from limit 1; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000006 # Rotate # # master-bin.000002;pos=4 +slave-relay-bin.000005 # Rotate # # master-bin.000002;pos=4 ******** [slave] SHOW RELAYLOG EVENTS IN LIMIT 1,3 ******** -show relaylog events in 'slave-relay-bin.000006' from limit 1,3; +show relaylog events in 'slave-relay-bin.000005' from limit 1,3; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000006 # Format_desc # # SERVER_VERSION, BINLOG_VERSION -slave-relay-bin.000006 # Binlog_checkpoint # # master-bin.000001 -slave-relay-bin.000006 # Binlog_checkpoint # # master-bin.000002 +slave-relay-bin.000005 # Format_desc # # SERVER_VERSION, BINLOG_VERSION +slave-relay-bin.000005 # Binlog_checkpoint # # master-bin.000001 +slave-relay-bin.000005 # Binlog_checkpoint # # master-bin.000002 ******** [slave] SHOW RELAYLOG EVENTS ******** show relaylog events from ; Log_name Pos Event_type Server_id End_log_pos Info -slave-relay-bin.000005 # Rotate # # master-bin.000002;pos=4 -slave-relay-bin.000005 # Rotate # # slave-relay-bin.000006;pos=4 +slave-relay-bin.000004 # Rotate # # master-bin.000002;pos=4 +slave-relay-bin.000004 # Rotate # # slave-relay-bin.000005;pos=4 include/rpl_end.inc diff --git a/sql/log.cc b/sql/log.cc index 54340f94679..1f3c529f491 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3598,11 +3598,11 @@ err: /** Delete all logs refered to in the index file. - Start writing to a new log file. The new index file will only contain this file. - @param thd Thread + @param thd Thread + @param create_new_log 1 if we should start writing to a new log file @note If not called from slave thread, write start event to new log @@ -3613,7 +3613,7 @@ err: 1 error */ -bool MYSQL_BIN_LOG::reset_logs(THD* thd) +bool MYSQL_BIN_LOG::reset_logs(THD* thd, bool create_new_log) { LOG_INFO linfo; bool error=0; @@ -3780,7 +3780,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) goto err; } } - if (!open_index_file(index_file_name, 0, FALSE)) + if (create_new_log && !open_index_file(index_file_name, 0, FALSE)) if ((error= open(save_name, log_type, 0, io_cache_type, max_size, 0, FALSE))) goto err; my_free((void *) save_name); diff --git a/sql/log.h b/sql/log.h index cd1845908ef..0ade3618fd7 100644 --- a/sql/log.h +++ b/sql/log.h @@ -748,7 +748,7 @@ public: int register_create_index_entry(const char* entry); int purge_index_entry(THD *thd, ulonglong *decrease_log_space, bool need_mutex); - bool reset_logs(THD* thd); + bool reset_logs(THD* thd, bool create_new_log); void close(uint exiting); void clear_inuse_flag_when_closing(File file); diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 3dc3e38f419..366b271851a 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -657,7 +657,20 @@ void create_signed_file_name(char *res_file_name, uint length, Master_info_index::Master_info_index() { - index_file_name[0] = 0; + size_t filename_length, dir_length; + /* + Create the Master_info index file by prepending 'multi-' before + the master_info_file file name. + */ + fn_format(index_file_name, master_info_file, mysql_data_home, + "", MY_UNPACK_FILENAME); + filename_length= strlen(index_file_name) + 1; /* Count 0 byte */ + dir_length= dirname_length(index_file_name); + bmove_upp((uchar*) index_file_name + filename_length + 6, + (uchar*) index_file_name + filename_length, + filename_length - dir_length); + memcpy(index_file_name + dir_length, "multi-", 6); + bzero((char*) &index_file, sizeof(index_file)); } @@ -684,22 +697,8 @@ bool Master_info_index::init_all_master_info() int err_num= 0, succ_num= 0; // The number of success read Master_info char sign[MAX_CONNECTION_NAME]; File index_file_nr; - size_t filename_length, dir_length; DBUG_ENTER("init_all_master_info"); - /* - Create the Master_info index file by prepending 'multi-' before - the master_info_file file name. - */ - fn_format(index_file_name, master_info_file, mysql_data_home, - "", MY_UNPACK_FILENAME); - filename_length= strlen(index_file_name) + 1; /* Count 0 byte */ - dir_length= dirname_length(index_file_name); - bmove_upp((uchar*) index_file_name + filename_length + 6, - (uchar*) index_file_name + filename_length, - filename_length - dir_length); - memcpy(index_file_name + dir_length, "multi-", 6); - if ((index_file_nr= my_open(index_file_name, O_RDWR | O_CREAT | O_BINARY , MYF(MY_WME | ME_NOREFRESH))) < 0 || @@ -891,6 +890,10 @@ Master_info_index::get_master_info(LEX_STRING *connection_name, Master_info *mi; char buff[MAX_CONNECTION_NAME+1], *res; uint buff_length; + DBUG_ENTER("get_master_info"); + DBUG_PRINT("enter", + ("connection_name: '%.*s'", (int) connection_name->length, + connection_name->str)); /* Make name lower case for comparison */ res= strmake(buff, connection_name->str, connection_name->length); @@ -907,7 +910,7 @@ Master_info_index::get_master_info(LEX_STRING *connection_name, (int) connection_name->length, connection_name->str); } - return mi; + DBUG_RETURN(mi); } @@ -917,6 +920,7 @@ bool Master_info_index::check_duplicate_master_info(LEX_STRING *name_arg, uint port) { Master_info *mi; + DBUG_ENTER("check_duplicate_master_info"); /* Get full host and port name */ if ((mi= master_info_index->get_master_info(name_arg, @@ -928,7 +932,7 @@ bool Master_info_index::check_duplicate_master_info(LEX_STRING *name_arg, port= mi->port; } if (!host || !port) - return FALSE; // Not comparable yet + DBUG_RETURN(FALSE); // Not comparable yet for (uint i= 0; i < master_info_hash.records; ++i) { @@ -938,13 +942,15 @@ bool Master_info_index::check_duplicate_master_info(LEX_STRING *name_arg, continue; // Current connection if (!strcasecmp(host, tmp_mi->host) && port == tmp_mi->port) { - sql_print_error(ER(ER_CONNECTION_ALREADY_EXISTS), - (int) tmp_mi->connection_name.length, - tmp_mi->connection_name.str); - return TRUE; + my_error(ER_CONNECTION_ALREADY_EXISTS, MYF(0), + (int) name_arg->length, + name_arg->str, + (int) tmp_mi->connection_name.length, + tmp_mi->connection_name.str); + DBUG_RETURN(TRUE); } } - return FALSE; + DBUG_RETURN(FALSE); } @@ -994,9 +1000,6 @@ bool Master_info_index::remove_master_info(LEX_STRING *name) my_close(index_file.file, MYF(MY_WME)); // Reopen File and truncate it - fn_format(index_file_name, master_info_file, mysql_data_home, - ".index", MY_UNPACK_FILENAME | MY_APPEND_EXT); - if ((index_file_nr= my_open(index_file_name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY , MYF(MY_WME))) < 0 || diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 442a9895f6b..49c8390ff9b 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1015,28 +1015,37 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, rli->cur_log_fd= -1; } - if (rli->relay_log.reset_logs(thd)) + if (rli->relay_log.reset_logs(thd, !just_reset)) { *errmsg = "Failed during log reset"; error=1; goto err; } - /* Save name of used relay log file */ - strmake(rli->group_relay_log_name, rli->relay_log.get_log_fname(), - sizeof(rli->group_relay_log_name)-1); - strmake(rli->event_relay_log_name, rli->relay_log.get_log_fname(), - sizeof(rli->event_relay_log_name)-1); - rli->group_relay_log_pos= rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE; - if (count_relay_log_space(rli)) - { - *errmsg= "Error counting relay log space"; - error=1; - goto err; - } if (!just_reset) + { + /* Save name of used relay log file */ + strmake(rli->group_relay_log_name, rli->relay_log.get_log_fname(), + sizeof(rli->group_relay_log_name)-1); + strmake(rli->event_relay_log_name, rli->relay_log.get_log_fname(), + sizeof(rli->event_relay_log_name)-1); + rli->group_relay_log_pos= rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE; + rli->log_space_total= 0; + + if (count_relay_log_space(rli)) + { + *errmsg= "Error counting relay log space"; + error=1; + goto err; + } error= init_relay_log_pos(rli, rli->group_relay_log_name, rli->group_relay_log_pos, 0 /* do not need data lock */, errmsg, 0); + } + else + { + /* Ensure relay log names are not used */ + rli->group_relay_log_name[0]= rli->event_relay_log_name[0]= 0; + } err: #ifndef DBUG_OFF diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index bb5506756e1..803575b7ba0 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6589,7 +6589,6 @@ ER_NO_SUCH_TABLE_IN_ENGINE 42S02 eng "Table '%-.192s.%-.192s' doesn't exist in engine" swe "Det finns ingen tabell som heter '%-.192s.%-.192s' i handlern" ER_CONNECTION_ALREADY_EXISTS - eng "Connection '%.*s' already exists" + eng "Connection '%.*s' conflicts with existing connection '%.*s'" ER_MASTER_LOG_PREFIX eng "Master '%.*s': " - diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 114035bc16d..831931e1ef2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2377,6 +2377,7 @@ case SQLCOM_PREPARE: work. */ master_info_index->remove_master_info(&lex_mi->connection_name); + delete mi; } mysql_mutex_unlock(&LOCK_active_mi); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 036afb45a19..ed00fcaaddf 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1682,12 +1682,7 @@ bool change_master(THD* thd, Master_info* mi) if (master_info_index->check_duplicate_master_info(&lex_mi->connection_name, lex_mi->host, lex_mi->port)) - { - my_error(ER_MASTER_INFO, MYF(0), - (int) lex_mi->connection_name.length, - lex_mi->connection_name.str); DBUG_RETURN(TRUE); - } lock_slave_threads(mi); init_thread_mask(&thread_mask,mi,0 /*not inverse*/); @@ -1996,7 +1991,7 @@ int reset_master(THD* thd) return 1; } - if (mysql_bin_log.reset_logs(thd)) + if (mysql_bin_log.reset_logs(thd, 1)) return 1; RUN_HOOK(binlog_transmit, after_reset_master, (thd, 0 /* flags */)); return 0; From 8ac1b41cf358029b8e08e977f45bb6197a1c1c19 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 1 Oct 2012 02:30:44 +0300 Subject: [PATCH 5/6] Made max_relay_log_size depending on master connection. Changed names of multi-source log files so that original suffixes are kept. include/my_sys.h: Added fn_ext2(), which returns pointer to last '.' in file name mysql-test/extra/rpl_tests/rpl_max_relay_size.test: Updated test mysql-test/suite/multi_source/info_logs-master.opt: Test with strange file names mysql-test/suite/multi_source/info_logs.result: Updated results mysql-test/suite/multi_source/info_logs.test: Changed to test with complex names to be able to verify the filename generator code mysql-test/suite/multi_source/relaylog_events.result: Updated results mysql-test/suite/multi_source/reset_slave.result: Updated results mysql-test/suite/multi_source/skip_counter.result: Updated results mysql-test/suite/multi_source/skip_counter.test: Added testing of max_relay_log_size mysql-test/suite/rpl/r/rpl_row_max_relay_size.result: Updated results mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result: Updated results mysql-test/suite/sys_vars/r/max_relay_log_size_basic.result: Updated results mysql-test/suite/sys_vars/t/max_relay_log_size_basic.test: Updated results mysys/mf_fn_ext.c: Added fn_ext2(), which returns pointer to last '.' in file name sql/log.cc: Removed some wrong casts sql/log.h: Updated comment to reflect new code sql/log_event.cc: Updated DBUG_PRINT sql/mysqld.cc: Added that max_relay_log_size copies it's values from max_binlog_size sql/mysqld.h: Removed max_relay_log_size sql/rpl_mi.cc: Changed names of multi-source log files so that original suffixes are kept. sql/rpl_mi.h: Updated prototype sql/rpl_rli.cc: Updated comment to reflect new code Made max_relay_log_size depending on master connection. sql/rpl_rli.h: Made max_relay_log_size depending on master connection. sql/set_var.h: Made option global so that one can check and change min & max values (sorry Sergei) sql/sql_class.h: Made max_relay_log_size depending on master connection. sql/sql_repl.cc: Updated calls to create_signed_file_name() sql/sys_vars.cc: Made max_relay_log_size depending on master connection. Made old code more reusable sql/sys_vars.h: Changed Sys_var_multi_source_uint to ulong to be able to handle max_relay_log_size Made old code more reusable --- include/my_sys.h | 1 + .../extra/rpl_tests/rpl_max_relay_size.test | 3 +- .../suite/multi_source/info_logs-master.opt | 1 + .../suite/multi_source/info_logs.result | 60 +++++++------- mysql-test/suite/multi_source/info_logs.test | 16 ++-- .../suite/multi_source/relaylog_events.result | 1 + .../suite/multi_source/reset_slave.result | 2 +- .../suite/multi_source/skip_counter.result | 45 ++++++++++ .../suite/multi_source/skip_counter.test | 29 ++++++- .../suite/rpl/r/rpl_row_max_relay_size.result | 7 +- .../suite/rpl/r/rpl_stm_max_relay_size.result | 7 +- .../r/max_relay_log_size_basic.result | 29 ++++--- .../sys_vars/t/max_relay_log_size_basic.test | 3 - mysys/mf_fn_ext.c | 37 +++++++++ sql/log.cc | 4 +- sql/log.h | 5 +- sql/log_event.cc | 6 +- sql/mysqld.cc | 24 +++++- sql/mysqld.h | 2 +- sql/rpl_mi.cc | 38 ++++++--- sql/rpl_mi.h | 2 +- sql/rpl_rli.cc | 17 +--- sql/rpl_rli.h | 3 +- sql/set_var.h | 3 +- sql/sql_class.h | 5 +- sql/sql_repl.cc | 12 +-- sql/sys_vars.cc | 83 ++++++++++--------- sql/sys_vars.h | 42 ++++++---- 28 files changed, 326 insertions(+), 161 deletions(-) create mode 100644 mysql-test/suite/multi_source/info_logs-master.opt diff --git a/include/my_sys.h b/include/my_sys.h index 1d666cb4a60..336b5635dd8 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -679,6 +679,7 @@ extern my_bool has_path(const char *name); extern char *convert_dirname(char *to, const char *from, const char *from_end); extern void to_unix_path(char * name); extern char * fn_ext(const char *name); +extern char * fn_ext2(const char *name); extern char * fn_same(char * toname,const char *name,int flag); extern char * fn_format(char * to,const char *name,const char *dir, const char *form, uint flag); diff --git a/mysql-test/extra/rpl_tests/rpl_max_relay_size.test b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test index d8cd4f2d284..0fcff5ebe6c 100644 --- a/mysql-test/extra/rpl_tests/rpl_max_relay_size.test +++ b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test @@ -34,7 +34,7 @@ reset slave; --echo # Test 1 --echo # -set @my_max_binlog_size= @@global.max_binlog_size; +set @my_max_binlog_size= @@global.max_binlog_size, @my_max_relay_log_size=@@global.max_relay_log_size; set global max_binlog_size=8192; set global max_relay_log_size=8192-1; # mapped to 4096 select @@global.max_relay_log_size; @@ -110,6 +110,7 @@ source include/show_master_status.inc; # Restore max_binlog_size connection slave; set global max_binlog_size= @my_max_binlog_size; +set global max_relay_log_size= @my_max_relay_log_size; --echo # --echo # End of 4.1 tests diff --git a/mysql-test/suite/multi_source/info_logs-master.opt b/mysql-test/suite/multi_source/info_logs-master.opt new file mode 100644 index 00000000000..da4e6d3c455 --- /dev/null +++ b/mysql-test/suite/multi_source/info_logs-master.opt @@ -0,0 +1 @@ +--relay-log=relay.bin --relay-log-info=relay.bin.info diff --git a/mysql-test/suite/multi_source/info_logs.result b/mysql-test/suite/multi_source/info_logs.result index 4947244068a..1da44992ec6 100644 --- a/mysql-test/suite/multi_source/info_logs.result +++ b/mysql-test/suite/multi_source/info_logs.result @@ -15,35 +15,35 @@ set default_master_connection = 'master1'; include/wait_for_slave_to_start.inc # # List of files matching '*info*' pattern while 'master1' is running -master.info.master1 +master-master1.info multi-master.info -relay-log.info.master1 +relay.bin-master1.info # End of list # # Contents of multi-master.info master1 # EOF # -change master 'master2' to +change master 'MASTER 2.2' to master_port=MYPORT_2, master_host='127.0.0.1', master_user='root'; -start slave 'master2'; -set default_master_connection = 'master2'; +start slave 'MASTER 2.2'; +set default_master_connection = 'MASTER 2.2'; include/wait_for_slave_to_start.inc # # List of files matching '*info*' pattern -# while 'master1' and 'master2' are running -master.info.master1 -master.info.master2 +# while 'master1' and 'MASTER 2.2' are running +master-master1.info +master-master@00202@002e2.info multi-master.info -relay-log.info.master1 -relay-log.info.master2 +relay.bin-master1.info +relay.bin-master@00202@002e2.info # End of list # # Contents of multi-master.info master1 -master2 +MASTER 2.2 # EOF # stop slave 'master1'; @@ -52,14 +52,14 @@ include/wait_for_slave_to_stop.inc reset slave 'master1' all; # # List of files matching '*info*' pattern -# after 'master1' was completely reset, 'master2' still running -master.info.master2 +# after 'master1' was completely reset, 'MASTER 2.2' still running +master-master@00202@002e2.info multi-master.info -relay-log.info.master2 +relay.bin-master@00202@002e2.info # End of list # # Contents of multi-master.info -master2 +MASTER 2.2 # EOF # set default_master_connection = ''; @@ -71,44 +71,44 @@ start slave; include/wait_for_slave_to_start.inc # # List of files matching '*info*' pattern -# while 'master2' and '' are running +# while 'MASTER 2.2' and '' are running +master-master@00202@002e2.info master.info -master.info.master2 multi-master.info -relay-log.info -relay-log.info.master2 +relay.bin-master@00202@002e2.info +relay.bin.info # End of list # # Contents of multi-master.info -master2 +MASTER 2.2 # EOF # show full slave status; Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id - Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 mysqld-relay-bin.000002 572 master-bin.000001 Yes Yes 0 0 286 868 None 0 No 0 No 0 0 1 -master2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-master2.000002 572 master-bin.000001 Yes Yes 0 0 286 876 None 0 No 0 No 0 0 2 + Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 relay.000002 572 master-bin.000001 Yes Yes 0 0 286 857 None 0 No 0 No 0 0 1 +MASTER 2.2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 relay-master@00202@002e2.000002 572 master-bin.000001 Yes Yes 0 0 286 876 None 0 No 0 No 0 0 2 show full slave status; Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id - Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 mysqld-relay-bin.000004 532 master-bin.000001 Yes Yes 0 0 286 828 None 0 No 0 No 0 0 1 -master2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-master2.000004 532 master-bin.000001 Yes Yes 0 0 286 836 None 0 No 0 No 0 0 2 + Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 relay.000004 532 master-bin.000001 Yes Yes 0 0 286 817 None 0 No 0 No 0 0 1 +MASTER 2.2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 relay-master@00202@002e2.000004 532 master-bin.000001 Yes Yes 0 0 286 836 None 0 No 0 No 0 0 2 # # List of files matching '*info*' pattern # after slave server restart -# while 'master2' and '' are running +# while 'MASTER 2.2' and '' are running +master-master@00202@002e2.info master.info -master.info.master2 multi-master.info -relay-log.info -relay-log.info.master2 +relay.bin-master@00202@002e2.info +relay.bin.info # End of list # # Contents of multi-master.info -master2 +MASTER 2.2 # EOF # stop slave; include/wait_for_slave_to_stop.inc -set default_master_connection = 'master2'; +set default_master_connection = 'MASTER 2.2'; stop slave; include/wait_for_slave_to_stop.inc reset slave all; diff --git a/mysql-test/suite/multi_source/info_logs.test b/mysql-test/suite/multi_source/info_logs.test index 40e1b481d2c..f06880faca6 100644 --- a/mysql-test/suite/multi_source/info_logs.test +++ b/mysql-test/suite/multi_source/info_logs.test @@ -47,20 +47,20 @@ set default_master_connection = 'master1'; # Start replication from the second master --replace_result $SERVER_MYPORT_2 MYPORT_2 -eval change master 'master2' to +eval change master 'MASTER 2.2' to master_port=$SERVER_MYPORT_2, master_host='127.0.0.1', master_user='root'; -start slave 'master2'; -set default_master_connection = 'master2'; +start slave 'MASTER 2.2'; +set default_master_connection = 'MASTER 2.2'; --source include/wait_for_slave_to_start.inc # Check the files --echo # --echo # List of files matching '*info*' pattern ---echo # while 'master1' and 'master2' are running +--echo # while 'master1' and 'MASTER 2.2' are running --list_files $datadir *info* --echo # End of list --echo # @@ -80,7 +80,7 @@ reset slave 'master1' all; --echo # --echo # List of files matching '*info*' pattern ---echo # after 'master1' was completely reset, 'master2' still running +--echo # after 'master1' was completely reset, 'MASTER 2.2' still running --list_files $datadir *info* --echo # End of list --echo # @@ -106,7 +106,7 @@ start slave; --echo # --echo # List of files matching '*info*' pattern ---echo # while 'master2' and '' are running +--echo # while 'MASTER 2.2' and '' are running --list_files $datadir *info* --echo # End of list --echo # @@ -136,7 +136,7 @@ show full slave status; --echo # --echo # List of files matching '*info*' pattern --echo # after slave server restart ---echo # while 'master2' and '' are running +--echo # while 'MASTER 2.2' and '' are running --list_files $datadir *info* --echo # End of list --echo # @@ -151,7 +151,7 @@ show full slave status; stop slave; --source include/wait_for_slave_to_stop.inc -set default_master_connection = 'master2'; +set default_master_connection = 'MASTER 2.2'; stop slave; --source include/wait_for_slave_to_stop.inc reset slave all; diff --git a/mysql-test/suite/multi_source/relaylog_events.result b/mysql-test/suite/multi_source/relaylog_events.result index a91ae82970b..437dc87788a 100644 --- a/mysql-test/suite/multi_source/relaylog_events.result +++ b/mysql-test/suite/multi_source/relaylog_events.result @@ -9,6 +9,7 @@ drop table if exists t1; create table t1 (i int) engine=MyISAM; mysqld-relay-bin-master1.000001 mysqld-relay-bin-master1.000002 +mysqld-relay-bin-master1.index show relaylog events in 'mysqld-relay-bin-master1.000002'; Log_name Pos Event_type Server_id End_log_pos Info mysqld-relay-bin-master1.000002 4 Format_desc 3 246 Server version diff --git a/mysql-test/suite/multi_source/reset_slave.result b/mysql-test/suite/multi_source/reset_slave.result index a1256988bbf..ab59f54315a 100644 --- a/mysql-test/suite/multi_source/reset_slave.result +++ b/mysql-test/suite/multi_source/reset_slave.result @@ -14,7 +14,7 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File 127.0.0.1 root MYPORT_1 60 master-bin.000001 729 mysqld-relay-bin-master1.000002 1015 master-bin.000001 No No 0 0 729 1319 None 0 No NULL No 0 0 1 mysqld-relay-bin-master1.000001 mysqld-relay-bin-master1.000002 -mysqld-relay-bin.index-master1 +mysqld-relay-bin-master1.index reset slave 'master1'; show slave 'master1' status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id diff --git a/mysql-test/suite/multi_source/skip_counter.result b/mysql-test/suite/multi_source/skip_counter.result index 1fb1c255d80..51ad36c4ee8 100644 --- a/mysql-test/suite/multi_source/skip_counter.result +++ b/mysql-test/suite/multi_source/skip_counter.result @@ -55,6 +55,49 @@ set default_master_connection = 'master2'; select @@session.sql_slave_skip_counter; @@session.sql_slave_skip_counter 3 +select @@global.max_relay_log_size; +@@global.max_relay_log_size +1073741824 +set global max_relay_log_size = 1*1024*1024; +select @@global.max_relay_log_size; +@@global.max_relay_log_size +1048576 +select @@session.max_relay_log_size; +@@session.max_relay_log_size +1048576 +set session max_relay_log_size = 3*1024*1024; +select @@global.max_relay_log_size; +@@global.max_relay_log_size +3145728 +select @@session.max_relay_log_size; +@@session.max_relay_log_size +3145728 +set global max_relay_log_size= default; +select @@global.max_relay_log_size; +@@global.max_relay_log_size +1073741824 +select @@session.max_relay_log_size; +@@session.max_relay_log_size +1073741824 +set global max_relay_log_size= 3*1024*1024; +set default_master_connection = 'master1'; +select @@session.max_relay_log_size; +@@session.max_relay_log_size +1073741824 +set default_master_connection = 'qqq'; +select @@session.max_relay_log_size; +@@session.max_relay_log_size +0 +Warnings: +Warning 1617 There is no master connection 'qqq' +set default_master_connection = 'master2'; +select @@session.max_relay_log_size; +@@session.max_relay_log_size +3145728 +set global max_binlog_size= 4*1024*1024; +select @@global.max_relay_log_size; +@@global.max_relay_log_size +3145728 start slave 'master2'; include/wait_for_slave_to_start.inc set default_master_connection = ''; @@ -72,6 +115,8 @@ set default_master_connection = 'master2'; stop slave; include/wait_for_slave_to_stop.inc set global sql_slave_skip_counter = 0; +set global max_relay_log_size = 1073741824; +set global max_binlog_size = 1073741824; disconnect slave; connection master1; drop database db; diff --git a/mysql-test/suite/multi_source/skip_counter.test b/mysql-test/suite/multi_source/skip_counter.test index fe5df69097a..ceb7eb93f0f 100644 --- a/mysql-test/suite/multi_source/skip_counter.test +++ b/mysql-test/suite/multi_source/skip_counter.test @@ -1,5 +1,5 @@ # -# Test of sql_slave_skip_counter +# Test of sql_slave_skip_counter and rpl_max_size # --enable_connect_log @@ -16,7 +16,6 @@ create database db; create table db.t1 (i int) engine=MyISAM; --save_master_pos - # Create the same schema and another table # on the 2nd master @@ -62,6 +61,8 @@ master_user='root'; # to modify the test later --let $skip_counter_saved = `select @@global.sql_slave_skip_counter` +--let $max_relay_log_size_saved= `select @@global.max_relay_log_size` +--let $max_binlog_size_saved= `select @@global.max_binlog_size` set global sql_slave_skip_counter = 2; select @@global.sql_slave_skip_counter; select @@session.sql_slave_skip_counter; @@ -79,6 +80,28 @@ select @@session.sql_slave_skip_counter; set default_master_connection = 'master2'; select @@session.sql_slave_skip_counter; +# Test of setting max_relay_log_size +select @@global.max_relay_log_size; +set global max_relay_log_size = 1*1024*1024; +select @@global.max_relay_log_size; +select @@session.max_relay_log_size; +set session max_relay_log_size = 3*1024*1024; +select @@global.max_relay_log_size; +select @@session.max_relay_log_size; +set global max_relay_log_size= default; +select @@global.max_relay_log_size; +select @@session.max_relay_log_size; +set global max_relay_log_size= 3*1024*1024; +set default_master_connection = 'master1'; +select @@session.max_relay_log_size; +set default_master_connection = 'qqq'; +select @@session.max_relay_log_size; +set default_master_connection = 'master2'; +select @@session.max_relay_log_size; +set global max_binlog_size= 4*1024*1024; +select @@global.max_relay_log_size; + + start slave 'master2'; --source include/wait_for_slave_to_start.inc set default_master_connection = ''; @@ -113,6 +136,8 @@ stop slave; --source include/wait_for_slave_to_stop.inc --eval set global sql_slave_skip_counter = $skip_counter_saved +--eval set global max_relay_log_size = $max_relay_log_size_saved +--eval set global max_binlog_size = $max_binlog_size_saved --enable_connect_log --disconnect slave diff --git a/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result b/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result index 379cea4d3fc..88d68bb50ee 100644 --- a/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result +++ b/mysql-test/suite/rpl/r/rpl_row_max_relay_size.result @@ -10,7 +10,7 @@ reset slave; # # Test 1 # -set @my_max_binlog_size= @@global.max_binlog_size; +set @my_max_binlog_size= @@global.max_binlog_size, @my_max_relay_log_size=@@global.max_relay_log_size; set global max_binlog_size=8192; set global max_relay_log_size=8192-1; Warnings: @@ -36,8 +36,10 @@ include/check_slave_is_running.inc stop slave; reset slave; set global max_relay_log_size=0; +Warnings: +Warning 1292 Truncated incorrect max_relay_log_size value: '0' select @@global.max_relay_log_size; -@@global.max_relay_log_size 0 +@@global.max_relay_log_size 4096 start slave; include/check_slave_is_running.inc # @@ -65,6 +67,7 @@ show master status; File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000002 # set global max_binlog_size= @my_max_binlog_size; +set global max_relay_log_size= @my_max_relay_log_size; # # End of 4.1 tests # diff --git a/mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result b/mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result index 379cea4d3fc..88d68bb50ee 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result +++ b/mysql-test/suite/rpl/r/rpl_stm_max_relay_size.result @@ -10,7 +10,7 @@ reset slave; # # Test 1 # -set @my_max_binlog_size= @@global.max_binlog_size; +set @my_max_binlog_size= @@global.max_binlog_size, @my_max_relay_log_size=@@global.max_relay_log_size; set global max_binlog_size=8192; set global max_relay_log_size=8192-1; Warnings: @@ -36,8 +36,10 @@ include/check_slave_is_running.inc stop slave; reset slave; set global max_relay_log_size=0; +Warnings: +Warning 1292 Truncated incorrect max_relay_log_size value: '0' select @@global.max_relay_log_size; -@@global.max_relay_log_size 0 +@@global.max_relay_log_size 4096 start slave; include/check_slave_is_running.inc # @@ -65,6 +67,7 @@ show master status; File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000002 # set global max_binlog_size= @my_max_binlog_size; +set global max_relay_log_size= @my_max_relay_log_size; # # End of 4.1 tests # diff --git a/mysql-test/suite/sys_vars/r/max_relay_log_size_basic.result b/mysql-test/suite/sys_vars/r/max_relay_log_size_basic.result index d61e9dd20b0..6025e28ccaa 100644 --- a/mysql-test/suite/sys_vars/r/max_relay_log_size_basic.result +++ b/mysql-test/suite/sys_vars/r/max_relay_log_size_basic.result @@ -1,7 +1,7 @@ SET @start_value = @@global.max_relay_log_size; SELECT @start_value; @start_value -0 +1073741824 '#--------------------FN_DYNVARS_082_01------------------------#' SET @@global.max_relay_log_size = 5000; Warnings: @@ -9,7 +9,7 @@ Warning 1292 Truncated incorrect max_relay_log_size value: '5000' SET @@global.max_relay_log_size = DEFAULT; SELECT @@global.max_relay_log_size; @@global.max_relay_log_size -0 +1073741824 '#---------------------FN_DYNVARS_082_02-------------------------#' SET @@global.max_relay_log_size = @start_value; SELECT @@global.max_relay_log_size = 1024; @@ -17,15 +17,17 @@ SELECT @@global.max_relay_log_size = 1024; 0 '#--------------------FN_DYNVARS_082_03------------------------#' SET @@global.max_relay_log_size = 0; +Warnings: +Warning 1292 Truncated incorrect max_relay_log_size value: '0' SELECT @@global.max_relay_log_size; @@global.max_relay_log_size -0 +4096 SET @@global.max_relay_log_size = 1; Warnings: Warning 1292 Truncated incorrect max_relay_log_size value: '1' SELECT @@global.max_relay_log_size; @@global.max_relay_log_size -0 +4096 SET @@global.max_relay_log_size = 1073741824; SELECT @@global.max_relay_log_size; @@global.max_relay_log_size @@ -48,7 +50,7 @@ Warnings: Warning 1292 Truncated incorrect max_relay_log_size value: '-1' SELECT @@global.max_relay_log_size; @@global.max_relay_log_size -0 +4096 SET @@global.max_relay_log_size = 100000000000; Warnings: Warning 1292 Truncated incorrect max_relay_log_size value: '100000000000' @@ -65,7 +67,7 @@ Warnings: Warning 1292 Truncated incorrect max_relay_log_size value: '-1024' SELECT @@global.max_relay_log_size; @@global.max_relay_log_size -0 +4096 SET @@global.max_relay_log_size = 1073741825; Warnings: Warning 1292 Truncated incorrect max_relay_log_size value: '1073741825' @@ -90,9 +92,9 @@ SELECT @@global.max_relay_log_size; 1073741824 '#-------------------FN_DYNVARS_082_05----------------------------#' SET @@session.max_relay_log_size = 4096; -ERROR HY000: Variable 'max_relay_log_size' is a GLOBAL variable and should be set with SET GLOBAL SELECT @@session.max_relay_log_size; -ERROR HY000: Variable 'max_relay_log_size' is a GLOBAL variable +@@session.max_relay_log_size +4096 '#----------------------FN_DYNVARS_082_06------------------------#' SELECT @@global.max_relay_log_size = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES @@ -110,11 +112,13 @@ Warnings: Warning 1292 Truncated incorrect max_relay_log_size value: '1' SELECT @@global.max_relay_log_size; @@global.max_relay_log_size -0 +4096 SET @@global.max_relay_log_size = FALSE; +Warnings: +Warning 1292 Truncated incorrect max_relay_log_size value: '0' SELECT @@global.max_relay_log_size; @@global.max_relay_log_size -0 +4096 '#---------------------FN_DYNVARS_082_08----------------------#' SET @@global.max_relay_log_size = 5000; Warnings: @@ -124,7 +128,8 @@ SELECT @@max_relay_log_size = @@global.max_relay_log_size; 1 '#---------------------FN_DYNVARS_082_09----------------------#' SET max_relay_log_size = 6000; -ERROR HY000: Variable 'max_relay_log_size' is a GLOBAL variable and should be set with SET GLOBAL +Warnings: +Warning 1292 Truncated incorrect max_relay_log_size value: '6000' SELECT @@max_relay_log_size; @@max_relay_log_size 4096 @@ -141,4 +146,4 @@ ERROR 42S22: Unknown column 'max_relay_log_size' in 'field list' SET @@global.max_relay_log_size = @start_value; SELECT @@global.max_relay_log_size; @@global.max_relay_log_size -0 +1073741824 diff --git a/mysql-test/suite/sys_vars/t/max_relay_log_size_basic.test b/mysql-test/suite/sys_vars/t/max_relay_log_size_basic.test index e39778baca8..2e8983f5f01 100644 --- a/mysql-test/suite/sys_vars/t/max_relay_log_size_basic.test +++ b/mysql-test/suite/sys_vars/t/max_relay_log_size_basic.test @@ -105,9 +105,7 @@ SELECT @@global.max_relay_log_size; # Test if accessing session max_relay_log_size gives error # ######################################################################## ---Error ER_GLOBAL_VARIABLE SET @@session.max_relay_log_size = 4096; ---Error ER_INCORRECT_GLOBAL_LOCAL_VAR SELECT @@session.max_relay_log_size; @@ -150,7 +148,6 @@ SELECT @@max_relay_log_size = @@global.max_relay_log_size; # Check if max_relay_log_size can be accessed with and without @@ sign # ############################################################################# ---Error ER_GLOBAL_VARIABLE SET max_relay_log_size = 6000; SELECT @@max_relay_log_size; --Error ER_PARSE_ERROR diff --git a/mysys/mf_fn_ext.c b/mysys/mf_fn_ext.c index 47fc67cabbd..cbf0d5dd9e4 100644 --- a/mysys/mf_fn_ext.c +++ b/mysys/mf_fn_ext.c @@ -52,3 +52,40 @@ char *fn_ext(const char *name) pos=strchr(gpos,FN_EXTCHAR); DBUG_RETURN((char*) (pos ? pos : strend(gpos))); } /* fn_ext */ + + +/* + Return a pointer to the extension of the filename. + + SYNOPSIS + fn_ext() + name Name of file + + DESCRIPTION + The extension is defined as everything after the last extension character + (normally '.') after the directory name. + + RETURN VALUES + Pointer to to the extension character. If there isn't any extension, + points at the end ASCII(0) of the filename. +*/ + +char *fn_ext2(const char *name) +{ + register const char *pos, *gpos; + DBUG_ENTER("fn_ext"); + DBUG_PRINT("mfunkt",("name: '%s'",name)); + +#if defined(FN_DEVCHAR) || defined(BASKSLASH_MBTAIL) + { + char buff[FN_REFLEN]; + size_t res_length; + gpos= name+ dirname_part(buff,(char*) name, &res_length); + } +#else + if (!(gpos= strrchr(name, FN_LIBCHAR))) + gpos= name; +#endif + pos=strrchr(gpos,FN_EXTCHAR); + DBUG_RETURN((char*) (pos ? pos : strend(gpos))); +} /* fn_ext */ diff --git a/sql/log.cc b/sql/log.cc index 1f3c529f491..6b0507943c3 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4703,7 +4703,7 @@ bool MYSQL_BIN_LOG::append(Log_event* ev) DBUG_PRINT("info",("max_size: %lu",max_size)); if (flush_and_sync(0)) goto err; - if ((uint) my_b_append_tell(&log_file) > max_size) + if (my_b_append_tell(&log_file) > max_size) error= new_file_without_locking(); err: mysql_mutex_unlock(&LOCK_log); @@ -4734,7 +4734,7 @@ bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...) DBUG_PRINT("info",("max_size: %lu",max_size)); if (flush_and_sync(0)) goto err; - if ((uint) my_b_append_tell(&log_file) > max_size) + if (my_b_append_tell(&log_file) > max_size) error= new_file_without_locking(); err: if (!error) diff --git a/sql/log.h b/sql/log.h index 0ade3618fd7..0e887b48462 100644 --- a/sql/log.h +++ b/sql/log.h @@ -502,11 +502,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG The max size before rotation (usable only if log_type == LOG_BIN: binary logs and relay logs). For a binlog, max_size should be max_binlog_size. - For a relay log, it should be max_relay_log_size if this is non-zero, - max_binlog_size otherwise. max_size is set in init(), and dynamically changed (when one does SET - GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and - fix_max_relay_log_size). + GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) from sys_vars.cc */ ulong max_size; // current file sequence number for load data infile binary logging diff --git a/sql/log_event.cc b/sql/log_event.cc index 132f778ee08..1d525aa94d8 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -906,9 +906,9 @@ int Log_event::do_update_pos(Relay_log_info *rli) Log_event::enum_skip_reason Log_event::do_shall_skip(Relay_log_info *rli) { - DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu," - " rli->replicate_same_server_id=%d," - " rli->slave_skip_counter=%d", + DBUG_PRINT("info", ("ev->server_id: %lu, ::server_id: %lu," + " rli->replicate_same_server_id: %d," + " rli->slave_skip_counter: %lu", (ulong) server_id, (ulong) ::server_id, rli->replicate_same_server_id, rli->slave_skip_counter)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index defd3a71b93..3a89de32b8a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -52,6 +52,7 @@ #include "des_key_file.h" // load_des_key_file #include "sql_manager.h" // stop_handle_manager, start_handle_manager #include "sql_expression_cache.h" // subquery_cache_miss, subquery_cache_hit +#include "sys_vars_shared.h" #include #include @@ -469,7 +470,7 @@ ulong back_log, connect_timeout, concurrency, server_id; ulong table_cache_size, table_def_size; ulong what_to_log; ulong slow_launch_time, slave_open_temp_tables; -ulong open_files_limit, max_binlog_size, max_relay_log_size; +ulong open_files_limit, max_binlog_size; ulong slave_trans_retries; uint slave_net_timeout; ulong slave_exec_mode_options; @@ -8017,8 +8018,27 @@ static int get_options(int *argc_ptr, char ***argv_ptr) if (!max_long_data_size_used) max_long_data_size= global_system_variables.max_allowed_packet; - /* Rember if max_user_connections was 0 at startup */ + /* Remember if max_user_connections was 0 at startup */ max_user_connections_checking= global_system_variables.max_user_connections != 0; + + { + sys_var *max_relay_log_size_var, *max_binlog_size_var; + /* If max_relay_log_size is 0, then set it to max_binlog_size */ + if (!global_system_variables.max_relay_log_size) + global_system_variables.max_relay_log_size= max_binlog_size; + + /* + Fix so that DEFAULT and limit checking works with max_relay_log_size + (Yes, this is a hack, but it's required as the definition of + max_relay_log_size allows it to be set to 0). + */ + max_relay_log_size_var= intern_find_sys_var("max_relay_log_size", 0); + max_binlog_size_var= intern_find_sys_var("max_binlog_size", 0); + max_relay_log_size_var->option.min_value= + max_binlog_size_var->option.min_value; + max_relay_log_size_var->option.def_value= + max_binlog_size_var->option.def_value; + } return 0; } diff --git a/sql/mysqld.h b/sql/mysqld.h index fd33ca0cf85..4250898cc5b 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -169,7 +169,7 @@ extern ulong max_prepared_stmt_count, prepared_stmt_count; extern ulong open_files_limit; extern ulonglong binlog_cache_size, binlog_stmt_cache_size; extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size; -extern ulong max_binlog_size, max_relay_log_size; +extern ulong max_binlog_size; extern ulong slave_max_allowed_packet; extern ulong opt_binlog_rows_event_max_size; extern ulong rpl_recovery_rank, thread_cache_size; diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 366b271851a..1491d970472 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -622,27 +622,34 @@ bool check_master_connection_name(LEX_STRING *name) res_file_name Store result here length Length of res_file_name buffer info_file Original file name (prefix) - separator Separator character + append 1 if we should add suffix last (not before ext) suffix Suffix @note + The suffix is added before the extension of the file name prefixed with '-'. + The suffix is also converted to lower case and we transform + all not safe character, as we do with MySQL table names. + If suffix is an empty string, then we don't add any suffix. This is to allow one to use this function also to generate old file names without a prefix. */ void create_signed_file_name(char *res_file_name, uint length, - const char *info_file, - char separator, LEX_STRING *suffix) + const char *info_file, bool append, + LEX_STRING *suffix) { char buff[MAX_CONNECTION_NAME+1], res[MAX_CONNECTION_NAME+1], *p; - p= strmake(res_file_name, info_file, length); - if (suffix->length != 0 && p != info_file + length) - { - uint errors; - size_t res_length; - *p++= separator; + p= strmake(res_file_name, info_file, length); + /* If not empty suffix and there is place left for some part of the suffix */ + if (suffix->length != 0 && p <= res_file_name + length -1) + { + const char *info_file_end= info_file + (p - res_file_name); + const char *ext= append ? info_file_end : fn_ext2(info_file); + size_t res_length, ext_pos; + uint errors; + /* Create null terminated string */ strmake(buff, suffix->str, suffix->length); /* Convert to lower case */ @@ -650,7 +657,14 @@ void create_signed_file_name(char *res_file_name, uint length, /* Convert to characters usable in a file name */ res_length= strconvert(system_charset_info, buff, &my_charset_filename, res, sizeof(res), &errors); - strmake(p, res, min(length - (p - res_file_name), res_length)); + + ext_pos= (size_t) (ext - info_file); + length-= (suffix->length - ext_pos); /* Leave place for extension */ + p= res_file_name + ext_pos; + *p++= '-'; /* Add separator */ + p= strmake(p, res, min(length - (p - res_file_name), res_length)); + /* Add back extension. We have checked above that there is space for it */ + strmov(p, ext); } } @@ -748,10 +762,10 @@ bool Master_info_index::init_all_master_info() init_thread_mask(&thread_mask,mi,0 /*not inverse*/); create_signed_file_name(buf_master_info_file, sizeof(buf_master_info_file), - master_info_file, '.', &connection_name); + master_info_file, 0, &connection_name); create_signed_file_name(buf_relay_log_info_file, sizeof(buf_relay_log_info_file), - relay_log_info_file, '.', &connection_name); + relay_log_info_file, 0, &connection_name); if (global_system_variables.log_warnings > 1) sql_print_information("Reading Master_info: '%s' Relay_info:'%s'", buf_master_info_file, buf_relay_log_info_file); diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 6892ecdb9d1..6c7bd3a5d28 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -169,7 +169,7 @@ public: bool check_master_connection_name(LEX_STRING *name); void create_signed_file_name(char *res_file_name, uint length, const char *info_file, - char separator, + bool append, LEX_STRING *suffix); uchar *get_key_master_info(Master_info *mi, size_t *length, diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 49c8390ff9b..362ebab9fa0 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -69,6 +69,7 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery) group_relay_log_name[0]= event_relay_log_name[0]= group_master_log_name[0]= 0; until_log_name[0]= ign_master_log_name_end[0]= 0; + max_relay_log_size= global_system_variables.max_relay_log_size; bzero((char*) &info_file, sizeof(info_file)); bzero((char*) &cache_buf, sizeof(cache_buf)); cached_charset_invalidate(); @@ -149,15 +150,6 @@ int init_relay_log_info(Relay_log_info* rli, event, in flush_master_info(mi, 1, ?). */ - /* - For the maximum log size, we choose max_relay_log_size if it is - non-zero, max_binlog_size otherwise. If later the user does SET - GLOBAL on one of these variables, fix_max_binlog_size and - fix_max_relay_log_size will reconsider the choice (for example - if the user changes max_relay_log_size to zero, we have to - switch to using max_binlog_size for the relay log) and update - rli->relay_log.max_size (and mysql_bin_log.max_size). - */ { /* Reports an error and returns, if the --relay-log's path is a directory.*/ @@ -212,7 +204,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name); char *buf_relaylog_index_name= opt_relaylog_index_name; create_signed_file_name(buf_relay_logname, sizeof(buf_relay_logname), - ln, '-', &mi->connection_name); + ln, 1, &mi->connection_name); ln= buf_relay_logname; if (opt_relaylog_index_name) @@ -220,7 +212,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name); buf_relaylog_index_name= buf_relaylog_index_name_buff; create_signed_file_name(buf_relaylog_index_name_buff, sizeof(buf_relaylog_index_name_buff), - opt_relaylog_index_name, '-', + opt_relaylog_index_name, 0, &mi->connection_name); } @@ -232,8 +224,7 @@ a file name for --relay-log-index option", opt_relaylog_index_name); */ if (rli->relay_log.open_index_file(buf_relaylog_index_name, ln, TRUE) || rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, - (max_relay_log_size ? max_relay_log_size : - max_binlog_size), 1, TRUE)) + mi->rli.max_relay_log_size, 1, TRUE)) { mysql_mutex_unlock(&rli->data_lock); sql_print_error("Failed when trying to open logs for '%s' in init_relay_log_info(). Error: %M", ln, my_errno); diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index eb808351a34..c543b4d3198 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -229,9 +229,10 @@ public: skipping one or more events in the master log that have caused errors, and have been manually applied by DBA already. */ - volatile uint slave_skip_counter; /* Must be uint */ + volatile ulong slave_skip_counter; /* Must be ulong */ volatile ulong abort_pos_wait; /* Incremented on change master */ volatile ulong slave_run_id; /* Incremented on slave start */ + ulong max_relay_log_size; mysql_mutex_t log_space_lock; mysql_cond_t log_space_cond; THD * sql_thd; diff --git a/sql/set_var.h b/sql/set_var.h index 6edfd6adb39..fea947aa1da 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -68,13 +68,14 @@ public: enum binlog_status_enum { VARIABLE_NOT_IN_BINLOG, SESSION_VARIABLE_IN_BINLOG } binlog_status; + my_option option; ///< min, max, default values are stored here + protected: typedef bool (*on_check_function)(sys_var *self, THD *thd, set_var *var); typedef bool (*on_update_function)(sys_var *self, THD *thd, enum_var_type type); int flags; ///< or'ed flag_enum values const SHOW_TYPE show_val_type; ///< what value_ptr() returns for sql_show.cc - my_option option; ///< min, max, default values are stored here PolyLock *guard; ///< *second* lock that protects the variable ptrdiff_t offset; ///< offset to the value from global_system_variables on_check_function on_check; diff --git a/sql/sql_class.h b/sql/sql_class.h index 7f44a4b468a..50c99af29d1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -534,10 +534,11 @@ typedef struct system_variables */ my_thread_id pseudo_thread_id; /** - Place holder to store sql_slave_skip_counter in sys_var.cc during + Place holders to store Multi-source variables in sys_var.cc during update and show of variables. */ - uint slave_skip_counter; + ulong slave_skip_counter; + ulong max_relay_log_size; my_bool low_priority_updates; my_bool query_cache_wlock_invalidate; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ed00fcaaddf..0238a98f5d0 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1308,10 +1308,10 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) create_signed_file_name(master_info_file_tmp, sizeof(master_info_file_tmp), - master_info_file, '.', &mi->connection_name); + master_info_file, 0, &mi->connection_name); create_signed_file_name(relay_log_info_file_tmp, sizeof(relay_log_info_file_tmp), - relay_log_info_file, '.', &mi->connection_name); + relay_log_info_file, 0, &mi->connection_name); if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0)) DBUG_RETURN(1); @@ -1557,10 +1557,10 @@ int reset_slave(THD *thd, Master_info* mi) // and delete these two files create_signed_file_name(master_info_file_tmp, sizeof(master_info_file_tmp), - master_info_file, '.', &mi->connection_name); + master_info_file, 0, &mi->connection_name); create_signed_file_name(relay_log_info_file_tmp, sizeof(relay_log_info_file_tmp), - relay_log_info_file, '.', &mi->connection_name); + relay_log_info_file, 0, &mi->connection_name); fn_format(fname, master_info_file_tmp, mysql_data_home, "", 4+32); if (mysql_file_stat(key_file_master_info, fname, &stat_area, MYF(0)) && @@ -1697,10 +1697,10 @@ bool change_master(THD* thd, Master_info* mi) create_signed_file_name(master_info_file_tmp, sizeof(master_info_file_tmp), - master_info_file, '.', &mi->connection_name); + master_info_file, 0, &mi->connection_name); create_signed_file_name(relay_log_info_file_tmp, sizeof(relay_log_info_file_tmp), - relay_log_info_file, '.', &mi->connection_name); + relay_log_info_file, 0, &mi->connection_name); /* if new Master_info doesn't exists, add it */ if (!master_info_index->get_master_info(&mi->connection_name, diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 30cfe1a5680..9421dca5c05 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1105,16 +1105,12 @@ static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size( static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type) { mysql_bin_log.set_max_size(max_binlog_size); -#ifdef HAVE_REPLICATION - if (!max_relay_log_size) - active_mi->rli.relay_log.set_max_size(max_binlog_size); -#endif return false; } static Sys_var_ulong Sys_max_binlog_size( "max_binlog_size", "Binary log will be rotated automatically when the size exceeds this " - "value. Will also apply to relay logs if max_relay_log_size is 0", + "value.", GLOBAL_VAR(max_binlog_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(IO_SIZE, 1024*1024L*1024L), DEFAULT(1024*1024L*1024L), BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), @@ -1259,24 +1255,6 @@ static Sys_var_ulong Sys_max_prepared_stmt_count( VALID_RANGE(0, 1024*1024), DEFAULT(16382), BLOCK_SIZE(1), &PLock_prepared_stmt_count); -static bool fix_max_relay_log_size(sys_var *self, THD *thd, enum_var_type type) -{ -#ifdef HAVE_REPLICATION - active_mi->rli.relay_log.set_max_size(max_relay_log_size ? - max_relay_log_size: max_binlog_size); -#endif - return false; -} -static Sys_var_ulong Sys_max_relay_log_size( - "max_relay_log_size", - "If non-zero: relay log will be rotated automatically when the " - "size exceeds this value; if zero: when the size " - "exceeds max_binlog_size", - GLOBAL_VAR(max_relay_log_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, 1024L*1024*1024), DEFAULT(0), BLOCK_SIZE(IO_SIZE), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(fix_max_relay_log_size)); - static Sys_var_ulong Sys_max_sort_length( "max_sort_length", "The number of bytes to use when sorting BLOB or TEXT values (only " @@ -3459,7 +3437,7 @@ static bool fix_slave_net_timeout(sys_var *self, THD *thd, enum_var_type type) mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_lock(&LOCK_active_mi); - DBUG_PRINT("info", ("slave_net_timeout=%u mi->heartbeat_period=%.3f", + DBUG_PRINT("info", ("slave_net_timeout: %u mi->heartbeat_period: %.3f", slave_net_timeout, (active_mi? active_mi->heartbeat_period : 0.0))); if (active_mi && slave_net_timeout < active_mi->heartbeat_period) @@ -3484,7 +3462,7 @@ static Sys_var_uint Sys_slave_net_timeout( Return 0 + warning if it doesn't exist */ -uint Sys_var_multi_source_uint:: +uint Sys_var_multi_source_ulong:: get_master_info_uint_value(THD *thd, ptrdiff_t offset) { Master_info *mi; @@ -3504,11 +3482,13 @@ get_master_info_uint_value(THD *thd, ptrdiff_t offset) } -static bool update_slave_skip_counter(sys_var *self, THD *thd, - enum_var_type type) +bool update_multi_source_variable(sys_var *self_var, THD *thd, + enum_var_type type) { + Sys_var_multi_source_ulong *self= (Sys_var_multi_source_ulong*) self_var; bool result= true; Master_info *mi; + mysql_mutex_lock(&LOCK_active_mi); mi= master_info_index-> get_master_info(&thd->variables.default_master_connection, @@ -3516,30 +3496,57 @@ static bool update_slave_skip_counter(sys_var *self, THD *thd, if (mi) { mysql_mutex_lock(&mi->rli.run_lock); - if (mi->rli.slave_running) - my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); - else - { - result= false; // ok - mysql_mutex_lock(&mi->rli.data_lock); - /* The value was stored temporarly in thd */ - mi->rli.slave_skip_counter= thd->variables.slave_skip_counter; - mysql_mutex_unlock(&mi->rli.data_lock); - } + mysql_mutex_lock(&mi->rli.data_lock); + result= self->update_variable(thd, mi); + mysql_mutex_unlock(&mi->rli.data_lock); mysql_mutex_unlock(&mi->rli.run_lock); } mysql_mutex_unlock(&LOCK_active_mi); return result; } -static Sys_var_multi_source_uint +static bool update_slave_skip_counter(sys_var *self, THD *thd, Master_info *mi) +{ + if (mi->rli.slave_running) + { + my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); + return true; + } + /* The value was stored temporarly in thd */ + mi->rli.slave_skip_counter= thd->variables.slave_skip_counter; + return false; +} + + +static Sys_var_multi_source_ulong Sys_slave_skip_counter("sql_slave_skip_counter", "Skip the next N events from the master log", SESSION_VAR(slave_skip_counter), + NO_CMD_LINE, offsetof(Master_info, rli.slave_skip_counter), VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1), ON_UPDATE(update_slave_skip_counter)); + +static bool update_max_relay_log_size(sys_var *self, THD *thd, Master_info *mi) +{ + mi->rli.max_relay_log_size= thd->variables.max_relay_log_size; + mi->rli.relay_log.set_max_size(mi->rli.max_relay_log_size); + return false; +} + +static Sys_var_multi_source_ulong +Sys_max_relay_log_size( "max_relay_log_size", + "relay log will be rotated automatically when the " + "size exceeds this value. If 0 are startup, it's " + "set to max_binlog_size", + SESSION_VAR(max_relay_log_size), + CMD_LINE(REQUIRED_ARG), + offsetof(Master_info, rli.max_relay_log_size), + VALID_RANGE(0, 1024L*1024*1024), DEFAULT(0), + BLOCK_SIZE(IO_SIZE), + ON_UPDATE(update_max_relay_log_size)); + static Sys_var_charptr Sys_slave_skip_errors( "slave_skip_errors", "Tells the slave thread to continue " "replication when a query event returns an error from the " diff --git a/sql/sys_vars.h b/sql/sys_vars.h index 6509ba6a5f4..8e832e57630 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -1954,24 +1954,34 @@ public: like sql_slave_skip_counter are GLOBAL. */ -class Sys_var_multi_source_uint :public Sys_var_uint +class Sys_var_multi_source_ulong; +class Master_info; + +typedef bool (*on_multi_source_update_function)(sys_var *self, THD *thd, + Master_info *mi); +bool update_multi_source_variable(sys_var *self, + THD *thd, enum_var_type type); + + +class Sys_var_multi_source_ulong :public Sys_var_ulong { ptrdiff_t master_info_offset; + on_multi_source_update_function update_multi_source_variable_func; public: - Sys_var_multi_source_uint(const char *name_arg, - const char *comment, int flag_args, - ptrdiff_t off, size_t size, - ptrdiff_t master_info_offset_arg, - uint min_val, uint max_val, uint def_val, - uint block_size, - on_update_function on_update_func) - :Sys_var_uint(name_arg, comment, flag_args, off, size, - NO_CMD_LINE, min_val, max_val, def_val, block_size, - 0, VARIABLE_NOT_IN_BINLOG, 0, on_update_func), - master_info_offset(master_info_offset_arg) + Sys_var_multi_source_ulong(const char *name_arg, + const char *comment, int flag_args, + ptrdiff_t off, size_t size, + CMD_LINE getopt, + ptrdiff_t master_info_offset_arg, + uint min_val, uint max_val, uint def_val, + uint block_size, + on_multi_source_update_function on_update_func) + :Sys_var_ulong(name_arg, comment, flag_args, off, size, + getopt, min_val, max_val, def_val, block_size, + 0, VARIABLE_NOT_IN_BINLOG, 0, update_multi_source_variable), + master_info_offset(master_info_offset_arg), + update_multi_source_variable_func(on_update_func) { - /* No global storage of variables. Cause a crash if we try an update */ - option.value= (uchar**)1; } bool session_update(THD *thd, set_var *var) { @@ -2001,6 +2011,10 @@ public: return session_value_ptr(thd, base); } uint get_master_info_uint_value(THD *thd, ptrdiff_t offset); + bool update_variable(THD *thd, Master_info *mi) + { + return update_multi_source_variable_func(this, thd, mi); + } }; From 572560f38c248d5020f0e63aeb3f8905cd568208 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 3 Oct 2012 01:44:54 +0300 Subject: [PATCH 6/6] Changed SHOW_FUNC variabels that don't return SHOW_ARRAY to SHOW_SIMPLE_FUNC. This allows us to avoid calculating variables (including those involving mutex) that doesn't match the given wildcard in SHOW STATUS LIKE '...' Removed all references to active_mi that could cause problems for multi-source replication. Added START|STOP ALL SLAVES Added SHOW ALL SLAVES STATUS include/mysql/plugin.h: Added SHOW_SIMPLE_FUNC include/mysql/plugin_audit.h.pp: Updated .pp file include/mysql/plugin_auth.h.pp: Updated .pp file include/mysql/plugin_ftparser.h.pp: Updated .pp file mysql-test/suite/multi_source/info_logs.result: New columns in SHOW ALL SLAVES STATUS mysql-test/suite/multi_source/info_logs.test: Test new syntax mysql-test/suite/multi_source/simple.result: New columns in SHOW ALL SLAVES STATUS mysql-test/suite/multi_source/simple.test: test new syntax mysql-test/suite/multi_source/syntax.result: Updated result mysql-test/suite/multi_source/syntax.test: Test new syntax mysql-test/suite/rpl/r/rpl_skip_replication.result: Updated result plugin/semisync/semisync_master_plugin.cc: SHOW_FUNC -> SHOW_SIMPLE_FUNC sql/item_create.cc: Simplify code sql/lex.h: Added SLAVES keyword sql/log.cc: Constant -> define sql/log_event.cc: Added comment sql/mysqld.cc: SHOW_FUNC -> SHOW_SIMPLE_FUNC Made slave_retried_trans, slave_received_heartbeats and heartbeat_period multi-source safe Clear variable denied_connections and slave_retried_transactions on startup sql/mysqld.h: Added slave_retried_transactions sql/rpl_mi.cc: create_signed_file_name -> create_logfile_name_with_suffix Added start_all_slaves() and stop_all_slaves() sql/rpl_mi.h: Added prototypes sql/rpl_rli.cc: create_signed_file_name -> create_logfile_name_with_suffix added executed_entries sql/rpl_rli.h: Added executed_entries sql/share/errmsg-utf8.txt: More and better error messages sql/slave.cc: Added more fields to SHOW ALL SLAVES STATUS Added slave_retried_transactions Changed constants -> defines sql/sql_class.h: Added comment sql/sql_insert.cc: active_mi.rli -> thd->rli_slave sql/sql_lex.h: Added SQLCOM_SLAVE_ALL_START & SQLCOM_SLAVE_ALL_STOP sql/sql_load.cc: active_mi.rli -> thd->rli_slave sql/sql_parse.cc: Added START|STOP ALL SLAVES sql/sql_prepare.cc: Added SQLCOM_SLAVE_ALL_START & SQLCOM_SLAVE_ALL_STOP sql/sql_reload.cc: Made REFRESH RELAY LOG multi-source safe sql/sql_repl.cc: create_signed_file_name -> create_logfile_name_with_suffix Don't send my_ok() from start_slave() or stop_slave() so that we can call it for all master connections sql/sql_show.cc: Compare wild cards early for all variables sql/sql_yacc.yy: Added START|STOP ALL SLAVES Added SHOW ALL SLAVES STATUS sql/sys_vars.cc: Made replicate_events_marked_for_skip,slave_net_timeout and rpl_filter multi-source safe. sql/sys_vars.h: Simplify Sys_var_rpl_filter --- include/mysql/plugin.h | 2 +- include/mysql/plugin_audit.h.pp | 2 +- include/mysql/plugin_auth.h.pp | 2 +- include/mysql/plugin_ftparser.h.pp | 2 +- .../suite/multi_source/info_logs.result | 16 +- mysql-test/suite/multi_source/info_logs.test | 4 +- mysql-test/suite/multi_source/simple.result | 38 +++-- mysql-test/suite/multi_source/simple.test | 19 ++- mysql-test/suite/multi_source/syntax.result | 8 +- mysql-test/suite/multi_source/syntax.test | 2 +- .../suite/rpl/r/rpl_deadlock_innodb.result | 2 + .../suite/rpl/r/rpl_filter_dbs_dynamic.result | 4 +- .../rpl/r/rpl_filter_tables_dynamic.result | 4 +- .../r/rpl_filter_wild_tables_dynamic.result | 4 +- mysql-test/suite/rpl/r/rpl_flush_logs.result | 10 +- mysql-test/suite/rpl/r/rpl_heartbeat.result | 2 - .../suite/rpl/r/rpl_heartbeat_basic.result | 2 - .../suite/rpl/r/rpl_skip_replication.result | 2 +- .../rpl_start_slave_deadlock_sys_vars.result | 31 ---- mysql-test/suite/rpl/t/rpl_flush_logs.test | 24 +-- .../t/rpl_start_slave_deadlock_sys_vars.test | 57 ------- plugin/semisync/semisync_master_plugin.cc | 18 +-- sql/item_create.cc | 4 +- sql/lex.h | 1 + sql/log.cc | 2 +- sql/log_event.cc | 3 + sql/mysqld.cc | 146 ++++++++---------- sql/mysqld.h | 1 + sql/rpl_mi.cc | 144 +++++++++++++++-- sql/rpl_mi.h | 7 +- sql/rpl_rli.cc | 6 +- sql/rpl_rli.h | 4 +- sql/share/errmsg-utf8.txt | 30 ++-- sql/slave.cc | 59 +++++-- sql/sql_class.h | 6 +- sql/sql_insert.cc | 8 +- sql/sql_lex.h | 3 +- sql/sql_load.cc | 6 +- sql/sql_parse.cc | 30 +++- sql/sql_prepare.cc | 2 + sql/sql_reload.cc | 18 ++- sql/sql_repl.cc | 48 +++--- sql/sql_show.cc | 26 +++- sql/sql_yacc.yy | 20 ++- sql/sys_vars.cc | 138 +++-------------- sql/sys_vars.h | 13 +- storage/example/ha_example.cc | 5 +- storage/sphinx/ha_sphinx.cc | 12 +- storage/xtradb/handler/ha_innodb.cc | 4 +- 49 files changed, 532 insertions(+), 469 deletions(-) delete mode 100644 mysql-test/suite/rpl/r/rpl_start_slave_deadlock_sys_vars.result delete mode 100644 mysql-test/suite/rpl/t/rpl_start_slave_deadlock_sys_vars.test diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index b73f2d75193..b8e90f764bd 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -167,7 +167,7 @@ enum enum_mysql_show_type SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG, SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, - SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, + SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC, SHOW_always_last }; diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index b987f690592..dea2446ac9c 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -94,7 +94,7 @@ enum enum_mysql_show_type SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG, SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, - SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, + SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC, SHOW_always_last }; struct st_mysql_show_var { diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 113aaf62d19..f1213a73bc6 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -94,7 +94,7 @@ enum enum_mysql_show_type SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG, SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, - SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, + SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC, SHOW_always_last }; struct st_mysql_show_var { diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 6011e7f7519..74b298098dd 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -94,7 +94,7 @@ enum enum_mysql_show_type SHOW_UNDEF, SHOW_BOOL, SHOW_UINT, SHOW_ULONG, SHOW_ULONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE, - SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, + SHOW_SINT, SHOW_SLONG, SHOW_SLONGLONG, SHOW_SIMPLE_FUNC, SHOW_always_last }; struct st_mysql_show_var { diff --git a/mysql-test/suite/multi_source/info_logs.result b/mysql-test/suite/multi_source/info_logs.result index 1da44992ec6..2d4c52b936d 100644 --- a/mysql-test/suite/multi_source/info_logs.result +++ b/mysql-test/suite/multi_source/info_logs.result @@ -83,14 +83,14 @@ relay.bin.info MASTER 2.2 # EOF # -show full slave status; -Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id - Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 relay.000002 572 master-bin.000001 Yes Yes 0 0 286 857 None 0 No 0 No 0 0 1 -MASTER 2.2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 relay-master@00202@002e2.000002 572 master-bin.000001 Yes Yes 0 0 286 876 None 0 No 0 No 0 0 2 -show full slave status; -Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id - Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 relay.000004 532 master-bin.000001 Yes Yes 0 0 286 817 None 0 No 0 No 0 0 1 -MASTER 2.2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 relay-master@00202@002e2.000004 532 master-bin.000001 Yes Yes 0 0 286 836 None 0 No 0 No 0 0 2 +show all slaves status; +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Retried_transactions Max_relay_log_size Executed_log_entries + Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 relay.000002 572 master-bin.000001 Yes Yes 0 0 286 857 None 0 No 0 No 0 0 1 0 1073741824 6 +MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 relay-master@00202@002e2.000002 572 master-bin.000001 Yes Yes 0 0 286 876 None 0 No 0 No 0 0 2 0 1073741824 6 +show all slaves status; +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Retried_transactions Max_relay_log_size Executed_log_entries + Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 relay.000004 532 master-bin.000001 Yes Yes 0 0 286 817 None 0 No 0 No 0 0 1 0 1073741824 6 +MASTER 2.2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 relay-master@00202@002e2.000004 532 master-bin.000001 Yes Yes 0 0 286 836 None 0 No 0 No 0 0 2 0 1073741824 6 # # List of files matching '*info*' pattern # after slave server restart diff --git a/mysql-test/suite/multi_source/info_logs.test b/mysql-test/suite/multi_source/info_logs.test index f06880faca6..6314a94434c 100644 --- a/mysql-test/suite/multi_source/info_logs.test +++ b/mysql-test/suite/multi_source/info_logs.test @@ -117,7 +117,7 @@ start slave; --sleep 5 --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 -show full slave status; +show all slaves status; # Restart the slave server @@ -129,7 +129,7 @@ EOF --source include/wait_until_connected_again.inc --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 -show full slave status; +show all slaves status; # Check the files diff --git a/mysql-test/suite/multi_source/simple.result b/mysql-test/suite/multi_source/simple.result index 003622a1b46..302db59c4e4 100644 --- a/mysql-test/suite/multi_source/simple.result +++ b/mysql-test/suite/multi_source/simple.result @@ -4,13 +4,16 @@ start slave 'slave1'; set default_master_connection = 'slave1'; include/wait_for_slave_to_start.inc set default_master_connection = 'slave2'; -start slave 'slave2'; +start all slaves; +Warnings: +Note 1936 SLAVE 'slave2' started include/wait_for_slave_to_start.inc set default_master_connection = ''; -show full slave status; -Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id -slave1 Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 mysqld-relay-bin-slave1.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 1 -slave2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 +show all slaves status; +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Retried_transactions Max_relay_log_size Executed_log_entries +slave1 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_1 60 master-bin.000001 286 mysqld-relay-bin-slave1.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 1 0 1073741824 6 +slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 0 1073741824 6 +start all slaves; stop slave 'slave1'; show slave 'slave1' status; Slave_IO_State @@ -54,16 +57,19 @@ Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id 1 reset slave 'slave1'; -show full slave status; -Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id -slave1 127.0.0.1 root MYPORT_1 60 4 572 No No 0 0 0 875 None 0 No NULL No 0 0 1 -slave2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 +show all slaves status; +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Retried_transactions Max_relay_log_size Executed_log_entries +slave1 127.0.0.1 root MYPORT_1 60 4 572 No No 0 0 0 875 None 0 No NULL No 0 0 1 0 1073741824 6 +slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 0 1073741824 6 reset slave 'slave1' all; -show full slave status; -Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id -slave2 Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 -stop slave 'slave2'; -show full slave status; -Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id -slave2 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 No No 0 0 286 875 None 0 No NULL No 0 0 2 +show all slaves status; +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Retried_transactions Max_relay_log_size Executed_log_entries +slave2 Slave has read all relay log; waiting for the slave I/O thread to update it Waiting for master to send event 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 Yes Yes 0 0 286 875 None 0 No 0 No 0 0 2 0 1073741824 6 +stop all slaves; +Warnings: +Note 1937 SLAVE 'slave2' stopped +show all slaves status; +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Retried_transactions Max_relay_log_size Executed_log_entries +slave2 127.0.0.1 root MYPORT_2 60 master-bin.000001 286 mysqld-relay-bin-slave2.000002 572 master-bin.000001 No No 0 0 286 875 None 0 No NULL No 0 0 2 0 1073741824 6 +stop all slaves; reset slave 'slave2' all; diff --git a/mysql-test/suite/multi_source/simple.test b/mysql-test/suite/multi_source/simple.test index 2b4f06aa1fe..4b13623785a 100644 --- a/mysql-test/suite/multi_source/simple.test +++ b/mysql-test/suite/multi_source/simple.test @@ -15,7 +15,8 @@ start slave 'slave1'; set default_master_connection = 'slave1'; --source include/wait_for_slave_to_start.inc set default_master_connection = 'slave2'; -start slave 'slave2'; +start all slaves; + --source include/wait_for_slave_to_start.inc set default_master_connection = ''; @@ -30,7 +31,10 @@ set default_master_connection = ''; --sync_with_master 0,'slave2' --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 -show full slave status; +show all slaves status; + +# Ensure that start all slaves doesn't do anything as all slaves are started +start all slaves; stop slave 'slave1'; @@ -39,15 +43,18 @@ query_vertical show slave 'slave1' status; reset slave 'slave1'; --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 -show full slave status; +show all slaves status; reset slave 'slave1' all; --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 -show full slave status; +show all slaves status; -stop slave 'slave2'; +stop all slaves; --replace_result $SERVER_MYPORT_1 MYPORT_1 $SERVER_MYPORT_2 MYPORT_2 -show full slave status; +show all slaves status; + +# Ensure that start all slaves doesn't do anything as all slaves are stopped +stop all slaves; # # clean up diff --git a/mysql-test/suite/multi_source/syntax.result b/mysql-test/suite/multi_source/syntax.result index 23ea4d9fd3d..28003c99040 100644 --- a/mysql-test/suite/multi_source/syntax.result +++ b/mysql-test/suite/multi_source/syntax.result @@ -4,8 +4,8 @@ show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id show slave '' status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id -show full slave status; -Connection_name Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id +show all slaves status; +Connection_name Slave_SQL_State Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error Replicate_Ignore_Server_Ids Master_Server_Id Retried_transactions Max_relay_log_size Executed_log_entries # # Check error handling # @@ -82,8 +82,6 @@ Slave_running ON set @@default_master_connection='qqq'; show status like "Slave_running"; Variable_name Value -Slave_running OFF -Warnings: -Warning 1617 There is no master connection 'qqq' +Slave_running set @@default_master_connection=''; include/rpl_end.inc diff --git a/mysql-test/suite/multi_source/syntax.test b/mysql-test/suite/multi_source/syntax.test index af793fe6100..15e862ab607 100644 --- a/mysql-test/suite/multi_source/syntax.test +++ b/mysql-test/suite/multi_source/syntax.test @@ -5,7 +5,7 @@ source include/master-slave.inc; show slave status; show slave '' status; -show full slave status; +show all slaves status; --echo # --echo # Check error handling diff --git a/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result b/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result index 37d209bbcf6..f2128f8d855 100644 --- a/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_deadlock_innodb.result @@ -76,6 +76,8 @@ include/check_slave_is_running.inc *** Test lock wait timeout and purged relay logs *** SET @my_max_relay_log_size= @@global.max_relay_log_size; SET global max_relay_log_size=0; +Warnings: +Warning 1292 Truncated incorrect max_relay_log_size value: '0' include/stop_slave.inc DELETE FROM t2; CHANGE MASTER TO MASTER_LOG_POS=; diff --git a/mysql-test/suite/rpl/r/rpl_filter_dbs_dynamic.result b/mysql-test/suite/rpl/r/rpl_filter_dbs_dynamic.result index 321b8d912e6..eaa2ed9a61d 100644 --- a/mysql-test/suite/rpl/r/rpl_filter_dbs_dynamic.result +++ b/mysql-test/suite/rpl/r/rpl_filter_dbs_dynamic.result @@ -1,9 +1,9 @@ include/master-slave.inc [connection master] SET @@GLOBAL.replicate_do_db="db1"; -ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first SET @@GLOBAL.replicate_ignore_db="db2"; -ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first include/stop_slave.inc SET @@GLOBAL.replicate_do_db="db1"; SET @@GLOBAL.replicate_ignore_db="db2"; diff --git a/mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result b/mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result index 9eb803d17ea..3d03d36828a 100644 --- a/mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result +++ b/mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result @@ -1,9 +1,9 @@ include/master-slave.inc [connection master] SET @@GLOBAL.replicate_do_table="test.t1,test.t2,test.t3"; -ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6"; -ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first include/stop_slave.inc SET @@GLOBAL.replicate_do_table="test.t1,test.t2,test.t3"; SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6"; diff --git a/mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result b/mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result index 6858181234e..19d8e513e6f 100644 --- a/mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result +++ b/mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result @@ -1,9 +1,9 @@ include/master-slave.inc [connection master] SET @@GLOBAL.replicate_wild_do_table="test.a%"; -ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first SET @@GLOBAL.replicate_wild_ignore_table="test.b%"; -ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first include/stop_slave.inc SET @@GLOBAL.replicate_wild_do_table="test.a%"; SET @@GLOBAL.replicate_wild_ignore_table="test.b%"; diff --git a/mysql-test/suite/rpl/r/rpl_flush_logs.result b/mysql-test/suite/rpl/r/rpl_flush_logs.result index 4fce91a7234..1f543cd9f43 100644 --- a/mysql-test/suite/rpl/r/rpl_flush_logs.result +++ b/mysql-test/suite/rpl/r/rpl_flush_logs.result @@ -8,7 +8,7 @@ flush error logs; # after execute 'flush error logs' statement. # Test if support 'flush relay logs' statement. flush relay logs; -# Check the 'slave-relay-bin.000003' file is created +# Check the 'slave-relay-bin.000003' file is not created # after executed 'flush relay logs' statement. # Make sure binary logs was not be flushed # after execute 'flush relay logs' statement. @@ -30,21 +30,21 @@ flush engine logs; flush binary logs; # Check the 'master-bin.000002' file is created # after executed 'flush binary logs' statement. -# Make sure the 'slave-relay-bin.000006' file does not exist +# Make sure the 'slave-relay-bin.000005' file does not exist # exist before execute 'flush error logs, relay logs' statement. # Test if support to combine all kinds of logs into one statement. flush error logs, relay logs; # Make sure binary logs was not be flushed # after execute 'flush error logs, relay logs' statement. -# Check the 'slave-relay-bin.000006' file is created after +# Check the 'slave-relay-bin.000004' file is created after # execute 'flush error logs, relay logs' statement. -# Make sure the 'slave-relay-bin.000007' and 'slave-relay-bin.000008' +# Make sure the 'slave-relay-bin.000005' and 'slave-relay-bin.000006' # files do not exist before execute 'flush error logs, relay logs' # statement. # Test if 'flush logs' statement works fine and flush all the logs. flush logs; # Check 'master-bin.000003' is created # after execute 'flush logs' statement. -# Check the 'slave-relay-bin.000007' and 'slave-relay-bin.000008' +# Check the 'slave-relay-bin.000005' and 'slave-relay-bin.000006' # files are created after execute 'flush logs' statement. include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat.result b/mysql-test/suite/rpl/r/rpl_heartbeat.result index d4bdb77ef0b..b0f36558d10 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat.result @@ -41,8 +41,6 @@ show status like 'Slave_heartbeat_period';; Variable_name Slave_heartbeat_period Value 4.000 set @@global.slave_net_timeout= 3 /* must be a warning */; -Warnings: -Warning 1704 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. reset slave; drop table if exists t1; set @@global.slave_net_timeout= 10; diff --git a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result index cc9d1f99f7c..0c274165e1e 100644 --- a/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result +++ b/mysql-test/suite/rpl/r/rpl_heartbeat_basic.result @@ -33,8 +33,6 @@ RESET SLAVE; *** Warning if updated slave_net_timeout < slave_heartbeat_timeout *** SET @@global.slave_net_timeout=FLOOR(SLAVE_HEARTBEAT_TIMEOUT)-1; -Warnings: -Warning 1704 The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout. SET @@global.slave_net_timeout=@restore_slave_net_timeout; RESET SLAVE; diff --git a/mysql-test/suite/rpl/r/rpl_skip_replication.result b/mysql-test/suite/rpl/r/rpl_skip_replication.result index c19f9009021..92b5fa5f629 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_replication.result +++ b/mysql-test/suite/rpl/r/rpl_skip_replication.result @@ -10,7 +10,7 @@ SELECT @@global.replicate_events_marked_for_skip; @@global.replicate_events_marked_for_skip replicate SET GLOBAL replicate_events_marked_for_skip=FILTER_ON_SLAVE; -ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first +ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first SELECT @@global.replicate_events_marked_for_skip; @@global.replicate_events_marked_for_skip replicate diff --git a/mysql-test/suite/rpl/r/rpl_start_slave_deadlock_sys_vars.result b/mysql-test/suite/rpl/r/rpl_start_slave_deadlock_sys_vars.result deleted file mode 100644 index f69a323f980..00000000000 --- a/mysql-test/suite/rpl/r/rpl_start_slave_deadlock_sys_vars.result +++ /dev/null @@ -1,31 +0,0 @@ -include/master-slave.inc -[connection master] -# connection: slave -SET @save_slave_net_timeout = @@GLOBAL.slave_net_timeout; -STOP SLAVE; -include/wait_for_slave_to_stop.inc -# open an extra connection to the slave -# connection: slave2 -# set debug synchronization point -SET DEBUG_SYNC='fix_slave_net_timeout SIGNAL parked WAIT_FOR go'; -# attempt to set slave_net_timeout, will wait on sync point -SET @@GLOBAL.slave_net_timeout = 100; -# connection: slave -SET DEBUG_SYNC='now WAIT_FOR parked'; -# connection: slave1 -# attempt to start the SQL thread -START SLAVE SQL_THREAD; -# connection: slave -# wait until SQL thread has been started -# sleep a bit so that the SQL thread THD handle is initialized -# signal the set slave_net_timeout to continue -SET DEBUG_SYNC='now SIGNAL go'; -# connection: slave2 -# reap result of set slave_net_timeout -# connection: slave1 -# reap result of starting the SQL thread -# disconnect: slave2 -# connection: slave -# cleanup -SET @@GLOBAL.slave_net_timeout = @save_slave_net_timeout; -include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_flush_logs.test b/mysql-test/suite/rpl/t/rpl_flush_logs.test index 6e9de634157..1d19576d47c 100644 --- a/mysql-test/suite/rpl/t/rpl_flush_logs.test +++ b/mysql-test/suite/rpl/t/rpl_flush_logs.test @@ -31,8 +31,9 @@ connection master; flush relay logs; sync_slave_with_master; ---echo # Check the 'slave-relay-bin.000003' file is created +--echo # Check the 'slave-relay-bin.000003' file is not created --echo # after executed 'flush relay logs' statement. +--error 1 file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000003; connection master; @@ -89,10 +90,10 @@ file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000001; # Test 'flush error logs, relay logs' statement sync_slave_with_master; ---echo # Make sure the 'slave-relay-bin.000006' file does not exist +--echo # Make sure the 'slave-relay-bin.000005' file does not exist --echo # exist before execute 'flush error logs, relay logs' statement. --error 1 -file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000006; +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000005; connection master; @@ -107,19 +108,18 @@ file_exists $MYSQLTEST_VARDIR/tmp/master_log.err; file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000003; sync_slave_with_master; ---echo # Check the 'slave-relay-bin.000006' file is created after +--echo # Check the 'slave-relay-bin.000004' file is created after --echo # execute 'flush error logs, relay logs' statement. -file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000006; - +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000004; # Test 'flush logs' statement ---echo # Make sure the 'slave-relay-bin.000007' and 'slave-relay-bin.000008' +--echo # Make sure the 'slave-relay-bin.000005' and 'slave-relay-bin.000006' --echo # files do not exist before execute 'flush error logs, relay logs' --echo # statement. --error 1 -file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000007; +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000005; --error 1 -file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000008; +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000006; connection master; @@ -133,9 +133,9 @@ file_exists $MYSQLTEST_VARDIR/tmp/master_log.err; file_exists $MYSQLTEST_VARDIR/mysqld.1/data/master-bin.000003; sync_slave_with_master; ---echo # Check the 'slave-relay-bin.000007' and 'slave-relay-bin.000008' +--echo # Check the 'slave-relay-bin.000005' and 'slave-relay-bin.000006' --echo # files are created after execute 'flush logs' statement. -file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000007; -file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000008; +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000005; +file_exists $MYSQLTEST_VARDIR/mysqld.2/data/slave-relay-bin.000006; --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_start_slave_deadlock_sys_vars.test b/mysql-test/suite/rpl/t/rpl_start_slave_deadlock_sys_vars.test deleted file mode 100644 index 3eaff761108..00000000000 --- a/mysql-test/suite/rpl/t/rpl_start_slave_deadlock_sys_vars.test +++ /dev/null @@ -1,57 +0,0 @@ -source include/have_debug_sync.inc; -source include/master-slave.inc; - ---echo # connection: slave -connection slave; -SET @save_slave_net_timeout = @@GLOBAL.slave_net_timeout; -STOP SLAVE; -source include/wait_for_slave_to_stop.inc; - ---echo # open an extra connection to the slave -connect(slave2,127.0.0.1,root,,test,$SLAVE_MYPORT,); ---echo # connection: slave2 ---echo # set debug synchronization point -SET DEBUG_SYNC='fix_slave_net_timeout SIGNAL parked WAIT_FOR go'; ---echo # attempt to set slave_net_timeout, will wait on sync point ---send SET @@GLOBAL.slave_net_timeout = 100 - ---echo # connection: slave -connection slave; -SET DEBUG_SYNC='now WAIT_FOR parked'; - ---echo # connection: slave1 -connection slave1; ---echo # attempt to start the SQL thread ---send START SLAVE SQL_THREAD - ---echo # connection: slave -connection slave; ---echo # wait until SQL thread has been started -let $wait_condition= - select count(*) = 1 from information_schema.processlist - where state = "Waiting for slave thread to start" and info = "START SLAVE SQL_THREAD"; ---source include/wait_condition.inc ---echo # sleep a bit so that the SQL thread THD handle is initialized -sleep 2; ---echo # signal the set slave_net_timeout to continue -SET DEBUG_SYNC='now SIGNAL go'; - ---echo # connection: slave2 -connection slave2; ---echo # reap result of set slave_net_timeout ---reap - ---echo # connection: slave1 -connection slave1; ---echo # reap result of starting the SQL thread ---reap - ---echo # disconnect: slave2 -disconnect slave2; - ---echo # connection: slave -connection slave; ---echo # cleanup -SET @@GLOBAL.slave_net_timeout = @save_slave_net_timeout; - -source include/rpl_end.inc; diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc index b6ff23cd1ad..c811cb1cc9e 100644 --- a/plugin/semisync/semisync_master_plugin.cc +++ b/plugin/semisync/semisync_master_plugin.cc @@ -297,10 +297,10 @@ DEF_SHOW_FUNC(avg_trx_wait_time, SHOW_LONG) static SHOW_VAR semi_sync_master_status_vars[]= { {"Rpl_semi_sync_master_status", (char*) &SHOW_FNAME(status), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {"Rpl_semi_sync_master_clients", (char*) &SHOW_FNAME(clients), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {"Rpl_semi_sync_master_yes_tx", (char*) &rpl_semi_sync_master_yes_transactions, SHOW_LONG}, @@ -309,7 +309,7 @@ static SHOW_VAR semi_sync_master_status_vars[]= { SHOW_LONG}, {"Rpl_semi_sync_master_wait_sessions", (char*) &SHOW_FNAME(wait_sessions), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {"Rpl_semi_sync_master_no_times", (char*) &rpl_semi_sync_master_off_times, SHOW_LONG}, @@ -321,22 +321,22 @@ static SHOW_VAR semi_sync_master_status_vars[]= { SHOW_LONG}, {"Rpl_semi_sync_master_tx_wait_time", (char*) &SHOW_FNAME(trx_wait_time), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {"Rpl_semi_sync_master_tx_waits", (char*) &SHOW_FNAME(trx_wait_num), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {"Rpl_semi_sync_master_tx_avg_wait_time", (char*) &SHOW_FNAME(avg_trx_wait_time), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {"Rpl_semi_sync_master_net_wait_time", (char*) &SHOW_FNAME(net_wait_time), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {"Rpl_semi_sync_master_net_waits", (char*) &SHOW_FNAME(net_wait_num), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {"Rpl_semi_sync_master_net_avg_wait_time", (char*) &SHOW_FNAME(avg_net_wait_time), - SHOW_FUNC}, + SHOW_SIMPLE_FUNC}, {NULL, NULL, SHOW_LONG}, }; diff --git a/sql/item_create.cc b/sql/item_create.cc index 87e90ed4f8b..07e7f7b7ff9 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -4393,7 +4393,7 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name, if (item_list != NULL) arg_count= item_list->elements; - if (arg_count < 2 || arg_count >4) + if (arg_count < 2 || arg_count > 4) { my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name.str); return func; @@ -4413,7 +4413,6 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name, { Item *param_3= item_list->pop(); func= new (thd->mem_root) Item_master_pos_wait(param_1, param_2, param_3); - thd->lex->safe_to_cache_query= 0; break; } case 4: @@ -4422,7 +4421,6 @@ Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name, Item *param_4= item_list->pop(); func= new (thd->mem_root) Item_master_pos_wait(param_1, param_2, param_3, param_4); - thd->lex->safe_to_cache_query= 0; break; } } diff --git a/sql/lex.h b/sql/lex.h index 9bf4c439cb6..dab9e2adbc4 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -514,6 +514,7 @@ static SYMBOL symbols[] = { { "SIGNED", SYM(SIGNED_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)}, { "SLAVE", SYM(SLAVE)}, + { "SLAVES", SYM(SLAVES)}, { "SLOW", SYM(SLOW)}, { "SNAPSHOT", SYM(SNAPSHOT_SYM)}, { "SMALLINT", SYM(SMALLINT)}, diff --git a/sql/log.cc b/sql/log.cc index 6b0507943c3..e664540f0d6 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3866,7 +3866,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) DBUG_ENTER("purge_first_log"); DBUG_ASSERT(is_open()); - DBUG_ASSERT(rli->slave_running == 1); + DBUG_ASSERT(rli->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT); DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name)); mysql_mutex_lock(&LOCK_index); diff --git a/sql/log_event.cc b/sql/log_event.cc index 1d525aa94d8..e802c7db16e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11247,6 +11247,9 @@ Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len, There is a dummy replacement for this in the embedded library that returns FALSE; this is used by XtraDB to allow it to access replication stuff while still being able to use the same plugin in both stand-alone and embedded. + + In this function it's ok to use active_mi, as this is only called for + the main replication server. */ bool rpl_get_position_info(const char **log_file_name, ulonglong *log_pos, const char **group_relay_log_name, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3a89de32b8a..24408849eed 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -496,6 +496,7 @@ ulong binlog_cache_use= 0, binlog_cache_disk_use= 0; ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0; ulong max_connections, max_connect_errors; ulong extra_max_connections; +ulong slave_retried_transactions; ulonglong denied_connections; my_decimal decimal_zero; @@ -3379,8 +3380,8 @@ SHOW_VAR com_status_vars[]= { {"show_user_statistics", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_USER_STATS]), SHOW_LONG_STATUS}, {"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS}, {"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS}, - {"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS}, - {"slave_stop", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS}, + {"start_all_slaves", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_ALL_START]), SHOW_LONG_STATUS}, + {"start_slave", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS}, {"stmt_close", (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS}, {"stmt_execute", (char*) offsetof(STATUS_VAR, com_stmt_execute), SHOW_LONG_STATUS}, {"stmt_fetch", (char*) offsetof(STATUS_VAR, com_stmt_fetch), SHOW_LONG_STATUS}, @@ -3388,6 +3389,8 @@ SHOW_VAR com_status_vars[]= { {"stmt_reprepare", (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS}, {"stmt_reset", (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS}, {"stmt_send_long_data", (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS}, + {"stop_all_slaves", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_ALL_STOP]), SHOW_LONG_STATUS}, + {"stop_slave", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS}, {"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS}, {"uninstall_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]), SHOW_LONG_STATUS}, {"unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS}, @@ -4911,7 +4914,7 @@ int mysqld_main(int argc, char **argv) /* We must have LOCK_open before LOCK_global_system_variables because - LOCK_open is hold while sql_plugin.c::intern_sys_var_ptr() is called. + LOCK_open is held while sql_plugin.c::intern_sys_var_ptr() is called. */ mysql_mutex_record_order(&LOCK_open, &LOCK_global_system_variables); @@ -6532,66 +6535,51 @@ static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff) { Master_info *mi; var->type= SHOW_MY_BOOL; - mysql_mutex_lock(&LOCK_active_mi); var->value= buff; + mysql_mutex_lock(&LOCK_active_mi); mi= master_info_index-> get_master_info(&thd->variables.default_master_connection, - MYSQL_ERROR::WARN_LEVEL_WARN); - *((my_bool *)buff)= (my_bool) (mi && - mi->slave_running == - MYSQL_SLAVE_RUN_CONNECT && - mi->rli.slave_running); - mysql_mutex_unlock(&LOCK_active_mi); - return 0; -} - -static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff) -{ - /* - TODO: with multimaster, have one such counter per line in - SHOW SLAVE STATUS, and have the sum over all lines here. - */ - mysql_mutex_lock(&LOCK_active_mi); - if (active_mi) - { - var->type= SHOW_LONG; - var->value= buff; - mysql_mutex_lock(&active_mi->rli.data_lock); - *((long *)buff)= (long)active_mi->rli.retried_trans; - mysql_mutex_unlock(&active_mi->rli.data_lock); - } + MYSQL_ERROR::WARN_LEVEL_NOTE); + if (mi) + *((my_bool *)buff)= (my_bool) (mi->slave_running == + MYSQL_SLAVE_RUN_CONNECT && + mi->rli.slave_running); else var->type= SHOW_UNDEF; mysql_mutex_unlock(&LOCK_active_mi); return 0; } + static int show_slave_received_heartbeats(THD *thd, SHOW_VAR *var, char *buff) { + Master_info *mi; + var->type= SHOW_LONGLONG; + var->value= buff; mysql_mutex_lock(&LOCK_active_mi); - if (active_mi) - { - var->type= SHOW_LONGLONG; - var->value= buff; - mysql_mutex_lock(&active_mi->rli.data_lock); - *((longlong *)buff)= active_mi->received_heartbeats; - mysql_mutex_unlock(&active_mi->rli.data_lock); - } + mi= master_info_index-> + get_master_info(&thd->variables.default_master_connection, + MYSQL_ERROR::WARN_LEVEL_NOTE); + if (mi) + *((longlong *)buff)= mi->received_heartbeats; else var->type= SHOW_UNDEF; mysql_mutex_unlock(&LOCK_active_mi); return 0; } + static int show_heartbeat_period(THD *thd, SHOW_VAR *var, char *buff) { + Master_info *mi; + var->type= SHOW_CHAR; + var->value= buff; mysql_mutex_lock(&LOCK_active_mi); - if (active_mi) - { - var->type= SHOW_CHAR; - var->value= buff; - sprintf(buff, "%.3f", active_mi->heartbeat_period); - } + mi= master_info_index-> + get_master_info(&thd->variables.default_master_connection, + MYSQL_ERROR::WARN_LEVEL_NOTE); + if (mi) + sprintf(buff, "%.3f", mi->heartbeat_period); else var->type= SHOW_UNDEF; mysql_mutex_unlock(&LOCK_active_mi); @@ -6952,7 +6940,7 @@ SHOW_VAR status_vars[]= { {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS}, {"Binlog_bytes_written", (char*) offsetof(STATUS_VAR, binlog_bytes_written), SHOW_LONGLONG_STATUS}, {"Com", (char*) com_status_vars, SHOW_ARRAY}, - {"Compression", (char*) &show_net_compression, SHOW_FUNC}, + {"Compression", (char*) &show_net_compression, SHOW_SIMPLE_FUNC}, {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH}, {"Cpu_time", (char*) offsetof(STATUS_VAR, cpu_time), SHOW_DOUBLE_STATUS}, {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS}, @@ -7006,13 +6994,13 @@ SHOW_VAR status_vars[]= { {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH}, {"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH}, {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_NOFLUSH}, - {"Open_table_definitions", (char*) &show_table_definitions, SHOW_FUNC}, - {"Open_tables", (char*) &show_open_tables, SHOW_FUNC}, + {"Open_table_definitions", (char*) &show_table_definitions, SHOW_SIMPLE_FUNC}, + {"Open_tables", (char*) &show_open_tables, SHOW_SIMPLE_FUNC}, {"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH}, {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS}, {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS}, - {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC}, + {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_SIMPLE_FUNC}, {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS}, {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS}, {"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS}, @@ -7026,10 +7014,10 @@ SHOW_VAR status_vars[]= { {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH}, {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH}, #endif /*HAVE_QUERY_CACHE*/ - {"Queries", (char*) &show_queries, SHOW_FUNC}, + {"Queries", (char*) &show_queries, SHOW_SIMPLE_FUNC}, {"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS}, #ifdef HAVE_REPLICATION - {"Rpl_status", (char*) &show_rpl_status, SHOW_FUNC}, + {"Rpl_status", (char*) &show_rpl_status, SHOW_SIMPLE_FUNC}, #endif {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS}, {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS}, @@ -7038,10 +7026,10 @@ SHOW_VAR status_vars[]= { {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS}, {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG}, #ifdef HAVE_REPLICATION - {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC}, - {"Slave_heartbeat_period", (char*) &show_heartbeat_period, SHOW_FUNC}, - {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_FUNC}, - {"Slave_running", (char*) &show_slave_running, SHOW_FUNC}, + {"Slave_retried_transactions",(char*)&slave_retried_transactions, SHOW_LONG}, + {"Slave_heartbeat_period", (char*) &show_heartbeat_period, SHOW_SIMPLE_FUNC}, + {"Slave_received_heartbeats",(char*) &show_slave_received_heartbeats, SHOW_SIMPLE_FUNC}, + {"Slave_running", (char*) &show_slave_running, SHOW_SIMPLE_FUNC}, #endif {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG}, {"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS}, @@ -7051,29 +7039,29 @@ SHOW_VAR status_vars[]= { {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS}, #ifdef HAVE_OPENSSL #ifndef EMBEDDED_LIBRARY - {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_FUNC}, - {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_FUNC}, - {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_FUNC}, - {"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_FUNC}, - {"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_FUNC}, - {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_FUNC}, - {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_FUNC}, - {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_FUNC}, - {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_FUNC}, - {"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_FUNC}, - {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_FUNC}, - {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_FUNC}, - {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_FUNC}, - {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_FUNC}, - {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_FUNC}, - {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_FUNC}, - {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_FUNC}, - {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_FUNC}, - {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_FUNC}, - {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_FUNC}, - {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_FUNC}, - {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC}, - {"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC}, + {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_SIMPLE_FUNC}, + {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_SIMPLE_FUNC}, + {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_SIMPLE_FUNC}, + {"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_SIMPLE_FUNC}, + {"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_SIMPLE_FUNC}, + {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_SIMPLE_FUNC}, + {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_SIMPLE_FUNC}, + {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_SIMPLE_FUNC}, + {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_SIMPLE_FUNC}, + {"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_SIMPLE_FUNC}, + {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_SIMPLE_FUNC}, + {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_SIMPLE_FUNC}, + {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_SIMPLE_FUNC}, + {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_SIMPLE_FUNC}, + {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_SIMPLE_FUNC}, + {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_SIMPLE_FUNC}, + {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_SIMPLE_FUNC}, + {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_SIMPLE_FUNC}, + {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_SIMPLE_FUNC}, + {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_SIMPLE_FUNC}, + {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_SIMPLE_FUNC}, + {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_SIMPLE_FUNC}, + {"Ssl_version", (char*) &show_ssl_get_version, SHOW_SIMPLE_FUNC}, #endif #endif /* HAVE_OPENSSL */ {"Syncs", (char*) &my_sync_count, SHOW_LONG_NOFLUSH}, @@ -7091,16 +7079,16 @@ SHOW_VAR status_vars[]= { {"Tc_log_page_waits", (char*) &tc_log_page_waits, SHOW_LONG}, #endif #ifdef HAVE_POOL_OF_THREADS - {"Threadpool_idle_threads", (char *) &show_threadpool_idle_threads, SHOW_FUNC}, + {"Threadpool_idle_threads", (char *) &show_threadpool_idle_threads, SHOW_SIMPLE_FUNC}, {"Threadpool_threads", (char *) &tp_stats.num_worker_threads, SHOW_INT}, #endif {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_NOFLUSH}, {"Threads_connected", (char*) &connection_count, SHOW_INT}, {"Threads_created", (char*) &thread_created, SHOW_LONG_NOFLUSH}, {"Threads_running", (char*) &thread_running, SHOW_INT}, - {"Uptime", (char*) &show_starttime, SHOW_FUNC}, + {"Uptime", (char*) &show_starttime, SHOW_SIMPLE_FUNC}, #ifdef ENABLED_PROFILING - {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_FUNC}, + {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_SIMPLE_FUNC}, #endif {NullS, NullS, SHOW_LONG} }; @@ -7299,6 +7287,7 @@ static int mysql_init_variables(void) protocol_version= PROTOCOL_VERSION; what_to_log= ~ (1L << (uint) COM_TIME); refresh_version= 1L; /* Increments on each reload */ + denied_connections= 0; executed_events= 0; global_query_id= thread_id= 1L; my_atomic_rwlock_init(&global_query_id_lock); @@ -7326,6 +7315,7 @@ static int mysql_init_variables(void) relay_log_info_file= (char*) "relay-log.info"; report_user= report_password = report_host= 0; /* TO BE DELETED */ opt_relay_logname= opt_relaylog_index_name= 0; + slave_retried_transactions= 0; /* Variables in libraries */ charsets_dir= 0; diff --git a/sql/mysqld.h b/sql/mysqld.h index 4250898cc5b..430811a956c 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -95,6 +95,7 @@ extern my_bool opt_safe_user_create; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; extern my_bool opt_slave_compressed_protocol, use_temp_pool; extern ulong slave_exec_mode_options; +extern ulong slave_retried_transactions; extern ulonglong slave_type_conversions_options; extern my_bool read_only, opt_readonly; extern my_bool lower_case_file_system; diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index 1491d970472..e004e3495c7 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -21,6 +21,7 @@ #include "rpl_mi.h" #include "slave.h" // SLAVE_MAX_HEARTBEAT_PERIOD #include "strfunc.h" +#include "sql_repl.h" #ifdef HAVE_REPLICATION @@ -42,7 +43,10 @@ Master_info::Master_info(LEX_STRING *connection_name_arg, ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0; ssl_cipher[0]= 0; ssl_key[0]= 0; - /* Store connection name and lower case connection name */ + /* + Store connection name and lower case connection name + It's safe to ignore any OMM errors as this is checked by error() + */ connection_name.length= cmp_connection_name.length= connection_name_arg->length; if ((connection_name.str= (char*) my_malloc(connection_name_arg->length*2+2, @@ -599,7 +603,7 @@ void free_key_master_info(Master_info *mi) /** Check if connection name for master_info is valid. - It's valid if it's a valid system name, is less than + It's valid if it's a valid system name of length less than MAX_CONNECTION_NAME. @return @@ -616,7 +620,7 @@ bool check_master_connection_name(LEX_STRING *name) /** - Create a log file with a signed suffix. + Create a log file with a given suffix. @param res_file_name Store result here @@ -635,7 +639,7 @@ bool check_master_connection_name(LEX_STRING *name) file names without a prefix. */ -void create_signed_file_name(char *res_file_name, uint length, +void create_logfile_name_with_suffix(char *res_file_name, uint length, const char *info_file, bool append, LEX_STRING *suffix) { @@ -761,9 +765,9 @@ bool Master_info_index::init_all_master_info() lock_slave_threads(mi); init_thread_mask(&thread_mask,mi,0 /*not inverse*/); - create_signed_file_name(buf_master_info_file, sizeof(buf_master_info_file), + create_logfile_name_with_suffix(buf_master_info_file, sizeof(buf_master_info_file), master_info_file, 0, &connection_name); - create_signed_file_name(buf_relay_log_info_file, + create_logfile_name_with_suffix(buf_relay_log_info_file, sizeof(buf_relay_log_info_file), relay_log_info_file, 0, &connection_name); if (global_system_variables.log_warnings > 1) @@ -827,7 +831,7 @@ bool Master_info_index::init_all_master_info() buf_relay_log_info_file, SLAVE_IO | SLAVE_SQL)) { - sql_print_error("Failed to create slave threads for connection %.*s", + sql_print_error("Failed to create slave threads for connection '%.*s'", (int) connection_name.length, connection_name.str); continue; @@ -1033,8 +1037,7 @@ bool Master_info_index::remove_master_info(LEX_STRING *name) } // Rewrite Master_info.index - uint i; - for (i= 0; i< master_info_hash.records; ++i) + for (uint i= 0; i< master_info_hash.records; ++i) { Master_info *tmp_mi; tmp_mi= (Master_info *) my_hash_element(&master_info_hash, i); @@ -1046,4 +1049,127 @@ bool Master_info_index::remove_master_info(LEX_STRING *name) DBUG_RETURN(FALSE); } + +/** + Master_info_index::give_error_if_slave_running() + + @return + TRUE If some slave is running. An error is printed + FALSE No slave is running +*/ + +bool Master_info_index::give_error_if_slave_running() +{ + DBUG_ENTER("warn_if_slave_running"); + mysql_mutex_assert_owner(&LOCK_active_mi); + + for (uint i= 0; i< master_info_hash.records; ++i) + { + Master_info *mi; + mi= (Master_info *) my_hash_element(&master_info_hash, i); + if (mi->rli.slave_running != MYSQL_SLAVE_NOT_RUN) + { + my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length, + mi->connection_name.str); + DBUG_RETURN(TRUE); + } + } + DBUG_RETURN(FALSE); +} + + +/** + Master_info_index::start_all_slaves() + + Start all slaves that was not running. + + @return + TRUE Error + FALSE Everything ok. +*/ + +bool Master_info_index::start_all_slaves(THD *thd) +{ + bool result= FALSE; + DBUG_ENTER("warn_if_slave_running"); + mysql_mutex_assert_owner(&LOCK_active_mi); + + for (uint i= 0; i< master_info_hash.records; ++i) + { + int error; + Master_info *mi; + mi= (Master_info *) my_hash_element(&master_info_hash, i); + + /* + Try to start all slaves that are configured (host is defined) + and are not already running + */ + if ((mi->slave_running != MYSQL_SLAVE_RUN_CONNECT || + !mi->rli.slave_running) && *mi->host) + { + if ((error= start_slave(thd, mi, 1))) + { + my_error(ER_CANT_START_STOP_SLAVE, MYF(0), + "START", + (int) mi->connection_name.length, + mi->connection_name.str); + result= 1; + if (error < 0) // fatal error + break; + } + else + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_SLAVE_STARTED, ER(ER_SLAVE_STARTED), + (int) mi->connection_name.length, + mi->connection_name.str); + } + } + DBUG_RETURN(result); +} + + +/** + Master_info_index::stop_all_slaves() + + Start all slaves that was not running. + + @return + TRUE Error + FALSE Everything ok. +*/ + +bool Master_info_index::stop_all_slaves(THD *thd) +{ + bool result= FALSE; + DBUG_ENTER("warn_if_slave_running"); + mysql_mutex_assert_owner(&LOCK_active_mi); + + for (uint i= 0; i< master_info_hash.records; ++i) + { + int error; + Master_info *mi; + mi= (Master_info *) my_hash_element(&master_info_hash, i); + if ((mi->slave_running != MYSQL_SLAVE_NOT_RUN || + mi->rli.slave_running)) + { + if ((error= stop_slave(thd, mi, 1))) + { + my_error(ER_CANT_START_STOP_SLAVE, MYF(0), + "STOP", + (int) mi->connection_name.length, + mi->connection_name.str); + result= 1; + if (error < 0) // Fatal error + break; + } + else + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_SLAVE_STOPPED, ER(ER_SLAVE_STOPPED), + (int) mi->connection_name.length, + mi->connection_name.str); + } + } + DBUG_RETURN(result); +} + #endif /* HAVE_REPLICATION */ diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index 6c7bd3a5d28..48fdd3937c5 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -70,7 +70,7 @@ class Master_info : public Slave_reporting_capability } /* the variables below are needed because we can change masters on the fly */ - char master_log_name[FN_REFLEN+6]; /* Place for multi-*/ + char master_log_name[FN_REFLEN+6]; /* Room for multi-*/ char host[HOSTNAME_LENGTH+1]; char user[USERNAME_LENGTH+1]; char password[MAX_PASSWORD_LENGTH+1]; @@ -164,10 +164,13 @@ public: bool remove_master_info(LEX_STRING *connection_name); Master_info *get_master_info(LEX_STRING *connection_name, MYSQL_ERROR::enum_warning_level warning); + bool give_error_if_slave_running(); + bool start_all_slaves(THD *thd); + bool stop_all_slaves(THD *thd); }; bool check_master_connection_name(LEX_STRING *name); -void create_signed_file_name(char *res_file_name, uint length, +void create_logfile_name_with_suffix(char *res_file_name, uint length, const char *info_file, bool append, LEX_STRING *suffix); diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 362ebab9fa0..e74831464fa 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -50,7 +50,7 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery) last_master_timestamp(0), slave_skip_counter(0), abort_pos_wait(0), slave_run_id(0), sql_thd(0), inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE), - until_log_pos(0), retried_trans(0), + until_log_pos(0), retried_trans(0), executed_entries(0), tables_to_lock(0), tables_to_lock_count(0), last_event_start_time(0), deferred_events(NULL),m_flags(0), row_stmt_start_timestamp(0), long_find_row_note_printed(false), @@ -203,14 +203,14 @@ a file name for --relay-log-index option", opt_relaylog_index_name); char buf_relay_logname[FN_REFLEN], buf_relaylog_index_name_buff[FN_REFLEN]; char *buf_relaylog_index_name= opt_relaylog_index_name; - create_signed_file_name(buf_relay_logname, sizeof(buf_relay_logname), + create_logfile_name_with_suffix(buf_relay_logname, sizeof(buf_relay_logname), ln, 1, &mi->connection_name); ln= buf_relay_logname; if (opt_relaylog_index_name) { buf_relaylog_index_name= buf_relaylog_index_name_buff; - create_signed_file_name(buf_relaylog_index_name_buff, + create_logfile_name_with_suffix(buf_relaylog_index_name_buff, sizeof(buf_relaylog_index_name_buff), opt_relaylog_index_name, 0, &mi->connection_name); diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index c543b4d3198..6144d37026b 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -228,8 +228,9 @@ public: Needed for problems when slave stops and we want to restart it skipping one or more events in the master log that have caused errors, and have been manually applied by DBA already. + Must be ulong as it's refered to from set_var.cc */ - volatile ulong slave_skip_counter; /* Must be ulong */ + volatile ulong slave_skip_counter; volatile ulong abort_pos_wait; /* Incremented on change master */ volatile ulong slave_run_id; /* Incremented on slave start */ ulong max_relay_log_size; @@ -286,6 +287,7 @@ public: slave started. */ ulong trans_retries, retried_trans; + ulong executed_entries; /* For SLAVE STATUS */ /* If the end of the hot relay log is made of master's events ignored by the diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 803575b7ba0..3832ee150e3 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -4271,18 +4271,18 @@ ER_TRANS_CACHE_FULL swe "Transaktionen krävde mera än 'max_binlog_cache_size' minne. Öka denna mysqld-variabel och försök på nytt" ukr "Транзакція з багатьма виразами вимагає більше ніж 'max_binlog_cache_size' байтів для зберігання. Збільште цю змінну mysqld та спробуйте знову" ER_SLAVE_MUST_STOP - dan "Denne handling kunne ikke udføres med kørende slave, brug først kommandoen STOP SLAVE" - nla "Deze operatie kan niet worden uitgevoerd met een actieve slave, doe eerst STOP SLAVE" - eng "This operation cannot be performed with a running slave; run STOP SLAVE first" - fre "Cette opération ne peut être réalisée avec un esclave actif, faites STOP SLAVE d'abord" - ger "Diese Operation kann bei einem aktiven Slave nicht durchgeführt werden. Bitte zuerst STOP SLAVE ausführen" - ita "Questa operazione non puo' essere eseguita con un database 'slave' che gira, lanciare prima STOP SLAVE" - por "Esta operação não pode ser realizada com um 'slave' em execução. Execute STOP SLAVE primeiro" - rus "Эту операцию невозможно выполнить при работающем потоке подчиненного сервера. Сначала выполните STOP SLAVE" - serbian "Ova operacija ne može biti izvršena dok je aktivan podređeni server. Zadajte prvo komandu 'STOP SLAVE' da zaustavite podređeni server." - spa "Esta operación no puede ser hecha con el esclavo funcionando, primero use STOP SLAVE" - swe "Denna operation kan inte göras under replikering; Gör STOP SLAVE först" - ukr "Операція не може бути виконана з запущеним підлеглим, спочатку виконайте STOP SLAVE" + dan "Denne handling kunne ikke udføres med kørende slave '%2$*1$s', brug først kommandoen STOP SLAVE '%2$*1$s'" + nla "Deze operatie kan niet worden uitgevoerd met een actieve slave '%2$*1$s', doe eerst STOP SLAVE '%2$*1$s'" + eng "This operation cannot be performed as you have a running slave '%2$*1$s'; run STOP SLAVE '%2$*1$s' first" + fre "Cette opération ne peut être réalisée avec un esclave '%2$*1$s' actif, faites STOP SLAVE '%2$*1$s' d'abord" + ger "Diese Operation kann bei einem aktiven Slave '%2$*1$s' nicht durchgeführt werden. Bitte zuerst STOP SLAVE '%2$*1$s' ausführen" + ita "Questa operazione non puo' essere eseguita con un database 'slave' '%2$*1$s' che gira, lanciare prima STOP SLAVE '%2$*1$s'" + por "Esta operação não pode ser realizada com um 'slave' '%2$*1$s' em execução. Execute STOP SLAVE '%2$*1$s' primeiro" + rus "Эту операцию невозможно выполнить при работающем потоке подчиненного сервера %2$*1$s. Сначала выполните STOP SLAVE '%2$*1$s'" + serbian "Ova operacija ne može biti izvršena dok je aktivan podređeni '%2$*1$s' server. Zadajte prvo komandu 'STOP SLAVE '%2$*1$s'' da zaustavite podređeni server." + spa "Esta operación no puede ser hecha con el esclavo '%2$*1$s' funcionando, primero use STOP SLAVE '%2$*1$s'" + swe "Denna operation kan inte göras under replikering; Du har en aktiv förbindelse till '%2$*1$s'. Gör STOP SLAVE '%2$*1$s' först" + ukr "Операція не може бути виконана з запущеним підлеглим '%2$*1$s', спочатку виконайте STOP SLAVE '%2$*1$s'" ER_SLAVE_NOT_RUNNING dan "Denne handling kræver en kørende slave. Konfigurer en slave og brug kommandoen START SLAVE" nla "Deze operatie vereist een actieve slave, configureer slave en doe dan START SLAVE" @@ -6592,3 +6592,9 @@ ER_CONNECTION_ALREADY_EXISTS eng "Connection '%.*s' conflicts with existing connection '%.*s'" ER_MASTER_LOG_PREFIX eng "Master '%.*s': " +ER_CANT_START_STOP_SLAVE + eng "Can't %s SLAVE '%.*s'" +ER_SLAVE_STARTED + eng "SLAVE '%.*s' started" +ER_SLAVE_STOPPED + eng "SLAVE '%.*s' stopped" diff --git a/sql/slave.cc b/sql/slave.cc index 8254e90b369..efaf25b3456 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -162,7 +162,7 @@ static int terminate_slave_thread(THD *thd, volatile uint *slave_running, bool skip_lock); static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info); -static bool send_show_master_info_header(THD *thd, Master_info *mi, bool full); +static bool send_show_master_info_header(THD *thd, bool full); static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full); /* @@ -1863,9 +1863,9 @@ Waiting for the slave SQL thread to free enough relay log space"); #endif if (rli->sql_force_rotate_relay) { - mysql_mutex_lock(&active_mi->data_lock); + mysql_mutex_lock(&mi->data_lock); rotate_relay_log(rli->mi); - mysql_mutex_unlock(&active_mi->data_lock); + mysql_mutex_unlock(&mi->data_lock); rli->sql_force_rotate_relay= false; } @@ -2024,7 +2024,7 @@ bool show_master_info(THD *thd, Master_info *mi, bool full) { DBUG_ENTER("show_master_info"); - if (send_show_master_info_header(thd, mi, full)) + if (send_show_master_info_header(thd, full)) DBUG_RETURN(TRUE); if (send_show_master_info_data(thd, mi, full)) DBUG_RETURN(TRUE); @@ -2032,18 +2032,23 @@ bool show_master_info(THD *thd, Master_info *mi, bool full) DBUG_RETURN(FALSE); } -static bool send_show_master_info_header(THD *thd, Master_info *mi, bool full) +static bool send_show_master_info_header(THD *thd, bool full) { List field_list; Protocol *protocol= thd->protocol; + Master_info *mi; DBUG_ENTER("show_master_info_header"); if (full) + { field_list.push_back(new Item_empty_string("Connection_name", MAX_CONNECTION_NAME)); + field_list.push_back(new Item_empty_string("Slave_SQL_State", + 30)); + } field_list.push_back(new Item_empty_string("Slave_IO_State", - 14)); + 30)); field_list.push_back(new Item_empty_string("Master_Host", sizeof(mi->host))); field_list.push_back(new Item_empty_string("Master_User", @@ -2106,7 +2111,15 @@ static bool send_show_master_info_header(THD *thd, Master_info *mi, bool full) FN_REFLEN)); field_list.push_back(new Item_return_int("Master_Server_Id", sizeof(ulong), MYSQL_TYPE_LONG)); - + if (full) + { + field_list.push_back(new Item_return_int("Retried_transactions", + 10, MYSQL_TYPE_LONG)); + field_list.push_back(new Item_return_int("Max_relay_log_size", + 10, MYSQL_TYPE_LONGLONG)); + field_list.push_back(new Item_return_int("Executed_log_entries", + 10, MYSQL_TYPE_LONG)); + } if (protocol->send_result_set_metadata(&field_list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); @@ -2134,6 +2147,9 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full) protocol->store(mi->connection_name.str, mi->connection_name.length, &my_charset_bin); mysql_mutex_lock(&mi->run_lock); + if (full) + protocol->store(mi->rli.sql_thd ? mi->rli.sql_thd->proc_info : "", + &my_charset_bin); protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin); mysql_mutex_unlock(&mi->run_lock); @@ -2266,6 +2282,12 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full) } // Master_Server_id protocol->store((uint32) mi->master_id); + if (full) + { + protocol->store((uint32) mi->rli.retried_trans); + protocol->store((ulonglong) mi->rli.max_relay_log_size); + protocol->store((uint32) mi->rli.executed_entries); + } mysql_mutex_unlock(&mi->rli.err_lock); mysql_mutex_unlock(&mi->err_lock); @@ -2299,6 +2321,9 @@ static int cmp_mi_by_name(const Master_info **arg1, @retval FALSE success @retval TRUE failure + + @note + master_info_index is protected by LOCK_active_mi. */ bool show_all_master_info(THD* thd) @@ -2306,8 +2331,9 @@ bool show_all_master_info(THD* thd) uint i, elements; Master_info **tmp; DBUG_ENTER("show_master_info"); + mysql_mutex_assert_owner(&LOCK_active_mi); - if (send_show_master_info_header(thd, active_mi, 1)) + if (send_show_master_info_header(thd, 1)) DBUG_RETURN(TRUE); if (!(elements= master_info_index->master_info_hash.records)) @@ -2973,6 +2999,7 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli) mysql_mutex_lock(&rli->data_lock); // because of SHOW STATUS rli->trans_retries++; rli->retried_trans++; + statistic_increment(slave_retried_transactions, LOCK_status); mysql_mutex_unlock(&rli->data_lock); DBUG_PRINT("info", ("Slave retries transaction " "rli->trans_retries: %lu", rli->trans_retries)); @@ -3156,7 +3183,7 @@ pthread_handler_t handle_slave_io(void *arg) mysql_mutex_lock(&LOCK_thread_count); threads.append(thd); mysql_mutex_unlock(&LOCK_thread_count); - mi->slave_running = 1; + mi->slave_running = MYSQL_SLAVE_RUN_NOT_CONNECT; mi->abort_slave = 0; mysql_mutex_unlock(&mi->run_lock); mysql_cond_broadcast(&mi->start_cond); @@ -3468,7 +3495,7 @@ err_during_init: delete thd; mysql_mutex_unlock(&LOCK_thread_count); mi->abort_slave= 0; - mi->slave_running= 0; + mi->slave_running= MYSQL_SLAVE_NOT_RUN; mi->io_thd= 0; /* Note: the order of the two following calls (first broadcast, then unlock) @@ -3573,7 +3600,7 @@ pthread_handler_t handle_slave_sql(void *arg) /* Inform waiting threads that slave has started */ rli->slave_run_id++; - rli->slave_running = 1; + rli->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT; pthread_detach_this_thread(); if (init_slave_thread(thd, mi, SLAVE_THD_SQL)) @@ -3817,6 +3844,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ } goto err; } + rli->executed_entries++; } /* Thread stopped. Print the current replication position to the log */ @@ -3847,9 +3875,9 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ err_during_init: /* We need data_lock, at least to wake up any waiting master_pos_wait() */ mysql_mutex_lock(&rli->data_lock); - DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun + DBUG_ASSERT(rli->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT); // tracking buffer overrun /* When master_pos_wait() wakes up it will check this and terminate */ - rli->slave_running= 0; + rli->slave_running= MYSQL_SLAVE_NOT_RUN; /* Forget the relay log's format */ delete rli->relay_log.description_event_for_exec; rli->relay_log.description_event_for_exec= 0; @@ -5635,11 +5663,10 @@ bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report, */ bool rpl_master_erroneous_autoinc(THD *thd) { - if (active_mi && active_mi->rli.sql_thd == thd) + if (thd->rli_slave) { - Relay_log_info *rli= &active_mi->rli; DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;); - return rpl_master_has_bug(rli, 33029, FALSE, NULL, NULL); + return rpl_master_has_bug(thd->rli_slave, 33029, FALSE, NULL, NULL); } return FALSE; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 50c99af29d1..dd203af2a1b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2201,7 +2201,11 @@ public: /* scramble - random string sent to client on handshake */ char scramble[SCRAMBLE_LENGTH+1]; - LEX_STRING connection_name; /* If slave */ + /* + If this is a slave, the name of the connection stored here. + This is used for taging error messages in the log files. + */ + LEX_STRING connection_name; char default_master_connection_buff[MAX_CONNECTION_NAME+1]; bool slave_thread, one_shot_set; bool extra_port; /* If extra connection */ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3c3b9f85727..4372f6dfbfe 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -850,10 +850,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, table->next_number_field=table->found_next_number_field; #ifdef HAVE_REPLICATION - if (thd->slave_thread && + if (thd->rli_slave && (info.handle_duplicates == DUP_UPDATE) && (table->next_number_field != NULL) && - rpl_master_has_bug(&active_mi->rli, 24432, TRUE, NULL, NULL)) + rpl_master_has_bug(thd->rli_slave, 24432, TRUE, NULL, NULL)) goto abort; #endif @@ -3436,10 +3436,10 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) table->next_number_field=table->found_next_number_field; #ifdef HAVE_REPLICATION - if (thd->slave_thread && + if (thd->rli_slave && (info.handle_duplicates == DUP_UPDATE) && (table->next_number_field != NULL) && - rpl_master_has_bug(&active_mi->rli, 24432, TRUE, NULL, NULL)) + rpl_master_has_bug(thd->rli_slave, 24432, TRUE, NULL, NULL)) DBUG_RETURN(1); #endif diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 7e92fe12dc3..be0c3d8a0df 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -156,7 +156,8 @@ enum enum_sql_command { SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT, SQLCOM_COMMIT, SQLCOM_SAVEPOINT, SQLCOM_RELEASE_SAVEPOINT, - SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, + SQLCOM_SLAVE_START, SQLCOM_SLAVE_ALL_START, + SQLCOM_SLAVE_STOP, SQLCOM_SLAVE_ALL_STOP, SQLCOM_BEGIN, SQLCOM_CHANGE_MASTER, SQLCOM_RENAME_TABLE, SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_PURGE_BEFORE, SQLCOM_SHOW_BINLOGS, diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 98031c96225..e2c744401b9 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -375,11 +375,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, MY_RETURN_REAL_PATH); } - if (thd->slave_thread) + if (thd->rli_slave) { #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) - if (strncmp(active_mi->rli.slave_patternload_file, name, - active_mi->rli.slave_patternload_file_size)) + if (strncmp(thd->rli_slave->slave_patternload_file, name, + thd->rli_slave->slave_patternload_file_size)) { /* LOAD DATA INFILE in the slave SQL Thread can only read from diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 831931e1ef2..60698dde421 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2708,7 +2708,8 @@ end_with_restore_list: if ((mi= (master_info_index-> get_master_info(&lex_mi->connection_name, MYSQL_ERROR::WARN_LEVEL_ERROR)))) - start_slave(thd, mi, 1 /* net report*/); + if (!start_slave(thd, mi, 1 /* net report*/)) + my_ok(thd); mysql_mutex_unlock(&LOCK_active_mi); break; } @@ -2743,7 +2744,32 @@ end_with_restore_list: if ((mi= (master_info_index-> get_master_info(&lex_mi->connection_name, MYSQL_ERROR::WARN_LEVEL_ERROR)))) - stop_slave(thd, mi, 1/* net report*/); + if (!stop_slave(thd, mi, 1/* net report*/)) + my_ok(thd); + mysql_mutex_unlock(&LOCK_active_mi); + break; + } + case SQLCOM_SLAVE_ALL_START: + { + mysql_mutex_lock(&LOCK_active_mi); + if (!master_info_index->start_all_slaves(thd)) + my_ok(thd); + mysql_mutex_unlock(&LOCK_active_mi); + break; + } + case SQLCOM_SLAVE_ALL_STOP: + { + if (thd->locked_tables_mode || + thd->in_active_multi_stmt_transaction() || + thd->global_read_lock.is_acquired()) + { + my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, + ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); + goto error; + } + mysql_mutex_lock(&LOCK_active_mi); + if (!master_info_index->stop_all_slaves(thd)) + my_ok(thd); mysql_mutex_unlock(&LOCK_active_mi); break; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index ed437c498e6..2954e9e1016 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2151,6 +2151,8 @@ static bool check_prepared_statement(Prepared_statement *stmt) case SQLCOM_FLUSH: case SQLCOM_SLAVE_START: case SQLCOM_SLAVE_STOP: + case SQLCOM_SLAVE_ALL_START: + case SQLCOM_SLAVE_ALL_STOP: case SQLCOM_INSTALL_PLUGIN: case SQLCOM_UNINSTALL_PLUGIN: case SQLCOM_CREATE_DB: diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index fcb7d15f5ba..21a07a51e49 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -158,10 +158,26 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, if (options & REFRESH_RELAY_LOG) { #ifdef HAVE_REPLICATION + LEX_MASTER_INFO* lex_mi= &thd->lex->mi; + Master_info *mi; + + /* + Writing this command to the binlog may cause problems as the + slave is not likely to have the same connection names. + */ + tmp_write_to_binlog= 0; + mysql_mutex_lock(&LOCK_active_mi); mysql_mutex_lock(&active_mi->data_lock); - if (rotate_relay_log(active_mi)) + if (!(mi= (master_info_index-> + get_master_info(&lex_mi->connection_name, + MYSQL_ERROR::WARN_LEVEL_ERROR)))) + { + result= 1; + } + else if (rotate_relay_log(mi)) *write_to_binlog= -1; mysql_mutex_unlock(&active_mi->data_lock); + mysql_mutex_unlock(&LOCK_active_mi); #endif } #ifdef HAVE_QUERY_CACHE diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 0238a98f5d0..e18b0cd04c0 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1297,7 +1297,9 @@ err: @retval 0 success @retval 1 error + @retval -1 fatal error */ + int start_slave(THD* thd , Master_info* mi, bool net_report) { int slave_errno= 0; @@ -1306,15 +1308,17 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) char relay_log_info_file_tmp[FN_REFLEN]; DBUG_ENTER("start_slave"); - create_signed_file_name(master_info_file_tmp, - sizeof(master_info_file_tmp), - master_info_file, 0, &mi->connection_name); - create_signed_file_name(relay_log_info_file_tmp, - sizeof(relay_log_info_file_tmp), - relay_log_info_file, 0, &mi->connection_name); - if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0)) - DBUG_RETURN(1); + DBUG_RETURN(-1); + + create_logfile_name_with_suffix(master_info_file_tmp, + sizeof(master_info_file_tmp), + master_info_file, 0, &mi->connection_name); + create_logfile_name_with_suffix(relay_log_info_file_tmp, + sizeof(relay_log_info_file_tmp), + relay_log_info_file, 0, + &mi->connection_name); + lock_slave_threads(mi); // this allows us to cleanly read slave_running // Get a mask of _stopped_ threads init_thread_mask(&thread_mask,mi,1 /* inverse */); @@ -1426,10 +1430,8 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) my_error(slave_errno, MYF(0), (int) mi->connection_name.length, mi->connection_name.str); - DBUG_RETURN(1); + DBUG_RETURN(slave_errno == ER_BAD_SLAVE ? -1 : 1); } - else if (net_report) - my_ok(thd); DBUG_RETURN(0); } @@ -1447,7 +1449,9 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) @retval 0 success @retval 1 error + @retval -1 error */ + int stop_slave(THD* thd, Master_info* mi, bool net_report ) { int slave_errno; @@ -1455,7 +1459,7 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report ) DBUG_PRINT("enter",("Connection: %s", mi->connection_name.str)); if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0)) - DBUG_RETURN(1); + DBUG_RETURN(-1); thd_proc_info(thd, "Killing slave"); int thread_mask; lock_slave_threads(mi); @@ -1491,8 +1495,6 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report ) my_message(slave_errno, ER(slave_errno), MYF(0)); DBUG_RETURN(1); } - else if (net_report) - my_ok(thd); DBUG_RETURN(0); } @@ -1524,9 +1526,10 @@ int reset_slave(THD *thd, Master_info* mi) init_thread_mask(&thread_mask,mi,0 /* not inverse */); if (thread_mask) // We refuse if any slave thread is running { - sql_errno= ER_SLAVE_MUST_STOP; - error=1; - goto err; + unlock_slave_threads(mi); + my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length, + mi->connection_name.str); + DBUG_RETURN(ER_SLAVE_MUST_STOP); } ha_reset_slave(thd); @@ -1555,10 +1558,10 @@ int reset_slave(THD *thd, Master_info* mi) end_master_info(mi); // and delete these two files - create_signed_file_name(master_info_file_tmp, + create_logfile_name_with_suffix(master_info_file_tmp, sizeof(master_info_file_tmp), master_info_file, 0, &mi->connection_name); - create_signed_file_name(relay_log_info_file_tmp, + create_logfile_name_with_suffix(relay_log_info_file_tmp, sizeof(relay_log_info_file_tmp), relay_log_info_file, 0, &mi->connection_name); @@ -1688,17 +1691,18 @@ bool change_master(THD* thd, Master_info* mi) init_thread_mask(&thread_mask,mi,0 /*not inverse*/); if (thread_mask) // We refuse if any slave thread is running { - my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); + my_error(ER_SLAVE_MUST_STOP, MYF(0), (int) mi->connection_name.length, + mi->connection_name.str); ret= TRUE; goto err; } thd_proc_info(thd, "Changing master"); - create_signed_file_name(master_info_file_tmp, + create_logfile_name_with_suffix(master_info_file_tmp, sizeof(master_info_file_tmp), master_info_file, 0, &mi->connection_name); - create_signed_file_name(relay_log_info_file_tmp, + create_logfile_name_with_suffix(relay_log_info_file_tmp, sizeof(relay_log_info_file_tmp), relay_log_info_file, 0, &mi->connection_name); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 8a106b8ec6f..c87538681a2 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2335,6 +2335,7 @@ static bool show_status_array(THD *thd, const char *wild, for (; variables->name; variables++) { + bool wild_checked; strnmov(prefix_end, variables->name, len); name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ if (ucase_names) @@ -2343,11 +2344,25 @@ static bool show_status_array(THD *thd, const char *wild, restore_record(table, s->default_values); table->field[0]->store(name_buffer, strlen(name_buffer), system_charset_info); + /* - if var->type is SHOW_FUNC, call the function. - Repeat as necessary, if new var is again SHOW_FUNC + Compare name for types that can't return arrays. We do this to not + calculate the value for function variables that we will not access */ - for (var=variables; var->type == SHOW_FUNC; var= &tmp) + if ((variables->type != SHOW_FUNC && variables->type != SHOW_ARRAY)) + { + if (wild && wild[0] && wild_case_compare(system_charset_info, + name_buffer, wild)) + continue; + wild_checked= 1; // Avoid checking it again + } + + /* + if var->type is SHOW_FUNC or SHOW_SIMPLE_FUNC, call the function. + Repeat as necessary, if new var is again one of the above + */ + for (var=variables; var->type == SHOW_FUNC || + var->type == SHOW_SIMPLE_FUNC; var= &tmp) ((mysql_show_var_func)(var->value))(thd, &tmp, buff); SHOW_TYPE show_type=var->type; @@ -2358,8 +2373,9 @@ static bool show_status_array(THD *thd, const char *wild, } else { - if (!(wild && wild[0] && wild_case_compare(system_charset_info, - name_buffer, wild)) && + if ((wild_checked || + (wild && wild[0] && wild_case_compare(system_charset_info, + name_buffer, wild))) && (!partial_cond || partial_cond->val_int())) { char *value=var->value; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ab07a2010f0..d7e7695207a 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1292,6 +1292,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SIGNED_SYM %token SIMPLE_SYM /* SQL-2003-N */ %token SLAVE +%token SLAVES %token SLOW %token SMALLINT /* SQL-2003-R */ %token SNAPSHOT_SYM @@ -7107,6 +7108,13 @@ slave: } slave_until {} + | START_SYM ALL SLAVES slave_thread_opts + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_ALL_START; + lex->type = 0; + } + {} | STOP_SYM SLAVE optional_connection_name slave_thread_opts { LEX *lex=Lex; @@ -7114,6 +7122,13 @@ slave: lex->type = 0; /* If you change this code don't forget to update SLAVE STOP too */ } + | STOP_SYM ALL SLAVES slave_thread_opts + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_ALL_STOP; + lex->type = 0; + /* If you change this code don't forget to update SLAVE STOP too */ + } | SLAVE optional_connection_name START_SYM slave_thread_opts { LEX *lex=Lex; @@ -11582,7 +11597,7 @@ show_param: { Lex->sql_command = SQLCOM_SHOW_MASTER_STAT; } - | FULL SLAVE STATUS_SYM + | ALL SLAVES STATUS_SYM { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; Lex->verbose= 1; @@ -11850,7 +11865,7 @@ flush_option: { Lex->type|= REFRESH_SLOW_LOG; } | BINARY LOGS_SYM { Lex->type|= REFRESH_BINARY_LOG; } - | RELAY LOGS_SYM + | RELAY LOGS_SYM optional_connection_name { Lex->type|= REFRESH_RELAY_LOG; } | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE_FREE; } @@ -13008,6 +13023,7 @@ keyword: | SIGNED_SYM {} | SOCKET_SYM {} | SLAVE {} + | SLAVES {} | SONAME_SYM {} | START_SYM {} | STOP_SYM {} diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 9421dca5c05..9eacc1c8392 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -2025,50 +2025,22 @@ static Sys_var_mybool Sys_master_verify_checksum( static const char *replicate_events_marked_for_skip_names[]= { "replicate", "filter_on_slave", "filter_on_master", 0 }; -static bool -replicate_events_marked_for_skip_check(sys_var *self, THD *thd, - set_var *var) -{ - int thread_mask; - DBUG_ENTER("sys_var_replicate_events_marked_for_skip_check"); - /* Slave threads must be stopped to change the variable. */ - mysql_mutex_lock(&LOCK_active_mi); - lock_slave_threads(active_mi); - init_thread_mask(&thread_mask, active_mi, 0 /*not inverse*/); - unlock_slave_threads(active_mi); - mysql_mutex_unlock(&LOCK_active_mi); - - if (thread_mask) // We refuse if any slave thread is running - { - my_error(ER_SLAVE_MUST_STOP, MYF(0)); - DBUG_RETURN(true); - } - DBUG_RETURN(false); -} bool Sys_var_replicate_events_marked_for_skip::global_update(THD *thd, set_var *var) { - bool result; - int thread_mask; + bool result= true; // Assume error DBUG_ENTER("Sys_var_replicate_events_marked_for_skip::global_update"); - /* Slave threads must be stopped to change the variable. */ + mysql_mutex_unlock(&LOCK_global_system_variables); mysql_mutex_lock(&LOCK_active_mi); - lock_slave_threads(active_mi); - init_thread_mask(&thread_mask, active_mi, 0 /*not inverse*/); - if (thread_mask) // We refuse if any slave thread is running - { - my_error(ER_SLAVE_MUST_STOP, MYF(0)); - result= true; - } - else + if (!master_info_index->give_error_if_slave_running()) result= Sys_var_enum::global_update(thd, var); - - unlock_slave_threads(active_mi); mysql_mutex_unlock(&LOCK_active_mi); + mysql_mutex_lock(&LOCK_global_system_variables); DBUG_RETURN(result); } + static Sys_var_replicate_events_marked_for_skip Replicate_events_marked_for_skip ("replicate_events_marked_for_skip", "Whether the slave should replicate events that were created with " @@ -2079,8 +2051,7 @@ static Sys_var_replicate_events_marked_for_skip Replicate_events_marked_for_skip "the slave).", GLOBAL_VAR(opt_replicate_events_marked_for_skip), CMD_LINE(REQUIRED_ARG), replicate_events_marked_for_skip_names, DEFAULT(RPL_SKIP_REPLICATE), - NO_MUTEX_GUARD, NOT_IN_BINLOG, - ON_CHECK(replicate_events_marked_for_skip_check)); + NO_MUTEX_GUARD, NOT_IN_BINLOG); #endif @@ -3255,71 +3226,18 @@ static Sys_var_mybool Sys_relay_log_recovery( "processed", GLOBAL_VAR(relay_log_recovery), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); -bool Sys_var_rpl_filter::do_check(THD *thd, set_var *var) -{ - bool status; - - /* - We must not be holding LOCK_global_system_variables here, otherwise we can - deadlock with THD::init() which is invoked from within the slave threads - with opposite locking order. - */ - mysql_mutex_assert_not_owner(&LOCK_global_system_variables); - - mysql_mutex_lock(&LOCK_active_mi); - mysql_mutex_lock(&active_mi->rli.run_lock); - - status= active_mi->rli.slave_running; - - mysql_mutex_unlock(&active_mi->rli.run_lock); - mysql_mutex_unlock(&LOCK_active_mi); - - if (status) - my_error(ER_SLAVE_MUST_STOP, MYF(0)); - else - status= Sys_var_charptr::do_string_check(thd, var, charset(thd)); - - return status; -} - -void Sys_var_rpl_filter::lock(void) -{ - /* - Starting a slave thread causes the new thread to attempt to - acquire LOCK_global_system_variables (in THD::init) while - LOCK_active_mi is being held by the thread that initiated - the process. In order to not violate the lock order, unlock - LOCK_global_system_variables before grabbing LOCK_active_mi. - */ - mysql_mutex_unlock(&LOCK_global_system_variables); - - mysql_mutex_lock(&LOCK_active_mi); - mysql_mutex_lock(&active_mi->rli.run_lock); -} - -void Sys_var_rpl_filter::unlock(void) -{ - mysql_mutex_unlock(&active_mi->rli.run_lock); - mysql_mutex_unlock(&LOCK_active_mi); - - mysql_mutex_lock(&LOCK_global_system_variables); -} bool Sys_var_rpl_filter::global_update(THD *thd, set_var *var) { - bool slave_running, status= false; + bool result= true; // Assume error - lock(); - - if (! (slave_running= active_mi->rli.slave_running)) - status= set_filter_value(var->save_result.string_value.str); - - if (slave_running) - my_error(ER_SLAVE_MUST_STOP, MYF(0)); - - unlock(); - - return slave_running || status; + mysql_mutex_unlock(&LOCK_global_system_variables); + mysql_mutex_lock(&LOCK_active_mi); + if (!master_info_index->give_error_if_slave_running()) + result= set_filter_value(var->save_result.string_value.str); + mysql_mutex_unlock(&LOCK_active_mi); + mysql_mutex_lock(&LOCK_global_system_variables); + return result; } bool Sys_var_rpl_filter::set_filter_value(const char *value) @@ -3357,8 +3275,6 @@ uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd, LEX_STRING *base) tmp.length(0); - lock(); - switch (opt_id) { case OPT_REPLICATE_DO_DB: rpl_filter->get_do_db(&tmp); @@ -3380,8 +3296,6 @@ uchar *Sys_var_rpl_filter::global_value_ptr(THD *thd, LEX_STRING *base) break; } - unlock(); - return (uchar *) thd->strmake(tmp.ptr(), tmp.length()); } @@ -3431,30 +3345,13 @@ static Sys_var_charptr Sys_slave_load_tmpdir( READ_ONLY GLOBAL_VAR(slave_load_tmpdir), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(0)); -static bool fix_slave_net_timeout(sys_var *self, THD *thd, enum_var_type type) -{ - DEBUG_SYNC(thd, "fix_slave_net_timeout"); - - mysql_mutex_unlock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_active_mi); - DBUG_PRINT("info", ("slave_net_timeout: %u mi->heartbeat_period: %.3f", - slave_net_timeout, - (active_mi? active_mi->heartbeat_period : 0.0))); - if (active_mi && slave_net_timeout < active_mi->heartbeat_period) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX, - ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX)); - mysql_mutex_unlock(&LOCK_active_mi); - mysql_mutex_lock(&LOCK_global_system_variables); - return false; -} static Sys_var_uint Sys_slave_net_timeout( "slave_net_timeout", "Number of seconds to wait for more data " - "from a master/slave connection before aborting the read", + "from any master/slave connection before aborting the read", GLOBAL_VAR(slave_net_timeout), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(SLAVE_NET_TIMEOUT), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), - ON_UPDATE(fix_slave_net_timeout)); + ON_UPDATE(0)); /* @@ -3509,7 +3406,8 @@ static bool update_slave_skip_counter(sys_var *self, THD *thd, Master_info *mi) { if (mi->rli.slave_running) { - my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0)); + my_error(ER_SLAVE_MUST_STOP, MYF(0), mi->connection_name.length, + mi->connection_name.str); return true; } /* The value was stored temporarly in thd */ diff --git a/sql/sys_vars.h b/sql/sys_vars.h index 8e832e57630..6c46c816105 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -566,11 +566,13 @@ public: option.var_type= GET_STR; } + bool do_check(THD *thd, set_var *var) + { + return Sys_var_charptr::do_string_check(thd, var, charset(thd)); + } bool check_update_type(Item_result type) { return type != STRING_RESULT; } - bool do_check(THD *thd, set_var *var); - void session_save_default(THD *thd, set_var *var) { DBUG_ASSERT(FALSE); } @@ -588,8 +590,6 @@ public: protected: uchar *global_value_ptr(THD *thd, LEX_STRING *base); bool set_filter_value(const char *value); - void lock(void); - void unlock(void); }; /** @@ -1937,10 +1937,9 @@ public: const char *comment, int flag_args, ptrdiff_t off, size_t size, CMD_LINE getopt, const char *values[], uint def_val, PolyLock *lock, - enum binlog_status_enum binlog_status_arg, - on_check_function on_check_func) + enum binlog_status_enum binlog_status_arg) :Sys_var_enum(name_arg, comment, flag_args, off, size, getopt, - values, def_val, lock, binlog_status_arg, on_check_func) + values, def_val, lock, binlog_status_arg) {} bool global_update(THD *thd, set_var *var); }; diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 2c65fd657a9..81f6cbe707f 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -1097,7 +1097,8 @@ static struct st_mysql_sys_var* example_system_variables[]= { NULL }; -// this is an example of SHOW_FUNC and of my_snprintf() service +// this is an example of SHOW_SIMPLE_FUNC and of my_snprintf() service +// If this function would return an array, one should use SHOW_FUNC static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var, char *buf) { @@ -1111,7 +1112,7 @@ static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var, static struct st_mysql_show_var func_status[]= { - {"example_func_example", (char *)show_func_example, SHOW_FUNC}, + {"example_func_example", (char *)show_func_example, SHOW_SIMPLE_FUNC}, {0,0,SHOW_UNDEF} }; diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc index 27a463bf61f..97e83cd9221 100644 --- a/storage/sphinx/ha_sphinx.cc +++ b/storage/sphinx/ha_sphinx.cc @@ -3591,12 +3591,12 @@ struct st_mysql_storage_engine sphinx_storage_engine = struct st_mysql_show_var sphinx_status_vars[] = { - {"sphinx_total", (char *)sphinx_showfunc_total, SHOW_FUNC}, - {"sphinx_total_found", (char *)sphinx_showfunc_total_found, SHOW_FUNC}, - {"sphinx_time", (char *)sphinx_showfunc_time, SHOW_FUNC}, - {"sphinx_word_count", (char *)sphinx_showfunc_word_count, SHOW_FUNC}, - {"sphinx_words", (char *)sphinx_showfunc_words, SHOW_FUNC}, - {"sphinx_error", (char *)sphinx_showfunc_error, SHOW_FUNC}, + {"sphinx_total", (char *)sphinx_showfunc_total, SHOW_SIMPLE_FUNC}, + {"sphinx_total_found", (char *)sphinx_showfunc_total_found, SHOW_SIMPLE_FUNC}, + {"sphinx_time", (char *)sphinx_showfunc_time, SHOW_SIMPLE_FUNC}, + {"sphinx_word_count", (char *)sphinx_showfunc_word_count, SHOW_SIMPLE_FUNC}, + {"sphinx_words", (char *)sphinx_showfunc_words, SHOW_SIMPLE_FUNC}, + {"sphinx_error", (char *)sphinx_showfunc_error, SHOW_SIMPLE_FUNC}, {0, 0, (enum_mysql_show_type)0} }; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 97a30a81d12..9acda7ed13e 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -3190,7 +3190,9 @@ innobase_commit_low( #ifdef MYSQL_SERVER THD *thd=current_thd; - if (thd && thd_is_replication_slave_thread(thd)) { + if (innobase_overwrite_relay_log_info && + thd && thd_is_replication_slave_thread(thd) && + thd->connection_name.length) { /* Update the replication position info inside InnoDB. In embedded server, does nothing. */ const char *log_file_name, *group_relay_log_name;