#At file:///Users/malff/BZR_TREE/mysql-next-mr-wl4816/ based on revid:marc.alff@strippeda47e7led
3205 Marc Alff 2010-10-25 [merge]
Merge mysql-next-mr --> mysql-next-mr-wl4816
added:
mysql-test/suite/sys_vars/r/master_info_repository_basic.result
mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result
mysql-test/suite/sys_vars/t/master_info_repository_basic.test
mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test
sql/rpl_info.cc
sql/rpl_info.h
sql/rpl_info_factory.cc
sql/rpl_info_factory.h
sql/rpl_info_file.cc
sql/rpl_info_file.h
sql/rpl_info_handler.cc
sql/rpl_info_handler.h
sql/server_ids.h
modified:
client/mysql.cc
client/mysqladmin.cc
client/mysqlbinlog.cc
client/mysqlcheck.c
client/mysqldump.c
client/mysqlimport.c
client/mysqlshow.c
include/mysql.h
include/mysql.h.pp
mysql-test/collections/default.experimental
mysql-test/include/show_binlog_using_logname.inc
mysql-test/r/mysql.result
mysql-test/r/mysqladmin.result
mysql-test/r/mysqld--help-notwin.result
mysql-test/r/mysqld--help-win.result
mysql-test/r/mysqldump.result
mysql-test/r/mysqlshow.result
mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result
mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result
mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result
mysql-test/suite/ndb_team/r/rpl_ndb_mix_innodb.result
mysql-test/suite/rpl/r/rpl_flushlog_loop.result
mysql-test/suite/rpl/r/rpl_rotate_logs.result
mysql-test/suite/rpl/r/rpl_stm_auto_increment_bug33029.result
mysql-test/suite/rpl/t/rpl_rotate_logs.test
mysql-test/suite/rpl/t/rpl_stm_auto_increment_bug33029.test
mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result
mysql-test/t/mysql.test
mysql-test/t/mysqladmin.test
mysql-test/t/mysqlbinlog.test
mysql-test/t/mysqlcheck.test
mysql-test/t/mysqldump.test
mysql-test/t/mysqlshow.test
mysys/mf_iocache2.c
sql-common/client.c
sql/CMakeLists.txt
sql/Makefile.am
sql/binlog.cc
sql/binlog.h
sql/ha_ndbcluster.cc
sql/item_func.cc
sql/lock.cc
sql/log.cc
sql/log_event.cc
sql/log_event_old.cc
sql/mysqld.cc
sql/rpl_handler.cc
sql/rpl_mi.cc
sql/rpl_mi.h
sql/rpl_reporting.h
sql/rpl_rli.cc
sql/rpl_rli.h
sql/rpl_slave.cc
sql/rpl_slave.h
sql/sql_binlog.cc
sql/sql_insert.cc
sql/sql_load.cc
sql/sys_vars.cc
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc 2010-09-01 13:46:08 +0000
+++ b/client/mysql.cc 2010-10-18 12:18:18 +0000
@@ -152,6 +152,7 @@ static ulong opt_max_allowed_packet, opt
static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0;
static uint my_end_arg;
static char * opt_mysql_unix_port=0;
+static char *opt_bind_addr = NULL;
static int connect_flag=CLIENT_INTERACTIVE;
static char *current_host,*current_db,*current_user=0,*opt_password=0,
*current_prompt=0, *delimiter_str= 0,
@@ -1376,6 +1377,9 @@ static struct my_option my_long_options[
{"batch", 'B',
"Don't use history file. Disable interactive behavior. (Enables --silent.)",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"bind-address", 0, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -4265,6 +4269,8 @@ sql_real_connect(char *host,char *databa
mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT,
(char*) &timeout);
}
+ if (opt_bind_addr)
+ mysql_options(&mysql, MYSQL_OPT_BIND, opt_bind_addr);
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
if (opt_secure_auth)
=== modified file 'client/mysqladmin.cc'
--- a/client/mysqladmin.cc 2010-07-15 11:13:30 +0000
+++ b/client/mysqladmin.cc 2010-10-18 12:18:18 +0000
@@ -41,6 +41,7 @@ static my_bool option_force=0,interrupte
static my_bool debug_info_flag= 0, debug_check_flag= 0;
static uint tcp_port = 0, option_wait = 0, option_silent=0, nr_iterations;
static uint opt_count_iterations= 0, my_end_arg;
+static char *opt_bind_addr = NULL;
static ulong opt_connect_timeout, opt_shutdown_timeout;
static char * unix_port=0;
@@ -116,6 +117,9 @@ static TYPELIB command_typelib=
static struct my_option my_long_options[] =
{
+ {"bind-address", 0, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"count", 'c',
"Number of iterations to make. This works with -i (--sleep) only.",
&nr_iterations, &nr_iterations, 0, GET_UINT,
@@ -318,6 +322,8 @@ int main(int argc,char *argv[])
(void) signal(SIGINT,endprog); /* Here if abort */
(void) signal(SIGTERM,endprog); /* Here if abort */
+ if (opt_bind_addr)
+ mysql_options(&mysql,MYSQL_OPT_BIND,opt_bind_addr);
if (opt_compress)
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
if (opt_connect_timeout)
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc 2010-09-01 02:51:08 +0000
+++ b/client/mysqlbinlog.cc 2010-10-18 12:18:18 +0000
@@ -89,6 +89,7 @@ static char *shared_memory_base_name= 0;
#endif
static char* user = 0;
static char* pass = 0;
+static char *opt_bind_addr = NULL;
static char *charset= 0;
static uint verbose= 0;
@@ -1024,6 +1025,9 @@ static struct my_option my_long_options[
"argument, 'always' is used.",
&opt_base64_output_mode_str, &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"bind-address", 0, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
/*
mysqlbinlog needs charsets knowledge, to be able to convert a charset
number found in binlog to a charset name (to be able to print things
@@ -1419,6 +1423,8 @@ static Exit_status safe_connect()
if (opt_protocol)
mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
+ if (opt_bind_addr)
+ mysql_options(mysql, MYSQL_OPT_BIND, opt_bind_addr);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
@@ -1627,9 +1633,9 @@ static Exit_status dump_remote_log_entri
for (;;)
{
- const char *error_msg;
- Log_event *ev;
- Log_event_type type;
+ const char *error_msg= NULL;
+ Log_event *ev= NULL;
+ Log_event_type type= UNKNOWN_EVENT;
len= cli_safe_read(mysql);
if (len == packet_error)
=== modified file 'client/mysqlcheck.c'
--- a/client/mysqlcheck.c 2010-07-15 13:47:50 +0000
+++ b/client/mysqlcheck.c 2010-10-18 12:18:18 +0000
@@ -47,6 +47,7 @@ DYNAMIC_ARRAY tables4repair;
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
+static char *opt_bind_addr = NULL;
enum operations { DO_CHECK, DO_REPAIR, DO_ANALYZE, DO_OPTIMIZE, DO_UPGRADE };
@@ -66,6 +67,9 @@ static struct my_option my_long_options[
"If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.",
&opt_auto_repair, &opt_auto_repair, 0, GET_BOOL, NO_ARG, 0,
0, 0, 0, 0, 0},
+ {"bind-address", 0, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -786,6 +790,8 @@ static int dbConnect(char *host, char *u
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_bind_addr)
+ mysql_options(&mysql_connection, MYSQL_OPT_BIND, opt_bind_addr);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
=== modified file 'client/mysqldump.c'
--- a/client/mysqldump.c 2010-08-30 12:11:53 +0000
+++ b/client/mysqldump.c 2010-10-18 12:18:18 +0000
@@ -125,6 +125,7 @@ static uint opt_mysql_port= 0, opt_maste
static uint opt_slave_data;
static uint my_end_arg;
static char * opt_mysql_unix_port=0;
+static char *opt_bind_addr = NULL;
static int first_error=0;
static DYNAMIC_STRING extended_row;
#include <sslopt-vars.h>
@@ -214,6 +215,9 @@ static struct my_option my_long_options[
"Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
&opt_slave_apply, &opt_slave_apply, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
+ {"bind-address", 0, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1449,6 +1453,8 @@ static int connect_to_db(char *host, cha
#endif
if (opt_protocol)
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_bind_addr)
+ mysql_options(&mysql_connection,MYSQL_OPT_BIND,opt_bind_addr);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
=== modified file 'client/mysqlimport.c'
--- a/client/mysqlimport.c 2010-07-15 11:13:30 +0000
+++ b/client/mysqlimport.c 2010-10-18 12:18:18 +0000
@@ -57,6 +57,7 @@ static char *opt_password=0, *current_us
*escaped=0, *opt_columns=0,
*default_charset= (char*) MYSQL_AUTODETECT_CHARSET_NAME;
static uint opt_mysql_port= 0, opt_protocol= 0;
+static char *opt_bind_addr = NULL;
static char * opt_mysql_unix_port=0;
static longlong opt_ignore_lines= -1;
#include <sslopt-vars.h>
@@ -67,6 +68,9 @@ static char *shared_memory_base_name=0;
static struct my_option my_long_options[] =
{
+ {"bind-address", 0, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -424,6 +428,8 @@ static MYSQL *db_connect(char *host, cha
#endif
if (opt_protocol)
mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_bind_addr)
+ mysql_options(mysql,MYSQL_OPT_BIND,opt_bind_addr);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
=== modified file 'client/mysqlshow.c'
--- a/client/mysqlshow.c 2010-07-15 13:47:50 +0000
+++ b/client/mysqlshow.c 2010-10-18 12:18:18 +0000
@@ -38,6 +38,7 @@ static char *default_charset= (char*) MY
static char *shared_memory_base_name=0;
#endif
static uint opt_protocol=0;
+static char *opt_bind_addr = NULL;
static void get_options(int *argc,char ***argv);
static uint opt_mysql_port=0;
@@ -117,6 +118,8 @@ int main(int argc, char **argv)
#endif
if (opt_protocol)
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_bind_addr)
+ mysql_options(&mysql,MYSQL_OPT_BIND,opt_bind_addr);
#ifdef HAVE_SMEM
if (shared_memory_base_name)
mysql_options(&mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
@@ -160,6 +163,9 @@ int main(int argc, char **argv)
static struct my_option my_long_options[] =
{
+ {"bind-address", 0, "IP address to bind to.",
+ (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", 'c', "Directory for character set files.",
&charsets_dir, &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0,
0, 0, 0, 0, 0},
=== modified file 'include/mysql.h'
--- a/include/mysql.h 2010-09-07 07:49:47 +0000
+++ b/include/mysql.h 2010-10-19 09:54:17 +0000
@@ -167,7 +167,7 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_OPT_BIND
};
struct st_mysql_options {
@@ -191,7 +191,20 @@ struct st_mysql_options {
my_bool unused3;
my_bool unused4;
enum mysql_option methods_to_use;
- char *client_ip;
+ union {
+ /*
+ The ip/hostname to use when authenticating
+ client against embedded server built with
+ grant tables - only used in embedded server
+ */
+ char *client_ip;
+
+ /*
+ The local address to bind when connecting to
+ remote server - not used in embedded server
+ */
+ char *bind_address;
+ } ci;
/* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */
my_bool secure_auth;
/* 0 - never report, 1 - always report (default) */
=== modified file 'include/mysql.h.pp'
--- a/include/mysql.h.pp 2010-09-10 08:06:58 +0000
+++ b/include/mysql.h.pp 2010-10-19 09:54:17 +0000
@@ -262,7 +262,7 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_OPT_BIND
};
struct st_mysql_options {
unsigned int connect_timeout, read_timeout, write_timeout;
@@ -285,7 +285,10 @@ struct st_mysql_options {
my_bool unused3;
my_bool unused4;
enum mysql_option methods_to_use;
- char *client_ip;
+ union {
+ char *client_ip;
+ char *bind_address;
+ } ci;
my_bool secure_auth;
my_bool report_data_truncation;
int (*local_infile_init)(void **, const char *, void *);
=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental 2010-09-28 15:30:47 +0000
+++ b/mysql-test/collections/default.experimental 2010-10-18 10:32:23 +0000
@@ -33,6 +33,7 @@ perfschema.server_init
rpl.rpl_heartbeat_basic # BUG#54820 2010-06-26 alik rpl.rpl_heartbeat_basic fails sporadically again
rpl.rpl_innodb_bug28430* # Bug#46029
rpl.rpl_row_sp011* @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
+rpl.rpl_delayed_slave # BUG#57514 rpl_delayed_slave fails sporadically in pb
sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
sys_vars.slow_query_log_func @solaris # Bug#54819 2010-06-26 alik sys_vars.slow_query_log_func fails sporadically on Solaris 10
=== modified file 'mysql-test/include/show_binlog_using_logname.inc'
--- a/mysql-test/include/show_binlog_using_logname.inc 2007-06-21 19:58:59 +0000
+++ b/mysql-test/include/show_binlog_using_logname.inc 2010-06-27 01:42:41 +0000
@@ -9,5 +9,5 @@
--replace_result $start_pos <start_pos> $end_pos <end_pos>
--replace_column 2 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
---eval show binlog events in '$log_name' from $start_pos limit $off_set,1
+--eval show binlog events in '$log_name' from $start_pos limit $end_pos,1
=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result 2010-08-25 08:17:15 +0000
+++ b/mysql-test/r/mysql.result 2010-10-20 10:50:50 +0000
@@ -434,3 +434,5 @@ Bug #47147: mysql client option --skip-c
1
End of tests
+Connected
+1
=== modified file 'mysql-test/r/mysqladmin.result'
--- a/mysql-test/r/mysqladmin.result 2006-11-10 12:25:10 +0000
+++ b/mysql-test/r/mysqladmin.result 2010-09-30 10:28:49 +0000
@@ -2,3 +2,4 @@ mysqld is alive
mysqladmin: unknown variable 'database=db1'
Warning: mysqladmin: unknown variable 'loose-database=db2'
mysqld is alive
+mysqld is alive
=== modified file 'mysql-test/r/mysqld--help-notwin.result'
--- a/mysql-test/r/mysqld--help-notwin.result 2010-10-11 16:43:09 +0000
+++ b/mysql-test/r/mysqld--help-notwin.result 2010-10-25 13:46:20 +0000
@@ -282,6 +282,9 @@ The following options may be given as th
The location and name of the file that remembers the
master and where the I/O replication thread is in the
master's binlogs.
+ --master-info-repository=name
+ Defines the type of the repository for the master
+ information.
--master-retry-count=#
The number of tries the slave will make to connect to the
master before giving up.
@@ -508,6 +511,9 @@ The following options may be given as th
--relay-log-info-file=name
The location and name of the file that remembers where
the SQL replication thread is in the relay logs
+ --relay-log-info-repository=name
+ Defines the type of the repository for the relay log
+ information.
--relay-log-purge if disabled - do not purge relay logs. if enabled - purge
them as soon as they are no more needed
(Defaults to on; use --skip-relay-log-purge to disable.)
@@ -822,6 +828,7 @@ long-query-time 10
low-priority-updates FALSE
lower-case-table-names 1
master-info-file master.info
+master-info-repository FILE
master-retry-count 86400
max-allowed-packet 1048576
max-binlog-cache-size 18446744073709547520
@@ -904,6 +911,7 @@ read-rnd-buffer-size 262144
relay-log (No default value)
relay-log-index (No default value)
relay-log-info-file relay-log.info
+relay-log-info-repository FILE
relay-log-purge TRUE
relay-log-recovery FALSE
relay-log-space-limit 0
=== modified file 'mysql-test/r/mysqld--help-win.result'
--- a/mysql-test/r/mysqld--help-win.result 2010-10-11 16:43:09 +0000
+++ b/mysql-test/r/mysqld--help-win.result 2010-10-25 13:46:20 +0000
@@ -281,6 +281,9 @@ The following options may be given as th
The location and name of the file that remembers the
master and where the I/O replication thread is in the
master's binlogs.
+ --master-info-repository=name
+ Defines the type of the repository for the master
+ information.
--master-retry-count=#
The number of tries the slave will make to connect to the
master before giving up.
@@ -508,6 +511,9 @@ The following options may be given as th
--relay-log-info-file=name
The location and name of the file that remembers where
the SQL replication thread is in the relay logs
+ --relay-log-info-repository=name
+ Defines the type of the repository for the relay log
+ information.
--relay-log-purge if disabled - do not purge relay logs. if enabled - purge
them as soon as they are no more needed
(Defaults to on; use --skip-relay-log-purge to disable.)
@@ -825,6 +831,7 @@ long-query-time 10
low-priority-updates FALSE
lower-case-table-names 1
master-info-file master.info
+master-info-repository FILE
master-retry-count 86400
max-allowed-packet 1048576
max-binlog-cache-size 18446744073709547520
@@ -908,6 +915,7 @@ read-rnd-buffer-size 262144
relay-log (No default value)
relay-log-index (No default value)
relay-log-info-file relay-log.info
+relay-log-info-repository FILE
relay-log-purge TRUE
relay-log-recovery FALSE
relay-log-space-limit 0
=== modified file 'mysql-test/r/mysqldump.result'
--- a/mysql-test/r/mysqldump.result 2010-08-30 06:38:09 +0000
+++ b/mysql-test/r/mysqldump.result 2010-10-18 12:18:18 +0000
@@ -4575,6 +4575,11 @@ SELECT LENGTH(a) FROM t2;
LENGTH(a)
800
DROP TABLE t1, t2;
+create table t1 (first char(28) , last varchar(37));
+insert into t1 values ("Magnus", "Blåudd");
+truncate table t1;
+test.t1: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
+drop table t1;
#
# End of 5.1 tests
#
=== modified file 'mysql-test/r/mysqlshow.result'
--- a/mysql-test/r/mysqlshow.result 2010-06-10 04:54:54 +0000
+++ b/mysql-test/r/mysqlshow.result 2010-10-18 12:18:18 +0000
@@ -181,4 +181,9 @@ Wildcard: inf_rmation_schema
+--------------------+
| information_schema |
+--------------------+
+Database: test
++--------+
+| Tables |
++--------+
++--------+
End of 5.0 tests
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result 2010-01-15 11:42:15 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result 2010-07-06 22:01:07 +0000
@@ -143,6 +143,33 @@ def mysql servers Server_name 1 NO char
def mysql servers Socket 7 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
def mysql servers Username 4 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
def mysql servers Wrapper 8 NO char 64 192 NULL NULL utf8 utf8_general_ci char(64)
+def mysql slave_master_info Connect_retry 9 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
+def mysql slave_master_info Enabled_ssl 10 NULL NO tinyint NULL NULL 3 0 NULL NULL tinyint(1)
+def mysql slave_master_info Heartbeat 17 NULL NO float NULL NULL 12 NULL NULL NULL float
+def mysql slave_master_info Host 5 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Ignored_server_ids 18 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Master_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
+def mysql slave_master_info Master_log_name 3 NULL NO text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Master_log_pos 4 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
+def mysql slave_master_info Number_of_lines 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
+def mysql slave_master_info Port 8 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
+def mysql slave_master_info Retry_count 19 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
+def mysql slave_master_info Ssl_ca 11 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Ssl_capath 12 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Ssl_cert 13 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Ssl_cipher 14 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Ssl_key 15 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Ssl_verify_servert_cert 16 NULL NO tinyint NULL NULL 3 0 NULL NULL tinyint(1)
+def mysql slave_master_info User_name 6 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info User_password 7 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_master_info Uuid 20 NULL YES text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_relay_log_info Master_id 1 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned PRI
+def mysql slave_relay_log_info Master_log_name 5 NULL NO text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_relay_log_info Master_log_pos 6 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
+def mysql slave_relay_log_info Number_of_lines 2 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
+def mysql slave_relay_log_info Relay_log_name 3 NULL NO text 65535 65535 NULL NULL utf8 utf8_bin text
+def mysql slave_relay_log_info Relay_log_pos 4 NULL NO int NULL NULL 10 0 NULL NULL int(10) unsigned
+def mysql slave_relay_log_info Sql_delay 7 NULL NO int NULL NULL 10 0 NULL NULL int(11)
def mysql slow_log db 7 NULL NO varchar 512 1536 NULL NULL utf8 utf8_general_ci varchar(512)
def mysql slow_log insert_id 9 NULL NO int NULL NULL 10 0 NULL NULL int(11)
def mysql slow_log last_insert_id 8 NULL NO int NULL NULL 10 0 NULL NULL int(11)
@@ -265,6 +292,7 @@ ORDER BY CHARACTER_SET_NAME, COLLATION_N
COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME
NULL bigint NULL NULL
NULL datetime NULL NULL
+NULL float NULL NULL
NULL int NULL NULL
NULL smallint NULL NULL
NULL time NULL NULL
@@ -427,6 +455,33 @@ NULL mysql servers Port int NULL NULL NU
3.0000 mysql servers Socket char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql servers Wrapper char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql servers Owner char 64 192 utf8 utf8_general_ci char(64)
+NULL mysql slave_master_info Master_id int NULL NULL NULL NULL int(10) unsigned
+NULL mysql slave_master_info Number_of_lines int NULL NULL NULL NULL int(10) unsigned
+1.0000 mysql slave_master_info Master_log_name text 65535 65535 utf8 utf8_bin text
+NULL mysql slave_master_info Master_log_pos int NULL NULL NULL NULL int(10) unsigned
+1.0000 mysql slave_master_info Host text 65535 65535 utf8 utf8_bin text
+1.0000 mysql slave_master_info User_name text 65535 65535 utf8 utf8_bin text
+1.0000 mysql slave_master_info User_password text 65535 65535 utf8 utf8_bin text
+NULL mysql slave_master_info Port int NULL NULL NULL NULL int(10) unsigned
+NULL mysql slave_master_info Connect_retry int NULL NULL NULL NULL int(10) unsigned
+NULL mysql slave_master_info Enabled_ssl tinyint NULL NULL NULL NULL tinyint(1)
+1.0000 mysql slave_master_info Ssl_ca text 65535 65535 utf8 utf8_bin text
+1.0000 mysql slave_master_info Ssl_capath text 65535 65535 utf8 utf8_bin text
+1.0000 mysql slave_master_info Ssl_cert text 65535 65535 utf8 utf8_bin text
+1.0000 mysql slave_master_info Ssl_cipher text 65535 65535 utf8 utf8_bin text
+1.0000 mysql slave_master_info Ssl_key text 65535 65535 utf8 utf8_bin text
+NULL mysql slave_master_info Ssl_verify_servert_cert tinyint NULL NULL NULL NULL tinyint(1)
+NULL mysql slave_master_info Heartbeat float NULL NULL NULL NULL float
+1.0000 mysql slave_master_info Ignored_server_ids text 65535 65535 utf8 utf8_bin text
+NULL mysql slave_master_info Retry_count int NULL NULL NULL NULL int(10) unsigned
+1.0000 mysql slave_master_info Uuid text 65535 65535 utf8 utf8_bin text
+NULL mysql slave_relay_log_info Master_id int NULL NULL NULL NULL int(10) unsigned
+NULL mysql slave_relay_log_info Number_of_lines int NULL NULL NULL NULL int(10) unsigned
+1.0000 mysql slave_relay_log_info Relay_log_name text 65535 65535 utf8 utf8_bin text
+NULL mysql slave_relay_log_info Relay_log_pos int NULL NULL NULL NULL int(10) unsigned
+1.0000 mysql slave_relay_log_info Master_log_name text 65535 65535 utf8 utf8_bin text
+NULL mysql slave_relay_log_info Master_log_pos int NULL NULL NULL NULL int(10) unsigned
+NULL mysql slave_relay_log_info Sql_delay int NULL NULL NULL NULL int(11)
NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp
1.0000 mysql slow_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext
NULL mysql slow_log query_time time NULL NULL NULL NULL time
=== modified file 'mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result'
--- a/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result 2009-10-23 11:02:20 +0000
+++ b/mysql-test/suite/funcs_1/r/is_statistics_mysql_embedded.result 2010-07-06 22:01:07 +0000
@@ -6,108 +6,112 @@ GRANT SELECT ON db_datadict.* TO testuse
SELECT * FROM information_schema.statistics
WHERE table_schema = 'mysql'
ORDER BY table_schema, table_name, index_name, seq_in_index, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT
-def mysql columns_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql columns_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql columns_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
-def mysql columns_priv 0 mysql PRIMARY 4 Table_name A #CARD# NULL NULL BTREE
-def mysql columns_priv 0 mysql PRIMARY 5 Column_name A #CARD# NULL NULL BTREE
-def mysql db 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql db 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql db 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
-def mysql db 1 mysql User 1 User A #CARD# NULL NULL BTREE
-def mysql event 0 mysql PRIMARY 1 db A #CARD# NULL NULL BTREE
-def mysql event 0 mysql PRIMARY 2 name A #CARD# NULL NULL BTREE
-def mysql func 0 mysql PRIMARY 1 name A #CARD# NULL NULL BTREE
-def mysql help_category 0 mysql name 1 name A #CARD# NULL NULL BTREE
-def mysql help_category 0 mysql PRIMARY 1 help_category_id A #CARD# NULL NULL BTREE
-def mysql help_keyword 0 mysql name 1 name A #CARD# NULL NULL BTREE
-def mysql help_keyword 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE
-def mysql help_relation 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE
-def mysql help_relation 0 mysql PRIMARY 2 help_topic_id A #CARD# NULL NULL BTREE
-def mysql help_topic 0 mysql name 1 name A #CARD# NULL NULL BTREE
-def mysql help_topic 0 mysql PRIMARY 1 help_topic_id A #CARD# NULL NULL BTREE
-def mysql host 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql host 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql ndb_binlog_index 0 mysql PRIMARY 1 epoch A #CARD# NULL NULL BTREE
-def mysql plugin 0 mysql PRIMARY 1 name A #CARD# NULL NULL BTREE
-def mysql proc 0 mysql PRIMARY 1 db A #CARD# NULL NULL BTREE
-def mysql proc 0 mysql PRIMARY 2 name A #CARD# NULL NULL BTREE
-def mysql proc 0 mysql PRIMARY 3 type A #CARD# NULL NULL BTREE
-def mysql procs_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 4 Routine_name A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 5 Routine_type A #CARD# NULL NULL BTREE
-def mysql servers 0 mysql PRIMARY 1 Server_name A #CARD# NULL NULL BTREE
-def mysql tables_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE
-def mysql tables_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql tables_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql tables_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
-def mysql tables_priv 0 mysql PRIMARY 4 Table_name A #CARD# NULL NULL BTREE
-def mysql time_zone 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
-def mysql time_zone_leap_second 0 mysql PRIMARY 1 Transition_time A #CARD# NULL NULL BTREE
-def mysql time_zone_name 0 mysql PRIMARY 1 Name A #CARD# NULL NULL BTREE
-def mysql time_zone_transition 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
-def mysql time_zone_transition 0 mysql PRIMARY 2 Transition_time A #CARD# NULL NULL BTREE
-def mysql time_zone_transition_type 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
-def mysql time_zone_transition_type 0 mysql PRIMARY 2 Transition_type_id A #CARD# NULL NULL BTREE
-def mysql user 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql user 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT
+def mysql columns_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql columns_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql columns_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
+def mysql columns_priv 0 mysql PRIMARY 4 Table_name A #CARD# NULL NULL BTREE
+def mysql columns_priv 0 mysql PRIMARY 5 Column_name A #CARD# NULL NULL BTREE
+def mysql db 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql db 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql db 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
+def mysql db 1 mysql User 1 User A #CARD# NULL NULL BTREE
+def mysql event 0 mysql PRIMARY 1 db A #CARD# NULL NULL BTREE
+def mysql event 0 mysql PRIMARY 2 name A #CARD# NULL NULL BTREE
+def mysql func 0 mysql PRIMARY 1 name A #CARD# NULL NULL BTREE
+def mysql help_category 0 mysql name 1 name A #CARD# NULL NULL BTREE
+def mysql help_category 0 mysql PRIMARY 1 help_category_id A #CARD# NULL NULL BTREE
+def mysql help_keyword 0 mysql name 1 name A #CARD# NULL NULL BTREE
+def mysql help_keyword 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE
+def mysql help_relation 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE
+def mysql help_relation 0 mysql PRIMARY 2 help_topic_id A #CARD# NULL NULL BTREE
+def mysql help_topic 0 mysql name 1 name A #CARD# NULL NULL BTREE
+def mysql help_topic 0 mysql PRIMARY 1 help_topic_id A #CARD# NULL NULL BTREE
+def mysql host 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql host 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql ndb_binlog_index 0 mysql PRIMARY 1 epoch A #CARD# NULL NULL BTREE
+def mysql plugin 0 mysql PRIMARY 1 name A #CARD# NULL NULL BTREE
+def mysql proc 0 mysql PRIMARY 1 db A #CARD# NULL NULL BTREE
+def mysql proc 0 mysql PRIMARY 2 name A #CARD# NULL NULL BTREE
+def mysql proc 0 mysql PRIMARY 3 type A #CARD# NULL NULL BTREE
+def mysql procs_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 4 Routine_name A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 5 Routine_type A #CARD# NULL NULL BTREE
+def mysql servers 0 mysql PRIMARY 1 Server_name A #CARD# NULL NULL BTREE
+def mysql slave_master_info 0 mysql PRIMARY 1 Master_id A #CARD# NULL NULL BTREE
+def mysql slave_relay_log_info 0 mysql PRIMARY 1 Master_id A #CARD# NULL NULL BTREE
+def mysql tables_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE
+def mysql tables_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql tables_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql tables_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
+def mysql tables_priv 0 mysql PRIMARY 4 Table_name A #CARD# NULL NULL BTREE
+def mysql time_zone 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
+def mysql time_zone_leap_second 0 mysql PRIMARY 1 Transition_time A #CARD# NULL NULL BTREE
+def mysql time_zone_name 0 mysql PRIMARY 1 Name A #CARD# NULL NULL BTREE
+def mysql time_zone_transition 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
+def mysql time_zone_transition 0 mysql PRIMARY 2 Transition_time A #CARD# NULL NULL BTREE
+def mysql time_zone_transition_type 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
+def mysql time_zone_transition_type 0 mysql PRIMARY 2 Transition_type_id A #CARD# NULL NULL BTREE
+def mysql user 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql user 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE
# Establish connection testuser1 (user=testuser1)
SELECT * FROM information_schema.statistics
WHERE table_schema = 'mysql'
ORDER BY table_schema, table_name, index_name, seq_in_index, column_name;
-TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT
-def mysql columns_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql columns_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql columns_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
-def mysql columns_priv 0 mysql PRIMARY 4 Table_name A #CARD# NULL NULL BTREE
-def mysql columns_priv 0 mysql PRIMARY 5 Column_name A #CARD# NULL NULL BTREE
-def mysql db 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql db 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql db 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
-def mysql db 1 mysql User 1 User A #CARD# NULL NULL BTREE
-def mysql event 0 mysql PRIMARY 1 db A #CARD# NULL NULL BTREE
-def mysql event 0 mysql PRIMARY 2 name A #CARD# NULL NULL BTREE
-def mysql func 0 mysql PRIMARY 1 name A #CARD# NULL NULL BTREE
-def mysql help_category 0 mysql name 1 name A #CARD# NULL NULL BTREE
-def mysql help_category 0 mysql PRIMARY 1 help_category_id A #CARD# NULL NULL BTREE
-def mysql help_keyword 0 mysql name 1 name A #CARD# NULL NULL BTREE
-def mysql help_keyword 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE
-def mysql help_relation 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE
-def mysql help_relation 0 mysql PRIMARY 2 help_topic_id A #CARD# NULL NULL BTREE
-def mysql help_topic 0 mysql name 1 name A #CARD# NULL NULL BTREE
-def mysql help_topic 0 mysql PRIMARY 1 help_topic_id A #CARD# NULL NULL BTREE
-def mysql host 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql host 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql ndb_binlog_index 0 mysql PRIMARY 1 epoch A #CARD# NULL NULL BTREE
-def mysql plugin 0 mysql PRIMARY 1 name A #CARD# NULL NULL BTREE
-def mysql proc 0 mysql PRIMARY 1 db A #CARD# NULL NULL BTREE
-def mysql proc 0 mysql PRIMARY 2 name A #CARD# NULL NULL BTREE
-def mysql proc 0 mysql PRIMARY 3 type A #CARD# NULL NULL BTREE
-def mysql procs_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 4 Routine_name A #CARD# NULL NULL BTREE
-def mysql procs_priv 0 mysql PRIMARY 5 Routine_type A #CARD# NULL NULL BTREE
-def mysql servers 0 mysql PRIMARY 1 Server_name A #CARD# NULL NULL BTREE
-def mysql tables_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE
-def mysql tables_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql tables_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
-def mysql tables_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
-def mysql tables_priv 0 mysql PRIMARY 4 Table_name A #CARD# NULL NULL BTREE
-def mysql time_zone 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
-def mysql time_zone_leap_second 0 mysql PRIMARY 1 Transition_time A #CARD# NULL NULL BTREE
-def mysql time_zone_name 0 mysql PRIMARY 1 Name A #CARD# NULL NULL BTREE
-def mysql time_zone_transition 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
-def mysql time_zone_transition 0 mysql PRIMARY 2 Transition_time A #CARD# NULL NULL BTREE
-def mysql time_zone_transition_type 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
-def mysql time_zone_transition_type 0 mysql PRIMARY 2 Transition_type_id A #CARD# NULL NULL BTREE
-def mysql user 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
-def mysql user 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE
+TABLE_CATALOG TABLE_SCHEMA TABLE_NAME NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLUMN_NAME COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT INDEX_COMMENT
+def mysql columns_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql columns_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql columns_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
+def mysql columns_priv 0 mysql PRIMARY 4 Table_name A #CARD# NULL NULL BTREE
+def mysql columns_priv 0 mysql PRIMARY 5 Column_name A #CARD# NULL NULL BTREE
+def mysql db 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql db 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql db 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
+def mysql db 1 mysql User 1 User A #CARD# NULL NULL BTREE
+def mysql event 0 mysql PRIMARY 1 db A #CARD# NULL NULL BTREE
+def mysql event 0 mysql PRIMARY 2 name A #CARD# NULL NULL BTREE
+def mysql func 0 mysql PRIMARY 1 name A #CARD# NULL NULL BTREE
+def mysql help_category 0 mysql name 1 name A #CARD# NULL NULL BTREE
+def mysql help_category 0 mysql PRIMARY 1 help_category_id A #CARD# NULL NULL BTREE
+def mysql help_keyword 0 mysql name 1 name A #CARD# NULL NULL BTREE
+def mysql help_keyword 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE
+def mysql help_relation 0 mysql PRIMARY 1 help_keyword_id A #CARD# NULL NULL BTREE
+def mysql help_relation 0 mysql PRIMARY 2 help_topic_id A #CARD# NULL NULL BTREE
+def mysql help_topic 0 mysql name 1 name A #CARD# NULL NULL BTREE
+def mysql help_topic 0 mysql PRIMARY 1 help_topic_id A #CARD# NULL NULL BTREE
+def mysql host 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql host 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql ndb_binlog_index 0 mysql PRIMARY 1 epoch A #CARD# NULL NULL BTREE
+def mysql plugin 0 mysql PRIMARY 1 name A #CARD# NULL NULL BTREE
+def mysql proc 0 mysql PRIMARY 1 db A #CARD# NULL NULL BTREE
+def mysql proc 0 mysql PRIMARY 2 name A #CARD# NULL NULL BTREE
+def mysql proc 0 mysql PRIMARY 3 type A #CARD# NULL NULL BTREE
+def mysql procs_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 4 Routine_name A #CARD# NULL NULL BTREE
+def mysql procs_priv 0 mysql PRIMARY 5 Routine_type A #CARD# NULL NULL BTREE
+def mysql servers 0 mysql PRIMARY 1 Server_name A #CARD# NULL NULL BTREE
+def mysql slave_master_info 0 mysql PRIMARY 1 Master_id A #CARD# NULL NULL BTREE
+def mysql slave_relay_log_info 0 mysql PRIMARY 1 Master_id A #CARD# NULL NULL BTREE
+def mysql tables_priv 1 mysql Grantor 1 Grantor A #CARD# NULL NULL BTREE
+def mysql tables_priv 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql tables_priv 0 mysql PRIMARY 2 Db A #CARD# NULL NULL BTREE
+def mysql tables_priv 0 mysql PRIMARY 3 User A #CARD# NULL NULL BTREE
+def mysql tables_priv 0 mysql PRIMARY 4 Table_name A #CARD# NULL NULL BTREE
+def mysql time_zone 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
+def mysql time_zone_leap_second 0 mysql PRIMARY 1 Transition_time A #CARD# NULL NULL BTREE
+def mysql time_zone_name 0 mysql PRIMARY 1 Name A #CARD# NULL NULL BTREE
+def mysql time_zone_transition 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
+def mysql time_zone_transition 0 mysql PRIMARY 2 Transition_time A #CARD# NULL NULL BTREE
+def mysql time_zone_transition_type 0 mysql PRIMARY 1 Time_zone_id A #CARD# NULL NULL BTREE
+def mysql time_zone_transition_type 0 mysql PRIMARY 2 Transition_type_id A #CARD# NULL NULL BTREE
+def mysql user 0 mysql PRIMARY 1 Host A #CARD# NULL NULL BTREE
+def mysql user 0 mysql PRIMARY 2 User A #CARD# NULL NULL BTREE
# Switch to connection default and close connection testuser1
DROP USER testuser1@localhost;
DROP DATABASE db_datadict;
=== modified file 'mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result'
--- a/mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result 2009-10-23 11:02:20 +0000
+++ b/mysql-test/suite/funcs_1/r/is_table_constraints_mysql_embedded.result 2010-07-06 22:01:07 +0000
@@ -24,6 +24,8 @@ def mysql PRIMARY mysql plugin PRIMARY K
def mysql PRIMARY mysql proc PRIMARY KEY
def mysql PRIMARY mysql procs_priv PRIMARY KEY
def mysql PRIMARY mysql servers PRIMARY KEY
+def mysql PRIMARY mysql slave_master_info PRIMARY KEY
+def mysql PRIMARY mysql slave_relay_log_info PRIMARY KEY
def mysql PRIMARY mysql tables_priv PRIMARY KEY
def mysql PRIMARY mysql time_zone PRIMARY KEY
def mysql PRIMARY mysql time_zone_leap_second PRIMARY KEY
@@ -53,6 +55,8 @@ def mysql PRIMARY mysql plugin PRIMARY K
def mysql PRIMARY mysql proc PRIMARY KEY
def mysql PRIMARY mysql procs_priv PRIMARY KEY
def mysql PRIMARY mysql servers PRIMARY KEY
+def mysql PRIMARY mysql slave_master_info PRIMARY KEY
+def mysql PRIMARY mysql slave_relay_log_info PRIMARY KEY
def mysql PRIMARY mysql tables_priv PRIMARY KEY
def mysql PRIMARY mysql time_zone PRIMARY KEY
def mysql PRIMARY mysql time_zone_leap_second PRIMARY KEY
=== modified file 'mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result'
--- a/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result 2009-10-23 11:02:20 +0000
+++ b/mysql-test/suite/funcs_1/r/is_tables_mysql_embedded.result 2010-07-06 22:01:07 +0000
@@ -359,6 +359,52 @@ user_comment MySQL Foreign Servers table
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA mysql
+TABLE_NAME slave_master_info
+TABLE_TYPE BASE TABLE
+ENGINE MyISAM
+VERSION 10
+ROW_FORMAT Dynamic
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment Master Information
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA mysql
+TABLE_NAME slave_relay_log_info
+TABLE_TYPE BASE TABLE
+ENGINE MyISAM
+VERSION 10
+ROW_FORMAT Dynamic
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment Relay Log Information
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA mysql
TABLE_NAME slow_log
TABLE_TYPE BASE TABLE
ENGINE CSV
@@ -904,6 +950,52 @@ user_comment MySQL Foreign Servers table
Separator -----------------------------------------------------
TABLE_CATALOG def
TABLE_SCHEMA mysql
+TABLE_NAME slave_master_info
+TABLE_TYPE BASE TABLE
+ENGINE MyISAM
+VERSION 10
+ROW_FORMAT Dynamic
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment Master Information
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA mysql
+TABLE_NAME slave_relay_log_info
+TABLE_TYPE BASE TABLE
+ENGINE MyISAM
+VERSION 10
+ROW_FORMAT Dynamic
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment Relay Log Information
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA mysql
TABLE_NAME slow_log
TABLE_TYPE BASE TABLE
ENGINE CSV
=== modified file 'mysql-test/suite/ndb_team/r/rpl_ndb_mix_innodb.result'
--- a/mysql-test/suite/ndb_team/r/rpl_ndb_mix_innodb.result 2010-05-24 13:54:08 +0000
+++ b/mysql-test/suite/ndb_team/r/rpl_ndb_mix_innodb.result 2010-06-27 01:42:41 +0000
@@ -103,9 +103,8 @@ from mysql.ndb_apply_status;
@log_name:=log_name @start_pos:=start_pos @end_pos:=end_pos
<log_name> <start_pos> <end_pos>
-show binlog events in 'master-bin.000001' from <start_pos> limit 9,1;
+show binlog events in 'master-bin.000001' from <start_pos> limit <end_pos>,1;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Xid 1 <end_pos> COMMIT /* XID */
** Test 3 **
@@ -116,9 +115,8 @@ from mysql.ndb_apply_status;
@log_name:=log_name @start_pos:=start_pos @end_pos:=end_pos
<log_name> <start_pos> <end_pos>
-show binlog events in 'master-bin.000002' from <start_pos> limit 9,1;
+show binlog events in 'master-bin.000002' from <start_pos> limit <end_pos>,1;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Xid 1 <end_pos> COMMIT /* XID */
** Test 4 **
@@ -134,9 +132,8 @@ from mysql.ndb_apply_status;
@log_name:=log_name @start_pos:=start_pos @end_pos:=end_pos
<log_name> <start_pos> <end_pos>
-show binlog events in 'master-bin.000001' from <start_pos> limit 9,1;
+show binlog events in 'master-bin.000001' from <start_pos> limit <end_pos>,1;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Xid 1 <end_pos> COMMIT /* XID */
*** DUMP MASTER & SLAVE FOR COMPARE ********
DROP DATABASE tpcb;
=== modified file 'mysql-test/suite/rpl/r/rpl_flushlog_loop.result'
--- a/mysql-test/suite/rpl/r/rpl_flushlog_loop.result 2010-07-27 14:04:13 +0000
+++ b/mysql-test/suite/rpl/r/rpl_flushlog_loop.result 2010-08-05 17:45:25 +0000
@@ -9,6 +9,7 @@ Variable_name Value
relay_log MYSQLD_DATADIR/relay-log
relay_log_index
relay_log_info_file relay-log.info
+relay_log_info_repository FILE
relay_log_purge ON
relay_log_recovery OFF
relay_log_space_limit 0
=== modified file 'mysql-test/suite/rpl/r/rpl_rotate_logs.result'
--- a/mysql-test/suite/rpl/r/rpl_rotate_logs.result 2010-07-27 14:04:13 +0000
+++ b/mysql-test/suite/rpl/r/rpl_rotate_logs.result 2010-08-05 17:45:25 +0000
@@ -1,5 +1,7 @@
drop table if exists t1, t2, t3, t4;
drop table if exists t1, t2, t3, t4;
+CALL mtr.add_suppression("Failed to open the existing info file");
+CALL mtr.add_suppression("Error while reading from master info file");
start slave;
Got one of the listed errors
start slave;
=== modified file 'mysql-test/suite/rpl/r/rpl_stm_auto_increment_bug33029.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_auto_increment_bug33029.result 2010-08-10 11:58:46 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_auto_increment_bug33029.result 2010-10-08 14:23:55 +0000
@@ -4,8 +4,12 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
-CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+DROP TABLE IF EXISTS t1, t2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP TRIGGER IF EXISTS tr1;
+DROP FUNCTION IF EXISTS f1;
CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY);
CREATE PROCEDURE p1()
=== modified file 'mysql-test/suite/rpl/t/rpl_rotate_logs.test'
--- a/mysql-test/suite/rpl/t/rpl_rotate_logs.test 2010-06-19 09:24:34 +0000
+++ b/mysql-test/suite/rpl/t/rpl_rotate_logs.test 2010-10-08 16:11:32 +0000
@@ -1,6 +1,5 @@
# This test uses chmod, can't be run with root permissions
-- source include/not_as_root.inc
-
-- source include/have_log_bin.inc
#
@@ -32,6 +31,11 @@ connection slave;
drop table if exists t1, t2, t3, t4;
--enable_warnings
+--disable_result_log
+CALL mtr.add_suppression("Failed to open the existing info file");
+CALL mtr.add_suppression("Error while reading from master info file");
+--enable_result_log
+
# START SLAVE will fail because it can't read the file (mode 000)
# (system error 13)
--replace_result $MYSQL_TEST_DIR TESTDIR
=== modified file 'mysql-test/suite/rpl/t/rpl_stm_auto_increment_bug33029.test'
--- a/mysql-test/suite/rpl/t/rpl_stm_auto_increment_bug33029.test 2010-04-28 12:47:49 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stm_auto_increment_bug33029.test 2010-10-08 14:23:55 +0000
@@ -11,11 +11,20 @@
source include/have_binlog_format_statement.inc;
source include/master-slave.inc;
-CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
---connection slave
-CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.");
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP TRIGGER IF EXISTS tr1;
+DROP FUNCTION IF EXISTS f1;
+--enable_warnings
+
+--sync_slave_with_master
--connection master
+
CREATE TABLE t1 (id INT AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE t2 (id INT AUTO_INCREMENT PRIMARY KEY);
=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result 2010-05-24 13:54:08 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_stm_innodb.result 2010-06-27 01:42:41 +0000
@@ -104,9 +104,8 @@ from mysql.ndb_apply_status;
@log_name:=log_name @start_pos:=start_pos @end_pos:=end_pos
<log_name> <start_pos> <end_pos>
-show binlog events in 'master-bin.000001' from <start_pos> limit 6,1;
+show binlog events in 'master-bin.000001' from <start_pos> limit <end_pos>,1;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Xid 1 <end_pos> COMMIT /* XID */
** Test 3 **
@@ -117,9 +116,8 @@ from mysql.ndb_apply_status;
@log_name:=log_name @start_pos:=start_pos @end_pos:=end_pos
<log_name> <start_pos> <end_pos>
-show binlog events in 'master-bin.000002' from <start_pos> limit 6,1;
+show binlog events in 'master-bin.000002' from <start_pos> limit <end_pos>,1;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Xid 1 <end_pos> COMMIT /* XID */
** Test 4 **
@@ -135,9 +133,8 @@ from mysql.ndb_apply_status;
@log_name:=log_name @start_pos:=start_pos @end_pos:=end_pos
<log_name> <start_pos> <end_pos>
-show binlog events in 'master-bin.000001' from <start_pos> limit 6,1;
+show binlog events in 'master-bin.000001' from <start_pos> limit <end_pos>,1;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Xid 1 <end_pos> COMMIT /* XID */
*** DUMP MASTER & SLAVE FOR COMPARE ********
DROP DATABASE tpcb;
=== added file 'mysql-test/suite/sys_vars/r/master_info_repository_basic.result'
--- a/mysql-test/suite/sys_vars/r/master_info_repository_basic.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/master_info_repository_basic.result 2010-07-06 22:01:07 +0000
@@ -0,0 +1,44 @@
+'#---------------------BS_STVARS_002_01----------------------#'
+SELECT @@GLOBAL.master_info_repository;
+@@GLOBAL.master_info_repository
+FILE
+SELECT COUNT(@@GLOBAL.master_info_repository);
+COUNT(@@GLOBAL.master_info_repository)
+1
+1 Expected
+SELECT COUNT(@@SESSION.master_info_repository);
+ERROR HY000: Variable 'master_info_repository' is a GLOBAL variable
+'#---------------------BS_STVARS_002_02----------------------#'
+SET @@GLOBAL.master_info_repository= "TABLE";
+ERROR HY000: Variable 'master_info_repository' is a read only variable
+SELECT @@GLOBAL.master_info_repository;
+@@GLOBAL.master_info_repository
+FILE
+'#---------------------BS_STVARS_002_03----------------------#'
+SELECT @@GLOBAL.master_info_repository = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='master_info_repository';
+@@GLOBAL.master_info_repository = VARIABLE_VALUE
+1
+1 Expected
+SELECT COUNT(@@GLOBAL.master_info_repository);
+COUNT(@@GLOBAL.master_info_repository)
+1
+1 Expected
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='master_info_repository';
+COUNT(VARIABLE_VALUE)
+1
+1 Expected
+'#---------------------BS_STVARS_002_05----------------------#'
+SELECT COUNT(@@master_info_repository);
+COUNT(@@master_info_repository)
+1
+1 Expected
+SELECT COUNT(@@local.master_info_repository);
+ERROR HY000: Variable 'master_info_repository' is a GLOBAL variable
+SELECT COUNT(@@GLOBAL.master_info_repository);
+COUNT(@@GLOBAL.master_info_repository)
+1
+1 Expected
=== added file 'mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result'
--- a/mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result 2010-07-06 22:01:07 +0000
@@ -0,0 +1,44 @@
+'#---------------------BS_STVARS_002_01----------------------#'
+SELECT @@GLOBAL.relay_log_info_repository;
+@@GLOBAL.relay_log_info_repository
+FILE
+SELECT COUNT(@@GLOBAL.relay_log_info_repository);
+COUNT(@@GLOBAL.relay_log_info_repository)
+1
+1 Expected
+SELECT COUNT(@@SESSION.relay_log_info_repository);
+ERROR HY000: Variable 'relay_log_info_repository' is a GLOBAL variable
+'#---------------------BS_STVARS_002_02----------------------#'
+SET @@GLOBAL.relay_log_info_repository= "TABLE";
+ERROR HY000: Variable 'relay_log_info_repository' is a read only variable
+SELECT @@GLOBAL.relay_log_info_repository;
+@@GLOBAL.relay_log_info_repository
+FILE
+'#---------------------BS_STVARS_002_03----------------------#'
+SELECT @@GLOBAL.relay_log_info_repository = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='relay_log_info_repository';
+@@GLOBAL.relay_log_info_repository = VARIABLE_VALUE
+1
+1 Expected
+SELECT COUNT(@@GLOBAL.relay_log_info_repository);
+COUNT(@@GLOBAL.relay_log_info_repository)
+1
+1 Expected
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='relay_log_info_repository';
+COUNT(VARIABLE_VALUE)
+1
+1 Expected
+'#---------------------BS_STVARS_002_05----------------------#'
+SELECT COUNT(@@relay_log_info_repository);
+COUNT(@@relay_log_info_repository)
+1
+1 Expected
+SELECT COUNT(@@local.relay_log_info_repository);
+ERROR HY000: Variable 'relay_log_info_repository' is a GLOBAL variable
+SELECT COUNT(@@GLOBAL.relay_log_info_repository);
+COUNT(@@GLOBAL.relay_log_info_repository)
+1
+1 Expected
=== added file 'mysql-test/suite/sys_vars/t/master_info_repository_basic.test'
--- a/mysql-test/suite/sys_vars/t/master_info_repository_basic.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/master_info_repository_basic.test 2010-10-08 16:11:32 +0000
@@ -0,0 +1,75 @@
+############## mysql-test\t\master_info_repository_basic.test #################
+# #
+# Variable Name: master_info_repository #
+# Scope: Global #
+# Access Type: Static #
+# Data Type: enumeration #
+# #
+# #
+# Creation Date: 2010-06-19 #
+# Author : Alfranio Correia #
+# #
+# #
+# Description:Test Cases of System Variable master_info_repository #
+# that checks the behavior of this variable in the following ways #
+# * Value Check #
+# * Scope Check #
+# #
+# Reference: #
+# http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html #
+# #
+###############################################################################
+
+--echo '#---------------------BS_STVARS_002_01----------------------#'
+####################################################################
+# Displaying default value #
+####################################################################
+SELECT @@GLOBAL.master_info_repository;
+
+SELECT COUNT(@@GLOBAL.master_info_repository);
+--echo 1 Expected
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@SESSION.master_info_repository);
+
+--echo '#---------------------BS_STVARS_002_02----------------------#'
+####################################################################
+# Check if Value can set #
+####################################################################
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@GLOBAL.master_info_repository= "TABLE";
+
+SELECT @@GLOBAL.master_info_repository;
+
+
+--echo '#---------------------BS_STVARS_002_03----------------------#'
+#################################################################
+# Check if the value in GLOBAL Table matches value in variable #
+#################################################################
+SELECT @@GLOBAL.master_info_repository = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='master_info_repository';
+--echo 1 Expected
+
+SELECT COUNT(@@GLOBAL.master_info_repository);
+--echo 1 Expected
+
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='master_info_repository';
+--echo 1 Expected
+
+
+--echo '#---------------------BS_STVARS_002_05----------------------#'
+################################################################################
+# Check if master_info_repository can be accessed with and without @@ sign #
+################################################################################
+
+SELECT COUNT(@@master_info_repository);
+--echo 1 Expected
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@local.master_info_repository);
+
+SELECT COUNT(@@GLOBAL.master_info_repository);
+--echo 1 Expected
=== added file 'mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test'
--- a/mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test 2010-10-08 16:11:32 +0000
@@ -0,0 +1,74 @@
+############# mysql-test\t\relay_log_info_repository_basic.test ###############
+# #
+# Variable Name: relay_log_info_repository #
+# Scope: Global #
+# Access Type: Static #
+# Data Type: enumeration #
+# #
+# #
+# Creation Date: 2010-06-19 #
+# Author : Alfranio Correia #
+# #
+# #
+# Description:Test Cases of System Variable relay_log_info_repository #
+# that checks the behavior of this variable in the following ways #
+# * Value Check #
+# * Scope Check #
+# #
+# Reference: #
+# http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html #
+# #
+###############################################################################
+--echo '#---------------------BS_STVARS_002_01----------------------#'
+####################################################################
+# Displaying default value #
+####################################################################
+SELECT @@GLOBAL.relay_log_info_repository;
+
+SELECT COUNT(@@GLOBAL.relay_log_info_repository);
+--echo 1 Expected
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@SESSION.relay_log_info_repository);
+
+--echo '#---------------------BS_STVARS_002_02----------------------#'
+####################################################################
+# Check if Value can set #
+####################################################################
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@GLOBAL.relay_log_info_repository= "TABLE";
+
+SELECT @@GLOBAL.relay_log_info_repository;
+
+
+--echo '#---------------------BS_STVARS_002_03----------------------#'
+#################################################################
+# Check if the value in GLOBAL Table matches value in variable #
+#################################################################
+SELECT @@GLOBAL.relay_log_info_repository = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='relay_log_info_repository';
+--echo 1 Expected
+
+SELECT COUNT(@@GLOBAL.relay_log_info_repository);
+--echo 1 Expected
+
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='relay_log_info_repository';
+--echo 1 Expected
+
+
+--echo '#---------------------BS_STVARS_002_05----------------------#'
+################################################################################
+# Check if relay_log_info_repository can be accessed with and without @@ sign #
+################################################################################
+
+SELECT COUNT(@@relay_log_info_repository);
+--echo 1 Expected
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@local.relay_log_info_repository);
+
+SELECT COUNT(@@GLOBAL.relay_log_info_repository);
+--echo 1 Expected
=== modified file 'mysql-test/t/mysql.test'
--- a/mysql-test/t/mysql.test 2010-08-25 08:17:15 +0000
+++ b/mysql-test/t/mysql.test 2010-10-20 10:50:50 +0000
@@ -427,3 +427,10 @@ drop table t1;
--echo
--echo End of tests
+
+
+#
+# WL#3126 TCP address binding for mysql client library;
+# - running mysql --protocol=tcp --bind-address=127.0.0.1
+#
+--exec $MYSQL --protocol=tcp --bind-address=127.0.0.1 -e "select 1 as Connected"
=== modified file 'mysql-test/t/mysqladmin.test'
--- a/mysql-test/t/mysqladmin.test 2009-10-21 12:59:47 +0000
+++ b/mysql-test/t/mysqladmin.test 2010-09-30 10:28:49 +0000
@@ -33,3 +33,9 @@ EOF
--exec $MYSQLADMIN --defaults-file=$MYSQLTEST_VARDIR/tmp/bug10608.cnf --default-character-set=latin1 -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1
remove_file $MYSQLTEST_VARDIR/tmp/bug10608.cnf;
+
+#
+# WL#3126 TCP address binding for mysql client library;
+# - running mysqladmin --protcol=tcp --bind-address=127.0.0.1
+#
+--exec $MYSQLADMIN --no-defaults --protocol=tcp --bind-address=127.0.0.1 --host=127.0.0.1 -P $MASTER_MYPORT -u root ping 2>&1
=== modified file 'mysql-test/t/mysqlbinlog.test'
--- a/mysql-test/t/mysqlbinlog.test 2010-09-01 02:51:08 +0000
+++ b/mysql-test/t/mysqlbinlog.test 2010-10-18 12:18:18 +0000
@@ -487,3 +487,10 @@ diff_files $MYSQLTEST_VARDIR/tmp/mysqlbi
# Cleanup for this part of test
remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn.empty;
remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn;
+
+#
+# WL#3126 TCP address binding for mysql client library;
+# - running mysqlbinlog --protocol=tcp --bind-address=127.0.0.1
+#
+--exec $MYSQL_BINLOG --short-form --read-from-remote-server --protocol=tcp --bind-address=127.0.0.1 master-bin.000001 > /dev/null
+
=== modified file 'mysql-test/t/mysqlcheck.test'
--- a/mysql-test/t/mysqlcheck.test 2009-10-21 12:59:47 +0000
+++ b/mysql-test/t/mysqlcheck.test 2010-09-30 10:28:49 +0000
@@ -211,4 +211,11 @@ create table `#mysql50#t1-1` (a int);
show tables like 't1-1';
drop table `t1-1`;
+#
+# WL#3126 TCP address binding for mysql client library;
+# - running mysqlcheck --protcol=tcp --bind-address=127.0.0.1
+#
+--exec $MYSQL_CHECK --protocol=tcp --bind-address=127.0.0.1 --databases test
+
--echo End of 5.1 tests
+
=== modified file 'mysql-test/t/mysqldump.test'
--- a/mysql-test/t/mysqldump.test 2010-07-05 11:57:49 +0000
+++ b/mysql-test/t/mysqldump.test 2010-10-18 12:18:18 +0000
@@ -2168,6 +2168,18 @@ SELECT LENGTH(a) FROM t2;
DROP TABLE t1, t2;
+#
+# WL#3126 TCP address binding for mysql client library;
+# - running mysqldump --protocol=tcp --bind-address=127.0.0.1
+# - running mysqlimport --protocol=tcp --bind-address=127.0.0.1
+#
+create table t1 (first char(28) , last varchar(37));
+insert into t1 values ("Magnus", "Blåudd");
+--exec $MYSQL_DUMP --protocol=tcp --bind-address=127.0.0.1 --tab=$MYSQLTEST_VARDIR/tmp/ test
+truncate table t1;
+--exec $MYSQL_IMPORT --protocol=tcp --bind-address=127.0.0.1 test $MYSQLTEST_VARDIR/tmp/t1.txt
+drop table t1;
+
###########################################################################
--echo #
--echo # End of 5.1 tests
=== modified file 'mysql-test/t/mysqlshow.test'
--- a/mysql-test/t/mysqlshow.test 2009-08-07 20:04:53 +0000
+++ b/mysql-test/t/mysqlshow.test 2010-09-30 10:28:49 +0000
@@ -35,4 +35,10 @@ DROP TABLE t1, t2;
--exec $MYSQL_SHOW INFORMATION_SCHEMA
--exec $MYSQL_SHOW inf_rmation_schema
+#
+# WL#3126 TCP address binding for mysql client library;
+# - running mysqlshow --protcol=tcp --bind-address=127.0.0.1
+#
+--exec $MYSQL_SHOW --protocol=tcp --bind-address=127.0.0.1 test
+
--echo End of 5.0 tests
=== modified file 'mysys/mf_iocache2.c'
--- a/mysys/mf_iocache2.c 2010-07-23 20:16:29 +0000
+++ b/mysys/mf_iocache2.c 2010-10-14 17:20:07 +0000
@@ -418,7 +418,7 @@ process_flags:
{
register int iarg;
size_t length2;
- char buff[17];
+ char buff[32];
iarg = va_arg(args, int);
if (*fmt == 'd')
@@ -449,7 +449,7 @@ process_flags:
{
register long iarg;
size_t length2;
- char buff[17];
+ char buff[32];
iarg = va_arg(args, long);
if (*++fmt == 'd')
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2010-07-15 11:41:37 +0000
+++ b/sql-common/client.c 2010-10-19 09:54:17 +0000
@@ -1145,7 +1145,7 @@ static const char *default_options[]=
"connect-timeout", "local-infile", "disable-local-infile",
"ssl-cipher", "max-allowed-packet", "protocol", "shared-memory-base-name",
"multi-results", "multi-statements", "multi-queries", "secure-auth",
- "report-data-truncation",
+ "report-data-truncation", "bind-address",
NullS
};
@@ -1354,6 +1354,10 @@ void mysql_read_default_options(struct s
case 31: /* report-data-truncation */
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
break;
+ case 32: /* bind-address */
+ my_free(options->ci.bind_address);
+ options->ci.bind_address= my_strdup(opt_arg, MYF(MY_WME));
+ break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
}
@@ -2429,11 +2433,11 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
(!mysql->options.protocol ||
mysql->options.protocol == MYSQL_PROTOCOL_TCP))
{
- struct addrinfo *res_lst, hints, *t_res;
+ struct addrinfo *res_lst, *client_bind_ai_lst= NULL, hints, *t_res;
int gai_errno;
char port_buf[NI_MAXSERV];
my_socket sock= SOCKET_ERROR;
- int saved_error= 0, status= -1;
+ int saved_error= 0, status= -1, bind_result= 0;
unix_socket=0; /* This is not used */
@@ -2478,9 +2482,35 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
goto error;
}
+ /* Get address info for client bind name if it is provided */
+ if (mysql->options.ci.bind_address)
+ {
+ int bind_gai_errno= 0;
+
+ DBUG_PRINT("info",("Resolving addresses for client bind: '%s'",
+ mysql->options.ci.bind_address));
+ /* Lookup address info for name */
+ bind_gai_errno= getaddrinfo(mysql->options.ci.bind_address, 0,
+ &hints, &client_bind_ai_lst);
+ if (bind_gai_errno)
+ {
+ DBUG_PRINT("info",("client bind getaddrinfo error %d", bind_gai_errno));
+ set_mysql_extended_error(mysql, CR_UNKNOWN_HOST, unknown_sqlstate,
+ ER(CR_UNKNOWN_HOST),
+ mysql->options.ci.bind_address,
+ bind_gai_errno);
+
+ freeaddrinfo(res_lst);
+ goto error;
+ }
+ DBUG_PRINT("info", (" got address info for client bind name"));
+ }
+
/*
A hostname might map to multiple IP addresses (IPv4/IPv6). Go over the
list of IP addresses until a successful connection can be established.
+ For each IP address, attempt to bind the socket to each client address
+ for the client-side bind hostname until the bind is successful.
*/
DBUG_PRINT("info", ("Try connect on all addresses for host."));
for (t_res= res_lst; t_res; t_res= t_res->ai_next)
@@ -2488,13 +2518,57 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
DBUG_PRINT("info", ("Create socket, family: %d type: %d proto: %d",
t_res->ai_family, t_res->ai_socktype,
t_res->ai_protocol));
+
sock= socket(t_res->ai_family, t_res->ai_socktype, t_res->ai_protocol);
if (sock == SOCKET_ERROR)
{
+ DBUG_PRINT("info", ("Socket created was invalid"));
+ /* Try next address if there is one */
saved_error= socket_errno;
continue;
}
+ if (client_bind_ai_lst)
+ {
+ struct addrinfo* curr_bind_ai= NULL;
+ DBUG_PRINT("info", ("Attempting to bind socket to bind address(es)"));
+
+ /*
+ We'll attempt to bind to each of the addresses returned, until
+ we find one that works.
+ If none works, we'll try the next destination host address
+ (if any)
+ */
+ curr_bind_ai= client_bind_ai_lst;
+
+ while (curr_bind_ai != NULL)
+ {
+ /* Attempt to bind the socket to the given address */
+ bind_result= bind(sock,
+ curr_bind_ai->ai_addr,
+ curr_bind_ai->ai_addrlen);
+ if (!bind_result)
+ break; /* Success */
+
+ DBUG_PRINT("info", ("bind failed, attempting another bind address"));
+ /* Problem with the bind, move to next address if present */
+ curr_bind_ai= curr_bind_ai->ai_next;
+ }
+
+ if (bind_result)
+ {
+ /*
+ Could not bind to any client-side address with this destination
+ Try the next destination address (if any)
+ */
+ DBUG_PRINT("info", ("All bind attempts with this address failed"));
+ saved_error= socket_errno;
+ closesocket(sock);
+ continue;
+ }
+ DBUG_PRINT("info", ("Successfully bound client side of socket"));
+ }
+
DBUG_PRINT("info", ("Connect socket"));
status= my_connect(sock, t_res->ai_addr, t_res->ai_addrlen,
mysql->options.connect_timeout);
@@ -2520,6 +2594,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
sock, status, saved_error));
freeaddrinfo(res_lst);
+ if (client_bind_ai_lst)
+ freeaddrinfo(client_bind_ai_lst);
if (sock == SOCKET_ERROR)
{
@@ -3036,7 +3112,8 @@ static void mysql_close_free_options(MYS
my_free(mysql->options.my_cnf_group);
my_free(mysql->options.charset_dir);
my_free(mysql->options.charset_name);
- my_free(mysql->options.client_ip);
+ my_free(mysql->options.ci.client_ip);
+ /* ci.bind_adress is union with client_ip, already freed above */
if (mysql->options.init_commands)
{
DYNAMIC_ARRAY *init_commands= mysql->options.init_commands;
@@ -3511,7 +3588,7 @@ mysql_options(MYSQL *mysql,enum mysql_op
mysql->options.methods_to_use= option;
break;
case MYSQL_SET_CLIENT_IP:
- mysql->options.client_ip= my_strdup(arg, MYF(MY_WME));
+ mysql->options.ci.client_ip= my_strdup(arg, MYF(MY_WME));
break;
case MYSQL_SECURE_AUTH:
mysql->options.secure_auth= *(my_bool *) arg;
@@ -3522,6 +3599,10 @@ mysql_options(MYSQL *mysql,enum mysql_op
case MYSQL_OPT_RECONNECT:
mysql->reconnect= *(my_bool *) arg;
break;
+ case MYSQL_OPT_BIND:
+ my_free(mysql->options.ci.bind_address);
+ mysql->options.ci.bind_address= my_strdup(arg, MYF(MY_WME));
+ break;
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
if (*(my_bool*) arg)
mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt 2010-09-28 15:30:47 +0000
+++ b/sql/CMakeLists.txt 2010-10-08 16:11:32 +0000
@@ -102,7 +102,9 @@ SET (MASTER_SOURCE rpl_master.cc)
ADD_DEPENDENCIES(rpl GenError)
ADD_LIBRARY(master ${MASTER_SOURCE})
ADD_DEPENDENCIES(master GenError)
-SET (SLAVE_SOURCE rpl_slave.cc rpl_reporting.cc rpl_mi.cc rpl_rli.cc)
+SET (SLAVE_SOURCE rpl_slave.cc rpl_reporting.cc rpl_mi.cc rpl_rli.cc
+ rpl_info_handler.cc rpl_info_file.cc rpl_info.cc
+ rpl_info_factory.cc server_ids.h)
ADD_LIBRARY(slave ${SLAVE_SOURCE})
ADD_DEPENDENCIES(slave GenError)
ADD_LIBRARY(sqlgunitlib mdl.cc sql_list.cc sql_string.cc thr_malloc.cc)
=== modified file 'sql/Makefile.am'
--- a/sql/Makefile.am 2010-08-20 09:15:16 +0000
+++ b/sql/Makefile.am 2010-10-08 16:11:32 +0000
@@ -107,7 +107,10 @@ noinst_HEADERS = item.h item_func.h item
debug_sync.h \
opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \
rpl_reporting.h sql_locale.h sql_parse.h \
- log.h sql_show.h rpl_rli.h rpl_mi.h \
+ rpl_info_handler.h \
+ log.h sql_show.h rpl_info.h rpl_info_file.h \
+ rpl_rli.h rpl_mi.h \
+ rpl_info_factory.h server_ids.h \
sql_select.h structs.h table.h sql_udf.h hash_filo.h \
lex.h lex_symbol.h sql_acl.h sql_crypt.h sql_base.h \
sql_table.h key.h lock.h thr_malloc.h strfunc.h \
@@ -188,8 +191,9 @@ libbinlog_la_SOURCES = log_event.cc log_
rpl_utility.cc sql_binlog.cc rpl_injector.cc
librpl_la_SOURCES = rpl_handler.cc rpl_tblmap.cc
libmaster_la_SOURCES = rpl_master.cc
-libslave_la_SOURCES = rpl_slave.cc rpl_reporting.cc rpl_rli.cc rpl_mi.cc
-
+libslave_la_SOURCES = rpl_slave.cc rpl_reporting.cc rpl_rli.cc rpl_mi.cc \
+ rpl_info.cc rpl_info_factory.cc rpl_info_file.cc \
+ rpl_info_handler.cc
libndb_la_CPPFLAGS= @ndbcluster_includes@
libndb_la_SOURCES= ha_ndbcluster.cc \
ha_ndbcluster_binlog.cc \
=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc 2010-10-03 23:42:39 +0000
+++ b/sql/binlog.cc 2010-10-08 14:35:24 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
#include "rpl_rli.h"
#include "sql_plugin.h"
#include "rpl_handler.h"
+#include "rpl_info_factory.h"
#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
@@ -2097,25 +2098,25 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
DBUG_ASSERT(is_open());
DBUG_ASSERT(rli->slave_running == 1);
- DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name));
+ DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->get_event_relay_log_name()));
mysql_mutex_assert_owner(&rli->data_lock);
mysql_mutex_lock(&LOCK_index);
- to_purge_if_included= my_strdup(rli->group_relay_log_name, MYF(0));
+ to_purge_if_included= my_strdup(rli->get_group_relay_log_name(), MYF(0));
/*
Read the next log file name from the index file and pass it back to
the caller.
*/
- if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) ||
+ if((error=find_log_pos(&rli->linfo, rli->get_event_relay_log_name(), 0)) ||
(error=find_next_log(&rli->linfo, 0)))
{
char buff[22];
sql_print_error("next log error: %d offset: %s log: %s included: %d",
error,
llstr(rli->linfo.index_file_offset,buff),
- rli->event_relay_log_name,
+ rli->get_event_relay_log_name(),
included);
goto err;
}
@@ -2123,9 +2124,8 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
/*
Reset rli's coordinates to the current log.
*/
- rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
- strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->event_relay_log_name)-1);
+ rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
+ rli->set_event_relay_log_name(rli->linfo.log_file_name);
/*
If we removed the rli->group_relay_log_name file,
@@ -2134,14 +2134,13 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
*/
if (included)
{
- rli->group_relay_log_pos = BIN_LOG_HEADER_SIZE;
- strmake(rli->group_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->group_relay_log_name)-1);
+ rli->set_group_relay_log_pos(BIN_LOG_HEADER_SIZE);
+ rli->set_group_relay_log_name(rli->linfo.log_file_name);
rli->notify_group_relay_log_name_update();
}
/* Store where we are in the new file for the execution thread */
- flush_relay_log_info(rli);
+ rli->flush_info(TRUE);
DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_ABORT(););
@@ -2163,13 +2162,13 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
* Need to update the log pos because purge logs has been called
* after fetching initially the log pos at the begining of the method.
*/
- if((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)))
+ if((error=find_log_pos(&rli->linfo, rli->get_event_relay_log_name(), 0)))
{
char buff[22];
sql_print_error("next log error: %d offset: %s log: %s included: %d",
error,
llstr(rli->linfo.index_file_offset,buff),
- rli->group_relay_log_name,
+ rli->get_group_relay_log_name(),
included);
goto err;
}
@@ -2890,7 +2889,7 @@ err:
DBUG_RETURN(error);
}
-bool MYSQL_BIN_LOG::flush_and_sync(bool *synced)
+bool MYSQL_BIN_LOG::flush_and_sync(bool *synced, const bool force)
{
int err=0, fd=log_file.file;
if (synced)
@@ -2899,7 +2898,8 @@ bool MYSQL_BIN_LOG::flush_and_sync(bool
if (flush_io_cache(&log_file))
return 1;
uint sync_period= get_sync_period();
- if (sync_period && ++sync_counter >= sync_period)
+ if (force ||
+ (sync_period && ++sync_counter >= sync_period))
{
sync_counter= 0;
err= mysql_file_sync(fd, MYF(MY_WME));
=== modified file 'sql/binlog.h'
--- a/sql/binlog.h 2010-09-17 13:22:22 +0000
+++ b/sql/binlog.h 2010-10-04 10:16:31 +0000
@@ -194,11 +194,12 @@ public:
be set to 1, otherwise 0.
@param[out] synced if not NULL, set to 1 if file is synchronized, otherwise 0
+ @param[in] force if TRUE, ignores the 'sync_binlog' and synchronizes the file.
@retval 0 Success
@retval other Failure
*/
- bool flush_and_sync(bool *synced);
+ bool flush_and_sync(bool *synced, const bool force=FALSE);
int purge_logs(const char *to_log, bool included,
bool need_mutex, bool need_update_threads,
ulonglong *decrease_log_space);
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2010-08-20 09:15:16 +0000
+++ b/sql/ha_ndbcluster.cc 2010-09-06 11:10:01 +0000
@@ -4587,17 +4587,17 @@ static int ndbcluster_update_apply_statu
// log_name
char tmp_buf[FN_REFLEN];
ndb_pack_varchar(ndbtab->getColumn(2u), tmp_buf,
- active_mi->rli.group_master_log_name,
- strlen(active_mi->rli.group_master_log_name));
+ active_mi->rli->get_group_master_log_name(),
+ strlen(active_mi->rli->get_group_master_log_name()));
r|= op->setValue(2u, tmp_buf);
DBUG_ASSERT(r == 0);
// start_pos
- r|= op->setValue(3u, (Uint64)active_mi->rli.group_master_log_pos);
+ r|= op->setValue(3u, (Uint64)active_mi->rli->get_group_master_log_pos());
DBUG_ASSERT(r == 0);
// end_pos
- r|= op->setValue(4u, (Uint64)active_mi->rli.group_master_log_pos +
- ((Uint64)active_mi->rli.future_event_relay_log_pos -
- (Uint64)active_mi->rli.group_relay_log_pos));
+ r|= op->setValue(4u, (Uint64)active_mi->rli->get_group_master_log_pos() +
+ ((Uint64)active_mi->rli->get_future_event_relay_log_pos() -
+ (Uint64)active_mi->rli->get_group_relay_log_pos()));
DBUG_ASSERT(r == 0);
return 0;
}
=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc 2010-08-30 08:40:42 +0000
+++ b/sql/item_func.cc 2010-09-06 11:10:01 +0000
@@ -3685,7 +3685,7 @@ 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)
+ if ((event_count = active_mi->rli->wait_for_pos(thd, log_name, pos, timeout)) == -2)
{
null_value = 1;
event_count=0;
=== modified file 'sql/lock.cc'
--- a/sql/lock.cc 2010-08-20 08:48:59 +0000
+++ b/sql/lock.cc 2010-10-08 16:11:32 +0000
@@ -146,8 +146,8 @@ lock_tables_check(THD *thd, TABLE **tabl
or hold any type of lock in a session,
since this would be a DOS attack.
*/
- if ((t->reginfo.lock_type >= TL_READ_NO_INSERT)
- || (thd->lex->sql_command == SQLCOM_LOCK_TABLES))
+ if ((t->reginfo.lock_type >= TL_READ_NO_INSERT
+ || thd->lex->sql_command == SQLCOM_LOCK_TABLES))
{
my_error(ER_CANT_LOCK_LOG_TABLE, MYF(0));
DBUG_RETURN(1);
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2010-09-28 15:30:47 +0000
+++ b/sql/log.cc 2010-10-17 23:27:40 +0000
@@ -1125,7 +1125,7 @@ bool LOGGER::activate_log_handler(THD* t
void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
{
my_bool *tmp_opt= 0;
- MYSQL_LOG *file_log;
+ MYSQL_LOG *file_log= NULL;
switch (log_type) {
case QUERY_LOG_SLOW:
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2010-10-03 23:42:39 +0000
+++ b/sql/log_event.cc 2010-10-17 23:27:40 +0000
@@ -3227,7 +3227,7 @@ int Query_log_event::do_apply_event(Rela
END of the current log event (COMMIT). We save it in rli so that InnoDB can
access it.
*/
- const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
+ const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
@@ -3245,8 +3245,8 @@ int Query_log_event::do_apply_event(Rela
const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
"Error in cleaning up after an event preceeding the commit; "
"the group log file/position: %s %s",
- const_cast<Relay_log_info*>(rli)->group_master_log_name,
- llstr(const_cast<Relay_log_info*>(rli)->group_master_log_pos,
+ const_cast<Relay_log_info*>(rli)->get_group_master_log_name(),
+ llstr(const_cast<Relay_log_info*>(rli)->get_group_master_log_pos(),
llbuff));
}
/*
@@ -3571,13 +3571,15 @@ int Query_log_event::do_update_pos(Relay
after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
from its following updating query.
*/
+ int ret= 0;
if (thd->one_shot_set)
{
rli->inc_event_relay_log_pos();
- return 0;
}
else
- return Log_event::do_update_pos(rli);
+ ret= Log_event::do_update_pos(rli);
+
+ return ret;
}
@@ -4757,7 +4759,7 @@ void Load_log_event::set_fields(const ch
@param rli
@param use_rli_only_for_errors If set to 1, rli is provided to
Load_log_event::exec_event only for this
- function to have RPL_LOG_NAME and
+ function to have rli->get_rpl_log_name and
rli->last_slave_error, both being used by
error reports. rli's position advancing
is skipped (done by the caller which is
@@ -4807,7 +4809,7 @@ int Load_log_event::do_apply_event(NET*
Saved for InnoDB, see comment in
Query_log_event::do_apply_event()
*/
- const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
+ const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
}
@@ -4957,7 +4959,8 @@ int Load_log_event::do_apply_event(NET*
"log position %s in log '%s' produced %ld "
"warning(s). Default database: '%s'",
(char*) table_name,
- llstr(log_pos,llbuff), RPL_LOG_NAME,
+ llstr(log_pos,llbuff),
+ const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
(ulong) thd->cuted_fields,
print_slave_db_safe(thd->db));
}
@@ -5209,17 +5212,19 @@ int Rotate_log_event::do_update_pos(Rela
mysql_mutex_lock(&rli->data_lock);
DBUG_PRINT("info", ("old group_master_log_name: '%s' "
"old group_master_log_pos: %lu",
- rli->group_master_log_name,
- (ulong) rli->group_master_log_pos));
- memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
+ rli->get_group_master_log_name(),
+ (ulong) rli->get_group_master_log_pos()));
+ memcpy((void *)rli->get_group_master_log_name(),
+ new_log_ident, ident_len + 1);
rli->notify_group_master_log_name_update();
rli->inc_group_relay_log_pos(pos, TRUE /* skip_lock */);
+
DBUG_PRINT("info", ("new group_master_log_name: '%s' "
"new group_master_log_pos: %lu",
- rli->group_master_log_name,
- (ulong) rli->group_master_log_pos));
+ rli->get_group_master_log_name(),
+ (ulong) rli->get_group_master_log_pos()));
mysql_mutex_unlock(&rli->data_lock);
- flush_relay_log_info(rli);
+ rli->flush_info(TRUE);
/*
Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
@@ -5581,14 +5586,15 @@ void Xid_log_event::print(FILE* file, PR
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
int Xid_log_event::do_apply_event(Relay_log_info const *rli)
{
- bool res;
+ int error= 0;
+
/* For a slave Xid_log_event is COMMIT */
general_log_print(thd, COM_QUERY,
"COMMIT /* implicit, from Xid_log_event */");
- res= trans_commit(thd); /* Automatically rolls back on error. */
+ error= trans_commit(thd); /* Automatically rolls back on error. */
thd->mdl_context.release_transactional_locks();
- return res;
+ return error;
}
Log_event::enum_skip_reason
@@ -6076,7 +6082,7 @@ Slave_log_event::Slave_log_event(THD* th
mysql_mutex_lock(&mi->data_lock);
mysql_mutex_lock(&rli->data_lock);
master_host_len = strlen(mi->host);
- master_log_len = strlen(rli->group_master_log_name);
+ master_log_len = strlen(rli->get_group_master_log_name());
// on OOM, just do not initialize the structure and print the error
if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
MYF(MY_WME))))
@@ -6084,9 +6090,9 @@ Slave_log_event::Slave_log_event(THD* th
master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
memcpy(master_host, mi->host, master_host_len + 1);
master_log = master_host + master_host_len + 1;
- memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
+ memcpy(master_log, rli->get_group_master_log_name(), master_log_len + 1);
master_port = mi->port;
- master_pos = rli->group_master_log_pos;
+ master_pos = rli->get_group_master_log_pos();
DBUG_PRINT("info", ("master_log: %s pos: %lu", master_log,
(ulong) master_pos));
}
@@ -6235,7 +6241,7 @@ int Stop_log_event::do_update_pos(Relay_
else
{
rli->inc_group_relay_log_pos(0);
- flush_relay_log_info(rli);
+ rli->flush_info(TRUE);
}
return 0;
}
@@ -6908,8 +6914,7 @@ int Execute_load_log_event::do_apply_eve
lev->do_apply_event is the place where the table is loaded (it
calls mysql_load()).
*/
-
- const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
+ const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
if (lev->do_apply_event(0,rli,1))
{
/*
@@ -7579,7 +7584,7 @@ int Rows_log_event::do_apply_event(Relay
do_apply_event(). We still check here to prevent future coding
errors.
*/
- DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->info_thd == thd);
/*
If there is no locks taken, this is the first binrow event seen
@@ -7810,7 +7815,8 @@ int Rows_log_event::do_apply_event(Relay
if (global_system_variables.log_warnings)
slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
get_type_str(),
- RPL_LOG_NAME, (ulong) log_pos);
+ const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
+ (ulong) log_pos);
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
error= 0;
if (idempotent_error == 0)
@@ -7864,7 +7870,8 @@ int Rows_log_event::do_apply_event(Relay
if (global_system_variables.log_warnings)
slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
get_type_str(),
- RPL_LOG_NAME, (ulong) log_pos);
+ const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
+ (ulong) log_pos);
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
error= 0;
}
@@ -7875,7 +7882,8 @@ int Rows_log_event::do_apply_event(Relay
{
slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
get_type_str(),
- RPL_LOG_NAME, (ulong) log_pos);
+ const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
+ (ulong) log_pos);
/*
@todo We should probably not call
reset_current_stmt_binlog_format_row() from here.
@@ -8422,7 +8430,7 @@ int Table_map_log_event::do_apply_event(
size_t dummy_len;
void *memory;
DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
- DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->info_thd == thd);
/* Step the query id to mark what columns that are actually used. */
thd->set_query_id(next_query_id());
@@ -8446,7 +8454,7 @@ int Table_map_log_event::do_apply_event(
int error= 0;
- if (rli->sql_thd->slave_thread /* filtering is for slave only */ &&
+ if (rli->info_thd->slave_thread /* filtering is for slave only */ &&
(!rpl_filter->db_ok(table_list->db) ||
(rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list))))
{
@@ -8811,7 +8819,7 @@ Rows_log_event::write_row(const Relay_lo
auto_afree_ptr<char> key(NULL);
/* fill table->record[0] with default values */
- bool abort_on_warnings= (rli->sql_thd->variables.sql_mode &
+ bool abort_on_warnings= (rli->info_thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
if ((error= prepare_record(table, &m_cols,
table->file->ht->db_type != DB_TYPE_NDBCLUSTER,
@@ -8831,7 +8839,7 @@ Rows_log_event::write_row(const Relay_lo
the size of the first row and use that value to initialize
storage engine for bulk insertion */
DBUG_ASSERT(!(m_curr_row > m_curr_row_end));
- ulong estimated_rows;
+ ulong estimated_rows= 0;
if (m_curr_row < m_curr_row_end)
estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
else if (m_curr_row == m_curr_row_end)
@@ -9941,7 +9949,7 @@ Update_rows_log_event::do_exec_row(const
store_record(m_table,record[1]);
- bool abort_on_warnings= (rli->sql_thd->variables.sql_mode &
+ bool abort_on_warnings= (rli->info_thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
m_curr_row= m_curr_row_end;
/* this also updates m_curr_row_end */
@@ -10215,7 +10223,7 @@ Rows_query_log_event::write_data_body(IO
int Rows_query_log_event::do_apply_event(Relay_log_info const *rli)
{
DBUG_ENTER("Rows_query_log_event::do_apply_event");
- DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->info_thd == thd);
/* Set query for writing Rows_query log event into binlog later.*/
thd->set_query(m_rows_query, (uint32) strlen(m_rows_query));
DBUG_RETURN(0);
=== modified file 'sql/log_event_old.cc'
--- a/sql/log_event_old.cc 2010-09-04 00:46:58 +0000
+++ b/sql/log_event_old.cc 2010-10-08 14:35:24 +0000
@@ -1,3 +1,17 @@
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "sql_priv.h"
#ifndef MYSQL_CLIENT
@@ -53,7 +67,7 @@ Old_rows_log_event::do_apply_event(Old_r
do_apply_event(). We still check here to prevent future coding
errors.
*/
- DBUG_ASSERT(rli->sql_thd == ev_thd);
+ DBUG_ASSERT(rli->info_thd == ev_thd);
/*
If there is no locks taken, this is the first binrow event seen
@@ -1470,7 +1484,7 @@ int Old_rows_log_event::do_apply_event(R
do_apply_event(). We still check here to prevent future coding
errors.
*/
- DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->info_thd == thd);
/*
If there is no locks taken, this is the first binrow event seen
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2010-10-03 23:42:39 +0000
+++ b/sql/mysqld.cc 2010-10-08 14:35:24 +0000
@@ -6218,7 +6218,7 @@ static int show_slave_running(THD *thd,
var->value= buff;
*((my_bool *)buff)= (my_bool) (active_mi &&
active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
- active_mi->rli.slave_running);
+ active_mi->rli->slave_running);
mysql_mutex_unlock(&LOCK_active_mi);
return 0;
}
@@ -6234,9 +6234,9 @@ static int show_slave_retried_trans(THD
{
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_mutex_lock(&active_mi->rli->data_lock);
+ *((long *)buff)= (long)active_mi->rli->retried_trans;
+ mysql_mutex_unlock(&active_mi->rli->data_lock);
}
else
var->type= SHOW_UNDEF;
@@ -6251,9 +6251,9 @@ static int show_slave_received_heartbeat
{
var->type= SHOW_LONGLONG;
var->value= buff;
- mysql_mutex_lock(&active_mi->rli.data_lock);
+ mysql_mutex_lock(&active_mi->rli->data_lock);
*((longlong *)buff)= active_mi->received_heartbeats;
- mysql_mutex_unlock(&active_mi->rli.data_lock);
+ mysql_mutex_unlock(&active_mi->rli->data_lock);
}
else
var->type= SHOW_UNDEF;
=== modified file 'sql/rpl_handler.cc'
--- a/sql/rpl_handler.cc 2010-07-16 21:00:50 +0000
+++ b/sql/rpl_handler.cc 2010-07-27 14:14:21 +0000
@@ -411,8 +411,8 @@ void Binlog_relay_IO_delegate::init_para
param->user= mi->user;
param->host= mi->host;
param->port= mi->port;
- param->master_log_name= mi->master_log_name;
- param->master_log_pos= mi->master_log_pos;
+ param->master_log_name= const_cast<char *>(mi->get_master_log_name());
+ param->master_log_pos= mi->get_master_log_pos();
}
int Binlog_relay_IO_delegate::thread_start(THD *thd, Master_info *mi)
=== added file 'sql/rpl_info.cc'
--- a/sql/rpl_info.cc 1970-01-01 00:00:00 +0000
+++ b/sql/rpl_info.cc 2010-07-27 19:26:54 +0000
@@ -0,0 +1,63 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#include <sql_priv.h>
+#include "rpl_info.h"
+
+Rpl_info::Rpl_info(const char* type,
+ PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond)
+ :Slave_reporting_capability(type),
+ key_info_run_lock(param_key_info_run_lock),
+ key_info_data_lock(param_key_info_data_lock),
+ key_info_data_cond(param_key_info_data_cond),
+ key_info_start_cond(param_key_info_start_cond),
+ key_info_stop_cond(param_key_info_stop_cond),
+ info_thd(0), inited(0), abort_slave(0),
+ slave_running(0), slave_run_id(0),
+ handler(0)
+{
+ mysql_mutex_init(*key_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST);
+ mysql_mutex_init(*key_info_data_lock,
+ &data_lock, MY_MUTEX_INIT_FAST);
+ mysql_cond_init(*key_info_data_cond, &data_cond, NULL);
+ mysql_cond_init(*key_info_start_cond, &start_cond, NULL);
+ mysql_cond_init(*key_info_stop_cond, &stop_cond, NULL);
+}
+
+Rpl_info::~Rpl_info()
+{
+ DBUG_ENTER("Rpl_info::~Rpl_info");
+
+ mysql_mutex_destroy(&run_lock);
+ mysql_mutex_destroy(&data_lock);
+ mysql_cond_destroy(&data_cond);
+ mysql_cond_destroy(&start_cond);
+ mysql_cond_destroy(&stop_cond);
+
+ if (handler)
+ delete handler;
+
+ DBUG_VOID_RETURN;
+}
+
+void Rpl_info::set_rpl_info_handler(Rpl_info_handler * param_handler)
+{
+ handler= param_handler;
+}
=== added file 'sql/rpl_info.h'
--- a/sql/rpl_info.h 1970-01-01 00:00:00 +0000
+++ b/sql/rpl_info.h 2010-10-08 14:23:55 +0000
@@ -0,0 +1,107 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef RPL_INFO_H
+#define RPL_INFO_H
+
+#include "sql_priv.h"
+#include "sql_class.h"
+#include "rpl_info_handler.h"
+#include "rpl_reporting.h"
+
+class Rpl_info : public Slave_reporting_capability
+{
+public:
+ /*
+ standard lock acquisition order to avoid deadlocks:
+ run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index
+ */
+ mysql_mutex_t data_lock,run_lock;
+ /*
+ start_cond is broadcast when SQL thread is started
+ stop_cond - when stopped
+ data_cond - when data protected by data_lock changes
+ */
+ mysql_cond_t data_cond,start_cond,stop_cond;
+
+ PSI_mutex_key *key_info_run_lock, *key_info_data_lock;
+
+ PSI_mutex_key *key_info_data_cond, *key_info_start_cond, *key_info_stop_cond;
+
+ THD *info_thd;
+
+ bool inited;
+ volatile bool abort_slave;
+ volatile uint slave_running;
+ volatile ulong slave_run_id;
+
+#ifndef DBUG_OFF
+ int events_until_exit;
+#endif
+
+ Rpl_info(const char* type,
+ PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond);
+ virtual ~Rpl_info();
+
+ int check_info()
+ {
+ return (handler->check_info());
+ }
+
+ int reset_info()
+ {
+ return (handler->reset_info());
+ }
+
+ bool is_transactional()
+ {
+ return (handler->is_transactional());
+ }
+
+ char *get_description_info()
+ {
+ return (handler->get_description_info());
+ }
+
+ bool copy_info(Rpl_info_handler *from, Rpl_info_handler *to)
+ {
+ if (read_info(from) || write_info(to, TRUE))
+ return(TRUE);
+
+ return(FALSE);
+ }
+
+ /**
+ Sets the persistency component/handler.
+
+ @param[in] hanlder Pointer to the handler.
+ */
+ void set_rpl_info_handler(Rpl_info_handler * handler);
+
+protected:
+ Rpl_info_handler *handler;
+
+private:
+ virtual bool read_info(Rpl_info_handler *from)= 0;
+ virtual bool write_info(Rpl_info_handler *to, bool force)= 0;
+
+ Rpl_info& operator=(const Rpl_info& info);
+ Rpl_info(const Rpl_info& info);
+};
+#endif /* RPL_INFO_H */
=== added file 'sql/rpl_info_factory.cc'
--- a/sql/rpl_info_factory.cc 1970-01-01 00:00:00 +0000
+++ b/sql/rpl_info_factory.cc 2010-10-08 16:11:32 +0000
@@ -0,0 +1,179 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#include "sql_priv.h"
+#include "rpl_slave.h"
+#include "rpl_info_factory.h"
+#include "rpl_info_file.h"
+#include "rpl_mi.h"
+#include "rpl_rli.h"
+
+/**
+ Creates both a Master info and a Relay log info repository whose types are
+ defined as parameters.
+
+ @todo Make the repository a pluggable component.
+
+ @param[in] mi_option Type of the Master info repository
+ @param[out] mi Reference to the Master info repository
+ @param[in] rli_option Type of the Relay log info repository
+ @param[out] rli Reference to the Relay log info repository
+
+ @retval FALSE No error
+ @retval TRUE Failure
+*/
+bool Rpl_info_factory::create(uint mi_option, Master_info **mi,
+ uint rli_option, Relay_log_info **rli)
+{
+ bool error= FALSE;
+
+ DBUG_ENTER("Rpl_info_factory::Rpl_info_factory");
+
+ if ((error= Rpl_info_factory::create_mi(mi_option, mi)))
+ {
+ *mi= NULL;
+ DBUG_RETURN(error);
+ }
+
+ if ((error= Rpl_info_factory::create_rli(rli_option, relay_log_recovery,
+ rli)))
+ {
+ delete *mi;
+ *mi= NULL;
+ DBUG_RETURN(error);
+ }
+
+ /*
+ Setting the cross dependency used all over the code.
+ */
+ (*mi)->set_relay_log_info(*rli);
+ (*rli)->set_master_info(*mi);
+
+ DBUG_RETURN(error);
+}
+
+/**
+ Creates a Master info repository whose type is defined as a parameter.
+
+ @param[in] mi_option Type of the Master info repository
+ @param[out] mi Reference to the Master info repository
+
+ The execution fails if a user requests a type but a different type
+ already exists in the system. This is done to avoid that a user
+ accidentally accesses the wrong repository and make the slave go out
+ of sync.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+*/
+bool Rpl_info_factory::create_mi(uint mi_option, Master_info **mi)
+{
+ bool error= TRUE;
+ Rpl_info_file* mi_file= NULL;
+ const char *msg= "Failed to allocate memory for the master info "
+ "structure";
+
+ DBUG_ENTER("Rpl_info_factory::Rpl_info_factory");
+
+ *mi= new Master_info(&key_master_info_run_lock, &key_master_info_data_lock,
+ &key_master_info_data_cond, &key_master_info_start_cond,
+ &key_master_info_stop_cond);
+ if (!(*mi))
+ goto err;
+
+ /*
+ Now we instantiate all info repos and later decide which one to take,
+ but not without first checking if there is already existing data for
+ a repo different from the one that is being requested.
+ */
+ mi_file= new Rpl_info_file((*mi)->get_number_info_mi_fields(),
+ master_info_file);
+ if (!mi_file)
+ goto err;
+
+ DBUG_ASSERT(mi_option == MI_REPOSITORY_FILE);
+
+ (*mi)->set_rpl_info_handler(mi_file);
+ error= FALSE;
+
+ DBUG_RETURN(error);
+
+err:
+ if (*mi) delete (*mi);
+ if (mi_file) delete mi_file;
+ sql_print_error("%s", msg);
+ DBUG_RETURN(error);
+}
+
+/**
+ Creates a Relay log info repository whose type is defined as a parameter.
+
+ @param[in] rli_option Type of the Relay log info repository
+ @param[in] is_slave_recovery If the slave should try to start a recovery
+ process to get consistent relay log files
+ @param[out] rli Reference to the Relay log info repository
+
+ The execution fails if a user requests a type but a different type
+ already exists in the system. This is done to avoid that a user
+ accidentally accesses the wrong repository and make the slave go out
+ of sync.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+*/
+bool Rpl_info_factory::create_rli(uint rli_option, bool is_slave_recovery,
+ Relay_log_info **rli)
+{
+ bool error= TRUE;
+ Rpl_info_file* rli_file= NULL;
+ const char *msg= "Failed to allocate memory for the relay log info "
+ "structure";
+
+ DBUG_ENTER("Rpl_info_factory::create_rli");
+
+ (*rli)=
+ new Relay_log_info(
+ is_slave_recovery,
+ &key_relay_log_info_run_lock, &key_relay_log_info_data_lock,
+ &key_relay_log_info_data_cond, &key_relay_log_info_start_cond,
+ &key_relay_log_info_stop_cond);
+
+ if (!(*rli))
+ goto err;
+
+ /*
+ Now we instantiate all info repos and later decide which one to take,
+ but not without first checking if there is already existing data for
+ a repo different from the one that is being requested.
+ */
+ rli_file= new Rpl_info_file((*rli)->get_number_info_rli_fields(),
+ relay_log_info_file);
+ if (!rli_file)
+ goto err;
+
+ DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE);
+
+ (*rli)->set_rpl_info_handler(rli_file);
+ error= FALSE;
+
+ DBUG_RETURN(error);
+
+err:
+ if (*rli) delete (*rli);
+ if (rli_file) delete rli_file;
+ sql_print_error("%s", msg);
+ DBUG_RETURN(error);
+}
=== added file 'sql/rpl_info_factory.h'
--- a/sql/rpl_info_factory.h 1970-01-01 00:00:00 +0000
+++ b/sql/rpl_info_factory.h 2010-10-08 16:11:32 +0000
@@ -0,0 +1,49 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef RPL_INFO_FACTORY_H
+#define RPL_INFO_FACTORY_H
+
+#include "rpl_info.h"
+#include "rpl_mi.h"
+#include "rpl_rli.h"
+#include "rpl_info_handler.h"
+
+enum enum_mi_repository
+{
+ MI_REPOSITORY_FILE= 0
+};
+extern ulong opt_mi_repository_id;
+
+enum enum_rli_repository
+{
+ RLI_REPOSITORY_FILE= 0
+};
+extern ulong opt_rli_repository_id;
+
+class Rpl_info_factory
+{
+ public:
+
+ bool static create(uint mi_option, Master_info **mi,
+ uint rli_option, Relay_log_info **rli);
+ bool static create_mi(uint rli_option, Master_info **rli);
+ bool static create_rli(uint rli_option, bool is_slave_recovery,
+ Relay_log_info **rli);
+ bool static decide_repository(Rpl_info *info, Rpl_info_handler *table,
+ Rpl_info_handler *file, bool is_table,
+ const char **msg);
+};
+#endif
=== added file 'sql/rpl_info_file.cc'
--- a/sql/rpl_info_file.cc 1970-01-01 00:00:00 +0000
+++ b/sql/rpl_info_file.cc 2010-09-13 23:30:43 +0000
@@ -0,0 +1,469 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#include <sql_priv.h>
+#include <my_dir.h>
+#include "rpl_info_file.h"
+#include "mysqld.h"
+#include "log.h"
+
+int init_ulongvar_from_file(ulong* var, IO_CACHE* f, ulong default_val);
+int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
+ const char *default_val);
+int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
+int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val);
+bool init_dynarray_intvar_from_file(char *buffer, char **buffer_act, IO_CACHE* f);
+
+Rpl_info_file::Rpl_info_file(const int nparam, const char* param_info_fname)
+ :Rpl_info_handler(nparam), info_fd(-1)
+{
+ DBUG_ENTER("Rpl_info_file::Rpl_info_file");
+
+ bzero((char*) &info_file, sizeof(info_file));
+ fn_format(info_fname, param_info_fname, mysql_data_home, "", 4 + 32);
+
+ DBUG_VOID_RETURN;
+}
+
+int Rpl_info_file::do_init_info()
+{
+ int error= 0;
+
+ /* Don't init if there is no storage */
+ DBUG_ENTER("Rpl_info_file::do_init_info");
+
+ /* does info file exist ? */
+ if (do_check_info())
+ {
+ /*
+ If someone removed the file from underneath our feet, just close
+ the old descriptor and re-create the old file
+ */
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(MY_WME));
+ if ((info_fd = my_open(info_fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
+ {
+ sql_print_error("Failed to create a new info file (\
+file '%s', errno %d)", info_fname, my_errno);
+ error= 1;
+ }
+ else if (init_io_cache(&info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
+ MYF(MY_WME)))
+ {
+ sql_print_error("Failed to create a cache on info file (\
+file '%s')", info_fname);
+ error= 1;
+ }
+ if (error)
+ {
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(0));
+ info_fd= -1;
+ }
+ }
+ /* file exists */
+ else
+ {
+ if (info_fd >= 0)
+ reinit_io_cache(&info_file, READ_CACHE, 0L,0,0);
+ else
+ {
+ if ((info_fd = my_open(info_fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
+ {
+ sql_print_error("Failed to open the existing info file (\
+file '%s', errno %d)", info_fname, my_errno);
+ error= 1;
+ }
+ else if (init_io_cache(&info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,
+ 0, MYF(MY_WME)))
+ {
+ sql_print_error("Failed to create a cache on info file (\
+file '%s')", info_fname);
+ error= 1;
+ }
+ if (error)
+ {
+ if (info_fd >= 0)
+ my_close(info_fd, MYF(0));
+ info_fd= -1;
+ }
+ }
+ }
+ DBUG_RETURN(error);
+}
+
+int Rpl_info_file::do_prepare_info_for_read()
+{
+ cursor= 0;
+ prv_error= FALSE;
+ return (reinit_io_cache(&info_file, READ_CACHE, 0L, 0, 0));
+}
+
+int Rpl_info_file::do_prepare_info_for_write()
+{
+ cursor= 0;
+ prv_error= FALSE;
+ return (reinit_io_cache(&info_file, WRITE_CACHE, 0L, 0, 1));
+}
+
+int Rpl_info_file::do_check_info()
+{
+ return (access(info_fname,F_OK));
+}
+
+int Rpl_info_file::do_flush_info(const bool force)
+{
+ int error= 0;
+
+ DBUG_ENTER("Rpl_info_file::do_flush_info");
+
+ if (flush_io_cache(&info_file))
+ error= 1;
+ if (!error && (force ||
+ (sync_period &&
+ ++(sync_counter) >= sync_period)))
+ {
+ if (my_sync(info_fd, MYF(MY_WME)))
+ error= 1;
+ sync_counter= 0;
+ }
+
+ DBUG_RETURN(error);
+}
+
+void Rpl_info_file::do_end_info()
+{
+ DBUG_ENTER("Rpl_info_file::do_end_info");
+
+ if (info_fd >= 0)
+ {
+ end_io_cache(&info_file);
+ my_close(info_fd, MYF(MY_WME));
+ info_fd = -1;
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+int Rpl_info_file::do_reset_info()
+{
+ MY_STAT stat_area;
+ int error= 0;
+
+ DBUG_ENTER("Rpl_info_file::do_reset_info");
+
+ if (my_stat(info_fname, &stat_area, MYF(0)) && my_delete(info_fname, MYF(MY_WME)))
+ error= 1;
+
+ DBUG_RETURN(error);
+}
+
+bool Rpl_info_file::do_set_info(const int pos, const char *value)
+{
+ return (my_b_printf(&info_file, "%s\n", value) > (size_t) 0 ?
+ FALSE : TRUE);
+}
+
+bool Rpl_info_file::do_set_info(const int pos, const ulong value)
+{
+ return (my_b_printf(&info_file, "%lu\n", value) > (size_t) 0 ?
+ FALSE : TRUE);
+}
+
+bool Rpl_info_file::do_set_info(const int pos, const int value)
+{
+ return (my_b_printf(&info_file, "%d\n", value) > (size_t) 0 ?
+ FALSE : TRUE);
+}
+
+bool Rpl_info_file::do_set_info(const int pos, const float value)
+{
+ /*
+ 64 bytes provide enough space considering that the precision is 3
+ bytes (See the appropriate set funciton):
+
+ FLT_MAX The value of this macro is the maximum number representable
+ in type float. It is supposed to be at least 1E+37.
+ FLT_MIN Similar to the FLT_MAX, we have 1E-37.
+
+ If a file is manually and not properly changed, this function may
+ crash the server.
+ */
+ char buffer[64];
+
+ sprintf(buffer, "%.3f", value);
+
+ return (my_b_printf(&info_file, "%s\n", buffer) > (size_t) 0 ?
+ FALSE : TRUE);
+}
+
+bool Rpl_info_file::do_set_info(const int pos, const Server_ids *value)
+{
+ bool error= TRUE;
+ char *server_ids_buffer= (char*) my_malloc((sizeof(::server_id) * 3 + 1) *
+ (1 + value->server_ids.elements), MYF(0));
+
+ if (server_ids_buffer == NULL)
+ return error;
+
+ /*
+ This produces a line listing the total number and all the server_ids.
+ */
+ if (const_cast<Server_ids *>(value)->pack_server_ids(server_ids_buffer))
+ goto err;
+
+ error= (my_b_printf(&info_file, "%s\n", server_ids_buffer) >
+ (size_t) 0 ? FALSE : TRUE);
+
+err:
+ my_free(server_ids_buffer);
+ return error;
+}
+
+bool Rpl_info_file::do_get_info(const int pos, char *value, const size_t size,
+ const char *default_value)
+{
+ return (init_strvar_from_file(value, size, &info_file,
+ default_value));
+}
+
+bool Rpl_info_file::do_get_info(const int pos, ulong *value,
+ const ulong default_value)
+{
+ return (init_ulongvar_from_file(value, &info_file,
+ default_value));
+}
+
+bool Rpl_info_file::do_get_info(const int pos, int *value,
+ const int default_value)
+{
+ return (init_intvar_from_file((int *) value, &info_file,
+ (int) default_value));
+}
+
+bool Rpl_info_file::do_get_info(const int pos, float *value,
+ const float default_value)
+{
+ return (init_floatvar_from_file(value, &info_file,
+ default_value));
+}
+
+bool Rpl_info_file::do_get_info(const int pos, Server_ids *value,
+ const Server_ids *default_value __attribute__((unused)))
+{
+ /*
+ Static buffer to use most of the times. However, if it is not big
+ enough to accommodate the server ids, a new buffer is allocated.
+ */
+ const int array_size= 16 * (sizeof(long) * 4 + 1);
+ char buffer[array_size];
+ char *buffer_act= buffer;
+
+ bool error= init_dynarray_intvar_from_file(buffer, &buffer_act,
+ &info_file);
+ if (!error)
+ value->unpack_server_ids(buffer_act);
+
+ if (buffer != buffer_act)
+ {
+ /*
+ Release the buffer allocated while reading the server ids
+ from the file.
+ */
+ my_free(buffer_act);
+ }
+
+ return error;
+}
+
+char* Rpl_info_file::do_get_description_info()
+{
+ return info_fname;
+}
+
+bool Rpl_info_file::do_is_transactional()
+{
+ return FALSE;
+}
+
+int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
+ const char *default_val)
+{
+ uint length;
+ DBUG_ENTER("init_strvar_from_file");
+
+ if ((length=my_b_gets(f,var, max_size)))
+ {
+ char* last_p = var + length -1;
+ if (*last_p == '\n')
+ *last_p = 0; // if we stopped on newline, kill it
+ else
+ {
+ /*
+ If we truncated a line or stopped on last char, remove all chars
+ up to and including newline.
+ */
+ int c;
+ while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)) ;
+ }
+ DBUG_RETURN(0);
+ }
+ else if (default_val)
+ {
+ strmake(var, default_val, max_size-1);
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(1);
+}
+
+int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
+{
+ /*
+ 32 bytes provide enough space:
+
+ INT_MIN –2,147,483,648
+ INT_MAX +2,147,483,647
+ */
+ char buf[32];
+ DBUG_ENTER("init_intvar_from_file");
+
+ if (my_b_gets(f, buf, sizeof(buf)))
+ {
+ *var = atoi(buf);
+ DBUG_RETURN(0);
+ }
+ else if (default_val)
+ {
+ *var = default_val;
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(1);
+}
+
+int init_ulongvar_from_file(ulong* var, IO_CACHE* f, ulong default_val)
+{
+ /*
+ 32 bytes provide enough space:
+
+ ULONG_MAX 32 bit compiler +4,294,967,295
+ 64 bit compiler +18,446,744,073,709,551,615
+ */
+ char buf[32];
+ DBUG_ENTER("init_ulongvar_from_file");
+
+ if (my_b_gets(f, buf, sizeof(buf)))
+ {
+ *var = strtoul(buf, 0, 10);
+ DBUG_RETURN(0);
+ }
+ else if (default_val)
+ {
+ *var = default_val;
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(1);
+}
+
+int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val)
+{
+ /*
+ 64 bytes provide enough space considering that the precision is 3
+ bytes (See the appropriate set funciton):
+
+ FLT_MAX The value of this macro is the maximum number representable
+ in type float. It is supposed to be at least 1E+37.
+ FLT_MIN Similar to the FLT_MAX, we have 1E-37.
+
+ If a file is manually and not properly changed, this function may
+ crash the server.
+ */
+ char buf[64];
+ DBUG_ENTER("init_floatvar_from_file");
+
+ if (my_b_gets(f, buf, sizeof(buf)))
+ {
+ if (sscanf(buf, "%f", var) != 1)
+ DBUG_RETURN(1);
+ else
+ DBUG_RETURN(0);
+ }
+ else if (default_val != 0.0)
+ {
+ *var = default_val;
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(1);
+}
+
+/**
+ Particularly, this function is responsible for restoring IGNORE_SERVER_IDS
+ list of servers whose events the slave is going to ignore (to not log them
+ in the relay log).
+
+ Items being read are supposed to be decimal output of values of a type
+ shorter or equal of @c long and separated by the single space.
+
+ @param buffer Put the read values in this static buffer
+ @param buffer_act Points to the final buffer as dynamic buffer may
+ be used if the static buffer is not big enough.
+
+ @retval 0 All OK
+ @retval non-zero An error
+*/
+bool init_dynarray_intvar_from_file(char *buffer, char **buffer_act, IO_CACHE* f)
+{
+ char *buf= buffer; // actual buffer can be dynamic if static is short
+ char *buf_act= buffer;
+ char *last;
+ uint num_items; // number of items of `arr'
+ size_t read_size;
+
+ DBUG_ENTER("init_dynarray_intvar_from_file");
+
+ if ((read_size= my_b_gets(f, buf_act, sizeof(buf))) == 0)
+ {
+ DBUG_RETURN(FALSE); // no line in master.info
+ }
+ if (read_size + 1 == sizeof(buf) && buf[sizeof(buf) - 2] != '\n')
+ {
+ /*
+ short read happend; allocate sufficient memory and make the 2nd read
+ */
+ char buf_work[(sizeof(long)*3 + 1)*16];
+ memcpy(buf_work, buf, sizeof(buf_work));
+ num_items= atoi(strtok_r(buf_work, " ", &last));
+ size_t snd_size;
+ /*
+ max size lower bound approximate estimation bases on the formula:
+ (the items number + items themselves) *
+ (decimal size + space) - 1 + `\n' + '\0'
+ */
+ size_t max_size= (1 + num_items) * (sizeof(long)*3 + 1) + 1;
+ buf_act= (char*) my_malloc(max_size, MYF(MY_WME));
+ buffer_act= &buf_act;
+ memcpy(buf_act, buf, read_size);
+ snd_size= my_b_gets(f, buf_act + read_size, max_size - read_size);
+ if (snd_size == 0 ||
+ ((snd_size + 1 == max_size - read_size) && buf[max_size - 2] != '\n'))
+ {
+ /*
+ failure to make the 2nd read or short read again
+ */
+ DBUG_RETURN(TRUE);
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
=== added file 'sql/rpl_info_file.h'
--- a/sql/rpl_info_file.h 1970-01-01 00:00:00 +0000
+++ b/sql/rpl_info_file.h 2010-07-06 22:01:07 +0000
@@ -0,0 +1,73 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef RPL_INFO_FILE_H
+#define RPL_INFO_FILE_H
+
+#include <my_global.h>
+#include <sql_priv.h>
+#include "rpl_info_handler.h"
+
+/**
+ Defines a file hander.
+*/
+class Rpl_info_file : public Rpl_info_handler
+{
+public:
+ Rpl_info_file(int const nparam, const char* param_info_fname);
+ virtual ~Rpl_info_file() { };
+
+private:
+ char info_fname[FN_REFLEN + 128];
+
+ /*
+ info_fd - file descriptor of the info file. set only during
+ initialization or clean up - safe to read anytime
+ */
+ File info_fd;
+
+ /* IO_CACHE of the info file - set only during init or end */
+ IO_CACHE info_file;
+
+ int do_init_info();
+ int do_check_info();
+ void do_end_info();
+ int do_flush_info(const bool force);
+ int do_reset_info();
+
+ int do_prepare_info_for_read();
+ int do_prepare_info_for_write();
+ bool do_set_info(const int pos, const char *value);
+ bool do_set_info(const int pos, const int value);
+ bool do_set_info(const int pos, const ulong value);
+ bool do_set_info(const int pos, const float value);
+ bool do_set_info(const int pos, const Server_ids *value);
+ bool do_get_info(const int pos, char *value, const size_t size,
+ const char *default_value);
+ bool do_get_info(const int pos, int *value,
+ const int default_value);
+ bool do_get_info(const int pos, ulong *value,
+ const ulong default_value);
+ bool do_get_info(const int pos, float *value,
+ const float default_value);
+ bool do_get_info(const int pos, Server_ids *value,
+ const Server_ids *default_value);
+ char* do_get_description_info();
+ bool do_is_transactional();
+
+ Rpl_info_file& operator=(const Rpl_info_file& info);
+ Rpl_info_file(const Rpl_info_file& info);
+};
+#endif /* RPL_INFO_FILE_H */
=== added file 'sql/rpl_info_handler.cc'
--- a/sql/rpl_info_handler.cc 1970-01-01 00:00:00 +0000
+++ b/sql/rpl_info_handler.cc 2010-10-08 16:11:32 +0000
@@ -0,0 +1,35 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <my_global.h>
+#include <sql_priv.h>
+#include "rpl_info_handler.h"
+
+Rpl_info_handler::Rpl_info_handler(const int nparam)
+ :ninfo(nparam), cursor((my_off_t)0),
+ prv_error(0), sync_counter(0), sync_period(0)
+{
+ /* Nothing to do here. */
+}
+
+Rpl_info_handler::~Rpl_info_handler()
+{
+ /* Nothing to do here. */
+}
+
+void Rpl_info_handler::set_sync_period(uint period)
+{
+ sync_period= period;
+}
=== added file 'sql/rpl_info_handler.h'
--- a/sql/rpl_info_handler.h 1970-01-01 00:00:00 +0000
+++ b/sql/rpl_info_handler.h 2010-10-17 23:27:40 +0000
@@ -0,0 +1,314 @@
+/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef RPL_INFO_HANDLER_H
+#define RPL_INFO_HANDLER_H
+
+#include <my_global.h>
+#include <server_ids.h>
+
+class Rpl_info_handler
+{
+public:
+ Rpl_info_handler(const int nparam);
+ virtual ~Rpl_info_handler();
+
+ /**
+ After creating an object and assembling components, this method is
+ used to initialize internal structures. Everything that does not
+ depend on other components (e.g. mutexes) should be placed in the
+ object's constructor though.
+
+ @retval FALSE success,
+ @retval TRUE otherwise error.
+ */
+ int init_info()
+ {
+ return do_init_info();
+ }
+
+ /**
+ Checks if any necessary dependency is satisfied such as a
+ file exists.
+
+ @retval FALSE success,
+ @retval TRUE otherwise error.
+ */
+ int check_info()
+ {
+ return do_check_info();
+ }
+
+ /**
+ Flushes and syncs in-memory information into a stable storage (i.e.
+ repository). Usually, syncing after flushing depends on other options
+ such as @code relay-log-info-sync, master-info-sync. These options
+ dictate after how many events or transactions the information
+ should be synced. We can ignore them and always sync by setting the
+ parameter @code force, which is by default false, to @code true.
+
+ So if the number of events is below a threshold, the parameter
+ @code force is FALSE and we are using a file system as a storage
+ system, it may happen that the changes will only end up in the
+ operating system's cache and a crash may lead to inconsistencies.
+
+ @param[in] force Always sync the information.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ int flush_info(const bool force)
+ {
+ return do_flush_info(force);
+ }
+
+ /**
+ Deletes any information in the repository.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ int reset_info()
+ {
+ return do_reset_info();
+ }
+
+ /**
+ Closes access to the repository.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ void end_info()
+ {
+ do_end_info();
+ }
+
+ /**
+ Enables the storage system to receive reads, i.e.
+ getters.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ int prepare_info_for_read()
+ {
+ return (do_prepare_info_for_read());
+ }
+
+ /**
+ Enables the storage system to receive writes, i.e.
+ setters.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ int prepare_info_for_write()
+ {
+ return (do_prepare_info_for_write());
+ }
+
+ /**
+ Sets the value of a field to @c value.
+ Any call must be done in the right order which
+ is defined by the caller that wants to persist
+ the information.
+
+ @param[in] value Value to be set.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ template <class TypeHandler>
+ bool set_info(TypeHandler const value)
+ {
+ if (cursor >= ninfo || prv_error)
+ return TRUE;
+
+ if (!(prv_error= do_set_info(cursor, value)))
+ cursor++;
+
+ return(prv_error);
+ }
+
+ /**
+ Returns the value of a field.
+ Any call must be done in the right order which
+ is defined by the caller that wants to return
+ the information.
+
+ @param[in] value Value to be set.
+ @param[in] default_value Returns a default value
+ if the field is empty.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ template <class TypeHandlerPointer, class TypeHandler>
+ bool get_info(TypeHandlerPointer value,
+ TypeHandler const default_value)
+ {
+ if (cursor >= ninfo || prv_error)
+ return TRUE;
+
+ if (!(prv_error= do_get_info(cursor, value, default_value)))
+ cursor++;
+
+ return(prv_error);
+ }
+
+ /**
+ Returns the value of a string field.
+ Any call must be done in the right order which
+ is defined by the caller that wants to return
+ the information.
+
+ @param[in] value Value to be returned.
+ @param[in] size Max size of the string to be
+ returned.
+ @param[in] default_value Returns a default value
+ if the field is empty.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ bool get_info(char *value, const size_t size,
+ const char *default_value)
+ {
+ if (cursor >= ninfo || prv_error)
+ return TRUE;
+
+ if (!(prv_error= do_get_info(cursor, value, size, default_value)))
+ cursor++;
+
+ return(prv_error);
+ }
+
+ /**
+ Returns the value of a Server_id field.
+ Any call must be done in the right order which
+ is defined by the caller that wants to return
+ the information.
+
+ @param[out] value Value to be return.
+ @param[in] default_value Returns a default value
+ if the field is empty.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ bool get_info(Server_ids *value,
+ const Server_ids *default_value)
+ {
+ if (cursor >= ninfo || prv_error)
+ return TRUE;
+
+ if (!(prv_error= do_get_info(cursor, value, default_value)))
+ cursor++;
+
+ return(prv_error);
+ }
+
+ /**
+ Returns the number of fields handled by this handler.
+
+ @return Number of fields handled by the handler.
+ */
+ int get_number_info() { return ninfo; }
+
+ /**
+ Configures the number of events after which the info (e.g.
+ master info, relay log info) must be synced when flush() is
+ called.
+
+ @param[in] period Number of events.
+ */
+ void set_sync_period(uint period);
+
+ /**
+ Returns a string describing the repository. For instance, if the
+ repository is a file, the returned string is path where data is
+ stored.
+
+ @return a pointer to a string.
+ */
+ char *get_description_info()
+ {
+ return (do_get_description_info());
+ }
+
+ /**
+ Any transactional repository may have its updates rolled back in case
+ of a failure. If this is possible, the repository is classified as
+ transactional.
+
+ @retval TRUE If transactional.
+ @retval FALSE Otherwise.
+ */
+ bool is_transactional() { return do_is_transactional(); }
+
+protected:
+ /* Number of fields to be stored in the repository. */
+ int ninfo;
+
+ /* From/To where we should start reading/writing. */
+ int cursor;
+
+ /* Registers if there was failure while accessing a field/information. */
+ bool prv_error;
+
+ /*
+ Keeps track of the number of events before fsyncing. The option
+ --sync-master-info and --sync-relay-log-info determine how many
+ events should be processed before fsyncing.
+ */
+ uint sync_counter;
+
+ /*
+ The number of events after which we should fsync.
+ */
+ uint sync_period;
+
+private:
+ virtual int do_init_info()= 0;
+ virtual int do_check_info()= 0;
+ virtual int do_flush_info(const bool force)= 0;
+ virtual int do_reset_info()= 0;
+ virtual void do_end_info()= 0;
+ virtual int do_prepare_info_for_read()= 0;
+ virtual int do_prepare_info_for_write()= 0;
+
+ virtual bool do_set_info(const int pos, const char *value)= 0;
+ virtual bool do_set_info(const int pos, const ulong value)= 0;
+ virtual bool do_set_info(const int pos, const int value)= 0;
+ virtual bool do_set_info(const int pos, const float value)= 0;
+ virtual bool do_set_info(const int pos, const Server_ids *value)= 0;
+ virtual bool do_get_info(const int pos, char *value, const size_t size,
+ const char *default_value)= 0;
+ virtual bool do_get_info(const int pos, ulong *value,
+ const ulong default_value)= 0;
+ virtual bool do_get_info(const int pos, int *value,
+ const int default_value)= 0;
+ virtual bool do_get_info(const int pos, float *value,
+ const float default_value)= 0;
+ virtual bool do_get_info(const int pos, Server_ids *value,
+ const Server_ids *default_value)= 0;
+ virtual char* do_get_description_info()= 0;
+ virtual bool do_is_transactional()= 0;
+
+ Rpl_info_handler& operator=(const Rpl_info_handler& handler);
+ Rpl_info_handler(const Rpl_info_handler& handler);
+};
+#endif /* RPL_INFO_HANDLER_H */
=== modified file 'sql/rpl_mi.cc'
--- a/sql/rpl_mi.cc 2010-07-29 09:31:24 +0000
+++ b/sql/rpl_mi.cc 2010-08-24 08:39:26 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -10,8 +10,8 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h> // For HAVE_REPLICATION
#include "sql_priv.h"
@@ -22,40 +22,83 @@
#ifdef HAVE_REPLICATION
-#define DEFAULT_CONNECT_RETRY 60
+enum {
+ LINES_IN_MASTER_INFO_WITH_SSL= 14,
+
+ /* 5.1.16 added value of master_ssl_verify_server_cert */
+ LINE_FOR_MASTER_SSL_VERIFY_SERVER_CERT= 15,
+
+ /* 5.5 added value of master_heartbeat_period */
+ LINE_FOR_MASTER_HEARTBEAT_PERIOD= 16,
+
+ /* MySQL Cluster 6.3 added master_bind */
+ LINE_FOR_MASTER_BIND = 17,
+ /* 6.0 added value of master_ignore_server_id */
+ LINE_FOR_REPLICATE_IGNORE_SERVER_IDS= 18,
+
+ /* 6.0 added value of master_uuid */
+ LINE_FOR_MASTER_UUID= 19,
-Master_info::Master_info(bool is_slave_recovery)
- :Slave_reporting_capability("I/O"),
- ssl(0), ssl_verify_server_cert(0), fd(-1), io_thd(0),
- rli(is_slave_recovery), port(MYSQL_PORT),
- connect_retry(DEFAULT_CONNECT_RETRY), inited(0), abort_slave(0),
- slave_running(0), slave_run_id(0), clock_diff_with_master(0),
- sync_counter(0), heartbeat_period(0), received_heartbeats(0),
- master_id(0), retry_count(master_retry_count)
+ /* line for master_retry_count */
+ LINE_FOR_MASTER_RETRY_COUNT= 20,
+
+ /* Number of lines currently used when saving master info file */
+ LINES_IN_MASTER_INFO= LINE_FOR_MASTER_RETRY_COUNT
+};
+
+/*
+ Please every time you add a new field to the mater info, update
+ what follows. For now, this is just used to get the number of
+ fields.
+*/
+const char *info_mi_fields []=
+{
+ "number_of_lines",
+ "master_log_name",
+ "master_log_pos",
+ "host",
+ "user",
+ "password",
+ "port",
+ "connect_retry",
+ "ssl",
+ "ssl_ca",
+ "ssl_capath",
+ "ssl_cert",
+ "ssl_cipher",
+ "ssl_key",
+ "ssl_verify_server_cert",
+ "heartbeat_period",
+ "bind",
+ "ignore_server_ids",
+ "uuid",
+ "retry_count"
+};
+
+Master_info::Master_info(PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond)
+ :Rpl_info("I/O", param_key_info_run_lock, param_key_info_data_lock,
+ param_key_info_data_cond, param_key_info_start_cond,
+ param_key_info_stop_cond),
+ ssl(0), ssl_verify_server_cert(0),
+ port(MYSQL_PORT), connect_retry(DEFAULT_CONNECT_RETRY),
+ clock_diff_with_master(0), heartbeat_period(0),
+ received_heartbeats(0), master_id(0), retry_count(master_retry_count)
{
host[0] = 0; user[0] = 0; password[0] = 0;
ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
ssl_cipher[0]= 0; ssl_key[0]= 0;
- master_uuid[0]=0;
-
- 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);
- mysql_mutex_init(key_master_info_data_lock, &data_lock, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_master_info_data_cond, &data_cond, NULL);
- mysql_cond_init(key_master_info_start_cond, &start_cond, NULL);
- mysql_cond_init(key_master_info_stop_cond, &stop_cond, NULL);
+ master_uuid[0]= 0;
+ ignore_server_ids= new Server_ids();
}
Master_info::~Master_info()
{
- delete_dynamic(&ignore_server_ids);
- mysql_mutex_destroy(&run_lock);
- mysql_mutex_destroy(&data_lock);
- mysql_cond_destroy(&data_cond);
- mysql_cond_destroy(&start_cond);
- mysql_cond_destroy(&stop_cond);
+ delete ignore_server_ids;
}
/**
@@ -70,7 +113,6 @@ int change_master_server_id_cmp(ulong *i
return *id1 < *id2? -1 : (*id1 > *id2? 1 : 0);
}
-
/**
Reports if the s_id server has been configured to ignore events
it generates with
@@ -86,484 +128,339 @@ int change_master_server_id_cmp(ulong *i
*/
bool Master_info::shall_ignore_server_id(ulong s_id)
{
- if (likely(ignore_server_ids.elements == 1))
- return (* (ulong*) dynamic_array_ptr(&ignore_server_ids, 0)) == s_id;
+ if (likely(ignore_server_ids->server_ids.elements == 1))
+ return (* (ulong*)
+ dynamic_array_ptr(&(ignore_server_ids->server_ids), 0)) == s_id;
else
return bsearch((const ulong *) &s_id,
- ignore_server_ids.buffer,
- ignore_server_ids.elements, sizeof(ulong),
+ ignore_server_ids->server_ids.buffer,
+ ignore_server_ids->server_ids.elements, sizeof(ulong),
(int (*) (const void*, const void*)) change_master_server_id_cmp)
!= NULL;
}
-void init_master_log_pos(Master_info* mi)
+void Master_info::init_master_log_pos()
{
- DBUG_ENTER("init_master_log_pos");
+ DBUG_ENTER("Master_info::init_master_log_pos");
- mi->master_log_name[0] = 0;
- mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
+ master_log_name[0]= 0;
+ master_log_pos= BIN_LOG_HEADER_SIZE; // skip magic number
/* Intentionally init ssl_verify_server_cert to 0, no option available */
- mi->ssl_verify_server_cert= 0;
+ ssl_verify_server_cert= 0;
/*
always request heartbeat unless master_heartbeat_period is set
explicitly zero. Here is the default value for heartbeat period
if CHANGE MASTER did not specify it. (no data loss in conversion
as hb period has a max)
*/
- mi->heartbeat_period= (float) min(SLAVE_MAX_HEARTBEAT_PERIOD,
- (slave_net_timeout/2.0));
- DBUG_ASSERT(mi->heartbeat_period > (float) 0.001
- || mi->heartbeat_period == 0);
+ heartbeat_period= (float) min(SLAVE_MAX_HEARTBEAT_PERIOD,
+ (slave_net_timeout/2.0));
+ DBUG_ASSERT(heartbeat_period > (float) 0.001
+ || heartbeat_period == 0);
DBUG_VOID_RETURN;
}
-
-enum {
- LINES_IN_MASTER_INFO_WITH_SSL= 14,
-
- /* 5.1.16 added value of master_ssl_verify_server_cert */
- LINE_FOR_MASTER_SSL_VERIFY_SERVER_CERT= 15,
- /* 6.0 added value of master_heartbeat_period */
- LINE_FOR_MASTER_HEARTBEAT_PERIOD= 16,
- /* MySQL Cluster 6.3 added master_bind */
- LINE_FOR_MASTER_BIND = 17,
- /* 6.0 added value of master_ignore_server_id */
- LINE_FOR_REPLICATE_IGNORE_SERVER_IDS= 18,
- /* 6.0 added value of master_uuid */
- LINE_FOR_MASTER_UUID= 19,
- /* line for master_retry_count */
- LINE_FOR_MASTER_RETRY_COUNT= 20,
-
- /* Number of lines currently used when saving master info file */
- LINES_IN_MASTER_INFO= LINE_FOR_MASTER_RETRY_COUNT
-};
-
-int init_master_info(Master_info* mi, const char* master_info_fname,
- const char* slave_info_fname,
- bool abort_if_no_master_info_file,
- int thread_mask)
+void Master_info::end_info()
{
- int fd,error;
- DBUG_ENTER("init_master_info");
+ DBUG_ENTER("Master_info::end_info");
- if (mi->inited)
- {
- /*
- We have to reset read position of relay-log-bin as we may have
- already been reading from 'hotlog' when the slave was stopped
- last time. If this case pos_in_file would be set and we would
- get a crash when trying to read the signature for the binary
- relay log.
-
- We only rewind the read position if we are starting the SQL
- thread. The handle_slave_sql thread assumes that the read
- position is at the beginning of the file, and will read the
- "signature" and then fast-forward to the last position read.
- */
- if (thread_mask & SLAVE_SQL)
- {
- bool hot_log= FALSE;
- /*
- my_b_seek does an implicit flush_io_cache, so we need to:
-
- 1. check if this log is active (hot)
- 2. if it is we keep log_lock until the seek ends, otherwise
- release it right away.
-
- If we did not take log_lock, SQL thread might race with IO
- thread for the IO_CACHE mutex.
-
- */
- mysql_mutex_t *log_lock= mi->rli.relay_log.get_log_lock();
- mysql_mutex_lock(log_lock);
- hot_log= mi->rli.relay_log.is_active(mi->rli.linfo.log_file_name);
-
- if (!hot_log)
- mysql_mutex_unlock(log_lock);
-
- my_b_seek(mi->rli.cur_log, (my_off_t) 0);
-
- if (hot_log)
- mysql_mutex_unlock(log_lock);
- }
- DBUG_RETURN(0);
- }
+ if (!inited)
+ DBUG_VOID_RETURN;
- mi->mysql=0;
- mi->file_id=1;
- fn_format(mi->info_file_name, master_info_fname, mysql_data_home, "",
- MYF(MY_UNPACK_FILENAME|MY_RETURN_REAL_PATH));
+ handler->end_info();
- /*
- We need a mutex while we are changing master info parameters to
- keep other threads from reading bogus info
- */
+ inited = 0;
- mysql_mutex_lock(&mi->data_lock);
- fd = mi->fd;
+ DBUG_VOID_RETURN;
+}
- /* does master.info exist ? */
+/**
+ Store the file and position where the slave's SQL thread are in the
+ relay log.
- if (access(mi->info_file_name, F_OK))
- {
- if (abort_if_no_master_info_file)
- {
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(0);
- }
- /*
- if someone removed the file from underneath our feet, just close
- the old descriptor and re-create the old file
- */
- if (fd >= 0)
- mysql_file_close(fd, MYF(MY_WME));
- if ((fd= mysql_file_open(key_file_master_info, mi->info_file_name,
- O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
- {
- sql_print_error("Failed to create a new master info file (\
-file '%s', errno %d)", mi->info_file_name, my_errno);
- goto err;
- }
- if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
- MYF(MY_WME)))
- {
- sql_print_error("Failed to create a cache on master info file (\
-file '%s')", mi->info_file_name);
- goto err;
- }
+ - This function should be called either from the slave SQL thread,
+ or when the slave thread is not running. (It reads the
+ group_{relay|master}_log_{pos|name} and delay fields in the rli
+ object. These may only be modified by the slave SQL thread or by
+ a client thread when the slave SQL thread is not running.)
+
+ - If there is an active transaction, then we do not update the
+ position in the relay log. This is to ensure that we re-execute
+ statements if we die in the middle of an transaction that was
+ rolled back.
+
+ - As a transaction never spans binary logs, we don't have to handle
+ the case where we do a relay-log-rotation in the middle of the
+ transaction. If transactions could span several binlogs, we would
+ have to ensure that we do not delete the relay log file where the
+ transaction started before switching to a new relay log file.
- mi->fd = fd;
- init_master_log_pos(mi);
+ - Error can happen if writing to file fails or if flushing the file
+ fails.
- }
- else // file exists
- {
- if (fd >= 0)
- reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
- else
- {
- if ((fd= mysql_file_open(key_file_master_info,
- mi->info_file_name, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
- {
- sql_print_error("Failed to open the existing master info file (\
-file '%s', errno %d)", mi->info_file_name, my_errno);
- goto err;
- }
- if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
- 0, MYF(MY_WME)))
- {
- sql_print_error("Failed to create a cache on master info file (\
-file '%s')", mi->info_file_name);
- goto err;
- }
- }
-
- mi->fd = fd;
- int port, connect_retry, master_log_pos, lines;
- int ssl= 0, ssl_verify_server_cert= 0;
- float master_heartbeat_period= 0.0;
- char *first_non_digit;
- char dummy_buf[HOSTNAME_LENGTH+1];
- long retry_count= master_retry_count;
+ @param rli The object representing the Relay_log_info.
- /*
- Starting from 4.1.x master.info has new format. Now its
- first line contains number of lines in file. By reading this
- number we will be always distinguish to which version our
- master.info corresponds to. We can't simply count lines in
- file since versions before 4.1.x could generate files with more
- lines than needed.
- If first line doesn't contain a number or contain number less than
- LINES_IN_MASTER_INFO_WITH_SSL then such file is treated like file
- from pre 4.1.1 version.
- There is no ambiguity when reading an old master.info, as before
- 4.1.1, the first line contained the binlog's name, which is either
- empty or has an extension (contains a '.'), so can't be confused
- with an integer.
+ @todo Change the log file information to a binary format to avoid
+ calling longlong2str.
+*/
+int Master_info::flush_info(bool force)
+{
+ DBUG_ENTER("Master_info::flush_info");
+ DBUG_PRINT("enter",("master_pos: %lu", (ulong) master_log_pos));
- So we're just reading first line and trying to figure which version
- is this.
- */
+ /*
+ We update the sync_period at this point because only here we
+ now that we are handling a master info. This needs to be
+ update every time we call flush because the option maybe
+ dinamically set.
+ */
+ handler->set_sync_period(sync_masterinfo_period);
- /*
- The first row is temporarily stored in mi->master_log_name,
- if it is line count and not binlog name (new format) it will be
- overwritten by the second row later.
- */
- if (init_strvar_from_file(mi->master_log_name,
- sizeof(mi->master_log_name), &mi->file,
- ""))
- goto errwithmsg;
-
- lines= strtoul(mi->master_log_name, &first_non_digit, 10);
-
- if (mi->master_log_name[0]!='\0' &&
- *first_non_digit=='\0' && lines >= LINES_IN_MASTER_INFO_WITH_SSL)
- {
- /* Seems to be new format => read master log name from next line */
- if (init_strvar_from_file(mi->master_log_name,
- sizeof(mi->master_log_name), &mi->file, ""))
- goto errwithmsg;
- }
- else
- lines= 7;
-
- if (init_intvar_from_file(&master_log_pos, &mi->file, 4) ||
- init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file, 0) ||
- init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file, "test") ||
- init_strvar_from_file(mi->password, SCRAMBLED_PASSWORD_CHAR_LENGTH+1,
- &mi->file, 0) ||
- init_intvar_from_file(&port, &mi->file, MYSQL_PORT) ||
- init_intvar_from_file(&connect_retry, &mi->file,
- DEFAULT_CONNECT_RETRY))
- goto errwithmsg;
+ if (write_info(handler, force))
+ goto err;
- /*
- If file has ssl part use it even if we have server without
- SSL support. But these options will be ignored later when
- slave will try connect to master, so in this case warning
- is printed.
- */
- if (lines >= LINES_IN_MASTER_INFO_WITH_SSL)
- {
- if (init_intvar_from_file(&ssl, &mi->file, 0) ||
- init_strvar_from_file(mi->ssl_ca, sizeof(mi->ssl_ca),
- &mi->file, 0) ||
- init_strvar_from_file(mi->ssl_capath, sizeof(mi->ssl_capath),
- &mi->file, 0) ||
- init_strvar_from_file(mi->ssl_cert, sizeof(mi->ssl_cert),
- &mi->file, 0) ||
- init_strvar_from_file(mi->ssl_cipher, sizeof(mi->ssl_cipher),
- &mi->file, 0) ||
- init_strvar_from_file(mi->ssl_key, sizeof(mi->ssl_key),
- &mi->file, 0))
- goto errwithmsg;
+ DBUG_RETURN(0);
- /*
- Starting from 5.1.16 ssl_verify_server_cert might be
- in the file
- */
- if (lines >= LINE_FOR_MASTER_SSL_VERIFY_SERVER_CERT &&
- init_intvar_from_file(&ssl_verify_server_cert, &mi->file, 0))
- goto errwithmsg;
- /*
- Starting from 6.0 master_heartbeat_period might be
- in the file
- */
- if (lines >= LINE_FOR_MASTER_HEARTBEAT_PERIOD &&
- init_floatvar_from_file(&master_heartbeat_period, &mi->file, 0.0))
- goto errwithmsg;
- /*
- Starting from MySQL Cluster 6.3 master_bind might be in the file
- (this is just a reservation to avoid future upgrade problems)
- */
- if (lines >= LINE_FOR_MASTER_BIND &&
- init_strvar_from_file(dummy_buf, sizeof(dummy_buf), &mi->file, ""))
- goto errwithmsg;
- /*
- Starting from 6.0 list of server_id of ignorable servers might be
- in the file
- */
- if (lines >= LINE_FOR_REPLICATE_IGNORE_SERVER_IDS &&
- init_dynarray_intvar_from_file(&mi->ignore_server_ids, &mi->file))
- {
- sql_print_error("Failed to initialize master info ignore_server_ids");
- goto errwithmsg;
- }
-
- if (lines >= LINE_FOR_MASTER_UUID &&
- init_strvar_from_file(mi->master_uuid, sizeof(mi->master_uuid), &mi->file, 0))
- goto errwithmsg;
-
- /* master_retry_count may be in the file. */
- if (lines >= LINE_FOR_MASTER_RETRY_COUNT &&
- init_longvar_from_file(&retry_count, &mi->file, master_retry_count))
- {
- sql_print_error("Failed to initialize master info master_retry_count");
- goto errwithmsg;
- }
+err:
+ sql_print_error("Error writing master configuration");
+ DBUG_RETURN(1);
+}
- }
+void Master_info::set_relay_log_info(Relay_log_info* info)
+{
+ rli= info;
+}
+int Master_info::init_info()
+{
+ DBUG_ENTER("Master_info::init_info");
-#ifndef HAVE_OPENSSL
- if (ssl)
- sql_print_warning("SSL information in the master info file "
- "('%s') are ignored because this MySQL slave was "
- "compiled without SSL support.", mi->info_file_name);
-#endif /* HAVE_OPENSSL */
+ if (inited)
+ DBUG_RETURN(0);
- /*
- This has to be handled here as init_intvar_from_file can't handle
- my_off_t types
- */
- mi->master_log_pos= (my_off_t) master_log_pos;
- mi->port= (uint) port;
- mi->connect_retry= (uint) connect_retry;
- mi->ssl= (my_bool) ssl;
- mi->ssl_verify_server_cert= ssl_verify_server_cert;
- mi->heartbeat_period= master_heartbeat_period;
- mi->retry_count= retry_count;
- }
- DBUG_PRINT("master_info",("log_file_name: %s position: %ld",
- mi->master_log_name,
- (ulong) mi->master_log_pos));
+ /*
+ The init_info() is used to either create or read information
+ from the repository, in order to initialize the Master_info.
+ */
+ mysql= 0; file_id= 1;
+ int necessary_to_configure= check_info();
+
+ if (handler->init_info())
+ goto err;
- mi->rli.mi = mi;
- if (init_relay_log_info(&mi->rli, slave_info_fname))
+ if (necessary_to_configure)
+ {
+ init_master_log_pos();
+ goto end;
+ }
+ else if (read_info(handler))
goto err;
- mi->inited = 1;
- mi->rli.is_relay_log_recovery= FALSE;
- // now change cache READ -> WRITE - must do this before flush_master_info
- reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1);
- if ((error=test(flush_master_info(mi, TRUE, TRUE))))
- sql_print_error("Failed to flush master info file");
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(error);
+end:
+ if (flush_info(TRUE))
+ goto err;
-errwithmsg:
- sql_print_error("Error reading master configuration");
+ inited= 1;
+ DBUG_RETURN(0);
err:
- if (fd >= 0)
- {
- mysql_file_close(fd, MYF(0));
- end_io_cache(&mi->file);
- }
- mi->fd= -1;
- mysql_mutex_unlock(&mi->data_lock);
+ sql_print_error("Error reading master configuration");
DBUG_RETURN(1);
}
+size_t Master_info::get_number_info_mi_fields()
+{
+ return sizeof(info_mi_fields)/sizeof(info_mi_fields[0]);
+}
-/*
- RETURN
- 2 - flush relay log failed
- 1 - flush master info failed
- 0 - all ok
-*/
-int flush_master_info(Master_info* mi,
- bool flush_relay_log_cache,
- bool need_lock_relay_log)
-{
- IO_CACHE* file = &mi->file;
- char lbuf[22];
- int err= 0;
+bool Master_info::read_info(Rpl_info_handler *from)
+{
+ int lines= 0;
+ char *first_non_digit= NULL;
+ ulong temp_master_log_pos= 0;
+ int temp_ssl= 0;
- DBUG_ENTER("flush_master_info");
- DBUG_PRINT("enter",("master_pos: %ld", (long) mi->master_log_pos));
+ DBUG_ENTER("Master_info::read_info");
/*
- Flush the relay log to disk. If we don't do it, then the relay log while
- have some part (its last kilobytes) in memory only, so if the slave server
- dies now, with, say, from master's position 100 to 150 in memory only (not
- on disk), and with position 150 in master.info, then when the slave
- restarts, the I/O thread will fetch binlogs from 150, so in the relay log
- we will have "[0, 100] U [150, infinity[" and nobody will notice it, so the
- SQL thread will jump from 100 to 150, and replication will silently break.
+ Starting from 4.1.x master.info has new format. Now its
+ first line contains number of lines in file. By reading this
+ number we will be always distinguish to which version our
+ master.info corresponds to. We can't simply count lines in
+ file since versions before 4.1.x could generate files with more
+ lines than needed.
+ If first line doesn't contain a number or contain number less than
+ LINES_IN_MASTER_INFO_WITH_SSL then such file is treated like file
+ from pre 4.1.1 version.
+ There is no ambiguity when reading an old master.info, as before
+ 4.1.1, the first line contained the binlog's name, which is either
+ empty or has an extension (contains a '.'), so can't be confused
+ with an integer.
- When we come to this place in code, relay log may or not be initialized;
- the caller is responsible for setting 'flush_relay_log_cache' accordingly.
+ So we're just reading first line and trying to figure which version
+ is this.
*/
- if (flush_relay_log_cache)
- {
- mysql_mutex_t *log_lock= mi->rli.relay_log.get_log_lock();
- IO_CACHE *log_file= mi->rli.relay_log.get_log_file();
-
- if (need_lock_relay_log)
- mysql_mutex_lock(log_lock);
- mysql_mutex_assert_owner(log_lock);
- err= flush_io_cache(log_file);
+ if (from->prepare_info_for_read() ||
+ from->get_info(master_log_name, sizeof(master_log_name), ""))
+ DBUG_RETURN(TRUE);
- if (need_lock_relay_log)
- mysql_mutex_unlock(log_lock);
+ lines= strtoul(master_log_name, &first_non_digit, 10);
- if (err)
- DBUG_RETURN(2);
+ if (master_log_name[0]!='\0' &&
+ *first_non_digit=='\0' && lines >= LINES_IN_MASTER_INFO_WITH_SSL)
+ {
+ /* Seems to be new format => read master log name */
+ if (from->get_info(master_log_name, sizeof(master_log_name), ""))
+ DBUG_RETURN(TRUE);
}
-
+ else
+ lines= 7;
+
+ if (from->get_info(&temp_master_log_pos,
+ (ulong) BIN_LOG_HEADER_SIZE) ||
+ from->get_info(host, sizeof(host), 0) ||
+ from->get_info(user, sizeof(user), "test") ||
+ from->get_info(password, sizeof(password), 0) ||
+ from->get_info((int *) &port, (int) MYSQL_PORT) ||
+ from->get_info((int *) &connect_retry,
+ (int) DEFAULT_CONNECT_RETRY))
+ DBUG_RETURN(TRUE);
+
/*
- produce a line listing the total number and all the ignored server_id:s
+ If file has ssl part use it even if we have server without
+ SSL support. But these options will be ignored later when
+ slave will try connect to master, so in this case warning
+ is printed.
*/
- char* ignore_server_ids_buf;
+ if (lines >= LINES_IN_MASTER_INFO_WITH_SSL)
{
- ignore_server_ids_buf=
- (char *) my_malloc((sizeof(::server_id) * 3 + 1) *
- (1 + mi->ignore_server_ids.elements), MYF(MY_WME));
- if (!ignore_server_ids_buf)
- DBUG_RETURN(1);
- ulong cur_len= sprintf(ignore_server_ids_buf, "%u",
- mi->ignore_server_ids.elements);
- for (ulong i= 0; i < mi->ignore_server_ids.elements; i++)
- {
- ulong s_id;
- get_dynamic(&mi->ignore_server_ids, (uchar*) &s_id, i);
- cur_len+= sprintf(ignore_server_ids_buf + cur_len, " %lu", s_id);
- }
+ if (from->get_info((int *) &temp_ssl, 0) ||
+ from->get_info(ssl_ca, sizeof(ssl_ca), 0) ||
+ from->get_info(ssl_capath, sizeof(ssl_capath), 0) ||
+ from->get_info(ssl_cert, sizeof(ssl_cert), 0) ||
+ from->get_info(ssl_cipher, sizeof(ssl_cipher), 0) ||
+ from->get_info(ssl_key, sizeof(ssl_key), 0))
+ DBUG_RETURN(TRUE);
}
/*
- We flushed the relay log BEFORE the master.info file, because if we crash
- now, we will get a duplicate event in the relay log at restart. If we
- flushed in the other order, we would get a hole in the relay log.
- And duplicate is better than hole (with a duplicate, in later versions we
- can add detection and scrap one event; with a hole there's nothing we can
- do).
+ Starting from 5.1.16 ssl_verify_server_cert might be
+ in the file
*/
+ if (lines >= LINE_FOR_MASTER_SSL_VERIFY_SERVER_CERT)
+ {
+ if (from->get_info((int *) &ssl_verify_server_cert, 0))
+ DBUG_RETURN(TRUE);
+ }
/*
- In certain cases this code may create master.info files that seems
- corrupted, because of extra lines filled with garbage in the end
- file (this happens if new contents take less space than previous
- contents of file). But because of number of lines in the first line
- of file we don't care about this garbage.
+ Starting from 5.5 master_heartbeat_period might be
+ in the file
*/
- char heartbeat_buf[sizeof(mi->heartbeat_period) * 4]; // buffer to suffice always
- sprintf(heartbeat_buf, "%.3f", mi->heartbeat_period);
- my_b_seek(file, 0L);
- my_b_printf(file,
- "%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n%s\n%s\n%ld\n",
- LINES_IN_MASTER_INFO,
- mi->master_log_name, llstr(mi->master_log_pos, lbuf),
- mi->host, mi->user,
- mi->password, mi->port, mi->connect_retry,
- (int)(mi->ssl), mi->ssl_ca, mi->ssl_capath, mi->ssl_cert,
- mi->ssl_cipher, mi->ssl_key, mi->ssl_verify_server_cert,
- heartbeat_buf, "", ignore_server_ids_buf, mi->master_uuid,
- mi->retry_count);
- my_free(ignore_server_ids_buf);
- err= flush_io_cache(file);
- if (sync_masterinfo_period && !err &&
- ++(mi->sync_counter) >= sync_masterinfo_period)
+ if (lines >= LINE_FOR_MASTER_HEARTBEAT_PERIOD)
{
- err= my_sync(mi->fd, MYF(MY_WME));
- mi->sync_counter= 0;
+ if (from->get_info(&heartbeat_period, (float) 0.0))
+ DBUG_RETURN(TRUE);
}
- DBUG_RETURN(-err);
-}
+ /*
+ Starting from 5.5 master_bind might be in the file
+ */
+ if (lines >= LINE_FOR_MASTER_BIND)
+ {
+ /*
+ This is a placeholder for the bind option.
+ Please, update this after WL#3126 and
+ WL#3127.
+ */
+ char fake_bind[2];
+ if (from->get_info(fake_bind, sizeof(fake_bind), ""))
+ DBUG_RETURN(TRUE);
+ }
-void end_master_info(Master_info* mi)
-{
- DBUG_ENTER("end_master_info");
+ /*
+ Starting from 5.5 list of server_id of ignorable servers might be
+ in the file
+ */
+ if (lines >= LINE_FOR_REPLICATE_IGNORE_SERVER_IDS)
+ {
+ if (from->get_info(ignore_server_ids, (Server_ids *) NULL))
+ DBUG_RETURN(TRUE);
+ }
- if (!mi->inited)
- DBUG_VOID_RETURN;
- end_relay_log_info(&mi->rli);
- if (mi->fd >= 0)
+ /* Starting from 5.5 the master_uuid may be in the repository. */
+ if (lines >= LINE_FOR_MASTER_UUID)
{
- end_io_cache(&mi->file);
- mysql_file_close(mi->fd, MYF(MY_WME));
- mi->fd = -1;
+ if (from->get_info(master_uuid, sizeof(master_uuid), 0))
+ DBUG_RETURN(TRUE);
}
- mi->inited = 0;
- DBUG_VOID_RETURN;
+ /* Starting from 5.5 the master_retry_count may be in the repository. */
+ retry_count= master_retry_count;
+ if (lines >= LINE_FOR_MASTER_RETRY_COUNT)
+ {
+ if (from->get_info(&retry_count, master_retry_count))
+ DBUG_RETURN(TRUE);
+ }
+
+ ssl= (my_bool) temp_ssl;
+ master_log_pos= (my_off_t) temp_master_log_pos;
+#ifndef HAVE_OPENSSL
+ if (ssl)
+ sql_print_warning("SSL information in the master info file "
+ "are ignored because this MySQL slave was "
+ "compiled without SSL support.");
+#endif /* HAVE_OPENSSL */
+
+ DBUG_RETURN(FALSE);
}
+bool Master_info::write_info(Rpl_info_handler *to, bool force)
+{
+ DBUG_ENTER("Master_info::write_info");
+ /*
+ In certain cases this code may create master.info files that seems
+ corrupted, because of extra lines filled with garbage in the end
+ file (this happens if new contents take less space than previous
+ contents of file). But because of number of lines in the first line
+ of file we don't care about this garbage.
+ */
+
+ if (to->prepare_info_for_write() ||
+ to->set_info((int) LINES_IN_MASTER_INFO) ||
+ to->set_info(master_log_name) ||
+ to->set_info((ulong)master_log_pos) ||
+ to->set_info(host) ||
+ to->set_info(user) ||
+ to->set_info(password) ||
+ to->set_info((int) port) ||
+ to->set_info((int) connect_retry) ||
+ to->set_info((int) ssl) ||
+ to->set_info(ssl_ca) ||
+ to->set_info(ssl_capath) ||
+ to->set_info(ssl_cert) ||
+ to->set_info(ssl_cipher) ||
+ to->set_info(ssl_key) ||
+ to->set_info(ssl_verify_server_cert) ||
+ to->set_info(heartbeat_period) ||
+ /*
+ This is a placeholder for the bind option.
+ Please, update this after WL#3126 and
+ WL#3127.
+ */
+ to->set_info("") ||
+ to->set_info(ignore_server_ids) ||
+ to->set_info(master_uuid) ||
+ to->set_info(retry_count))
+ DBUG_RETURN(TRUE);
+
+ if (to->flush_info(force))
+ DBUG_RETURN(TRUE);
+
+ DBUG_RETURN(FALSE);
+}
#endif /* HAVE_REPLICATION */
=== modified file 'sql/rpl_mi.h'
--- a/sql/rpl_mi.h 2010-07-29 09:31:24 +0000
+++ b/sql/rpl_mi.h 2010-08-05 17:45:25 +0000
@@ -18,8 +18,12 @@
#ifdef HAVE_REPLICATION
+#include <my_global.h>
+#include <sql_priv.h>
+
+#define DEFAULT_CONNECT_RETRY 60
+
#include "rpl_rli.h"
-#include "rpl_reporting.h"
#include "my_sys.h"
typedef struct st_mysql MYSQL;
@@ -33,12 +37,12 @@ typedef struct st_mysql MYSQL;
- current master log offset
- misc control variables
- Master_info is initialized once from the master.info file if such
+ Master_info is initialized once from the master.info repository if such
exists. Otherwise, data members corresponding to master.info fields
are initialized with defaults specified by master-* options. The
- initialization is done through init_master_info() call.
+ initialization is done through init_info() call.
- The format of master.info file:
+ Logically, the format of master.info repository is presented as follows:
log_name
log_pos
@@ -48,23 +52,25 @@ typedef struct st_mysql MYSQL;
master_port
master_connect_retry
- To write out the contents of master.info file to disk ( needed every
- time we read and queue data from the master ), a call to
- flush_master_info() is required.
+ To write out the contents of master.info to disk a call to flush_info()
+ is required. Currently, it is needed every time we read and queue data
+ from the master.
- To clean up, call end_master_info()
+ To clean up, call end_info()
*****************************************************************************/
-class Master_info : public Slave_reporting_capability
+class Master_info : public Rpl_info
{
public:
- Master_info(bool is_slave_recovery);
- ~Master_info();
- bool shall_ignore_server_id(ulong s_id);
+ Master_info(PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond);
+ virtual ~Master_info();
/* the variables below are needed because we can change masters on the fly */
- char master_log_name[FN_REFLEN];
char host[HOSTNAME_LENGTH+1];
char user[USERNAME_LENGTH+1];
char password[MAX_PASSWORD_LENGTH+1];
@@ -73,25 +79,11 @@ class Master_info : public Slave_reporti
char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN];
my_bool ssl_verify_server_cert;
- my_off_t master_log_pos;
- File fd; // we keep the file open, so we need to remember the file pointer
- IO_CACHE file;
-
- mysql_mutex_t data_lock, run_lock;
- mysql_cond_t data_cond, start_cond, stop_cond;
- THD *io_thd;
MYSQL* mysql;
uint32 file_id; /* for 3.23 load data infile */
- Relay_log_info rli;
+ Relay_log_info *rli;
uint port;
uint connect_retry;
-#ifndef DBUG_OFF
- int events_till_disconnect;
-#endif
- bool inited;
- volatile bool abort_slave;
- volatile uint slave_running;
- volatile ulong slave_run_id;
/*
The difference in seconds between the clock of the master and the clock of
the slave (second - first). It must be signed as it may be <0 or >0.
@@ -102,29 +94,49 @@ class Master_info : public Slave_reporti
*/
long clock_diff_with_master;
- /*
- Keeps track of the number of events before fsyncing.
- The option --sync-master-info determines how many
- events should happen before fsyncing.
- */
- uint sync_counter;
float heartbeat_period; // interface with CHANGE MASTER or master.info
ulonglong received_heartbeats; // counter of received heartbeat events
- DYNAMIC_ARRAY ignore_server_ids;
+ Server_ids *ignore_server_ids;
ulong master_id;
ulong retry_count;
char master_uuid[UUID_LENGTH+1];
- char info_file_name[FN_REFLEN + 128];
+
+ int init_info();
+ void end_info();
+ int flush_info(bool force= FALSE);
+ void set_relay_log_info(Relay_log_info *info);
+
+ bool shall_ignore_server_id(ulong s_id);
+
+protected:
+ char master_log_name[FN_REFLEN];
+ my_off_t master_log_pos;
+
+public:
+ void init_master_log_pos();
+ inline const char* get_master_log_name() { return master_log_name; }
+ inline ulonglong get_master_log_pos() { return master_log_pos; }
+ inline void set_master_log_name(const char *log_file_name)
+ {
+ strmake(master_log_name, log_file_name, sizeof(master_log_name) - 1);
+ }
+ inline void set_master_log_pos(ulonglong log_pos)
+ {
+ master_log_pos= log_pos;
+ }
+ inline const char* get_io_rpl_log_name()
+ {
+ return (master_log_name[0] ? master_log_name : "FIRST");
+ }
+ size_t get_number_info_mi_fields();
+
+private:
+ bool read_info(Rpl_info_handler *from);
+ bool write_info(Rpl_info_handler *to, bool force);
+
+ Master_info& operator=(const Master_info& info);
+ Master_info(const Master_info& info);
};
-void init_master_log_pos(Master_info* mi);
-int init_master_info(Master_info* mi, const char* master_info_fname,
- const char* slave_info_fname,
- bool abort_if_no_master_info_file,
- int thread_mask);
-void end_master_info(Master_info* mi);
-int flush_master_info(Master_info* mi,
- bool flush_relay_log_cache,
- bool need_lock_relay_log);
int change_master_server_id_cmp(ulong *id1, ulong *id2);
#endif /* HAVE_REPLICATION */
=== modified file 'sql/rpl_reporting.h'
--- a/sql/rpl_reporting.h 2010-07-27 14:04:13 +0000
+++ b/sql/rpl_reporting.h 2010-08-05 17:45:25 +0000
@@ -94,13 +94,13 @@ public:
localtime_r(&skr, &tm_tmp);
start=&tm_tmp;
- sprintf(timestamp, "%02d%02d%02d %02d:%02d:%02d",
- start->tm_year % 100,
- start->tm_mon+1,
- start->tm_mday,
- start->tm_hour,
- start->tm_min,
- start->tm_sec);
+ sprintf(timestamp, "%02d%02d%02d %02d:%02d:%02d",
+ start->tm_year % 100,
+ start->tm_mon+1,
+ start->tm_mday,
+ start->tm_hour,
+ start->tm_min,
+ start->tm_sec);
timestamp[15]= '\0';
}
=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc 2010-09-17 11:32:06 +0000
+++ b/sql/rpl_rli.cc 2010-10-17 23:27:40 +0000
@@ -28,21 +28,40 @@
#include "sql_parse.h" // end_trans, ROLLBACK
#include "rpl_slave.h"
-static int count_relay_log_space(Relay_log_info* rli);
+/*
+ Please every time you add a new field to the relay log info, update
+ what follows. For now, this is just used to get the number of
+ fields.
+*/
+const char* info_rli_fields[]=
+{
+ "number_of_lines",
+ "group_relay_log_name",
+ "group_relay_log_pos",
+ "group_master_log_name",
+ "group_master_log_pos",
+ "sql_delay"
+};
const char *const Relay_log_info::state_delaying_string = "Waiting until MASTER_DELAY seconds after master executed event";
-Relay_log_info::Relay_log_info(bool is_slave_recovery)
- :Slave_reporting_capability("SQL"),
+Relay_log_info::Relay_log_info(bool is_slave_recovery,
+ PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond)
+ :Rpl_info("SQL", param_key_info_run_lock, param_key_info_data_lock,
+ param_key_info_data_cond, param_key_info_start_cond,
+ param_key_info_stop_cond),
replicate_same_server_id(::replicate_same_server_id),
- info_fd(-1), cur_log_fd(-1), relay_log(&sync_relaylog_period),
- sync_counter(0), is_relay_log_recovery(is_slave_recovery),
+ cur_log_fd(-1), relay_log(&sync_relaylog_period),
+ is_relay_log_recovery(is_slave_recovery),
save_temporary_tables(0),
cur_log_old_open_count(0), group_relay_log_pos(0), event_relay_log_pos(0),
group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0),
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),
+ abort_pos_wait(0), until_condition(UNTIL_NONE),
until_log_pos(0), retried_trans(0),
tables_to_lock(0), tables_to_lock_count(0),
rows_query_ev(NULL), last_event_start_time(0),
@@ -54,382 +73,26 @@ Relay_log_info::Relay_log_info(bool is_s
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;
- bzero((char*) &info_file, sizeof(info_file));
bzero((char*) &cache_buf, sizeof(cache_buf));
cached_charset_invalidate();
- mysql_mutex_init(key_relay_log_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST);
- mysql_mutex_init(key_relay_log_info_data_lock,
- &data_lock, MY_MUTEX_INIT_FAST);
mysql_mutex_init(key_relay_log_info_log_space_lock,
&log_space_lock, MY_MUTEX_INIT_FAST);
- mysql_cond_init(key_relay_log_info_data_cond, &data_cond, NULL);
- mysql_cond_init(key_relay_log_info_start_cond, &start_cond, NULL);
- mysql_cond_init(key_relay_log_info_stop_cond, &stop_cond, NULL);
mysql_cond_init(key_relay_log_info_log_space_cond, &log_space_cond, NULL);
relay_log.init_pthread_objects();
DBUG_VOID_RETURN;
}
-
Relay_log_info::~Relay_log_info()
{
DBUG_ENTER("Relay_log_info::~Relay_log_info");
- mysql_mutex_destroy(&run_lock);
- mysql_mutex_destroy(&data_lock);
mysql_mutex_destroy(&log_space_lock);
- mysql_cond_destroy(&data_cond);
- mysql_cond_destroy(&start_cond);
- mysql_cond_destroy(&stop_cond);
mysql_cond_destroy(&log_space_cond);
relay_log.cleanup();
- DBUG_VOID_RETURN;
-}
-
-
-/**
- Wrapper around Relay_log_info::init(const char *).
-
- @todo Remove this and replace all calls to it by calls to
- Relay_log_info::init(const char *). /SVEN
-*/
-int init_relay_log_info(Relay_log_info* rli,
- const char* info_fname)
-{
- return rli->init(info_fname);
-}
-
-
-/**
- Read the relay_log.info file.
-
- @param info_fname The name of the file to read from.
- @retval 0 success
- @retval 1 failure
-*/
-int Relay_log_info::init(const char* info_fname)
-{
- char fname[FN_REFLEN+128];
- const char* msg = 0;
- int error = 0;
- DBUG_ENTER("init_relay_log_info");
-
- /*
- Should not read RLI from file in client threads. Client threads
- only use RLI to execute BINLOG statements.
-
- @todo Uncomment the following assertion. Currently,
- Relay_log_info::init() is called from init_master_info() before
- the THD object Relay_log_info::sql_thd is created. That means we
- cannot call belongs_to_client() since belongs_to_client()
- dereferences Relay_log_info::sql_thd. So we need to refactor
- slightly: the THD object should be created by Relay_log_info
- constructor (or passed to it), so that we are guaranteed that it
- exists at this point. /Sven
- */
- // DBUG_ASSERT(!belongs_to_client());
-
- if (inited) // Set if this function called
- DBUG_RETURN(0);
- fn_format(fname, info_fname, mysql_data_home, "", 4+32);
- mysql_mutex_lock(&data_lock);
- cur_log_fd = -1;
- slave_skip_counter=0;
- abort_pos_wait=0;
- log_space_limit= relay_log_space_limit;
- log_space_total= 0;
- tables_to_lock= 0;
- tables_to_lock_count= 0;
-
- char pattern[FN_REFLEN];
- (void) my_realpath(pattern, slave_load_tmpdir, 0);
- if (fn_format(pattern, PREFIX_SQL_LOAD, pattern, "",
- MY_SAFE_PATH | MY_RETURN_REAL_PATH) == NullS)
- {
- mysql_mutex_unlock(&data_lock);
- sql_print_error("Unable to use slave's temporary directory %s",
- slave_load_tmpdir);
- DBUG_RETURN(1);
- }
- unpack_filename(slave_patternload_file, pattern);
- slave_patternload_file_size= strlen(slave_patternload_file);
-
- /*
- The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
- Note that the I/O thread flushes it to disk after writing every
- 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
- relay_log.max_size (and mysql_bin_log.max_size).
- */
- {
- /* Reports an error and returns, if the --relay-log's path
- is a directory.*/
- if (opt_relay_logname &&
- opt_relay_logname[strlen(opt_relay_logname) - 1] == FN_LIBCHAR)
- {
- mysql_mutex_unlock(&data_lock);
- sql_print_error("Path '%s' is a directory name, please specify \
-a file name for --relay-log option", opt_relay_logname);
- DBUG_RETURN(1);
- }
-
- /* Reports an error and returns, if the --relay-log-index's path
- is a directory.*/
- if (opt_relaylog_index_name &&
- opt_relaylog_index_name[strlen(opt_relaylog_index_name) - 1]
- == FN_LIBCHAR)
- {
- mysql_mutex_unlock(&data_lock);
- sql_print_error("Path '%s' is a directory name, please specify \
-a file name for --relay-log-index option", opt_relaylog_index_name);
- DBUG_RETURN(1);
- }
-
- char buf[FN_REFLEN];
- const char *ln;
- static bool name_warning_sent= 0;
- ln= relay_log.generate_name(opt_relay_logname, "-relay-bin",
- 1, buf);
- /* We send the warning only at startup, not after every RESET SLAVE */
- if (!opt_relay_logname && !opt_relaylog_index_name && !name_warning_sent)
- {
- /*
- User didn't give us info to name the relay log index file.
- Picking `hostname`-relay-bin.index like we do, causes replication to
- fail if this slave's hostname is changed later. So, we would like to
- instead require a name. But as we don't want to break many existing
- setups, we only give warning, not error.
- */
- sql_print_warning("Neither --relay-log nor --relay-log-index were used;"
- " so replication "
- "may break when this MySQL server acts as a "
- "slave and has his hostname changed!! Please "
- "use '--relay-log=%s' to avoid this problem.", ln);
- name_warning_sent= 1;
- }
- /*
- note, that if open() fails, we'll still have index file open
- but a destructor will take care of that
- */
- if (relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE) ||
- relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
- (max_relay_log_size ? max_relay_log_size :
- max_binlog_size), 1, TRUE))
- {
- mysql_mutex_unlock(&data_lock);
- sql_print_error("Failed in open_log() called from init_relay_log_info()");
- DBUG_RETURN(1);
- }
- relay_log.is_relay_log= TRUE;
- }
-
- /* if file does not exist */
- if (access(fname,F_OK))
- {
- /*
- If someone removed the file from underneath our feet, just close
- the old descriptor and re-create the old file
- */
- if (info_fd >= 0)
- mysql_file_close(info_fd, MYF(MY_WME));
- if ((info_fd= mysql_file_open(key_file_relay_log_info,
- fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
- {
- sql_print_error("Failed to create a new relay log info file (\
-file '%s', errno %d)", fname, my_errno);
- msg= current_thd->stmt_da->message();
- goto err;
- }
- if (init_io_cache(&info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
- MYF(MY_WME)))
- {
- sql_print_error("Failed to create a cache on relay log info file '%s'",
- fname);
- msg= current_thd->stmt_da->message();
- goto err;
- }
-
- /* Init relay log with first entry in the relay index file */
- if (init_relay_log_pos(this,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */,
- &msg, 0))
- {
- sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4)");
- goto err;
- }
- group_master_log_name[0]= 0;
- group_master_log_pos= 0;
- }
- else // file exists
- {
- if (info_fd >= 0)
- reinit_io_cache(&info_file, READ_CACHE, 0L,0,0);
- else
- {
- int error=0;
- if ((info_fd= mysql_file_open(key_file_relay_log_info,
- fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
- {
- sql_print_error("\
-Failed to open the existing relay log info file '%s' (errno %d)",
- fname, my_errno);
- error= 1;
- }
- else if (init_io_cache(&info_file, info_fd,
- IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME)))
- {
- sql_print_error("Failed to create a cache on relay log info file '%s'",
- fname);
- error= 1;
- }
- if (error)
- {
- if (info_fd >= 0)
- mysql_file_close(info_fd, MYF(0));
- info_fd= -1;
- relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
- mysql_mutex_unlock(&data_lock);
- DBUG_RETURN(1);
- }
- }
-
- int relay_log_pos, master_log_pos, lines;
- char *first_non_digit;
-
- /*
- Starting from 5.1.x, relay-log.info has a new format. Now, its
- first line contains the number of lines in the file. By reading
- this number we can determine which version our master.info comes
- from. We can't simply count the lines in the file, since
- versions before 5.1.x could generate files with more lines than
- needed. If first line doesn't contain a number, or if it
- contains a number less than LINES_IN_RELAY_LOG_INFO_WITH_DELAY,
- then the file is treated like a file from pre-5.1.x version.
- There is no ambiguity when reading an old master.info: before
- 5.1.x, the first line contained the binlog's name, which is
- either empty or has an extension (contains a '.'), so can't be
- confused with an integer.
-
- So we're just reading first line and trying to figure which
- version is this.
- */
-
- /*
- The first row is temporarily stored in mi->master_log_name, if
- it is line count and not binlog name (new format) it will be
- overwritten by the second row later.
- */
- if (init_strvar_from_file(group_relay_log_name,
- sizeof(group_relay_log_name),
- &info_file, ""))
- {
- msg="Error reading slave log configuration";
- goto err;
- }
- lines= strtoul(group_relay_log_name, &first_non_digit, 10);
-
- if (group_relay_log_name[0] != '\0' &&
- *first_non_digit == '\0' &&
- lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY)
- {
- DBUG_PRINT("info", ("relay_log_info file is in new format."));
- /* Seems to be new format => read relay log name from next line */
- if (init_strvar_from_file(group_relay_log_name,
- sizeof(group_relay_log_name),
- &info_file, ""))
- {
- msg="Error reading slave log configuration";
- goto err;
- }
- }
- else
- DBUG_PRINT("info", ("relay_log_info file is in old format."));
-
- if (init_intvar_from_file(&relay_log_pos,
- &info_file, BIN_LOG_HEADER_SIZE) ||
- init_strvar_from_file(group_master_log_name,
- sizeof(group_master_log_name),
- &info_file, "") ||
- init_intvar_from_file(&master_log_pos, &info_file, 0) ||
- (lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY &&
- init_intvar_from_file(&sql_delay, &info_file, 0)))
- {
- msg="Error reading slave log configuration";
- goto err;
- }
-
- strmake(event_relay_log_name,group_relay_log_name,
- sizeof(event_relay_log_name)-1);
- group_relay_log_pos= event_relay_log_pos= relay_log_pos;
- group_master_log_pos= master_log_pos;
-
- if (is_relay_log_recovery && init_recovery(mi, &msg))
- goto err;
-
- if (init_relay_log_pos(this,
- group_relay_log_name,
- group_relay_log_pos,
- 0 /* no data lock*/,
- &msg, 0))
- {
- char llbuf[22];
- sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s)",
- group_relay_log_name,
- llstr(group_relay_log_pos, llbuf));
- goto err;
- }
- }
-
-#ifndef DBUG_OFF
- {
- char llbuf1[22], llbuf2[22];
- DBUG_PRINT("info", ("my_b_tell(cur_log)=%s event_relay_log_pos=%s",
- llstr(my_b_tell(cur_log),llbuf1),
- llstr(event_relay_log_pos,llbuf2)));
- DBUG_ASSERT(event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
- DBUG_ASSERT(my_b_tell(cur_log) == event_relay_log_pos);
- }
-#endif
-
- /*
- Now change the cache from READ to WRITE - must do this
- before flush_relay_log_info
- */
- reinit_io_cache(&info_file, WRITE_CACHE,0L,0,1);
- if ((error= flush_relay_log_info(this)))
- {
- msg= "Failed to flush relay log info file";
- goto err;
- }
- if (count_relay_log_space(this))
- {
- msg="Error counting relay log space";
- goto err;
- }
- inited= 1;
- mysql_mutex_unlock(&data_lock);
- DBUG_RETURN(error);
-
-err:
- sql_print_error("%s", msg);
- end_io_cache(&info_file);
- if (info_fd >= 0)
- mysql_file_close(info_fd, MYF(0));
- info_fd= -1;
- relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
- mysql_mutex_unlock(&data_lock);
- DBUG_RETURN(1);
+ DBUG_VOID_RETURN;
}
-
static inline int add_relay_log(Relay_log_info* rli,LOG_INFO* linfo)
{
MY_STAT s;
@@ -449,38 +112,32 @@ static inline int add_relay_log(Relay_lo
DBUG_RETURN(0);
}
-
-static int count_relay_log_space(Relay_log_info* rli)
+int Relay_log_info::count_relay_log_space()
{
- LOG_INFO linfo;
- DBUG_ENTER("count_relay_log_space");
- rli->log_space_total= 0;
- if (rli->relay_log.find_log_pos(&linfo, NullS, 1))
+ LOG_INFO flinfo;
+ DBUG_ENTER("Relay_log_info::count_relay_log_space");
+ log_space_total= 0;
+ if (relay_log.find_log_pos(&flinfo, NullS, 1))
{
sql_print_error("Could not find first log while counting relay log space");
DBUG_RETURN(1);
}
do
{
- if (add_relay_log(rli,&linfo))
+ if (add_relay_log(this, &flinfo))
DBUG_RETURN(1);
- } while (!rli->relay_log.find_next_log(&linfo, 1));
+ } while (!relay_log.find_next_log(&flinfo, 1));
/*
As we have counted everything, including what may have written in a
preceding write, we must reset bytes_written, or we may count some space
twice.
*/
- rli->relay_log.reset_bytes_written();
+ relay_log.reset_bytes_written();
DBUG_RETURN(0);
}
-
-/*
- Reset UNTIL condition for Relay_log_info
-
- SYNOPSYS
- clear_until_condition()
- rli - Relay_log_info structure where UNTIL condition should be reset
+/**
+ Resets UNTIL condition for Relay_log_info
*/
void Relay_log_info::clear_until_condition()
@@ -493,52 +150,46 @@ void Relay_log_info::clear_until_conditi
DBUG_VOID_RETURN;
}
+/**
+ Opens and intialize the given relay log. Specifically, it does what follows:
-/*
- Open the given relay log
-
- SYNOPSIS
- init_relay_log_pos()
- rli Relay information (will be initialized)
- log Name of relay log file to read from. NULL = First log
- pos Position in relay log file
- need_data_lock Set to 1 if this functions should do mutex locks
- errmsg Store pointer to error message here
- look_for_description_event
- 1 if we should look for such an event. We only need
- this when the SQL thread starts and opens an existing
- relay log and has to execute it (possibly from an
- offset >4); then we need to read the first event of
- the relay log to be able to parse the events we have
- to execute.
-
- DESCRIPTION
- - Close old open relay log files.
- - If we are using the same relay log as the running IO-thread, then set
+ - Closes old open relay log files.
+ - If we are using the same relay log as the running IO-thread, then sets.
rli->cur_log to point to the same IO_CACHE entry.
- - If not, open the 'log' binary file.
+ - If not, opens the 'log' binary file.
+
+ @todo check proper initialization of group_master_log_name/group_master_log_pos.
- TODO
- - check proper initialization of group_master_log_name/group_master_log_pos
- RETURN VALUES
- 0 ok
- 1 error. errmsg is set to point to the error message
+ @param rli[in] Relay information (will be initialized)
+ @param log[in] Name of relay log file to read from. NULL = First log
+ @param pos[in] Position in relay log file
+ @param need_data_lock[in] Set to 1 if this functions should do mutex locks
+ @param errmsg[out] Store pointer to error message here
+ @param look_for_description_event[in]
+ 1 if we should look for such an event. We only need
+ this when the SQL thread starts and opens an existing
+ relay log and has to execute it (possibly from an
+ offset >4); then we need to read the first event of
+ the relay log to be able to parse the events we have
+ to execute.
+ @retval 0 ok,
+ @retval 1 otherwise error, where errmsg is set to point to the error message.
*/
-int init_relay_log_pos(Relay_log_info* rli,const char* log,
- ulonglong pos, bool need_data_lock,
- const char** errmsg,
- bool look_for_description_event)
+int Relay_log_info::init_relay_log_pos(const char* log,
+ ulonglong pos, bool need_data_lock,
+ const char** errmsg,
+ bool look_for_description_event)
{
- DBUG_ENTER("init_relay_log_pos");
+ DBUG_ENTER("Relay_log_info::init_relay_log_pos");
DBUG_PRINT("info", ("pos: %lu", (ulong) pos));
*errmsg=0;
- mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
+ mysql_mutex_t *log_lock= relay_log.get_log_lock();
if (need_data_lock)
- mysql_mutex_lock(&rli->data_lock);
+ mysql_mutex_lock(&data_lock);
/*
Slave threads are not the only users of init_relay_log_pos(). CHANGE MASTER
@@ -548,68 +199,70 @@ int init_relay_log_pos(Relay_log_info* r
the description_event here, in case, so that there is no memory leak in
running, say, CHANGE MASTER.
*/
- delete rli->relay_log.description_event_for_exec;
+ delete relay_log.description_event_for_exec;
/*
By default the relay log is in binlog format 3 (4.0).
Even if format is 4, this will work enough to read the first event
(Format_desc) (remember that format 4 is just lenghtened compared to format
3; format 3 is a prefix of format 4).
*/
- rli->relay_log.description_event_for_exec= new
+ relay_log.description_event_for_exec= new
Format_description_log_event(3);
mysql_mutex_lock(log_lock);
/* Close log file and free buffers if it's already open */
- if (rli->cur_log_fd >= 0)
+ if (cur_log_fd >= 0)
{
- end_io_cache(&rli->cache_buf);
- mysql_file_close(rli->cur_log_fd, MYF(MY_WME));
- rli->cur_log_fd = -1;
+ end_io_cache(&cache_buf);
+ mysql_file_close(cur_log_fd, MYF(MY_WME));
+ cur_log_fd = -1;
}
- rli->group_relay_log_pos = rli->event_relay_log_pos = pos;
+ group_relay_log_pos= event_relay_log_pos= pos;
/*
Test to see if the previous run was with the skip of purging
If yes, we do not purge when we restart
*/
- if (rli->relay_log.find_log_pos(&rli->linfo, NullS, 1))
+ if (relay_log.find_log_pos(&linfo, NullS, 1))
{
*errmsg="Could not find first log during relay log initialization";
goto err;
}
- if (log && rli->relay_log.find_log_pos(&rli->linfo, log, 1))
+ if (log && relay_log.find_log_pos(&linfo, log, 1))
{
*errmsg="Could not find target log during relay log initialization";
goto err;
}
- strmake(rli->group_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->group_relay_log_name)-1);
- strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->event_relay_log_name)-1);
- if (rli->relay_log.is_active(rli->linfo.log_file_name))
+
+ strmake(group_relay_log_name, linfo.log_file_name,
+ sizeof(group_relay_log_name) - 1);
+ strmake(event_relay_log_name, linfo.log_file_name,
+ sizeof(event_relay_log_name) - 1);
+
+ if (relay_log.is_active(linfo.log_file_name))
{
/*
The IO thread is using this log file.
In this case, we will use the same IO_CACHE pointer to
read data as the IO thread is using to write data.
*/
- my_b_seek((rli->cur_log=rli->relay_log.get_log_file()), (off_t)0);
- if (check_binlog_magic(rli->cur_log,errmsg))
+ my_b_seek((cur_log=relay_log.get_log_file()), (off_t)0);
+ if (check_binlog_magic(cur_log, errmsg))
goto err;
- rli->cur_log_old_open_count=rli->relay_log.get_open_count();
+ cur_log_old_open_count=relay_log.get_open_count();
}
else
{
/*
- Open the relay log and set rli->cur_log to point at this one
+ Open the relay log and set cur_log to point at this one
*/
- if ((rli->cur_log_fd=open_binlog(&rli->cache_buf,
- rli->linfo.log_file_name,errmsg)) < 0)
+ if ((cur_log_fd=open_binlog(&cache_buf,
+ linfo.log_file_name,errmsg)) < 0)
goto err;
- rli->cur_log = &rli->cache_buf;
+ cur_log = &cache_buf;
}
/*
In all cases, check_binlog_magic() has been called so we're at offset 4 for
@@ -626,19 +279,19 @@ int init_relay_log_pos(Relay_log_info* r
*/
DBUG_PRINT("info",("looking for a Format_description_log_event"));
- if (my_b_tell(rli->cur_log) >= pos)
+ if (my_b_tell(cur_log) >= pos)
break;
/*
- Because of we have rli->data_lock and log_lock, we can safely read an
+ Because of we have data_lock and log_lock, we can safely read an
event
*/
- if (!(ev=Log_event::read_log_event(rli->cur_log,0,
- rli->relay_log.description_event_for_exec)))
+ if (!(ev=Log_event::read_log_event(cur_log,0,
+ relay_log.description_event_for_exec)))
{
- DBUG_PRINT("info",("could not read event, rli->cur_log->error=%d",
- rli->cur_log->error));
- if (rli->cur_log->error) /* not EOF */
+ DBUG_PRINT("info",("could not read event, cur_log->error=%d",
+ cur_log->error));
+ if (cur_log->error) /* not EOF */
{
*errmsg= "I/O error reading event at position 4";
goto err;
@@ -648,8 +301,8 @@ int init_relay_log_pos(Relay_log_info* r
else if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
{
DBUG_PRINT("info",("found Format_description_log_event"));
- delete rli->relay_log.description_event_for_exec;
- rli->relay_log.description_event_for_exec= (Format_description_log_event*) ev;
+ delete relay_log.description_event_for_exec;
+ relay_log.description_event_for_exec= (Format_description_log_event*) ev;
/*
As ev was returned by read_log_event, it has passed is_valid(), so
my_malloc() in ctor worked, no need to check again.
@@ -679,13 +332,13 @@ int init_relay_log_pos(Relay_log_info* r
delete ev;
}
}
- my_b_seek(rli->cur_log,(off_t)pos);
+ my_b_seek(cur_log,(off_t)pos);
#ifndef DBUG_OFF
{
char llbuf1[22], llbuf2[22];
- DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
- llstr(my_b_tell(rli->cur_log),llbuf1),
- llstr(rli->event_relay_log_pos,llbuf2)));
+ DBUG_PRINT("info", ("my_b_tell(cur_log)=%s >event_relay_log_pos=%s",
+ llstr(my_b_tell(cur_log),llbuf1),
+ llstr(get_event_relay_log_pos(),llbuf2)));
}
#endif
@@ -697,44 +350,37 @@ err:
silently discard it
*/
if (!relay_log_purge)
- rli->log_space_limit= 0;
- mysql_cond_broadcast(&rli->data_cond);
+ log_space_limit= 0;
+ mysql_cond_broadcast(&data_cond);
mysql_mutex_unlock(log_lock);
if (need_data_lock)
- mysql_mutex_unlock(&rli->data_lock);
- if (!rli->relay_log.description_event_for_exec->is_valid() && !*errmsg)
+ mysql_mutex_unlock(&data_lock);
+ if (!relay_log.description_event_for_exec->is_valid() && !*errmsg)
*errmsg= "Invalid Format_description log event; could be out of memory";
- DBUG_PRINT("info", ("Returning %d from init_relay_log_pos", (*errmsg)?1:0));
-
DBUG_RETURN ((*errmsg) ? 1 : 0);
}
-
-/*
+/**
Waits until the SQL thread reaches (has executed up to) the
log/position or timed out.
SYNOPSIS
- wait_for_pos()
- thd client thread that sent SELECT MASTER_POS_WAIT
- log_name log name to wait for
- log_pos position to wait for
- timeout timeout in seconds before giving up waiting
-
- NOTES
- timeout is longlong whereas it should be ulong ; but this is
- to catch if the user submitted a negative timeout.
+ @param[in] thd client thread that sent @c SELECT @c MASTER_POS_WAIT,
+ @param[in] log_name log name to wait for,
+ @param[in] log_pos position to wait for,
+ @param[in] timeout @c timeout in seconds before giving up waiting.
+ @c timeout is longlong whereas it should be ulong; but this is
+ to catch if the user submitted a negative timeout.
- RETURN VALUES
- -2 improper arguments (log_pos<0)
+ @retval -2 improper arguments (log_pos<0)
or slave not running, or master info changed
during the function's execution,
- or client thread killed. -2 is translated to NULL by caller
- -1 timed out
- >=0 number of log events the function had to wait
+ or client thread killed. -2 is translated to NULL by caller,
+ @retval -1 timed out
+ @retval >=0 number of log events the function had to wait
before reaching the desired log/position
*/
@@ -917,7 +563,6 @@ improper_arguments: %d timed_out: %d",
DBUG_RETURN( error ? error : event_count );
}
-
void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
bool skip_lock)
{
@@ -998,51 +643,55 @@ void Relay_log_info::close_temporary_tab
DBUG_VOID_RETURN;
}
-/*
- purge_relay_logs()
+/**
+ Purges relay logs. It assumes to have a run lock on rli and that no
+ slave thread are running.
+
+ @param[in] THD connection,
+ @param[in] just_reset if false, it tells that logs should be purged
+ and @c init_relay_log_pos() should be called,
+ @errmsg[out] errmsg store pointer to an error message.
- NOTES
- Assumes to have a run lock on rli and that no slave thread are running.
+ @retval 0 successfuly executed,
+ @retval 1 otherwise error, where errmsg is set to point to the error message.
*/
-int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
- const char** errmsg)
+int Relay_log_info::purge_relay_logs(THD *thd, bool just_reset,
+ const char** errmsg)
{
int error=0;
DBUG_ENTER("purge_relay_logs");
/*
- Even if rli->inited==0, we still try to empty rli->master_log_* variables.
- Indeed, rli->inited==0 does not imply that they already are empty.
- It could be that slave's info initialization partly succeeded :
- for example if relay-log.info existed but *relay-bin*.*
- have been manually removed, init_relay_log_info reads the old
- relay-log.info and fills rli->master_log_*, then init_relay_log_info
- checks for the existence of the relay log, this fails and
- init_relay_log_info leaves rli->inited to 0.
- In that pathological case, rli->master_log_pos* will be properly reinited
- at the next START SLAVE (as RESET SLAVE or CHANGE
- MASTER, the callers of purge_relay_logs, will delete bogus *.info files
- or replace them with correct files), however if the user does SHOW SLAVE
- STATUS before START SLAVE, he will see old, confusing rli->master_log_*.
- In other words, we reinit rli->master_log_* for SHOW SLAVE STATUS
- to display fine in any case.
- */
+ Even if inited==0, we still try to empty master_log_* variables. Indeed,
+ inited==0 does not imply that they already are empty.
- rli->group_master_log_name[0]= 0;
- rli->group_master_log_pos= 0;
+ It could be that slave's info initialization partly succeeded: for example
+ if relay-log.info existed but *relay-bin*.* have been manually removed,
+ init_info reads the old relay-log.info and fills rli->master_log_*, then
+ init_info checks for the existence of the relay log, this fails and
+ init_info leaves inited to 0.
+ In that pathological case, master_log_pos* will be properly reinited at
+ the next START SLAVE (as RESET SLAVE or CHANGE MASTER, the callers of
+ purge_relay_logs, will delete bogus *.info files or replace them with
+ correct files), however if the user does SHOW SLAVE STATUS before START
+ SLAVE, he will see old, confusing master_log_*. In other words, we reinit
+ master_log_* for SHOW SLAVE STATUS to display fine in any case.
+ */
+ group_master_log_name[0]= 0;
+ group_master_log_pos= 0;
- if (!rli->inited)
+ if (!inited)
{
- DBUG_PRINT("info", ("rli->inited == 0"));
+ DBUG_PRINT("info", ("inited == 0"));
DBUG_RETURN(0);
}
- DBUG_ASSERT(rli->slave_running == 0);
- DBUG_ASSERT(rli->mi->slave_running == 0);
+ DBUG_ASSERT(slave_running == 0);
+ DBUG_ASSERT(mi->slave_running == 0);
- rli->slave_skip_counter=0;
- mysql_mutex_lock(&rli->data_lock);
+ slave_skip_counter= 0;
+ mysql_mutex_lock(&data_lock);
/*
we close the relay log fd possibly left open by the slave SQL thread,
@@ -1050,77 +699,74 @@ int purge_relay_logs(Relay_log_info* rli
I/O thread will be closed naturally in reset_logs() by the
close(LOG_CLOSE_TO_BE_OPENED) call
*/
- if (rli->cur_log_fd >= 0)
+ if (cur_log_fd >= 0)
{
- end_io_cache(&rli->cache_buf);
- mysql_file_close(rli->cur_log_fd, MYF(MY_WME));
- rli->cur_log_fd= -1;
+ end_io_cache(&cache_buf);
+ my_close(cur_log_fd, MYF(MY_WME));
+ cur_log_fd= -1;
}
- if (rli->relay_log.reset_logs(thd))
+ if (relay_log.reset_logs(thd))
{
*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))
+ strmake(group_relay_log_name, relay_log.get_log_fname(),
+ sizeof(group_relay_log_name)-1);
+ strmake(event_relay_log_name, relay_log.get_log_fname(),
+ sizeof(event_relay_log_name)-1);
+ group_relay_log_pos= event_relay_log_pos= BIN_LOG_HEADER_SIZE;
+ if (count_relay_log_space())
{
*errmsg= "Error counting relay log space";
- error=1;
+ error= 1;
goto err;
}
if (!just_reset)
- error= init_relay_log_pos(rli, rli->group_relay_log_name,
- rli->group_relay_log_pos,
+ error= init_relay_log_pos(group_relay_log_name,
+ group_relay_log_pos,
0 /* do not need data lock */, errmsg, 0);
err:
#ifndef DBUG_OFF
char buf[22];
#endif
- DBUG_PRINT("info",("log_space_total: %s",llstr(rli->log_space_total,buf)));
- mysql_mutex_unlock(&rli->data_lock);
+ DBUG_PRINT("info",("log_space_total: %s",llstr(log_space_total,buf)));
+ mysql_mutex_unlock(&data_lock);
DBUG_RETURN(error);
}
-/*
- Check if condition stated in UNTIL clause of START SLAVE is reached.
- SYNOPSYS
- Relay_log_info::is_until_satisfied()
- master_beg_pos position of the beginning of to be executed event
- (not log_pos member of the event that points to the
- beginning of the following event)
-
+/**
+ Checks if condition stated in UNTIL clause of START SLAVE is reached.
- DESCRIPTION
- Checks if UNTIL condition is reached. Uses caching result of last
- comparison of current log file name and target log file name. So cached
- value should be invalidated if current log file name changes
- (see Relay_log_info::notify_... functions).
+ Specifically, it checks if UNTIL condition is reached. Uses caching result
+ of last comparison of current log file name and target log file name. So
+ cached value should be invalidated if current log file name changes (see
+ @c Relay_log_info::notify_... functions).
This caching is needed to avoid of expensive string comparisons and
- strtol() conversions needed for log names comparison. We don't need to
+ @c strtol() conversions needed for log names comparison. We don't need to
compare them each time this function is called, we only need to do this
- when current log name changes. If we have UNTIL_MASTER_POS condition we
- need to do this only after Rotate_log_event::do_apply_event() (which is
- rare, so caching gives real benifit), and if we have UNTIL_RELAY_POS
+ when current log name changes. If we have @c UNTIL_MASTER_POS condition we
+ need to do this only after @c Rotate_log_event::do_apply_event() (which is
+ rare, so caching gives real benifit), and if we have @c UNTIL_RELAY_POS
condition then we should invalidate cached comarison value after
- inc_group_relay_log_pos() which called for each group of events (so we
+ @c inc_group_relay_log_pos() which called for each group of events (so we
have some benefit if we have something like queries that use
autoincrement or if we have transactions).
- Should be called ONLY if until_condition != UNTIL_NONE !
- RETURN VALUE
- true - condition met or error happened (condition seems to have
- bad log file name)
- false - condition not met
+ Should be called ONLY if @c until_condition @c != @c UNTIL_NONE !
+
+ @param master_beg_pos position of the beginning of to be executed event
+ (not @c log_pos member of the event that points to
+ the beginning of the following event)
+
+ @retval true condition met or error happened (condition seems to have
+ bad log file name),
+ @retval false condition not met.
*/
bool Relay_log_info::is_until_satisfied(THD *thd, Log_event *ev)
@@ -1258,12 +904,12 @@ void Relay_log_info::stmt_done(my_off_t
middle of the "transaction". START SLAVE will resume at BEGIN
while the MyISAM table has already been updated.
*/
- if ((sql_thd->variables.option_bits & OPTION_BEGIN) && opt_using_transactions)
+ if ((info_thd->variables.option_bits & OPTION_BEGIN) && opt_using_transactions)
inc_event_relay_log_pos();
else
{
inc_group_relay_log_pos(event_master_log_pos);
- flush_relay_log_info(this);
+ flush_info(is_transactional() ? TRUE : FALSE);
}
}
@@ -1272,7 +918,7 @@ void Relay_log_info::cleanup_context(THD
{
DBUG_ENTER("Relay_log_info::cleanup_context");
- DBUG_ASSERT(sql_thd == thd);
+ DBUG_ASSERT(info_thd == thd);
/*
1) Instances of Table_map_log_event, if ::do_apply_event() was called on them,
may have opened tables, which we cannot be sure have been closed (because
@@ -1372,7 +1018,474 @@ bool mysql_show_relaylog_events(THD* thd
if (!active_mi)
DBUG_RETURN(TRUE);
- DBUG_RETURN(show_binlog_events(thd, &active_mi->rli.relay_log));
+ DBUG_RETURN(show_binlog_events(thd, &active_mi->rli->relay_log));
}
#endif
+
+int Relay_log_info::init_info()
+{
+ int error= 0;
+ const char *msg= NULL;
+
+ DBUG_ENTER("Relay_log_info::init_info");
+
+ if (inited)
+ {
+ /*
+ We have to reset read position of relay-log-bin as we may have
+ already been reading from 'hotlog' when the slave was stopped
+ last time. If this case pos_in_file would be set and we would
+ get a crash when trying to read the signature for the binary
+ relay log.
+
+ We only rewind the read position if we are starting the SQL
+ thread. The handle_slave_sql thread assumes that the read
+ position is at the beginning of the file, and will read the
+ "signature" and then fast-forward to the last position read.
+ */
+ bool hot_log= FALSE;
+ /*
+ my_b_seek does an implicit flush_io_cache, so we need to:
+
+ 1. check if this log is active (hot)
+ 2. if it is we keep log_lock until the seek ends, otherwise
+ release it right away.
+
+ If we did not take log_lock, SQL thread might race with IO
+ thread for the IO_CACHE mutex.
+
+ */
+ mysql_mutex_t *log_lock= relay_log.get_log_lock();
+ mysql_mutex_lock(log_lock);
+ hot_log= relay_log.is_active(linfo.log_file_name);
+
+ if (!hot_log)
+ mysql_mutex_unlock(log_lock);
+
+ my_b_seek(cur_log, (my_off_t) 0);
+
+ if (hot_log)
+ mysql_mutex_unlock(log_lock);
+
+ DBUG_RETURN(0);
+ }
+
+ cur_log_fd = -1;
+ slave_skip_counter= 0;
+ abort_pos_wait= 0;
+ log_space_limit= relay_log_space_limit;
+ log_space_total= 0;
+ tables_to_lock= 0;
+ tables_to_lock_count= 0;
+
+ char pattern[FN_REFLEN];
+ (void) my_realpath(pattern, slave_load_tmpdir, 0);
+ if (fn_format(pattern, PREFIX_SQL_LOAD, pattern, "",
+ MY_SAFE_PATH | MY_RETURN_REAL_PATH) == NullS)
+ {
+ sql_print_error("Unable to use slave's temporary directory %s",
+ slave_load_tmpdir);
+ DBUG_RETURN(1);
+ }
+ unpack_filename(slave_patternload_file, pattern);
+ slave_patternload_file_size= strlen(slave_patternload_file);
+
+ /*
+ The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
+ Note that the I/O thread flushes it to disk after writing every
+ event, in flush_info within the master info.
+ */
+ /*
+ 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
+ relay_log.max_size (and mysql_bin_log.max_size).
+ */
+ {
+ /* Reports an error and returns, if the --relay-log's path
+ is a directory.*/
+ if (opt_relay_logname &&
+ opt_relay_logname[strlen(opt_relay_logname) - 1] == FN_LIBCHAR)
+ {
+ sql_print_error("Path '%s' is a directory name, please specify \
+a file name for --relay-log option", opt_relay_logname);
+ DBUG_RETURN(1);
+ }
+
+ /* Reports an error and returns, if the --relay-log-index's path
+ is a directory.*/
+ if (opt_relaylog_index_name &&
+ opt_relaylog_index_name[strlen(opt_relaylog_index_name) - 1]
+ == FN_LIBCHAR)
+ {
+ sql_print_error("Path '%s' is a directory name, please specify \
+a file name for --relay-log-index option", opt_relaylog_index_name);
+ DBUG_RETURN(1);
+ }
+
+ char buf[FN_REFLEN];
+ const char *ln;
+ static bool name_warning_sent= 0;
+ ln= relay_log.generate_name(opt_relay_logname, "-relay-bin",
+ 1, buf);
+ /* We send the warning only at startup, not after every RESET SLAVE */
+ if (!opt_relay_logname && !opt_relaylog_index_name && !name_warning_sent)
+ {
+ /*
+ User didn't give us info to name the relay log index file.
+ Picking `hostname`-relay-bin.index like we do, causes replication to
+ fail if this slave's hostname is changed later. So, we would like to
+ instead require a name. But as we don't want to break many existing
+ setups, we only give warning, not error.
+ */
+ sql_print_warning("Neither --relay-log nor --relay-log-index were used;"
+ " so replication "
+ "may break when this MySQL server acts as a "
+ "slave and has his hostname changed!! Please "
+ "use '--relay-log=%s' to avoid this problem.", ln);
+ name_warning_sent= 1;
+ }
+ /*
+ note, that if open() fails, we'll still have index file open
+ but a destructor will take care of that
+ */
+ if (relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE) ||
+ relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
+ (max_relay_log_size ? max_relay_log_size :
+ max_binlog_size), 1, TRUE))
+ {
+ sql_print_error("Failed in open_log() called from Relay_log_info::init_info()");
+ DBUG_RETURN(1);
+ }
+ relay_log.is_relay_log= TRUE;
+ }
+
+ /*
+ This checks if the repository was created before and thus there
+ will be values to be read. Please, do not move this call after
+ the handler->init_info().
+ */
+ int necessary_to_configure= check_info();
+ if ((error= handler->init_info()))
+ {
+ msg= "Error reading relay log configuration";
+ error= 1;
+ goto err;
+ }
+
+ if (necessary_to_configure)
+ {
+ /* Init relay log with first entry in the relay index file */
+ if (init_relay_log_pos(NullS, BIN_LOG_HEADER_SIZE, 0 /* no data lock */,
+ &msg, 0))
+ {
+ error= 1;
+ goto err;
+ }
+ group_master_log_name[0]= 0;
+ group_master_log_pos= 0;
+ }
+ else
+ {
+ if (read_info(handler))
+ {
+ msg= "Error reading relay log configuration";
+ error= 1;
+ goto err;
+ }
+
+ if (is_relay_log_recovery && init_recovery(mi, &msg))
+ {
+ error= 1;
+ goto err;
+ }
+
+ if (init_relay_log_pos(group_relay_log_name,
+ group_relay_log_pos,
+ 0 /* no data lock*/,
+ &msg, 0))
+ {
+ char llbuf[22];
+ sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s)",
+ group_relay_log_name,
+ llstr(group_relay_log_pos, llbuf));
+ error= 1;
+ goto err;
+ }
+
+#ifndef DBUG_OFF
+ {
+ char llbuf1[22], llbuf2[22];
+ DBUG_PRINT("info", ("my_b_tell(cur_log)=%s event_relay_log_pos=%s",
+ llstr(my_b_tell(cur_log),llbuf1),
+ llstr(event_relay_log_pos,llbuf2)));
+ DBUG_ASSERT(event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
+ DBUG_ASSERT((my_b_tell(cur_log) == event_relay_log_pos));
+ }
+#endif
+ }
+
+ if ((error= flush_info(TRUE)))
+ {
+ msg= "Error reading relay log configuration";
+ error= 1;
+ goto err;
+ }
+
+ if (count_relay_log_space())
+ {
+ msg= "Error counting relay log space";
+ error= 1;
+ goto err;
+ }
+
+ inited= 1;
+ is_relay_log_recovery= FALSE;
+ DBUG_RETURN(error);
+
+err:
+ sql_print_error("%s", msg);
+ relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
+ DBUG_RETURN(error);
+}
+
+void Relay_log_info::end_info()
+{
+ DBUG_ENTER("Relay_log_info::end_info");
+
+ if (!inited)
+ DBUG_VOID_RETURN;
+
+ handler->end_info();
+
+ if (cur_log_fd >= 0)
+ {
+ end_io_cache(&cache_buf);
+ (void)my_close(cur_log_fd, MYF(MY_WME));
+ cur_log_fd= -1;
+ }
+ inited = 0;
+ relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
+ relay_log.harvest_bytes_written(&log_space_total);
+ /*
+ Delete the slave's temporary tables from memory.
+ In the future there will be other actions than this, to ensure persistance
+ of slave's temp tables after shutdown.
+ */
+ close_temporary_tables();
+
+ DBUG_VOID_RETURN;
+}
+
+int Relay_log_info::flush_current_log()
+{
+ DBUG_ENTER("Relay_log_info::flush_current_log");
+ /*
+ When we come to this place in code, relay log may or not be initialized;
+ the caller is responsible for setting 'flush_relay_log_cache' accordingly.
+ */
+ IO_CACHE *log_file= relay_log.get_log_file();
+ if (flush_io_cache(log_file))
+ DBUG_RETURN(2);
+
+ DBUG_RETURN(0);
+}
+
+void Relay_log_info::set_master_info(Master_info* info)
+{
+ mi= info;
+}
+
+/**
+ Stores the file and position where the execute-slave thread are in the
+ relay log:
+
+ - As this is only called by the slave thread or on STOP SLAVE, with the
+ log_lock grabbed and the slave thread stopped, we don't need to have
+ a lock here.
+ - If there is an active transaction, then we don't update the position
+ in the relay log. This is to ensure that we re-execute statements
+ if we die in the middle of an transaction that was rolled back.
+ - As a transaction never spans binary logs, we don't have to handle the
+ case where we do a relay-log-rotation in the middle of the transaction.
+ If this would not be the case, we would have to ensure that we
+ don't delete the relay log file where the transaction started when
+ we switch to a new relay log file.
+
+ @retval 0 ok,
+ @retval 1 write error, otherwise.
+*/
+
+/**
+ Store the file and position where the slave's SQL thread are in the
+ relay log.
+
+ Notes:
+
+ - This function should be called either from the slave SQL thread,
+ or when the slave thread is not running. (It reads the
+ group_{relay|master}_log_{pos|name} and delay fields in the rli
+ object. These may only be modified by the slave SQL thread or by
+ a client thread when the slave SQL thread is not running.)
+
+ - If there is an active transaction, then we do not update the
+ position in the relay log. This is to ensure that we re-execute
+ statements if we die in the middle of an transaction that was
+ rolled back.
+
+ - As a transaction never spans binary logs, we don't have to handle
+ the case where we do a relay-log-rotation in the middle of the
+ transaction. If transactions could span several binlogs, we would
+ have to ensure that we do not delete the relay log file where the
+ transaction started before switching to a new relay log file.
+
+ - Error can happen if writing to file fails or if flushing the file
+ fails.
+
+ @param rli The object representing the Relay_log_info.
+
+ @todo Change the log file information to a binary format to avoid
+ calling longlong2str.
+
+ @return 0 on success, 1 on error.
+*/
+int Relay_log_info::flush_info(bool force)
+{
+ DBUG_ENTER("Relay_log_info::flush_info");
+
+ /*
+ We update the sync_period at this point because only here we
+ now that we are handling a relay log info. This needs to be
+ update every time we call flush because the option maybe
+ dinamically set.
+ */
+ handler->set_sync_period(sync_relayloginfo_period);
+
+ if (write_info(handler, force))
+ goto err;
+
+ DBUG_RETURN(0);
+
+err:
+ sql_print_error("Error writing relay log configuration");
+ DBUG_RETURN(1);
+}
+
+size_t Relay_log_info::get_number_info_rli_fields()
+{
+ return sizeof(info_rli_fields)/sizeof(info_rli_fields[0]);
+}
+
+bool Relay_log_info::read_info(Rpl_info_handler *from)
+{
+ int lines= 0;
+ char *first_non_digit= NULL;
+ ulong temp_group_relay_log_pos= 0;
+ ulong temp_group_master_log_pos= 0;
+ int temp_sql_delay= 0;
+
+ DBUG_ENTER("Relay_log_info::read_info");
+
+ /*
+ Should not read RLI from file in client threads. Client threads
+ only use RLI to execute BINLOG statements.
+
+ @todo Uncomment the following assertion. Currently,
+ Relay_log_info::init() is called from init_master_info() before
+ the THD object Relay_log_info::sql_thd is created. That means we
+ cannot call belongs_to_client() since belongs_to_client()
+ dereferences Relay_log_info::sql_thd. So we need to refactor
+ slightly: the THD object should be created by Relay_log_info
+ constructor (or passed to it), so that we are guaranteed that it
+ exists at this point. /Sven
+ */
+ //DBUG_ASSERT(!belongs_to_client());
+
+ /*
+ Starting from 5.1.x, relay-log.info has a new format. Now, its
+ first line contains the number of lines in the file. By reading
+ this number we can determine which version our master.info comes
+ from. We can't simply count the lines in the file, since
+ versions before 5.1.x could generate files with more lines than
+ needed. If first line doesn't contain a number, or if it
+ contains a number less than LINES_IN_RELAY_LOG_INFO_WITH_DELAY,
+ then the file is treated like a file from pre-5.1.x version.
+ There is no ambiguity when reading an old master.info: before
+ 5.1.x, the first line contained the binlog's name, which is
+ either empty or has an extension (contains a '.'), so can't be
+ confused with an integer.
+
+ So we're just reading first line and trying to figure which
+ version is this.
+ */
+
+ /*
+ The first row is temporarily stored in mi->master_log_name, if
+ it is line count and not binlog name (new format) it will be
+ overwritten by the second row later.
+ */
+ if (from->prepare_info_for_read() ||
+ from->get_info(group_relay_log_name, sizeof(group_relay_log_name), ""))
+ DBUG_RETURN(TRUE);
+
+ lines= strtoul(group_relay_log_name, &first_non_digit, 10);
+
+ if (group_relay_log_name[0]!='\0' &&
+ *first_non_digit=='\0' && lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY)
+ {
+ /* Seems to be new format => read group relay log name */
+ if (from->get_info(group_relay_log_name, sizeof(group_relay_log_name), ""))
+ DBUG_RETURN(TRUE);
+ }
+ else
+ DBUG_PRINT("info", ("relay_log_info file is in old format."));
+
+ if (from->get_info((ulong *) &temp_group_relay_log_pos,
+ (ulong) BIN_LOG_HEADER_SIZE) ||
+ from->get_info(group_master_log_name,
+ sizeof(group_relay_log_name), "") ||
+ from->get_info((ulong *) &temp_group_master_log_pos,
+ (ulong) 0))
+ DBUG_RETURN(TRUE);
+
+ if (lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY)
+ {
+ if (from->get_info((int *) &temp_sql_delay,(int) 0))
+ DBUG_RETURN(TRUE);
+ }
+
+ group_relay_log_pos= temp_group_relay_log_pos;
+ group_master_log_pos= temp_group_master_log_pos;
+ sql_delay= (int32) temp_sql_delay;
+
+ DBUG_RETURN(FALSE);
+}
+
+bool Relay_log_info::write_info(Rpl_info_handler *to, bool force)
+{
+ DBUG_ENTER("Relay_log_info::write_info");
+
+ /*
+ @todo Uncomment the following assertion. See todo in
+ Relay_log_info::read_info() for details. /Sven
+ */
+ //DBUG_ASSERT(!belongs_to_client());
+
+ if (to->prepare_info_for_write() ||
+ to->set_info((int) LINES_IN_RELAY_LOG_INFO_WITH_DELAY) ||
+ to->set_info(group_relay_log_name) ||
+ to->set_info((ulong) group_relay_log_pos) ||
+ to->set_info(group_master_log_name) ||
+ to->set_info((ulong) group_master_log_pos) ||
+ to->set_info((int) sql_delay))
+ DBUG_RETURN(TRUE);
+
+ if (to->flush_info(force))
+ DBUG_RETURN(TRUE);
+
+ DBUG_RETURN(FALSE);
+}
=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h 2010-09-01 02:51:08 +0000
+++ b/sql/rpl_rli.h 2010-10-08 16:11:32 +0000
@@ -16,6 +16,9 @@
#ifndef RPL_RLI_H
#define RPL_RLI_H
+#include "sql_priv.h"
+#include "rpl_info.h"
+#include "rpl_utility.h"
#include "rpl_tblmap.h"
#include "rpl_reporting.h"
#include "rpl_utility.h"
@@ -27,33 +30,21 @@ struct RPL_TABLE_LIST;
class Master_info;
extern uint sql_slave_skip_counter;
-/****************************************************************************
-
- Replication SQL Thread
-
- Relay_log_info contains:
- - the current relay log
- - the current relay log offset
- - master log name
- - master log sequence corresponding to the last update
- - misc information specific to the SQL thread
-
- Relay_log_info is initialized from the slave.info file if such
- exists. Otherwise, data members are intialized with defaults. The
- initialization is done with init_relay_log_info() call.
-
- The format of slave.info file:
-
- relay_log_name
- relay_log_pos
- master_log_name
- master_log_pos
-
- To clean up, call end_relay_log_info()
+/*******************************************************************************
+Replication SQL Thread
-*****************************************************************************/
-
-class Relay_log_info : public Slave_reporting_capability
+Relay_log_info contains:
+ - the current relay log
+ - the current relay log offset
+ - master log name
+ - master log sequence corresponding to the last update
+ - misc information specific to the SQL thread
+
+Relay_log_info is initialized from a repository, e.g. table or file, if there is
+one. Otherwise, data members are intialized with defaults by calling
+init_relay_log_info(). Currently, only files are available as repositories.
+*******************************************************************************/
+class Relay_log_info : public Rpl_info
{
public:
/**
@@ -76,8 +67,8 @@ public:
*/
inline bool belongs_to_client()
{
- DBUG_ASSERT(sql_thd);
- return !sql_thd->slave_thread;
+ DBUG_ASSERT(info_thd);
+ return !info_thd->slave_thread;
}
/*
@@ -90,14 +81,10 @@ public:
bool replicate_same_server_id;
/*** The following variables can only be read when protect by data lock ****/
-
/*
- info_fd - file descriptor of the info file. set only during
- initialization or clean up - safe to read anytime
cur_log_fd - file descriptor of the current read relay log
*/
- File info_fd,cur_log_fd;
-
+ File cur_log_fd;
/*
Protected with internal locks.
Must get data_lock when resetting the logs.
@@ -107,23 +94,13 @@ public:
IO_CACHE cache_buf,*cur_log;
/*
- Keeps track of the number of transactions that commits
- before fsyncing. The option --sync-relay-log-info determines
- how many transactions should commit before fsyncing.
- */
- uint sync_counter;
-
- /*
Identifies when the recovery process is going on.
See sql/slave.cc:init_recovery for further details.
- */
+ */
bool is_relay_log_recovery;
/* The following variables are safe to read any time */
- /* IO_CACHE of the info file - set only during init or end */
- IO_CACHE info_file;
-
/*
When we restart slave thread we need to have access to the previously
created temporary tables. Modified only on init/end and by the SQL
@@ -131,19 +108,6 @@ public:
*/
TABLE *save_temporary_tables;
- /*
- standard lock acquisition order to avoid deadlocks:
- run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index
- */
- mysql_mutex_t data_lock, run_lock;
-
- /*
- start_cond is broadcast when SQL thread is started
- stop_cond - when stopped
- data_cond - when data protected by data_lock changes
- */
- mysql_cond_t start_cond, stop_cond, data_cond;
-
/* parent Master_info structure */
Master_info *mi;
@@ -152,7 +116,7 @@ public:
a different log under our feet
*/
uint32 cur_log_old_open_count;
-
+
/*
Let's call a group (of events) :
- a transaction
@@ -170,19 +134,15 @@ public:
relay log and finishing (commiting) on another relay log. Case which can
happen when, for example, the relay log gets rotated because of
max_binlog_size.
-
- Note: group_relay_log_name, group_relay_log_pos must only be
- written from the thread owning the Relay_log_info (SQL thread if
- !belongs_to_client(); client thread executing BINLOG statement if
- belongs_to_client()).
*/
+protected:
char group_relay_log_name[FN_REFLEN];
ulonglong group_relay_log_pos;
char event_relay_log_name[FN_REFLEN];
ulonglong event_relay_log_pos;
ulonglong future_event_relay_log_pos;
- /*
+ /*
Original log name and position of the group we're currently executing
(whose coordinates are group_relay_log_name/pos in the relay log)
in the master's binlog. These concern the *group*, because in the master's
@@ -198,15 +158,6 @@ public:
volatile my_off_t group_master_log_pos;
/*
- Handling of the relay_log_space_limit optional constraint.
- ignore_log_space_limit is used to resolve a deadlock between I/O and SQL
- threads, the SQL thread sets it to unblock the I/O thread and make it
- temporarily forget about the constraint.
- */
- ulonglong log_space_limit,log_space_total;
- bool ignore_log_space_limit;
-
- /*
When it commits, InnoDB internally stores the master log position it has
processed so far; the position to store is the one of the end of the
committing event (the COMMIT query event, or the event if in autocommit
@@ -218,9 +169,25 @@ public:
ulonglong future_group_master_log_pos;
#endif
+public:
+ int init_relay_log_pos(const char* log,
+ ulonglong pos, bool need_data_lock,
+ const char** errmsg,
+ bool look_for_description_event);
+
+ /*
+ Handling of the relay_log_space_limit optional constraint.
+ ignore_log_space_limit is used to resolve a deadlock between I/O and SQL
+ threads, the SQL thread sets it to unblock the I/O thread and make it
+ temporarily forget about the constraint.
+ */
+ ulonglong log_space_limit,log_space_total;
+ bool ignore_log_space_limit;
+
time_t last_master_timestamp;
void clear_until_condition();
+
/**
Reset the delay.
This is used by RESET SLAVE to clear the delay.
@@ -230,7 +197,6 @@ public:
sql_delay= 0;
}
-
/*
Needed for problems when slave stops and we want to restart it
skipping one or more events in the master log that have caused
@@ -238,36 +204,19 @@ public:
*/
volatile uint32 slave_skip_counter;
volatile ulong abort_pos_wait; /* Incremented on change master */
- volatile ulong slave_run_id; /* Incremented on slave start */
mysql_mutex_t log_space_lock;
mysql_cond_t log_space_cond;
- THD * sql_thd;
-#ifndef DBUG_OFF
- int events_till_abort;
-#endif
/*
- inited changes its value within LOCK_active_mi-guarded critical
- sections at times of start_slave_threads() (0->1) and end_slave() (1->0).
- Readers may not acquire the mutex while they realize potential concurrency
- issue.
- If not set, the value of other members of the structure are undefined.
- */
- volatile bool inited;
- volatile bool abort_slave;
- volatile uint slave_running;
-
- /*
Condition and its parameters from START SLAVE UNTIL clause.
- UNTIL condition is tested with is_until_satisfied() method that is
+ UNTIL condition is tested with is_until_satisfied() method that is
called by exec_relay_log_event(). is_until_satisfied() caches the result
of the comparison of log names because log names don't change very often;
this cache is invalidated by parts of code which change log names with
notify_*_log_name_updated() methods. (They need to be called only if SQL
thread is running).
*/
-
enum {UNTIL_NONE= 0, UNTIL_MASTER_POS, UNTIL_RELAY_POS} until_condition;
char until_log_name[FN_REFLEN];
ulonglong until_log_pos;
@@ -311,11 +260,16 @@ public:
char slave_patternload_file[FN_REFLEN];
size_t slave_patternload_file_size;
- Relay_log_info(bool is_slave_recovery);
- ~Relay_log_info();
+ Relay_log_info(bool is_slave_recovery,
+ PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond);
+ virtual ~Relay_log_info();
- /*
- Invalidate cached until_log_name and group_relay_log_name comparison
+ /**
+ Invalidates cached until_log_name and group_relay_log_name comparison
result. Should be called after any update of group_realy_log_name if
there chances that sql_thread is running.
*/
@@ -325,8 +279,9 @@ public:
until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
}
- /*
- The same as previous but for group_master_log_name.
+ /**
+ The same as @c notify_group_relay_log_name_update but for
+ @c group_master_log_name.
*/
inline void notify_group_master_log_name_update()
{
@@ -340,7 +295,7 @@ public:
}
void inc_group_relay_log_pos(ulonglong log_pos,
- bool skip_lock= 0);
+ bool skip_lock= FALSE);
int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
longlong timeout);
@@ -377,9 +332,9 @@ public:
return false;
}
- /*
+ /**
Last charset (6 bytes) seen by slave SQL thread is cached here; it helps
- the thread save 3 get_charset() per Query_log_event if the charset is not
+ the thread save 3 @c get_charset() per @c Query_log_event if the charset is not
changing from event to event (common situation).
When the 6 bytes are equal to 0 is used to mean "cache is invalidated".
*/
@@ -389,6 +344,7 @@ public:
void cleanup_context(THD *, bool);
void slave_close_thread_tables(THD *);
void clear_tables_to_lock();
+ int purge_relay_logs(THD *thd, bool just_reset, const char** errmsg);
/*
Used to defer stopping the SQL thread to give it a chance
@@ -456,21 +412,85 @@ public:
@retval false Replication thread is currently not inside a group
*/
bool is_in_group() const {
- return (sql_thd->variables.option_bits & OPTION_BEGIN) ||
+ return (info_thd->variables.option_bits & OPTION_BEGIN) ||
(m_flags & (1UL << IN_STMT));
}
- /**
- Text used in THD::proc_info when the slave SQL thread is delaying.
- */
- static const char *const state_delaying_string;
+ int count_relay_log_space();
+
+ int init_info();
+ void end_info();
+ int flush_info(bool force= FALSE);
+ int flush_current_log();
+ void set_master_info(Master_info *info);
+
+ inline ulonglong get_future_event_relay_log_pos() { return future_event_relay_log_pos; }
+ inline void set_future_event_relay_log_pos(ulonglong log_pos)
+ {
+ future_event_relay_log_pos= log_pos;
+ }
+
+ inline const char* get_group_master_log_name() { return group_master_log_name; }
+ inline ulonglong get_group_master_log_pos() { return group_master_log_pos; }
+ inline void set_group_master_log_name(const char *log_file_name)
+ {
+ strmake(group_master_log_name,log_file_name, sizeof(group_master_log_name)-1);
+ }
+ inline void set_group_master_log_pos(ulonglong log_pos)
+ {
+ group_master_log_pos= log_pos;
+ }
+
+ inline const char* get_group_relay_log_name() { return group_relay_log_name; }
+ inline ulonglong get_group_relay_log_pos() { return group_relay_log_pos; }
+ inline void set_group_relay_log_name(const char *log_file_name)
+ {
+ strmake(group_relay_log_name,log_file_name, sizeof(group_relay_log_name)-1);
+ }
+ inline void set_group_relay_log_name(const char *log_file_name, size_t len)
+ {
+ strmake(group_relay_log_name, log_file_name, len);
+ }
+ inline void set_group_relay_log_pos(ulonglong log_pos)
+ {
+ group_relay_log_pos= log_pos;
+ }
- bool flush();
+ inline const char* get_event_relay_log_name() { return event_relay_log_name; }
+ inline ulonglong get_event_relay_log_pos() { return event_relay_log_pos; }
+ inline void set_event_relay_log_name(const char *log_file_name)
+ {
+ strmake(event_relay_log_name,log_file_name, sizeof(event_relay_log_name)-1);
+ }
+ inline void set_event_relay_log_name(const char *log_file_name, size_t len)
+ {
+ strmake(event_relay_log_name,log_file_name, len);
+ }
+ inline void set_event_relay_log_pos(ulonglong log_pos)
+ {
+ event_relay_log_pos= log_pos;
+ }
+ inline const char* get_rpl_log_name()
+ {
+ return (group_master_log_name[0] ? group_master_log_name : "FIRST");
+ }
+
+#if MYSQL_VERSION_ID < 40100
+ inline ulonglong get_future_master_log_pos() { return future_master_log_pos; }
+#else
+ inline ulonglong get_future_group_master_log_pos() { return future_group_master_log_pos; }
+ inline void set_future_group_master_log_pos(ulonglong log_pos)
+ {
+ future_group_master_log_pos= log_pos;
+ }
+#endif
+
+ size_t get_number_info_rli_fields();
/**
- Reads the relay_log.info file.
+ Text used in THD::proc_info when the slave SQL thread is delaying.
*/
- int init(const char* info_filename);
+ static const char *const state_delaying_string;
/**
Indicate that a delay starts.
@@ -487,7 +507,7 @@ public:
{
mysql_mutex_assert_owner(&data_lock);
sql_delay_end= delay_end;
- thd_proc_info(sql_thd, state_delaying_string);
+ thd_proc_info(info_thd, state_delaying_string);
}
int32 get_sql_delay() { return sql_delay; }
@@ -505,7 +525,7 @@ private:
MASTER_DELAY=X. Read by SQL thread and by client threads
executing SHOW SLAVE STATUS. Note: must not be written while the
slave SQL thread is running, since the SQL thread reads it without
- a lock when executing flush_relay_log_info().
+ a lock when executing flush_info().
*/
int sql_delay;
@@ -520,33 +540,19 @@ private:
time_t sql_delay_end;
/*
- Before the MASTER_DELAY parameter was added (WL#344),
- relay_log.info had 4 lines. Now it has 5 lines.
+ Before the MASTER_DELAY parameter was added (WL#344), relay_log.info
+ had 4 lines. Now it has 5 lines.
*/
static const int LINES_IN_RELAY_LOG_INFO_WITH_DELAY= 5;
- uint32 m_flags;
-};
+ bool read_info(Rpl_info_handler *from);
+ bool write_info(Rpl_info_handler *to, bool force);
+ Relay_log_info& operator=(const Relay_log_info& info);
+ Relay_log_info(const Relay_log_info& info);
-/**
- Reads the relay_log.info file.
+ uint32 m_flags;
+};
- @todo This is a wrapper around Relay_log_info::init(). It's only
- kept for historical reasons. It would be good if we removed this
- function and replaced all calls to it by calls to
- Relay_log_info::init(). /SVEN
-*/
-int init_relay_log_info(Relay_log_info* rli, const char* info_fname);
-bool flush_relay_log_info(Relay_log_info* rli);
-void end_relay_log_info(Relay_log_info* rli);
-int init_relay_log_pos(Relay_log_info* rli,const char* log,ulonglong pos,
- bool need_data_lock, const char** errmsg,
- bool look_for_description_event);
-
-int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
- const char** errmsg);
-void rotate_relay_log(Master_info* mi);
bool mysql_show_relaylog_events(THD* thd);
-
#endif /* RPL_RLI_H */
=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc 2010-09-26 23:56:20 +0000
+++ b/sql/rpl_slave.cc 2010-10-17 23:27:40 +0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010 Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -10,8 +10,8 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/**
@@ -32,6 +32,7 @@
#include "rpl_mi.h"
#include "rpl_rli.h"
#include "rpl_filter.h"
+#include "rpl_info_factory.h"
#include "transaction.h"
#include <thr_alarm.h>
#include <my_dir.h>
@@ -49,6 +50,7 @@
#include "log_event.h" // Rotate_log_event,
// Create_file_log_event,
// Format_description_log_event
+#include "server_ids.h"
#ifdef HAVE_REPLICATION
@@ -134,7 +136,7 @@ log '%s' at postion %s",
failed read"
}
};
-
+
typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
@@ -182,9 +184,9 @@ static bool check_io_slave_killed(THD *t
If inverse == 1, stopped threads
*/
-void init_thread_mask(int* mask,Master_info* mi,bool inverse)
+void init_thread_mask(int* mask, Master_info* mi, bool inverse)
{
- bool set_io = mi->slave_running, set_sql = mi->rli.slave_running;
+ bool set_io = mi->slave_running, set_sql = mi->rli->slave_running;
register int tmp_mask=0;
DBUG_ENTER("init_thread_mask");
@@ -209,7 +211,7 @@ void lock_slave_threads(Master_info* mi)
//TODO: see if we can do this without dual mutex
mysql_mutex_lock(&mi->run_lock);
- mysql_mutex_lock(&mi->rli.run_lock);
+ mysql_mutex_lock(&mi->rli->run_lock);
DBUG_VOID_RETURN;
}
@@ -223,7 +225,7 @@ void unlock_slave_threads(Master_info* m
DBUG_ENTER("unlock_slave_threads");
//TODO: see if we can do this without dual mutex
- mysql_mutex_unlock(&mi->rli.run_lock);
+ mysql_mutex_unlock(&mi->rli->run_lock);
mysql_mutex_unlock(&mi->run_lock);
DBUG_VOID_RETURN;
}
@@ -256,6 +258,8 @@ int init_slave()
{
DBUG_ENTER("init_slave");
int error= 0;
+ int thread_mask= SLAVE_SQL | SLAVE_IO;
+ Relay_log_info* rli= NULL;
#ifdef HAVE_PSI_INTERFACE
init_slave_psi_keys();
@@ -267,14 +271,16 @@ 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))
+ DBUG_RETURN(1);
+
+ if ((error= Rpl_info_factory::create(opt_mi_repository_id, &active_mi,
+ opt_rli_repository_id, &rli)))
+ {
+ error= 1;
goto err;
+ }
/*
If --slave-skip-errors=... was not used, the string value for the
@@ -286,35 +292,31 @@ int init_slave()
}
/*
- If master_host is not specified, try to read it from the master_info file.
- If master_host is specified, create the master_info file if it doesn't
- exists.
+ This is the startup routine and as such we try to
+ configure both the SLAVE_SQL and SLAVE_IO.
*/
- 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)))
+ if (init_info(active_mi, TRUE, thread_mask))
{
sql_print_error("Failed to initialize the master info structure");
error= 1;
goto err;
}
- /* If server id is not set, start_slave_thread() will say it */
+ DBUG_PRINT("info", ("init group master %s %lu group relay %s %lu event %s %lu\n",
+ rli->get_group_master_log_name(),
+ (ulong) rli->get_group_master_log_pos(),
+ rli->get_group_relay_log_name(),
+ (ulong) rli->get_group_relay_log_pos(),
+ rli->get_event_relay_log_name(),
+ (ulong) rli->get_event_relay_log_pos()));
+ /* If server id is not set, start_slave_thread() will say it */
if (active_mi->host[0] && !opt_skip_slave_start)
{
if (start_slave_threads(1 /* need mutex */,
0 /* no wait for start*/,
active_mi,
- master_info_file,
- relay_log_info_file,
- SLAVE_IO | SLAVE_SQL))
+ thread_mask))
{
sql_print_error("Failed to create slave threads");
error= 1;
@@ -329,21 +331,21 @@ err:
/*
Updates the master info based on the information stored in the
- relay info and ignores relay logs previously retrieved by the IO
- thread, which thus starts fetching again based on to the
- group_master_log_pos and group_master_log_name. Eventually, the old
+ relay info and ignores relay logs previously retrieved by the IO
+ thread, which thus starts fetching again based on to the
+ master_log_pos and master_log_name. Eventually, the old
relay logs will be purged by the normal purge mechanism.
In the feature, we should improve this routine in order to avoid throwing
- away logs that are safely stored in the disk. Note also that this recovery
- routine relies on the correctness of the relay-log.info and only tolerates
+ away logs that are safely stored in the disk. Note also that this recovery
+ routine relies on the correctness of the relay-log.info and only tolerates
coordinate problems in master.info.
-
- In this function, there is no need for a mutex as the caller
+
+ In this function, there is no need for a mutex as the caller
(i.e. init_slave) already has one acquired.
-
+
Specifically, the following structures are updated:
-
+
1 - mi->master_log_pos <-- rli->group_master_log_pos
2 - mi->master_log_name <-- rli->group_master_log_name
3 - It moves the relay log to the new relay log file, by
@@ -351,35 +353,154 @@ err:
rli->event_relay_log_pos <-- BIN_LOG_HEADER_SIZE;
rli->group_relay_log_name <-- rli->relay_log.get_log_fname();
rli->event_relay_log_name <-- rli->relay_log.get_log_fname();
-
+
If there is an error, it returns (1), otherwise returns (0).
*/
int init_recovery(Master_info* mi, const char** errmsg)
{
DBUG_ENTER("init_recovery");
-
- Relay_log_info *rli= &mi->rli;
- if (rli->group_master_log_name[0])
- {
- mi->master_log_pos= max(BIN_LOG_HEADER_SIZE,
- rli->group_master_log_pos);
- strmake(mi->master_log_name, rli->group_master_log_name,
- sizeof(mi->master_log_name)-1);
-
+
+ Relay_log_info *rli= mi->rli;
+ const char *group_master_log_name= rli->get_group_master_log_name();
+ if (group_master_log_name[0])
+ {
+ mi->set_master_log_pos(max(BIN_LOG_HEADER_SIZE,
+ rli->get_group_master_log_pos()));
+ mi->set_master_log_name(rli->get_group_master_log_name());
+
sql_print_warning("Recovery from master pos %ld and file %s.",
- (ulong) mi->master_log_pos, mi->master_log_name);
-
- 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(mi->rli.event_relay_log_name)-1);
-
- rli->group_relay_log_pos= rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
+ (ulong) mi->get_master_log_pos(), mi->get_master_log_name());
+
+ rli->set_group_relay_log_name(rli->relay_log.get_log_fname());
+ rli->set_event_relay_log_name(rli->relay_log.get_log_fname());
+ rli->set_group_relay_log_pos(BIN_LOG_HEADER_SIZE);
+ rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
}
DBUG_RETURN(0);
}
-
+
+int init_info(Master_info* mi, bool ignore_if_no_info, int thread_mask)
+{
+ int error= 0;
+ int necessary_to_configure= 0;
+
+ DBUG_ENTER("init_info");
+ DBUG_ASSERT(mi != NULL && mi->rli != NULL);
+
+ /*
+ We need a mutex while we are changing master info parameters to
+ keep other threads from reading bogus info
+ */
+ mysql_mutex_lock(&mi->data_lock);
+ mysql_mutex_lock(&mi->rli->data_lock);
+
+ /*
+ This takes care of the startup dependency between the master_info
+ and relay_info. It initializes the master info if the SLAVE_IO
+ thread is being started and the relay log info if either the
+ SLAVE_SQL thread is being started or was not initialized as it is
+ required by the SLAVE_IO thread.
+ */
+ necessary_to_configure= mi->check_info();
+ if (!(ignore_if_no_info && necessary_to_configure))
+ {
+ if ((thread_mask & SLAVE_IO) != 0 && mi->init_info())
+ error= 1;
+ }
+
+ necessary_to_configure= mi->rli->check_info();
+ if (!(ignore_if_no_info && necessary_to_configure))
+ {
+ if (((thread_mask & SLAVE_SQL) != 0 || !(mi->rli->inited))
+ && mi->rli->init_info())
+ error= 1;
+ }
+
+ mysql_mutex_unlock(&mi->rli->data_lock);
+ mysql_mutex_unlock(&mi->data_lock);
+
+ DBUG_RETURN(error);
+}
+
+void end_info(Master_info* mi)
+{
+ DBUG_ENTER("end_info");
+ DBUG_ASSERT(mi != NULL && mi->rli != NULL);
+
+ /*
+ The previous implementation was not acquiring locks.
+ We do the same here. However, this is quite strange.
+ */
+ mi->end_info();
+ mi->rli->end_info();
+
+ DBUG_VOID_RETURN;
+}
+
+int reset_info(Master_info* mi)
+{
+ int error= 0;
+ DBUG_ENTER("reset_info");
+ DBUG_ASSERT(mi != NULL && mi->rli != NULL);
+
+ /*
+ The previous implementation was not acquiring locks.
+ We do the same here. However, this is quite strange.
+ */
+ /*
+ Reset errors (the idea is that we forget about the
+ old master).
+ */
+ mi->clear_error();
+ mi->rli->clear_error();
+ mi->rli->clear_until_condition();
+ mi->rli->clear_sql_delay();
+
+ mi->end_info();
+ mi->rli->end_info();
+
+ if (mi->reset_info() || mi->rli->reset_info())
+ error= 1;
+
+ DBUG_RETURN(error);
+}
+
+int flush_master_info(Master_info* mi, bool force)
+{
+ DBUG_ENTER("flush_master_info");
+ DBUG_ASSERT(mi != NULL && mi->rli != NULL);
+ /*
+ The previous implementation was not acquiring locks.
+ We do the same here. However, this is quite strange.
+ */
+ /*
+ With the appropriate recovery process, we will not need to flush
+ the content of the current log.
+
+ For now, we flush the relay log BEFORE the master.info file, because
+ if we crash, we will get a duplicate event in the relay log at restart.
+ If we change the order, there might be missing events.
+
+ If we don't do this and the slave server dies when the relay log has
+ some parts (its last kilobytes) in memory only, with, say, from master's
+ position 100 to 150 in memory only (not on disk), and with position 150
+ in master.info, there will be missing information. When the slave restarts,
+ the I/O thread will fetch binlogs from 150, so in the relay log we will
+ have "[0, 100] U [150, infinity[" and nobody will notice it, so the SQL
+ thread will jump from 100 to 150, and replication will silently break.
+ */
+ mysql_mutex_t *log_lock= mi->rli->relay_log.get_log_lock();
+
+ mysql_mutex_lock(log_lock);
+
+ int err= (mi->rli->flush_current_log() || mi->flush_info(force));
+
+ mysql_mutex_unlock(log_lock);
+
+ DBUG_RETURN (err);
+}
+
/**
Convert slave skip errors bitmap into a printable string.
*/
@@ -491,7 +612,7 @@ static void set_thd_in_use_temporary_tab
TABLE *table;
for (table= rli->save_temporary_tables ; table ; table= table->next)
- table->in_use= rli->sql_thd;
+ table->in_use= rli->info_thd;
}
int terminate_slave_threads(Master_info* mi,int thread_mask,bool skip_lock)
@@ -501,14 +622,14 @@ int terminate_slave_threads(Master_info*
if (!mi->inited)
DBUG_RETURN(0); /* successfully do nothing */
int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
- mysql_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock;
- mysql_mutex_t *log_lock= mi->rli.relay_log.get_log_lock();
+ mysql_mutex_t *sql_lock = &mi->rli->run_lock, *io_lock = &mi->run_lock;
+ mysql_mutex_t *log_lock= mi->rli->relay_log.get_log_lock();
if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
{
DBUG_PRINT("info",("Terminating IO thread"));
mi->abort_slave=1;
- if ((error=terminate_slave_thread(mi->io_thd, io_lock,
+ if ((error=terminate_slave_thread(mi->info_thd,io_lock,
&mi->stop_cond,
&mi->slave_running,
skip_lock)) &&
@@ -517,16 +638,20 @@ int terminate_slave_threads(Master_info*
mysql_mutex_lock(log_lock);
- DBUG_PRINT("info",("Flushing relay log and master info file."));
+ DBUG_PRINT("info",("Flushing relay log and master info repository."));
if (current_thd)
- thd_proc_info(current_thd, "Flushing relay log and master info files.");
- if (flush_master_info(mi, TRUE, FALSE))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
+ thd_proc_info(current_thd, "Flushing relay log and master info repository.");
- if (my_sync(mi->rli.relay_log.get_log_file()->file, MYF(MY_WME)))
+ /*
+ Flushes the master info regardles of the sync_master_info option.
+ */
+ if (mi->flush_info(TRUE))
DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
- if (my_sync(mi->fd, MYF(MY_WME)))
+ /*
+ Flushes the relay log regardles of the sync_relay_log option.
+ */
+ if (mi->rli->relay_log.flush_and_sync(0, TRUE))
DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
mysql_mutex_unlock(log_lock);
@@ -534,10 +659,10 @@ int terminate_slave_threads(Master_info*
if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
{
DBUG_PRINT("info",("Terminating SQL thread"));
- mi->rli.abort_slave=1;
- if ((error=terminate_slave_thread(mi->rli.sql_thd, sql_lock,
- &mi->rli.stop_cond,
- &mi->rli.slave_running,
+ mi->rli->abort_slave= 1;
+ if ((error=terminate_slave_thread(mi->rli->info_thd, sql_lock,
+ &mi->rli->stop_cond,
+ &mi->rli->slave_running,
skip_lock)) &&
!force_all)
DBUG_RETURN(error);
@@ -547,15 +672,16 @@ int terminate_slave_threads(Master_info*
DBUG_PRINT("info",("Flushing relay-log info file."));
if (current_thd)
thd_proc_info(current_thd, "Flushing relay-log info file.");
- if (flush_relay_log_info(&mi->rli))
- DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
-
- if (my_sync(mi->rli.info_fd, MYF(MY_WME)))
+
+ /*
+ Flushes the relay log info regardles of the sync_relay_log_info option.
+ */
+ if (mi->rli->flush_info(TRUE))
DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
mysql_mutex_unlock(log_lock);
}
- DBUG_RETURN(0);
+ DBUG_RETURN(0);
}
@@ -684,8 +810,6 @@ int start_slave_thread(
ulong start_id;
DBUG_ENTER("start_slave_thread");
- DBUG_ASSERT(mi->inited);
-
if (start_lock)
mysql_mutex_lock(start_lock);
if (!server_id)
@@ -750,8 +874,7 @@ int start_slave_thread(
*/
int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
- Master_info* mi, const char* master_info_fname,
- const char* slave_info_fname, int thread_mask)
+ Master_info* mi, int thread_mask)
{
mysql_mutex_t *lock_io=0, *lock_sql=0, *lock_cond_io=0, *lock_cond_sql=0;
mysql_cond_t* cond_io=0, *cond_sql=0;
@@ -761,14 +884,14 @@ int start_slave_threads(bool need_slave_
if (need_slave_mutex)
{
lock_io = &mi->run_lock;
- lock_sql = &mi->rli.run_lock;
+ lock_sql = &mi->rli->run_lock;
}
if (wait_for_start)
{
cond_io = &mi->start_cond;
- cond_sql = &mi->rli.start_cond;
+ cond_sql = &mi->rli->start_cond;
lock_cond_io = &mi->run_lock;
- lock_cond_sql = &mi->rli.run_lock;
+ lock_cond_sql = &mi->rli->run_lock;
}
if (thread_mask & SLAVE_IO)
@@ -788,7 +911,7 @@ int start_slave_threads(bool need_slave_
#endif
handle_slave_sql, lock_sql, lock_cond_sql,
cond_sql,
- &mi->rli.slave_running, &mi->rli.slave_run_id,
+ &mi->rli->slave_running, &mi->rli->slave_run_id,
mi);
if (error)
terminate_slave_threads(mi, thread_mask & SLAVE_IO, !need_slave_mutex);
@@ -796,7 +919,6 @@ int start_slave_threads(bool need_slave_
DBUG_RETURN(error);
}
-
/*
Release slave threads at time of executing shutdown.
@@ -843,7 +965,9 @@ void close_active_mi()
mysql_mutex_lock(&LOCK_active_mi);
if (active_mi)
{
- end_master_info(active_mi);
+ end_info(active_mi);
+ if (active_mi->rli)
+ delete active_mi->rli;
delete active_mi;
active_mi= 0;
}
@@ -854,7 +978,7 @@ static bool io_slave_killed(THD* thd, Ma
{
DBUG_ENTER("io_slave_killed");
- DBUG_ASSERT(mi->io_thd == thd);
+ DBUG_ASSERT(mi->info_thd == thd);
DBUG_ASSERT(mi->slave_running); // tracking buffer overrun
DBUG_RETURN(mi->abort_slave || abort_loop || thd->killed);
}
@@ -877,7 +1001,7 @@ static bool sql_slave_killed(THD* thd, R
bool ret= FALSE;
DBUG_ENTER("sql_slave_killed");
- DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->info_thd == thd);
DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
if (abort_loop || thd->killed || rli->abort_slave)
{
@@ -987,185 +1111,6 @@ const char *print_slave_db_safe(const ch
DBUG_RETURN((db ? db : ""));
}
-int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
- const char *default_val)
-{
- uint length;
- DBUG_ENTER("init_strvar_from_file");
-
- if ((length=my_b_gets(f,var, max_size)))
- {
- char* last_p = var + length -1;
- if (*last_p == '\n')
- *last_p = 0; // if we stopped on newline, kill it
- else
- {
- /*
- If we truncated a line or stopped on last char, remove all chars
- up to and including newline.
- */
- int c;
- while (((c=my_b_get(f)) != '\n' && c != my_b_EOF)) ;
- }
- DBUG_RETURN(0);
- }
- else if (default_val)
- {
- strmake(var, default_val, max_size-1);
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
-
-
-int init_intvar_from_file(int* var, IO_CACHE* f, int default_val)
-{
- char buf[32];
- DBUG_ENTER("init_intvar_from_file");
-
-
- if (my_b_gets(f, buf, sizeof(buf)))
- {
- *var = atoi(buf);
- DBUG_RETURN(0);
- }
- else if (default_val)
- {
- *var = default_val;
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
-
-int init_longvar_from_file(long* var, IO_CACHE* f, long default_val)
-{
- char buf[32];
- DBUG_ENTER("init_longvar_from_file");
-
-
- if (my_b_gets(f, buf, sizeof(buf)))
- {
- *var = atol(buf);
- DBUG_RETURN(0);
- }
- else if (default_val)
- {
- *var = default_val;
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
-
-int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val)
-{
- char buf[16];
- DBUG_ENTER("init_floatvar_from_file");
-
-
- if (my_b_gets(f, buf, sizeof(buf)))
- {
- if (sscanf(buf, "%f", var) != 1)
- DBUG_RETURN(1);
- else
- DBUG_RETURN(0);
- }
- else if (default_val != 0.0)
- {
- *var = default_val;
- DBUG_RETURN(0);
- }
- DBUG_RETURN(1);
-}
-
-
-/**
- A master info read method
-
- This function is called from @c init_master_info() along with
- relatives to restore some of @c active_mi members.
- Particularly, this function is responsible for restoring
- IGNORE_SERVER_IDS list of servers whose events the slave is
- going to ignore (to not log them in the relay log).
- Items being read are supposed to be decimal output of values of a
- type shorter or equal of @c long and separated by the single space.
-
- @param arr @c DYNAMIC_ARRAY pointer to storage for servers id
- @param f @c IO_CACHE pointer to the source file
-
- @retval 0 All OK
- @retval non-zero An error
-*/
-
-int init_dynarray_intvar_from_file(DYNAMIC_ARRAY* arr, IO_CACHE* f)
-{
- int ret= 0;
- char buf[16 * (sizeof(long)*4 + 1)]; // static buffer to use most of times
- char *buf_act= buf; // actual buffer can be dynamic if static is short
- char *token, *last;
- uint num_items; // number of items of `arr'
- size_t read_size;
- DBUG_ENTER("init_dynarray_intvar_from_file");
-
- if ((read_size= my_b_gets(f, buf_act, sizeof(buf))) == 0)
- {
- return 0; // no line in master.info
- }
- if (read_size + 1 == sizeof(buf) && buf[sizeof(buf) - 2] != '\n')
- {
- /*
- short read happend; allocate sufficient memory and make the 2nd read
- */
- char buf_work[(sizeof(long)*3 + 1)*16];
- memcpy(buf_work, buf, sizeof(buf_work));
- num_items= atoi(strtok_r(buf_work, " ", &last));
- size_t snd_size;
- /*
- max size lower bound approximate estimation bases on the formula:
- (the items number + items themselves) *
- (decimal size + space) - 1 + `\n' + '\0'
- */
- size_t max_size= (1 + num_items) * (sizeof(long)*3 + 1) + 1;
- buf_act= (char*) my_malloc(max_size, MYF(MY_WME));
- memcpy(buf_act, buf, read_size);
- snd_size= my_b_gets(f, buf_act + read_size, max_size - read_size);
- if (snd_size == 0 ||
- ((snd_size + 1 == max_size - read_size) && buf[max_size - 2] != '\n'))
- {
- /*
- failure to make the 2nd read or short read again
- */
- ret= 1;
- goto err;
- }
- }
- token= strtok_r(buf_act, " ", &last);
- if (token == NULL)
- {
- ret= 1;
- goto err;
- }
- num_items= atoi(token);
- for (uint i=0; i < num_items; i++)
- {
- token= strtok_r(NULL, " ", &last);
- if (token == NULL)
- {
- ret= 1;
- goto err;
- }
- else
- {
- ulong val= atol(token);
- insert_dynamic(arr, (uchar *) &val);
- }
- }
-err:
- if (buf_act != buf)
- my_free(buf_act);
- DBUG_RETURN(ret);
-}
-
-
/*
Check if the error is caused by network.
@param[in] errorno Number of the error.
@@ -1202,7 +1147,7 @@ int io_thread_init_commands(MYSQL *mysql
sprintf(query, "SET @slave_uuid= '%s'", server_uuid);
if (mysql_real_query(mysql, query, strlen(query))
- && !check_io_slave_killed(mi->io_thd, mi, NULL))
+ && !check_io_slave_killed(mi->info_thd, mi, NULL))
goto err;
mysql_free_result(mysql_store_result(mysql));
@@ -1222,6 +1167,7 @@ err:
const char *errmsg_fmt=
"The slave I/O thread stops because a fatal error is encountered "
"when it tries to send query to master(query: %s).";
+
sprintf(errmsg, errmsg_fmt, query);
mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
errmsg);
@@ -1260,7 +1206,7 @@ static int get_master_uuid(MYSQL *mysql,
(master_row= mysql_fetch_row(master_res)))
{
if (!strcmp(::server_uuid, master_row[1]) &&
- !mi->rli.replicate_same_server_id)
+ !mi->rli->replicate_same_server_id)
{
errmsg= "The slave I/O thread stops because master and slave have equal "
"MySQL server UUIDs; these UUIDs must be different for "
@@ -1340,8 +1286,8 @@ static int get_master_version_and_clock(
Free old description_event_for_queue (that is needed if we are in
a reconnection).
*/
- delete mi->rli.relay_log.description_event_for_queue;
- mi->rli.relay_log.description_event_for_queue= 0;
+ delete mi->rli->relay_log.description_event_for_queue;
+ mi->rli->relay_log.description_event_for_queue= 0;
if (!my_isdigit(&my_charset_bin,*mysql->server_version))
{
@@ -1364,11 +1310,11 @@ static int get_master_version_and_clock(
sprintf(err_buff, ER(err_code), errmsg);
break;
case '3':
- mi->rli.relay_log.description_event_for_queue= new
+ mi->rli->relay_log.description_event_for_queue= new
Format_description_log_event(1, mysql->server_version);
break;
case '4':
- mi->rli.relay_log.description_event_for_queue= new
+ mi->rli->relay_log.description_event_for_queue= new
Format_description_log_event(3, mysql->server_version);
break;
default:
@@ -1380,16 +1326,16 @@ static int get_master_version_and_clock(
(it has the format of the *slave*); it's only good to help know if the
master is 3.23, 4.0, etc.
*/
- mi->rli.relay_log.description_event_for_queue= new
+ mi->rli->relay_log.description_event_for_queue= new
Format_description_log_event(4, mysql->server_version);
break;
}
}
/*
- This does not mean that a 5.0 slave will be able to read a 6.0 master; but
+ This does not mean that a 5.0 slave will be able to read a 5.5 master; but
as we don't know yet, we don't want to forbid this for now. If a 5.0 slave
- can't read a 6.0 master, this will show up when the slave can't read some
+ can't read a 5.5 master, this will show up when the slave can't read some
events sent by the master, and there will be error messages.
*/
@@ -1397,7 +1343,7 @@ static int get_master_version_and_clock(
goto err;
/* as we are here, we tried to allocate the event */
- if (!mi->rli.relay_log.description_event_for_queue)
+ if (!mi->rli->relay_log.description_event_for_queue)
{
errmsg= "default Format_description_log_event";
err_code= ER_SLAVE_CREATE_EVENT_FAILURE;
@@ -1430,7 +1376,7 @@ static int get_master_version_and_clock(
(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
mysql_mutex_unlock(&mi->data_lock);
}
- else if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ else if (check_io_slave_killed(mi->info_thd, mi, NULL))
goto slave_killed_err;
else if (is_network_error(mysql_errno(mysql)))
{
@@ -1481,7 +1427,7 @@ static int get_master_version_and_clock(
(master_row= mysql_fetch_row(master_res)))
{
if ((::server_id == (mi->master_id= strtoul(master_row[1], 0, 10))) &&
- !mi->rli.replicate_same_server_id)
+ !mi->rli->replicate_same_server_id)
{
errmsg= "The slave I/O thread stops because master and slave have equal \
MySQL server ids; these ids must be different for replication to work (or \
@@ -1494,7 +1440,7 @@ not always make sense; please check the
}
else if (mysql_errno(mysql))
{
- if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ if (check_io_slave_killed(mi->info_thd, mi, NULL))
goto slave_killed_err;
else if (is_network_error(mysql_errno(mysql)))
{
@@ -1520,7 +1466,7 @@ maybe it is a *VERY OLD MASTER*.");
mysql_free_result(master_res);
master_res= NULL;
}
- if (mi->master_id == 0 && mi->ignore_server_ids.elements > 0)
+ if (mi->master_id == 0 && mi->ignore_server_ids->server_ids.elements > 0)
{
errmsg= "Slave configured with server id filtering could not detect the master server id.";
err_code= ER_SLAVE_FATAL_ERROR;
@@ -1567,7 +1513,7 @@ be equal for the Statement-format replic
goto err;
}
}
- else if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ else if (check_io_slave_killed(mi->info_thd, mi, NULL))
goto slave_killed_err;
else if (is_network_error(mysql_errno(mysql)))
{
@@ -1630,7 +1576,7 @@ be equal for the Statement-format replic
goto err;
}
}
- else if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ else if (check_io_slave_killed(mi->info_thd, mi, NULL))
goto slave_killed_err;
else if (is_network_error(mysql_errno(mysql)))
{
@@ -1666,7 +1612,7 @@ when it try to get the value of TIME_ZON
sprintf(query, query_format, llbuf);
if (mysql_real_query(mysql, query, strlen(query))
- && !check_io_slave_killed(mi->io_thd, mi, NULL))
+ && !check_io_slave_killed(mi->info_thd, mi, NULL))
{
errmsg= "The slave I/O thread stops because SET @master_heartbeat_period "
"on master failed.";
@@ -1707,7 +1653,7 @@ static bool wait_for_relay_log_space(Rel
bool slave_killed=0;
Master_info* mi = rli->mi;
const char *save_proc_info;
- THD* thd = mi->io_thd;
+ THD* thd = mi->info_thd;
DBUG_ENTER("wait_for_relay_log_space");
mysql_mutex_lock(&rli->log_space_lock);
@@ -1739,11 +1685,11 @@ Waiting for the slave SQL thread to free
*/
static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
{
- Relay_log_info *rli= &mi->rli;
+ Relay_log_info *rli= mi->rli;
mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
DBUG_ENTER("write_ignored_events_info_to_relay_log");
- DBUG_ASSERT(thd == mi->io_thd);
+ DBUG_ASSERT(thd == mi->info_thd);
mysql_mutex_lock(log_lock);
if (rli->ign_master_log_name_end[0])
{
@@ -1764,7 +1710,7 @@ static void write_ignored_events_info_to
" to the relay log, SHOW SLAVE STATUS may be"
" inaccurate");
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
- if (flush_master_info(mi, TRUE, TRUE))
+ if (flush_master_info(mi, TRUE))
sql_print_error("Failed to flush master info file");
delete ev;
}
@@ -1841,7 +1787,7 @@ int register_slave_on_master(MYSQL* mysq
{
*suppress_warnings= TRUE; // Suppress reconnect warning
}
- else if (!check_io_slave_killed(mi->io_thd, mi, NULL))
+ else if (!check_io_slave_killed(mi->info_thd, mi, NULL))
{
char buf[256];
my_snprintf(buf, sizeof(buf), "%s (Errno: %d)", mysql_error(mysql),
@@ -1939,7 +1885,7 @@ bool show_master_info(THD* thd, Master_i
MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Master_UUID", UUID_LENGTH));
field_list.push_back(new Item_empty_string("Master_Info_File",
- sizeof(mi->info_file_name)));
+ 2 * FN_REFLEN));
field_list.push_back(new Item_return_int("SQL_Delay", 10, MYSQL_TYPE_LONG));
field_list.push_back(new Item_return_int("SQL_Remaining_Delay", 8, MYSQL_TYPE_LONG));
field_list.push_back(new Item_empty_string("Slave_SQL_Running_State", 20));
@@ -1958,31 +1904,32 @@ bool show_master_info(THD* thd, Master_i
/*
slave_running can be accessed without run_lock but not other
- non-volotile members like mi->io_thd, which is guarded by the mutex.
+ non-volotile members like mi->info_thd, which is guarded by the mutex.
*/
mysql_mutex_lock(&mi->run_lock);
- protocol->store(mi->io_thd ? mi->io_thd->proc_info : "", &my_charset_bin);
+ protocol->store(mi->info_thd ? mi->info_thd->proc_info : "", &my_charset_bin);
mysql_mutex_unlock(&mi->run_lock);
mysql_mutex_lock(&mi->data_lock);
- mysql_mutex_lock(&mi->rli.data_lock);
+ mysql_mutex_lock(&mi->rli->data_lock);
mysql_mutex_lock(&mi->err_lock);
- mysql_mutex_lock(&mi->rli.err_lock);
+ mysql_mutex_lock(&mi->rli->err_lock);
+
protocol->store(mi->host, &my_charset_bin);
protocol->store(mi->user, &my_charset_bin);
protocol->store((uint32) mi->port);
protocol->store((uint32) mi->connect_retry);
- protocol->store(mi->master_log_name, &my_charset_bin);
- protocol->store((ulonglong) mi->master_log_pos);
- protocol->store(mi->rli.group_relay_log_name +
- dirname_length(mi->rli.group_relay_log_name),
+ protocol->store(mi->get_master_log_name(), &my_charset_bin);
+ protocol->store((ulonglong) mi->get_master_log_pos());
+ protocol->store(mi->rli->get_group_relay_log_name() +
+ dirname_length(mi->rli->get_group_relay_log_name()),
&my_charset_bin);
- protocol->store((ulonglong) mi->rli.group_relay_log_pos);
- protocol->store(mi->rli.group_master_log_name, &my_charset_bin);
+ protocol->store((ulonglong) mi->rli->get_group_relay_log_pos());
+ protocol->store(mi->rli->get_group_master_log_name(), &my_charset_bin);
protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
"Yes" : (mi->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT ?
"Connecting" : "No"), &my_charset_bin);
- protocol->store(mi->rli.slave_running ? "Yes":"No", &my_charset_bin);
+ protocol->store(mi->rli->slave_running ? "Yes":"No", &my_charset_bin);
protocol->store(rpl_filter->get_do_db());
protocol->store(rpl_filter->get_ignore_db());
@@ -1997,18 +1944,18 @@ bool show_master_info(THD* thd, Master_i
rpl_filter->get_wild_ignore_table(&tmp);
protocol->store(&tmp);
- protocol->store(mi->rli.last_error().number);
- protocol->store(mi->rli.last_error().message, &my_charset_bin);
- protocol->store((uint32) mi->rli.slave_skip_counter);
- protocol->store((ulonglong) mi->rli.group_master_log_pos);
- protocol->store((ulonglong) mi->rli.log_space_total);
+ protocol->store(mi->rli->last_error().number);
+ protocol->store(mi->rli->last_error().message, &my_charset_bin);
+ protocol->store((uint32) mi->rli->slave_skip_counter);
+ protocol->store((ulonglong) mi->rli->get_group_master_log_pos());
+ protocol->store((ulonglong) mi->rli->log_space_total);
protocol->store(
- mi->rli.until_condition==Relay_log_info::UNTIL_NONE ? "None":
- ( mi->rli.until_condition==Relay_log_info::UNTIL_MASTER_POS? "Master":
+ mi->rli->until_condition==Relay_log_info::UNTIL_NONE ? "None":
+ ( mi->rli->until_condition==Relay_log_info::UNTIL_MASTER_POS? "Master":
"Relay"), &my_charset_bin);
- protocol->store(mi->rli.until_log_name, &my_charset_bin);
- protocol->store((ulonglong) mi->rli.until_log_pos);
+ protocol->store(mi->rli->until_log_name, &my_charset_bin);
+ protocol->store((ulonglong) mi->rli->until_log_pos);
#ifdef HAVE_OPENSSL
protocol->store(mi->ssl? "Yes":"No", &my_charset_bin);
@@ -2026,9 +1973,9 @@ bool show_master_info(THD* thd, Master_i
connected, we can compute it otherwise show NULL (i.e. unknown).
*/
if ((mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) &&
- mi->rli.slave_running)
+ mi->rli->slave_running)
{
- long time_diff= ((long)(time(0) - mi->rli.last_master_timestamp)
+ long time_diff= ((long)(time(0) - mi->rli->last_master_timestamp)
- mi->clock_diff_with_master);
/*
Apparently on some systems time_diff can be <0. Here are possible
@@ -2050,7 +1997,7 @@ bool show_master_info(THD* thd, Master_i
last_master_timestamp == 0 (an "impossible" timestamp 1970) is a
special marker to say "consider we have caught up".
*/
- protocol->store((longlong)(mi->rli.last_master_timestamp ?
+ protocol->store((longlong)(mi->rli->last_master_timestamp ?
max(0, time_diff) : 0));
}
else
@@ -2073,30 +2020,30 @@ bool show_master_info(THD* thd, Master_i
else
protocol->store(mi->last_error().message, &my_charset_bin);
// Last_SQL_Errno
- protocol->store(mi->rli.last_error().number);
+ protocol->store(mi->rli->last_error().number);
// Last_SQL_Error
- if (*mi->rli.last_error().message != '\0')
+ if (*mi->rli->last_error().message != '\0')
{
String msg_buf;
- msg_buf.append(mi->rli.last_error().timestamp);
+ msg_buf.append(mi->rli->last_error().timestamp);
msg_buf.append(" ");
- msg_buf.append(mi->rli.last_error().message);
+ msg_buf.append(mi->rli->last_error().message);
protocol->store(msg_buf.c_ptr_safe(), &my_charset_bin);
}
else
- protocol->store(mi->rli.last_error().message, &my_charset_bin);
+ protocol->store(mi->rli->last_error().message, &my_charset_bin);
// Replicate_Ignore_Server_Ids
{
char buff[FN_REFLEN];
ulong i, cur_len;
for (i= 0, buff[0]= 0, cur_len= 0;
- i < mi->ignore_server_ids.elements; i++)
+ i < mi->ignore_server_ids->server_ids.elements; i++)
{
ulong s_id, slen;
char sbuff[FN_REFLEN];
- get_dynamic(&mi->ignore_server_ids, (uchar*) &s_id, i);
- slen= sprintf(sbuff, (i==0? "%lu" : ", %lu"), s_id);
+ get_dynamic(&(mi->ignore_server_ids->server_ids), (uchar*) &s_id, i);
+ slen= sprintf(sbuff, (i == 0 ? "%lu" : ", %lu"), s_id);
if (cur_len + slen + 4 > FN_REFLEN)
{
/*
@@ -2114,16 +2061,16 @@ bool show_master_info(THD* thd, Master_i
protocol->store((uint32) mi->master_id);
protocol->store(mi->master_uuid, &my_charset_bin);
// Master_Info_File
- protocol->store(mi->info_file_name, &my_charset_bin);
+ protocol->store(mi->get_description_info(), &my_charset_bin);
// SQL_Delay
- protocol->store((uint32) mi->rli.get_sql_delay());
+ protocol->store((uint32) mi->rli->get_sql_delay());
// SQL_Remaining_Delay
// THD::proc_info is not protected by any lock, so we read it once
// to ensure that we use the same value throughout this function.
- const char *slave_sql_running_state= mi->rli.sql_thd ? mi->rli.sql_thd->proc_info : "";
+ const char *slave_sql_running_state= mi->rli->info_thd ? mi->rli->info_thd->proc_info : "";
if (slave_sql_running_state == Relay_log_info::state_delaying_string)
{
- time_t t= my_time(0), sql_delay_end= mi->rli.get_sql_delay_end();
+ time_t t= my_time(0), sql_delay_end= mi->rli->get_sql_delay_end();
protocol->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0));
}
else
@@ -2133,9 +2080,9 @@ bool show_master_info(THD* thd, Master_i
// Master_Retry_Count
protocol->store((ulonglong) mi->retry_count);
- mysql_mutex_unlock(&mi->rli.err_lock);
+ mysql_mutex_unlock(&mi->rli->err_lock);
mysql_mutex_unlock(&mi->err_lock);
- mysql_mutex_unlock(&mi->rli.data_lock);
+ mysql_mutex_unlock(&mi->rli->data_lock);
mysql_mutex_unlock(&mi->data_lock);
if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(), packet->length()))
@@ -2301,7 +2248,7 @@ static int request_dump(THD *thd, MYSQL*
uchar buf[FN_REFLEN + 10];
int len;
ushort binlog_flags = 0; // for now
- char* logname = mi->master_log_name;
+ const char* logname = mi->get_master_log_name();
DBUG_ENTER("request_dump");
*suppress_warnings= FALSE;
@@ -2312,7 +2259,7 @@ static int request_dump(THD *thd, MYSQL*
DBUG_RETURN(1);
// TODO if big log files: Change next to int8store()
- int4store(buf, (ulong) mi->master_log_pos);
+ int4store(buf, (ulong) mi->get_master_log_pos());
int2store(buf + 4, binlog_flags);
int4store(buf + 6, server_id);
len = (uint) strlen(logname);
@@ -2365,7 +2312,7 @@ static ulong read_event(MYSQL* mysql, Ma
We check if we were told to die, and if not, try reading again
*/
#ifndef DBUG_OFF
- if (disconnect_slave_event_count && !(mi->events_till_disconnect--))
+ if (disconnect_slave_event_count && !(mi->events_until_exit--))
DBUG_RETURN(packet_error);
#endif
@@ -2581,7 +2528,7 @@ int apply_event_and_update_pos(Log_event
DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT),
FLAGSTR(thd->variables.option_bits, OPTION_BEGIN),
- (ulong) rli->last_event_start_time));
+ rli->last_event_start_time));
/*
Execute the event to change the database and update the binary
@@ -2617,7 +2564,6 @@ int apply_event_and_update_pos(Log_event
int reason= ev->shall_skip(rli);
if (reason == Log_event::EVENT_SKIP_COUNT)
sql_slave_skip_counter= --rli->slave_skip_counter;
-
if (reason == Log_event::EVENT_SKIP_NOT)
{
// Sleeps if needed, and unlocks rli->data_lock.
@@ -2652,6 +2598,12 @@ int apply_event_and_update_pos(Log_event
DBUG_PRINT("info", ("apply_event error = %d", exec_res));
if (exec_res == 0)
{
+ /*
+ Positions are not updated when an XID is processed, i.e. not skipped.
+ To make the slave crash-safe positions are updated while processing
+ the XID event and as such do not need to be updated again.
+ See sql/rpl_rli.h for further details.
+ */
int error= ev->update_pos(rli);
#ifndef DBUG_OFF
DBUG_PRINT("info", ("update_pos error = %d", error));
@@ -2659,11 +2611,11 @@ int apply_event_and_update_pos(Log_event
{
char buf[22];
DBUG_PRINT("info", ("group %s %s",
- llstr(rli->group_relay_log_pos, buf),
- rli->group_relay_log_name));
+ llstr(rli->get_group_relay_log_pos(), buf),
+ rli->get_group_relay_log_name()));
DBUG_PRINT("info", ("event %s %s",
- llstr(rli->event_relay_log_pos, buf),
- rli->event_relay_log_name));
+ llstr(rli->get_event_relay_log_pos(), buf),
+ rli->get_event_relay_log_name()));
}
#endif
/*
@@ -2681,8 +2633,8 @@ int apply_event_and_update_pos(Log_event
" of the relay log information: the slave may"
" be in an inconsistent state."
" Stopped in %s position %s",
- rli->group_relay_log_name,
- llstr(rli->group_relay_log_pos, buf));
+ rli->get_group_relay_log_name(),
+ llstr(rli->get_group_relay_log_pos(), buf));
DBUG_RETURN(2);
}
}
@@ -2711,7 +2663,7 @@ int apply_event_and_update_pos(Log_event
tried slave_trans_retries times. If the event has been retried
fewer times, 0 is returned.
- - init_master_info or init_relay_log_pos failed. (These are called
+ - init_info or init_relay_log_pos failed. (These are called
if a failure occurs when applying the event.)
- An error occurred when updating the binlog position.
@@ -2733,7 +2685,7 @@ static int exec_relay_log_event(THD* thd
Log_event * ev = next_event(rli);
- DBUG_ASSERT(rli->sql_thd==thd);
+ DBUG_ASSERT(rli->info_thd==thd);
if (sql_slave_killed(thd,rli))
{
@@ -2841,21 +2793,24 @@ static int exec_relay_log_event(THD* thd
Note, if lock wait timeout (innodb_lock_wait_timeout exceeded)
there is no rollback since 5.0.13 (ref: manual).
We have to not only seek but also
- a) init_master_info(), to seek back to hot relay log's start for later
+ a) init_info(), to seek back to hot relay log's start for later
(for when we will come back to this hot log after re-processing the
possibly existing old logs where BEGIN is: check_binlog_magic() will
then need the cache to be at position 0 (see comments at beginning of
- init_master_info()).
+ init_info()).
b) init_relay_log_pos(), because the BEGIN may be an older relay log.
*/
if (rli->trans_retries < slave_trans_retries)
{
- if (init_master_info(rli->mi, 0, 0, 0, SLAVE_SQL))
+ /*
+ We need to figure out if there is a test case that covers
+ this part. \Alfranio.
+ */
+ if (init_info(rli->mi, FALSE, SLAVE_SQL))
sql_print_error("Failed to initialize the master info structure");
- else if (init_relay_log_pos(rli,
- rli->group_relay_log_name,
- rli->group_relay_log_pos,
- 1, &errmsg, 1))
+ else if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
+ rli->get_group_relay_log_pos(),
+ 1, &errmsg, 1))
sql_print_error("Error initializing relay log position: %s",
errmsg);
else
@@ -2883,7 +2838,7 @@ static int exec_relay_log_event(THD* thd
}
else if ((exec_res && !temp_err) ||
(opt_using_transactions &&
- rli->group_relay_log_pos == rli->event_relay_log_pos))
+ rli->get_group_relay_log_pos() == rli->get_event_relay_log_pos()))
{
/*
Only reset the retry counter if the entire group succeeded
@@ -2912,7 +2867,6 @@ on this slave.\
DBUG_RETURN(1);
}
-
static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info)
{
if (io_slave_killed(thd, mi))
@@ -2974,7 +2928,8 @@ static int try_to_reconnect(THD *thd, MY
{
char buf[256], llbuff[22];
my_snprintf(buf, sizeof(buf), messages[SLAVE_RECON_MSG_FAILED],
- IO_RPL_LOG_NAME, llstr(mi->master_log_pos, llbuff));
+ mi->get_io_rpl_log_name(), llstr(mi->get_master_log_pos(),
+ llbuff));
/*
Raise a warining during registering on master/requesting dump.
Log a message reading event.
@@ -3013,7 +2968,7 @@ pthread_handler_t handle_slave_io(void *
THD *thd; // needs to be first for thread_stack
MYSQL *mysql;
Master_info *mi = (Master_info*)arg;
- Relay_log_info *rli= &mi->rli;
+ Relay_log_info *rli= mi->rli;
char llbuff[22];
uint retry_count;
bool suppress_warnings;
@@ -3034,12 +2989,12 @@ pthread_handler_t handle_slave_io(void *
mi->slave_run_id++;
#ifndef DBUG_OFF
- mi->events_till_disconnect = disconnect_slave_event_count;
+ mi->events_until_exit = disconnect_slave_event_count;
#endif
thd= new THD; // note that contructor of THD uses DBUG_ !
THD_CHECK_SENTRY(thd);
- mi->io_thd = thd;
+ mi->info_thd = thd;
pthread_detach_this_thread();
thd->thread_stack= (char*) &thd; // remember where our stack is
@@ -3060,8 +3015,8 @@ pthread_handler_t handle_slave_io(void *
mysql_cond_broadcast(&mi->start_cond);
DBUG_PRINT("master_info",("log_file_name: '%s' position: %s",
- mi->master_log_name,
- llstr(mi->master_log_pos,llbuff)));
+ mi->get_master_log_name(),
+ llstr(mi->get_master_log_pos(), llbuff)));
/* This must be called before run any binlog_relay_io hooks */
my_pthread_setspecific_ptr(RPL_MASTER_INFO, mi);
@@ -3087,8 +3042,8 @@ pthread_handler_t handle_slave_io(void *
sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',"
"replication started in log '%s' at position %s",
mi->user, mi->host, mi->port,
- IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
+ mi->get_io_rpl_log_name(),
+ llstr(mi->get_master_log_pos(), llbuff));
/*
Assign the max_packet_size with the bigger one of the values of
'max_packet_size' and 'opt_binlog_rows_event_max_size'. So that
@@ -3136,7 +3091,7 @@ connected:
if (ret == 2)
{
- if (check_io_slave_killed(mi->io_thd, mi, "Slave I/O thread killed"
+ if (check_io_slave_killed(mi->info_thd, mi, "Slave I/O thread killed"
"while calling get_master_version_and_clock(...)"))
goto err;
suppress_warnings= FALSE;
@@ -3147,7 +3102,7 @@ connected:
goto connected;
}
- if (mi->rli.relay_log.description_event_for_queue->binlog_version > 1)
+ if (mi->rli->relay_log.description_event_for_queue->binlog_version > 1)
{
/*
Register ourselves with the master.
@@ -3295,19 +3250,19 @@ Stopping slave I/O thread due to out-of-
goto err;
}
- if (flush_master_info(mi, TRUE, TRUE))
+ if (flush_master_info(mi, FALSE))
{
sql_print_error("Failed to flush master info file");
goto err;
}
/*
See if the relay logs take too much space.
- We don't lock mi->rli.log_space_lock here; this dirty read saves time
+ We don't lock mi->rli->log_space_lock here; this dirty read saves time
and does not introduce any problem:
- - if mi->rli.ignore_log_space_limit is 1 but becomes 0 just after (so
+ - if mi->rli->ignore_log_space_limit is 1 but becomes 0 just after (so
the clean value is 0), then we are reading only one more event as we
should, and we'll block only at the next event. No big deal.
- - if mi->rli.ignore_log_space_limit is 0 but becomes 1 just after (so
+ - if mi->rli->ignore_log_space_limit is 0 but becomes 1 just after (so
the clean value is 1), then we are going into wait_for_relay_log_space()
for no reason, but this function will do a clean read, notice the clean
value and exit immediately.
@@ -3339,7 +3294,7 @@ log space");
err:
// print the current replication position
sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
- IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
+ mi->get_io_rpl_log_name(), llstr(mi->get_master_log_pos(), llbuff));
RUN_HOOK(binlog_relay_io, thread_stop, (thd, mi));
thd->set_query(NULL, 0);
thd->reset_db(NULL, 0);
@@ -3364,8 +3319,8 @@ err:
mysql_mutex_lock(&mi->run_lock);
/* Forget the relay log's format */
- delete mi->rli.relay_log.description_event_for_queue;
- mi->rli.relay_log.description_event_for_queue= 0;
+ delete mi->rli->relay_log.description_event_for_queue;
+ mi->rli->relay_log.description_event_for_queue= 0;
DBUG_ASSERT(thd->net.buff != 0);
net_end(&thd->net); // destructor will not free it, because net.vio is 0
mysql_mutex_lock(&LOCK_thread_count);
@@ -3374,7 +3329,7 @@ err:
mysql_mutex_unlock(&LOCK_thread_count);
mi->abort_slave= 0;
mi->slave_running= 0;
- mi->io_thd= 0;
+ mi->info_thd= 0;
/*
Note: the order of the two following calls (first broadcast, then unlock)
is important. Otherwise a killer_thread can execute between the calls and
@@ -3383,11 +3338,10 @@ err:
mysql_cond_broadcast(&mi->stop_cond); // tell the world we are done
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
mysql_mutex_unlock(&mi->run_lock);
-
DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
pthread_exit(0);
- return 0; // Avoid compiler warnings
+ return(0); // Avoid compiler warnings
}
/*
@@ -3448,11 +3402,11 @@ pthread_handler_t handle_slave_sql(void
char llbuff[22],llbuff1[22];
char saved_log_name[FN_REFLEN];
char saved_master_log_name[FN_REFLEN];
- my_off_t UNINIT_VAR(saved_log_pos);
- my_off_t UNINIT_VAR(saved_master_log_pos);
+ my_off_t saved_log_pos= 0;
+ my_off_t saved_master_log_pos= 0;
my_off_t saved_skip= 0;
- Relay_log_info* rli = &((Master_info*)arg)->rli;
+ Relay_log_info* rli = ((Master_info*)arg)->rli;
const char *errmsg;
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
@@ -3464,12 +3418,12 @@ pthread_handler_t handle_slave_sql(void
DBUG_ASSERT(!rli->slave_running);
errmsg= 0;
#ifndef DBUG_OFF
- rli->events_till_abort = abort_slave_event_count;
+ rli->events_until_exit = abort_slave_event_count;
#endif
thd = new THD; // note that contructor of THD uses DBUG_ !
thd->thread_stack = (char*)&thd; // remember where our stack is
- rli->sql_thd= thd;
+ rli->info_thd= thd;
/* Inform waiting threads that slave has started */
rli->slave_run_id++;
@@ -3525,11 +3479,10 @@ pthread_handler_t handle_slave_sql(void
rli->trans_retries= 0; // start from "no error"
DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries));
- if (init_relay_log_pos(rli,
- rli->group_relay_log_name,
- rli->group_relay_log_pos,
- 1 /*need data lock*/, &errmsg,
- 1 /*look for a description_event*/))
+ if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
+ rli->get_group_relay_log_pos(),
+ 1 /*need data lock*/, &errmsg,
+ 1 /*look for a description_event*/))
{
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
"Error initializing relay log position: %s", errmsg);
@@ -3541,8 +3494,8 @@ pthread_handler_t handle_slave_sql(void
char llbuf1[22], llbuf2[22];
DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
llstr(my_b_tell(rli->cur_log),llbuf1),
- llstr(rli->event_relay_log_pos,llbuf2)));
- DBUG_ASSERT(rli->event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
+ llstr(rli->get_event_relay_log_pos(),llbuf2)));
+ DBUG_ASSERT(rli->get_event_relay_log_pos() >= BIN_LOG_HEADER_SIZE);
/*
Wonder if this is correct. I (Guilhem) wonder if my_b_tell() returns the
correct position when it's called just after my_b_seek() (the questionable
@@ -3556,20 +3509,20 @@ pthread_handler_t handle_slave_sql(void
DBUG_ASSERT().
*/
#ifdef SHOULD_BE_CHECKED
- DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->event_relay_log_pos);
+ DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->get_event_relay_log_pos());
#endif
}
#endif
- DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->info_thd == thd);
DBUG_PRINT("master_info",("log_file_name: %s position: %s",
- rli->group_master_log_name,
- llstr(rli->group_master_log_pos,llbuff)));
+ rli->get_group_master_log_name(),
+ llstr(rli->get_group_master_log_pos(),llbuff)));
if (global_system_variables.log_warnings)
sql_print_information("Slave SQL thread initialized, starting replication in \
-log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
- llstr(rli->group_master_log_pos,llbuff),rli->group_relay_log_name,
- llstr(rli->group_relay_log_pos,llbuff1));
+log '%s' at position %s, relay log '%s' position: %s", rli->get_rpl_log_name(),
+ llstr(rli->get_group_master_log_pos(),llbuff),rli->get_group_relay_log_name(),
+ llstr(rli->get_group_relay_log_pos(),llbuff1));
if (check_temp_dir(rli->slave_patternload_file))
{
@@ -3598,10 +3551,10 @@ log '%s' at position %s, relay log '%s'
mysql_mutex_lock(&rli->data_lock);
if (rli->slave_skip_counter)
{
- strmake(saved_log_name, rli->group_relay_log_name, FN_REFLEN - 1);
- strmake(saved_master_log_name, rli->group_master_log_name, FN_REFLEN - 1);
- saved_log_pos= rli->group_relay_log_pos;
- saved_master_log_pos= rli->group_master_log_pos;
+ strmake(saved_log_name, rli->get_group_relay_log_name(), FN_REFLEN - 1);
+ strmake(saved_master_log_name, rli->get_group_master_log_name(), FN_REFLEN - 1);
+ saved_log_pos= rli->get_group_relay_log_pos();
+ saved_master_log_pos= rli->get_group_master_log_pos();
saved_skip= rli->slave_skip_counter;
}
if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
@@ -3620,7 +3573,7 @@ log '%s' at position %s, relay log '%s'
while (!sql_slave_killed(thd,rli))
{
thd_proc_info(thd, "Reading event from the relay log");
- DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->info_thd == thd);
THD_CHECK_SENTRY(thd);
if (saved_skip && rli->slave_skip_counter == 0)
@@ -3632,8 +3585,8 @@ log '%s' at position %s, relay log '%s'
"master_log_pos='%ld' ",
(ulong) saved_skip, saved_log_name, (ulong) saved_log_pos,
saved_master_log_name, (ulong) saved_master_log_pos,
- rli->group_relay_log_name, (ulong) rli->group_relay_log_pos,
- rli->group_master_log_name, (ulong) rli->group_master_log_pos);
+ rli->get_group_relay_log_name(), (ulong) rli->get_group_relay_log_pos(),
+ rli->get_group_master_log_name(), (ulong) rli->get_group_master_log_pos());
saved_skip= 0;
}
@@ -3696,13 +3649,14 @@ log '%s' at position %s, relay log '%s'
sql_print_error("Error loading user-defined library, slave SQL "
"thread aborted. Install the missing library, and restart the "
"slave SQL thread with \"SLAVE START\". We stopped at log '%s' "
- "position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos,
- llbuff));
+ "position %s", rli->get_rpl_log_name(),
+ llstr(rli->get_group_master_log_pos(), llbuff));
else
sql_print_error("\
Error running query, slave SQL thread aborted. Fix the problem, and restart \
the slave SQL thread with \"SLAVE START\". We stopped at log \
-'%s' position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos, llbuff));
+'%s' position %s", rli->get_rpl_log_name(),
+llstr(rli->get_group_master_log_pos(), llbuff));
}
goto err;
}
@@ -3711,7 +3665,8 @@ the slave SQL thread with \"SLAVE START\
/* Thread stopped. Print the current replication position to the log */
sql_print_information("Slave SQL thread exiting, replication stopped in log "
"'%s' at position %s",
- RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
+ rli->get_rpl_log_name(),
+ llstr(rli->get_group_master_log_pos(), llbuff));
err:
@@ -3756,10 +3711,10 @@ the slave SQL thread with \"SLAVE START\
thd->temporary_tables = 0; // remove tempation from destructor to close them
DBUG_ASSERT(thd->net.buff != 0);
net_end(&thd->net); // destructor will not free it, because we are weird
- DBUG_ASSERT(rli->sql_thd == thd);
+ DBUG_ASSERT(rli->info_thd == thd);
THD_CHECK_SENTRY(thd);
- rli->sql_thd= 0;
- set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables
+ rli->info_thd= 0;
+ set_thd_in_use_temporary_tables(rli); // (re)set info_thd in use for saved temp tables
mysql_mutex_lock(&LOCK_thread_count);
THD_CHECK_SENTRY(thd);
delete thd;
@@ -3773,10 +3728,10 @@ the slave SQL thread with \"SLAVE START\
DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
mysql_mutex_unlock(&rli->run_lock); // tell the world we are done
- DBUG_LEAVE; // Must match DBUG_ENTER()
+ DBUG_LEAVE; // Must match DBUG_ENTER()
my_thread_end();
pthread_exit(0);
- return 0; // Avoid compiler warnings
+ return 0; // Avoid compiler warnings
}
@@ -3789,7 +3744,7 @@ static int process_io_create_file(Master
int error = 1;
ulong num_bytes;
bool cev_not_written;
- THD *thd = mi->io_thd;
+ THD *thd = mi->info_thd;
NET *net = &mi->mysql->net;
DBUG_ENTER("process_io_create_file");
@@ -3843,21 +3798,21 @@ static int process_io_create_file(Master
break;
Execute_load_log_event xev(thd,0,0);
xev.log_pos = cev->log_pos;
- if (unlikely(mi->rli.relay_log.append(&xev)))
+ if (unlikely(mi->rli->relay_log.append(&xev)))
{
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
"error writing Exec_load event to relay log");
goto err;
}
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ mi->rli->relay_log.harvest_bytes_written(&mi->rli->log_space_total);
break;
}
if (unlikely(cev_not_written))
{
cev->block = net->read_pos;
cev->block_len = num_bytes;
- if (unlikely(mi->rli.relay_log.append(cev)))
+ if (unlikely(mi->rli->relay_log.append(cev)))
{
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
@@ -3865,21 +3820,21 @@ static int process_io_create_file(Master
goto err;
}
cev_not_written=0;
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total);
+ mi->rli->relay_log.harvest_bytes_written(&mi->rli->log_space_total);
}
else
{
aev.block = net->read_pos;
aev.block_len = num_bytes;
aev.log_pos = cev->log_pos;
- if (unlikely(mi->rli.relay_log.append(&aev)))
+ if (unlikely(mi->rli->relay_log.append(&aev)))
{
mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
"error writing Append_block event to relay log");
goto err;
}
- mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ;
+ mi->rli->relay_log.harvest_bytes_written(&mi->rli->log_space_total);
}
}
}
@@ -3920,17 +3875,18 @@ static int process_io_rotate(Master_info
DBUG_RETURN(1);
/* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
- memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
- mi->master_log_pos= rev->pos;
+ memcpy(const_cast<char *>(mi->get_master_log_name()),
+ rev->new_log_ident, rev->ident_len + 1);
+ mi->set_master_log_pos(rev->pos);
DBUG_PRINT("info", ("master_log_pos: '%s' %lu",
- mi->master_log_name, (ulong) mi->master_log_pos));
+ mi->get_master_log_name(), (ulong) mi->get_master_log_pos()));
#ifndef DBUG_OFF
/*
If we do not do this, we will be getting the first
rotate event forever, so we need to not disconnect after one.
*/
if (disconnect_slave_event_count)
- mi->events_till_disconnect++;
+ mi->events_until_exit++;
#endif
/*
@@ -3940,11 +3896,11 @@ static int process_io_rotate(Master_info
no need to reset description_event_for_queue now. And if it's nothing (same
master version as before), no need (still using the slave's format).
*/
- if (mi->rli.relay_log.description_event_for_queue->binlog_version >= 4)
+ if (mi->rli->relay_log.description_event_for_queue->binlog_version >= 4)
{
- delete mi->rli.relay_log.description_event_for_queue;
+ delete mi->rli->relay_log.description_event_for_queue;
/* start from format 3 (MySQL 4.0) again */
- mi->rli.relay_log.description_event_for_queue= new
+ mi->rli->relay_log.description_event_for_queue= new
Format_description_log_event(3);
}
/*
@@ -3966,7 +3922,7 @@ static int queue_binlog_ver_1_event(Mast
ulong inc_pos;
bool ignore_event= 0;
char *tmp_buf = 0;
- Relay_log_info *rli= &mi->rli;
+ Relay_log_info *rli= mi->rli;
DBUG_ENTER("queue_binlog_ver_1_event");
/*
@@ -4000,18 +3956,18 @@ static int queue_binlog_ver_1_event(Mast
connected to the master).
*/
Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
- mi->rli.relay_log.description_event_for_queue);
+ mi->rli->relay_log.description_event_for_queue);
if (unlikely(!ev))
{
sql_print_error("Read invalid event from master: '%s',\
master could be corrupt but a more likely cause of this is a bug",
errmsg);
- my_free(tmp_buf);
+ my_free((char*) tmp_buf);
DBUG_RETURN(1);
}
mysql_mutex_lock(&mi->data_lock);
- ev->log_pos= mi->master_log_pos; /* 3.23 events don't contain log_pos */
+ mi->set_master_log_pos(ev->log_pos); /* 3.23 events don't contain log_pos */
switch (ev->get_type_code()) {
case STOP_EVENT:
ignore_event= 1;
@@ -4040,10 +3996,10 @@ static int queue_binlog_ver_1_event(Mast
ev->log_pos+= inc_pos;
int error = process_io_create_file(mi,(Create_file_log_event*)ev);
delete ev;
- mi->master_log_pos += inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
+ mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
mysql_mutex_unlock(&mi->data_lock);
- my_free(tmp_buf);
+ my_free((char*)tmp_buf);
DBUG_RETURN(error);
}
default:
@@ -4067,8 +4023,8 @@ static int queue_binlog_ver_1_event(Mast
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
}
delete ev;
- mi->master_log_pos+= inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
+ mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
mysql_mutex_unlock(&mi->data_lock);
DBUG_RETURN(0);
}
@@ -4083,18 +4039,18 @@ static int queue_binlog_ver_3_event(Mast
const char *errmsg = 0;
ulong inc_pos;
char *tmp_buf = 0;
- Relay_log_info *rli= &mi->rli;
+ Relay_log_info *rli= mi->rli;
DBUG_ENTER("queue_binlog_ver_3_event");
/* read_log_event() will adjust log_pos to be end_log_pos */
Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg,
- mi->rli.relay_log.description_event_for_queue);
+ mi->rli->relay_log.description_event_for_queue);
if (unlikely(!ev))
{
sql_print_error("Read invalid event from master: '%s',\
master could be corrupt but a more likely cause of this is a bug",
errmsg);
- my_free(tmp_buf);
+ my_free((char*) tmp_buf);
DBUG_RETURN(1);
}
mysql_mutex_lock(&mi->data_lock);
@@ -4122,9 +4078,9 @@ static int queue_binlog_ver_3_event(Mast
}
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
delete ev;
- mi->master_log_pos+= inc_pos;
+ mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
err:
- DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
mysql_mutex_unlock(&mi->data_lock);
DBUG_RETURN(0);
}
@@ -4146,7 +4102,7 @@ static int queue_old_event(Master_info *
{
DBUG_ENTER("queue_old_event");
- switch (mi->rli.relay_log.description_event_for_queue->binlog_version)
+ switch (mi->rli->relay_log.description_event_for_queue->binlog_version)
{
case 1:
DBUG_RETURN(queue_binlog_ver_1_event(mi,buf,event_len));
@@ -4154,7 +4110,7 @@ static int queue_old_event(Master_info *
DBUG_RETURN(queue_binlog_ver_3_event(mi,buf,event_len));
default: /* unsupported format; eg version 2 */
DBUG_PRINT("info",("unsupported binlog format %d in queue_old_event()",
- mi->rli.relay_log.description_event_for_queue->binlog_version));
+ mi->rli->relay_log.description_event_for_queue->binlog_version));
DBUG_RETURN(1);
}
}
@@ -4174,14 +4130,14 @@ static int queue_event(Master_info* mi,c
int error= 0;
String error_msg;
ulong inc_pos;
- Relay_log_info *rli= &mi->rli;
+ Relay_log_info *rli= mi->rli;
mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
ulong s_id;
DBUG_ENTER("queue_event");
LINT_INIT(inc_pos);
- if (mi->rli.relay_log.description_event_for_queue->binlog_version<4 &&
+ if (mi->rli->relay_log.description_event_for_queue->binlog_version<4 &&
buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT /* a way to escape */)
DBUG_RETURN(queue_old_event(mi,buf,event_len));
@@ -4197,7 +4153,7 @@ static int queue_event(Master_info* mi,c
server is shutting down cleanly, it has written all DROP TEMPORARY TABLE
prepared statements' deletion are TODO only when we binlog prep stmts).
- We don't even increment mi->master_log_pos, because we may be just after
+ We don't even increment mi->get_master_log_pos(), because we may be just after
a Rotate event. Btw, in a few milliseconds we are going to have a Start
event from the next binlog (unless the master is presently running
without --log-bin).
@@ -4205,15 +4161,15 @@ static int queue_event(Master_info* mi,c
goto err;
case ROTATE_EVENT:
{
- Rotate_log_event rev(buf,event_len,mi->rli.relay_log.description_event_for_queue);
+ Rotate_log_event rev(buf,event_len,mi->rli->relay_log.description_event_for_queue);
if (unlikely(process_io_rotate(mi,&rev)))
{
error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
goto err;
}
/*
- Now the I/O thread has just changed its mi->master_log_name, so
- incrementing mi->master_log_pos is nonsense.
+ Now the I/O thread has just changed its mi->get_master_log_name(), so
+ incrementing mi->get_master_log_pos() is nonsense.
*/
inc_pos= 0;
break;
@@ -4233,24 +4189,24 @@ static int queue_event(Master_info* mi,c
const char* errmsg;
if (!(tmp= (Format_description_log_event*)
Log_event::read_log_event(buf, event_len, &errmsg,
- mi->rli.relay_log.description_event_for_queue)))
+ mi->rli->relay_log.description_event_for_queue)))
{
error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
goto err;
}
- delete mi->rli.relay_log.description_event_for_queue;
- mi->rli.relay_log.description_event_for_queue= tmp;
+ delete mi->rli->relay_log.description_event_for_queue;
+ mi->rli->relay_log.description_event_for_queue= tmp;
/*
Though this does some conversion to the slave's format, this will
preserve the master's binlog format version, and number of event types.
*/
/*
If the event was not requested by the slave (the slave did not ask for
- it), i.e. has end_log_pos=0, we do not increment mi->master_log_pos
+ it), i.e. has end_log_pos=0, we do not increment mi->get_master_log_pos()
*/
inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0;
DBUG_PRINT("info",("binlog format is now %d",
- mi->rli.relay_log.description_event_for_queue->binlog_version));
+ mi->rli->relay_log.description_event_for_queue->binlog_version));
}
break;
@@ -4261,7 +4217,7 @@ static int queue_event(Master_info* mi,c
HB (heartbeat) cannot come before RL (Relay)
*/
char llbuf[22];
- Heartbeat_log_event hb(buf, event_len, mi->rli.relay_log.description_event_for_queue);
+ Heartbeat_log_event hb(buf, event_len, mi->rli->relay_log.description_event_for_queue);
if (!hb.is_valid())
{
error= ER_SLAVE_HEARTBEAT_FAILURE;
@@ -4280,15 +4236,16 @@ static int queue_event(Master_info* mi,c
Heartbeat is sent only after an event corresponding to the corrdinates
the heartbeat carries.
Slave can not have a difference in coordinates except in the only
- special case when mi->master_log_name, master_log_pos have never
+ special case when mi->get_master_log_name(), mi->get_master_log_pos() have never
been updated by Rotate event i.e when slave does not have any history
- with the master (and thereafter mi->master_log_pos is NULL).
+ with the master (and thereafter mi->get_master_log_pos() is NULL).
TODO: handling `when' for SHOW SLAVE STATUS' snds behind
*/
- if ((memcmp(mi->master_log_name, hb.get_log_ident(), hb.get_ident_len())
- && mi->master_log_name != NULL)
- || mi->master_log_pos != hb.log_pos)
+ if ((memcmp(const_cast<char *>(mi->get_master_log_name()),
+ hb.get_log_ident(), hb.get_ident_len())
+ && mi->get_master_log_name() != NULL)
+ || mi->get_master_log_pos() != hb.log_pos)
{
/* missed events of heartbeat from the past */
error= ER_SLAVE_HEARTBEAT_FAILURE;
@@ -4324,13 +4281,13 @@ static int queue_event(Master_info* mi,c
mysql_mutex_lock(log_lock);
s_id= uint4korr(buf + SERVER_ID_OFFSET);
- if ((s_id == ::server_id && !mi->rli.replicate_same_server_id) ||
+ if ((s_id == ::server_id && !mi->rli->replicate_same_server_id) ||
/*
the following conjunction deals with IGNORE_SERVER_IDS, if set
If the master is on the ignore list, execution of
format description log events and rotate events is necessary.
*/
- (mi->ignore_server_ids.elements > 0 &&
+ (mi->ignore_server_ids->server_ids.elements > 0 &&
mi->shall_ignore_server_id(s_id) &&
/* everything is filtered out from non-master */
(s_id != mi->master_id ||
@@ -4340,7 +4297,7 @@ static int queue_event(Master_info* mi,c
{
/*
Do not write it to the relay log.
- a) We still want to increment mi->master_log_pos, so that we won't
+ a) We still want to increment mi->get_master_log_pos(), so that we won't
re-read this event from the master if the slave IO thread is now
stopped/restarted (more efficient if the events we are ignoring are big
LOAD DATA INFILE).
@@ -4350,32 +4307,32 @@ static int queue_event(Master_info* mi,c
ignored.
But events which were generated by this slave and which do not exist in
the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
- mi->master_log_pos.
+ mi->get_master_log_pos().
If the event is originated remotely and is being filtered out by
- IGNORE_SERVER_IDS it increments mi->master_log_pos
+ IGNORE_SERVER_IDS it increments mi->get_master_log_pos()
as well as rli->group_relay_log_pos.
*/
- if (!(s_id == ::server_id && !mi->rli.replicate_same_server_id) ||
+ if (!(s_id == ::server_id && !mi->rli->replicate_same_server_id) ||
(buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT &&
buf[EVENT_TYPE_OFFSET] != ROTATE_EVENT &&
buf[EVENT_TYPE_OFFSET] != STOP_EVENT))
{
- mi->master_log_pos+= inc_pos;
- memcpy(rli->ign_master_log_name_end, mi->master_log_name, FN_REFLEN);
+ mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
+ memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(), FN_REFLEN);
DBUG_ASSERT(rli->ign_master_log_name_end[0]);
- rli->ign_master_log_pos_end= mi->master_log_pos;
+ rli->ign_master_log_pos_end= mi->get_master_log_pos();
}
rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
DBUG_PRINT("info", ("master_log_pos: %lu, event originating from %u server, ignored",
- (ulong) mi->master_log_pos, uint4korr(buf + SERVER_ID_OFFSET)));
+ (ulong) mi->get_master_log_pos(), uint4korr(buf + SERVER_ID_OFFSET)));
}
else
{
/* write the event to the relay log */
if (likely(!(rli->relay_log.appendv(buf,event_len,0))))
{
- mi->master_log_pos+= inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
+ mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
}
else
@@ -4399,38 +4356,6 @@ err:
DBUG_RETURN(error);
}
-
-void end_relay_log_info(Relay_log_info* rli)
-{
- DBUG_ENTER("end_relay_log_info");
-
- if (!rli->inited)
- DBUG_VOID_RETURN;
- if (rli->info_fd >= 0)
- {
- end_io_cache(&rli->info_file);
- mysql_file_close(rli->info_fd, MYF(MY_WME));
- rli->info_fd = -1;
- }
- if (rli->cur_log_fd >= 0)
- {
- end_io_cache(&rli->cache_buf);
- mysql_file_close(rli->cur_log_fd, MYF(MY_WME));
- rli->cur_log_fd = -1;
- }
- rli->inited = 0;
- rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
- rli->relay_log.harvest_bytes_written(&rli->log_space_total);
- /*
- Delete the slave's temporary tables from memory.
- In the future there will be other actions than this, to ensure persistance
- of slave's temp tables after shutdown.
- */
- rli->close_temporary_tables();
- DBUG_VOID_RETURN;
-}
-
-
/**
Hook to detach the active VIO before closing a connection handle.
@@ -4491,12 +4416,12 @@ static int connect_to_master(THD* thd, M
{
int slave_was_killed;
int last_errno= -2; // impossible error
- ulong err_count= 0;
+ ulong err_count=0;
char llbuff[22];
DBUG_ENTER("connect_to_master");
#ifndef DBUG_OFF
- mi->events_till_disconnect = disconnect_slave_event_count;
+ mi->events_until_exit = disconnect_slave_event_count;
#endif
ulong client_flag= CLIENT_REMEMBER_OPTIONS;
if (opt_slave_compressed_protocol)
@@ -4540,7 +4465,7 @@ static int connect_to_master(THD* thd, M
" - retry-time: %d retries: %lu",
(reconnect ? "reconnecting" : "connecting"),
mi->user, mi->host, mi->port,
- mi->connect_retry, err_count+1);
+ mi->connect_retry, err_count + 1);
/*
By default we try forever. The reason is that failure will trigger
master election, so if the user did not set mi->retry_count we
@@ -4565,8 +4490,8 @@ static int connect_to_master(THD* thd, M
sql_print_information("Slave: connected to master '%s@%s:%d',\
replication resumed in log '%s' at position %s", mi->user,
mi->host, mi->port,
- IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
+ mi->get_io_rpl_log_name(),
+ llstr(mi->get_master_log_pos(),llbuff));
}
else
{
@@ -4664,95 +4589,6 @@ MYSQL *rpl_connect_master(MYSQL *mysql)
return mysql;
}
-/**
- Store the file and position where the slave's SQL thread are in the
- relay log.
-
- Notes:
-
- - This function should be called either from the slave SQL thread,
- or when the slave thread is not running. (It reads the
- group_{relay|master}_log_{pos|name} and delay fields in the rli
- object. These may only be modified by the slave SQL thread or by
- a client thread when the slave SQL thread is not running.)
-
- - If there is an active transaction, then we do not update the
- position in the relay log. This is to ensure that we re-execute
- statements if we die in the middle of an transaction that was
- rolled back.
-
- - As a transaction never spans binary logs, we don't have to handle
- the case where we do a relay-log-rotation in the middle of the
- transaction. If transactions could span several binlogs, we would
- have to ensure that we do not delete the relay log file where the
- transaction started before switching to a new relay log file.
-
- - Error can happen if writing to file fails or if flushing the file
- fails.
-
- @param rli The object representing the Relay_log_info.
-
- @todo Change the log file information to a binary format to avoid
- calling longlong2str.
-
- @todo Move the member function into rpl_rli.cc and get rid of the
- global function. /SVEN
-
- @return 0 on success, 1 on error.
-*/
-bool flush_relay_log_info(Relay_log_info* rli)
-{
- return rli->flush();
-}
-
-bool Relay_log_info::flush()
-{
- bool error=0;
-
- DBUG_ENTER("Relay_log_info::flush()");
-
- /*
- @todo Uncomment the following assertion. See todo in
- Relay_log_info::init() for details. /Sven
- */
- //DBUG_ASSERT(!belongs_to_client());
-
- IO_CACHE *file = &info_file;
- // 2*file name, 2*long long, 2*unsigned long, 6*'\n'
- char buff[FN_REFLEN * 2 + 22 * 2 + 10 * 2 + 6], *pos;
- my_b_seek(file, 0L);
- pos= longlong2str(LINES_IN_RELAY_LOG_INFO_WITH_DELAY, buff, 10);
- *pos++='\n';
- pos=strmov(pos, group_relay_log_name);
- *pos++='\n';
- pos=longlong2str(group_relay_log_pos, pos, 10);
- *pos++='\n';
- pos=strmov(pos, group_master_log_name);
- *pos++='\n';
- pos=longlong2str(group_master_log_pos, pos, 10);
- *pos++= '\n';
- pos= longlong2str(sql_delay, pos, 10);
- *pos= '\n';
- if (my_b_write(file, (uchar*) buff, (size_t) (pos-buff)+1))
- error=1;
- if (flush_io_cache(file))
- error=1;
- if (sync_relayloginfo_period &&
- !error &&
- ++sync_counter >= sync_relayloginfo_period)
- {
- if (my_sync(info_fd, MYF(MY_WME)))
- error=1;
- sync_counter= 0;
- }
- /*
- Flushing the relay log is done by the slave I/O thread
- or by the user on STOP SLAVE.
- */
- DBUG_RETURN(error);
-}
-
-
/*
Called when we notice that the current "hot" log got rotated under our feet.
*/
@@ -4764,7 +4600,7 @@ static IO_CACHE *reopen_relay_log(Relay_
DBUG_ASSERT(rli->cur_log_fd == -1);
IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
- if ((rli->cur_log_fd=open_binlog(cur_log,rli->event_relay_log_name,
+ if ((rli->cur_log_fd=open_binlog(cur_log,rli->get_event_relay_log_name(),
errmsg)) <0)
DBUG_RETURN(0);
/*
@@ -4772,8 +4608,9 @@ static IO_CACHE *reopen_relay_log(Relay_
relay_log_pos Current log pos
pending Number of bytes already processed from the event
*/
- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
- my_b_seek(cur_log,rli->event_relay_log_pos);
+ rli->set_event_relay_log_pos(max(rli->get_event_relay_log_pos(),
+ BIN_LOG_HEADER_SIZE));
+ my_b_seek(cur_log,rli->get_event_relay_log_pos());
DBUG_RETURN(cur_log);
}
@@ -4794,13 +4631,13 @@ static Log_event* next_event(Relay_log_i
IO_CACHE* cur_log = rli->cur_log;
mysql_mutex_t *log_lock = rli->relay_log.get_log_lock();
const char* errmsg=0;
- THD* thd = rli->sql_thd;
+ THD* thd = rli->info_thd;
DBUG_ENTER("next_event");
DBUG_ASSERT(thd != 0);
#ifndef DBUG_OFF
- if (abort_slave_event_count && !rli->events_till_abort--)
+ if (abort_slave_event_count && !rli->events_until_exit--)
DBUG_RETURN(0);
#endif
@@ -4855,13 +4692,26 @@ static Log_event* next_event(Relay_log_i
goto err;
#ifndef DBUG_OFF
{
+ DBUG_PRINT("info", ("assertion skip %lu file pos %lu event relay log pos %lu file %s\n",
+ (ulong) rli->slave_skip_counter, (ulong) my_b_tell(cur_log),
+ (ulong) rli->get_event_relay_log_pos(),
+ rli->get_event_relay_log_name()));
+
/* This is an assertion which sometimes fails, let's try to track it */
char llbuf1[22], llbuf2[22];
DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
llstr(my_b_tell(cur_log),llbuf1),
- llstr(rli->event_relay_log_pos,llbuf2)));
+ llstr(rli->get_event_relay_log_pos(),llbuf2)));
DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
- DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos);
+ DBUG_ASSERT(my_b_tell(cur_log) == rli->get_event_relay_log_pos());
+
+ DBUG_PRINT("info", ("next_event group master %s %lu group relay %s %lu event %s %lu\n",
+ rli->get_group_master_log_name(),
+ (ulong) rli->get_group_master_log_pos(),
+ rli->get_group_relay_log_name(),
+ (ulong) rli->get_group_relay_log_pos(),
+ rli->get_event_relay_log_name(),
+ (ulong) rli->get_event_relay_log_pos()));
}
#endif
/*
@@ -4878,19 +4728,18 @@ static Log_event* next_event(Relay_log_i
*/
if ((ev=Log_event::read_log_event(cur_log,0,
rli->relay_log.description_event_for_exec)))
-
{
- DBUG_ASSERT(thd==rli->sql_thd);
+ DBUG_ASSERT(thd==rli->info_thd);
/*
read it while we have a lock, to avoid a mutex lock in
inc_event_relay_log_pos()
*/
- rli->future_event_relay_log_pos= my_b_tell(cur_log);
+ rli->set_future_event_relay_log_pos(my_b_tell(cur_log));
if (hot_log)
mysql_mutex_unlock(log_lock);
DBUG_RETURN(ev);
}
- DBUG_ASSERT(thd==rli->sql_thd);
+ DBUG_ASSERT(thd==rli->info_thd);
if (opt_reckless_slave) // For mysql-test
cur_log->error = 0;
if (cur_log->error < 0)
@@ -4999,7 +4848,7 @@ static Log_event* next_event(Relay_log_i
mysql_mutex_unlock(&rli->log_space_lock);
mysql_cond_broadcast(&rli->log_space_cond);
// Note that wait_for_update_relay_log unlocks lock_log !
- rli->relay_log.wait_for_update_relay_log(rli->sql_thd);
+ rli->relay_log.wait_for_update_relay_log(rli->info_thd);
// re-acquire data lock since we released it earlier
mysql_mutex_lock(&rli->data_lock);
continue;
@@ -5029,12 +4878,19 @@ static Log_event* next_event(Relay_log_i
*/
if (rli->relay_log.purge_first_log
(rli,
- rli->group_relay_log_pos == rli->event_relay_log_pos
- && !strcmp(rli->group_relay_log_name,rli->event_relay_log_name)))
+ rli->get_group_relay_log_pos() == rli->get_event_relay_log_pos()
+ && !strcmp(rli->get_group_relay_log_name(),rli->get_event_relay_log_name())))
{
errmsg = "Error purging processed logs";
goto err;
}
+ DBUG_PRINT("info", ("next_event group master %s %lu group relay %s %lu event %s %lu\n",
+ rli->get_group_master_log_name(),
+ (ulong) rli->get_group_master_log_pos(),
+ rli->get_group_relay_log_name(),
+ (ulong) rli->get_group_relay_log_pos(),
+ rli->get_event_relay_log_name(),
+ (ulong) rli->get_event_relay_log_pos()));
}
else
{
@@ -5050,10 +4906,9 @@ static Log_event* next_event(Relay_log_i
errmsg = "error switching to the next log";
goto err;
}
- rli->event_relay_log_pos = BIN_LOG_HEADER_SIZE;
- strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
- sizeof(rli->event_relay_log_name)-1);
- flush_relay_log_info(rli);
+ rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
+ rli->set_event_relay_log_name(rli->linfo.log_file_name);
+ rli->flush_info();
}
/*
@@ -5126,7 +4981,7 @@ static Log_event* next_event(Relay_log_i
event(errno: %d cur_log->error: %d)",
my_errno,cur_log->error);
// set read position to the beginning of the event
- my_b_seek(cur_log,rli->event_relay_log_pos);
+ my_b_seek(cur_log,rli->get_event_relay_log_pos());
/* otherwise, we have had a partial read */
errmsg = "Aborting slave SQL thread because of partial event read";
break; // To end of function
@@ -5156,7 +5011,7 @@ err:
void rotate_relay_log(Master_info* mi)
{
DBUG_ENTER("rotate_relay_log");
- Relay_log_info* rli= &mi->rli;
+ Relay_log_info* rli= mi->rli;
DBUG_EXECUTE_IF("crash_before_rotate_relaylog", abort(););
@@ -5283,9 +5138,9 @@ bool rpl_master_has_bug(const Relay_log_
*/
bool rpl_master_erroneous_autoinc(THD *thd)
{
- if (active_mi && active_mi->rli.sql_thd == thd)
+ if (active_mi && active_mi->rli->info_thd == thd)
{
- Relay_log_info *rli= &active_mi->rli;
+ Relay_log_info *rli= active_mi->rli;
DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
return rpl_master_has_bug(rli, 33029, FALSE, NULL, NULL);
}
@@ -5339,8 +5194,7 @@ int start_slave(THD* thd , Master_info*
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,
- thread_mask))
+ if (init_info(mi, FALSE, thread_mask))
slave_errno=ER_MASTER_INFO;
else if (server_id_supplied && *mi->host)
{
@@ -5351,38 +5205,38 @@ int start_slave(THD* thd , Master_info*
*/
if (thread_mask & SLAVE_SQL)
{
- mysql_mutex_lock(&mi->rli.data_lock);
+ mysql_mutex_lock(&mi->rli->data_lock);
if (thd->lex->mi.pos)
{
- mi->rli.until_condition= Relay_log_info::UNTIL_MASTER_POS;
- mi->rli.until_log_pos= thd->lex->mi.pos;
+ mi->rli->until_condition= Relay_log_info::UNTIL_MASTER_POS;
+ mi->rli->until_log_pos= thd->lex->mi.pos;
/*
We don't check thd->lex->mi.log_file_name for NULL here
since it is checked in sql_yacc.yy
*/
- strmake(mi->rli.until_log_name, thd->lex->mi.log_file_name,
- sizeof(mi->rli.until_log_name)-1);
+ strmake(mi->rli->until_log_name, thd->lex->mi.log_file_name,
+ sizeof(mi->rli->until_log_name)-1);
}
else if (thd->lex->mi.relay_log_pos)
{
- mi->rli.until_condition= Relay_log_info::UNTIL_RELAY_POS;
- mi->rli.until_log_pos= thd->lex->mi.relay_log_pos;
- strmake(mi->rli.until_log_name, thd->lex->mi.relay_log_name,
- sizeof(mi->rli.until_log_name)-1);
+ mi->rli->until_condition= Relay_log_info::UNTIL_RELAY_POS;
+ mi->rli->until_log_pos= thd->lex->mi.relay_log_pos;
+ strmake(mi->rli->until_log_name, thd->lex->mi.relay_log_name,
+ sizeof(mi->rli->until_log_name)-1);
}
else
- mi->rli.clear_until_condition();
+ mi->rli->clear_until_condition();
- if (mi->rli.until_condition != Relay_log_info::UNTIL_NONE)
+ if (mi->rli->until_condition != Relay_log_info::UNTIL_NONE)
{
/* Preparing members for effective until condition checking */
- const char *p= fn_ext(mi->rli.until_log_name);
+ const char *p= fn_ext(mi->rli->until_log_name);
char *p_end;
if (*p)
{
//p points to '.'
- mi->rli.until_log_name_extension= strtoul(++p,&p_end, 10);
+ mi->rli->until_log_name_extension= strtoul(++p,&p_end, 10);
/*
p_end points to the first invalid character. If it equals
to p, no digits were found, error. If it contains '\0' it
@@ -5395,7 +5249,7 @@ int start_slave(THD* thd , Master_info*
slave_errno=ER_BAD_SLAVE_UNTIL_COND;
/* mark the cached result of the UNTIL comparison as "undefined" */
- mi->rli.until_log_names_cmp_result=
+ mi->rli->until_log_names_cmp_result=
Relay_log_info::UNTIL_LOG_NAMES_CMP_UNKNOWN;
/* Issuing warning then started without --skip-slave-start */
@@ -5405,7 +5259,7 @@ int start_slave(THD* thd , Master_info*
ER(ER_MISSING_SKIP_SLAVE));
}
- mysql_mutex_unlock(&mi->rli.data_lock);
+ mysql_mutex_unlock(&mi->rli->data_lock);
}
else if (thd->lex->mi.pos || thd->lex->mi.relay_log_pos)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED,
@@ -5415,7 +5269,6 @@ int start_slave(THD* thd , Master_info*
slave_errno = start_slave_threads(0 /*no mutex */,
1 /* wait for start */,
mi,
- master_info_file,relay_log_info_file,
thread_mask);
}
else
@@ -5521,8 +5374,6 @@ int stop_slave(THD* thd, Master_info* mi
*/
int reset_slave(THD *thd, Master_info* mi)
{
- MY_STAT stat_area;
- char fname[FN_REFLEN];
int thread_mask= 0, error= 0;
uint sql_errno=ER_UNKNOWN_ERROR;
const char* errmsg= "Unknown error occured while reseting slave";
@@ -5540,41 +5391,20 @@ int reset_slave(THD *thd, Master_info* m
ha_reset_slave(thd);
// delete relay logs, clear relay log coordinates
- if ((error= purge_relay_logs(&mi->rli, thd,
- 1 /* just reset */,
- &errmsg)))
+ if ((error= mi->rli->purge_relay_logs(thd,
+ 1 /* just reset */,
+ &errmsg)))
{
sql_errno= ER_RELAY_LOG_FAIL;
goto err;
}
/* Clear master's log coordinates */
- init_master_log_pos(mi);
- /*
- Reset errors (the idea is that we forget about the
- old master).
- */
- mi->clear_error();
- mi->rli.clear_error();
- mi->rli.clear_until_condition();
- mi->rli.clear_sql_delay();
-
- // 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);
- 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;
- }
- // delete relay_log_info_file
- fn_format(fname, relay_log_info_file, 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)))
+ mi->init_master_log_pos();
+
+ if (reset_info(mi))
{
- error=1;
+ error= 1;
goto err;
}
@@ -5603,11 +5433,13 @@ bool change_master(THD* thd, Master_info
int thread_mask;
const char* errmsg= 0;
bool need_relay_log_purge= 1;
+ char *var_master_log_name= NULL, *var_group_master_log_name= NULL;
bool ret= FALSE;
char saved_host[HOSTNAME_LENGTH + 1];
- uint saved_port;
+ uint saved_port= 0;
char saved_log_name[FN_REFLEN];
- my_off_t saved_log_pos;
+ my_off_t saved_log_pos= 0;
+
DBUG_ENTER("change_master");
lock_slave_threads(mi);
@@ -5619,6 +5451,7 @@ bool change_master(THD* thd, Master_info
ret= TRUE;
goto err;
}
+ thread_mask= SLAVE_IO | SLAVE_SQL;
thd_proc_info(thd, "Changing master");
/*
@@ -5634,9 +5467,7 @@ bool change_master(THD* thd, Master_info
unlock_slave_threads(mi);
DBUG_RETURN(TRUE);
}
- // TODO: see if needs re-write
- if (init_master_info(mi, master_info_file, relay_log_info_file, 0,
- thread_mask))
+ if (init_info(mi, FALSE, thread_mask))
{
my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
ret= TRUE;
@@ -5654,8 +5485,8 @@ bool change_master(THD* thd, Master_info
*/
strmake(saved_host, mi->host, HOSTNAME_LENGTH);
saved_port= mi->port;
- strmake(saved_log_name, mi->master_log_name, FN_REFLEN - 1);
- saved_log_pos= mi->master_log_pos;
+ strmake(saved_log_name, mi->get_master_log_name(), FN_REFLEN - 1);
+ saved_log_pos= mi->get_master_log_pos();
/*
If the user specified host or port without binlog or position,
@@ -5671,18 +5502,18 @@ bool change_master(THD* thd, Master_info
if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
{
- mi->master_log_name[0] = 0;
- mi->master_log_pos= BIN_LOG_HEADER_SIZE;
+ var_master_log_name= const_cast<char*>(mi->get_master_log_name());
+ var_master_log_name[0]= '\0';
+ mi->set_master_log_pos(BIN_LOG_HEADER_SIZE);
}
if (lex_mi->log_file_name)
- strmake(mi->master_log_name, lex_mi->log_file_name,
- sizeof(mi->master_log_name)-1);
+ mi->set_master_log_name(lex_mi->log_file_name);
if (lex_mi->pos)
{
- mi->master_log_pos= lex_mi->pos;
+ mi->set_master_log_pos(lex_mi->pos);
}
- DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
if (lex_mi->host)
strmake(mi->host, lex_mi->host, sizeof(mi->host)-1);
@@ -5694,7 +5525,7 @@ bool change_master(THD* thd, Master_info
mi->port = lex_mi->port;
if (lex_mi->connect_retry)
mi->connect_retry = lex_mi->connect_retry;
- if (lex_mi->retry_count_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
+ if (lex_mi->retry_count_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
mi->retry_count = lex_mi->retry_count;
if (lex_mi->heartbeat_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
mi->heartbeat_period = lex_mi->heartbeat_period;
@@ -5707,7 +5538,7 @@ bool change_master(THD* thd, Master_info
is mentioning IGNORE_SERVER_IDS= (...)
*/
if (lex_mi->repl_ignore_server_ids_opt == LEX_MASTER_INFO::LEX_MI_ENABLE)
- reset_dynamic(&mi->ignore_server_ids);
+ reset_dynamic(&mi->ignore_server_ids->server_ids);
for (uint i= 0; i < lex_mi->repl_ignore_server_ids.elements; i++)
{
ulong s_id;
@@ -5721,20 +5552,20 @@ bool change_master(THD* thd, Master_info
else
{
if (bsearch((const ulong *) &s_id,
- mi->ignore_server_ids.buffer,
- mi->ignore_server_ids.elements, sizeof(ulong),
+ mi->ignore_server_ids->server_ids.buffer,
+ mi->ignore_server_ids->server_ids.elements, sizeof(ulong),
(int (*) (const void*, const void*))
change_master_server_id_cmp) == NULL)
- insert_dynamic(&mi->ignore_server_ids, (uchar*) &s_id);
+ insert_dynamic(&mi->ignore_server_ids->server_ids, (uchar*) &s_id);
}
}
- sort_dynamic(&mi->ignore_server_ids, (qsort_cmp) change_master_server_id_cmp);
+ sort_dynamic(&mi->ignore_server_ids->server_ids, (qsort_cmp) change_master_server_id_cmp);
if (lex_mi->ssl != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
mi->ssl= (lex_mi->ssl == LEX_MASTER_INFO::LEX_MI_ENABLE);
if (lex_mi->sql_delay != -1)
- mi->rli.set_sql_delay(lex_mi->sql_delay);
+ mi->rli->set_sql_delay(lex_mi->sql_delay);
if (lex_mi->ssl_verify_server_cert != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
mi->ssl_verify_server_cert=
@@ -5762,17 +5593,17 @@ bool change_master(THD* thd, Master_info
{
need_relay_log_purge= 0;
char relay_log_name[FN_REFLEN];
- mi->rli.relay_log.make_log_name(relay_log_name, lex_mi->relay_log_name);
- strmake(mi->rli.group_relay_log_name, relay_log_name,
- sizeof(mi->rli.group_relay_log_name)-1);
- strmake(mi->rli.event_relay_log_name, relay_log_name,
- sizeof(mi->rli.event_relay_log_name)-1);
+
+ mi->rli->relay_log.make_log_name(relay_log_name, lex_mi->relay_log_name);
+ mi->rli->set_group_relay_log_name(relay_log_name);
+ mi->rli->set_event_relay_log_name(relay_log_name);
}
if (lex_mi->relay_log_pos)
{
need_relay_log_purge= 0;
- mi->rli.group_relay_log_pos= mi->rli.event_relay_log_pos= lex_mi->relay_log_pos;
+ mi->rli->set_group_relay_log_pos(lex_mi->relay_log_pos);
+ mi->rli->set_event_relay_log_pos(lex_mi->relay_log_pos);
}
/*
@@ -5800,16 +5631,15 @@ bool change_master(THD* thd, Master_info
of replication is not 100% clear, so we guard against problems using
max().
*/
- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
- mi->rli.group_master_log_pos);
- strmake(mi->master_log_name, mi->rli.group_master_log_name,
- sizeof(mi->master_log_name)-1);
+ mi->set_master_log_pos(max(BIN_LOG_HEADER_SIZE,
+ mi->rli->get_group_master_log_pos()));
+ mi->set_master_log_name(mi->rli->get_group_master_log_name());
}
/*
Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never
a slave before).
*/
- if (flush_master_info(mi, FALSE, FALSE))
+ if (flush_master_info(mi, FALSE))
{
my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file");
ret= TRUE;
@@ -5819,9 +5649,9 @@ bool change_master(THD* thd, Master_info
{
relay_log_purge= 1;
thd_proc_info(thd, "Purging old relay logs");
- if (purge_relay_logs(&mi->rli, thd,
- 0 /* not only reset, but also reinit */,
- &errmsg))
+ if (mi->rli->purge_relay_logs(thd,
+ 0 /* not only reset, but also reinit */,
+ &errmsg))
{
my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg);
ret= TRUE;
@@ -5833,11 +5663,10 @@ bool change_master(THD* thd, Master_info
const char* msg;
relay_log_purge= 0;
/* Relay log is already initialized */
- if (init_relay_log_pos(&mi->rli,
- mi->rli.group_relay_log_name,
- mi->rli.group_relay_log_pos,
- 0 /*no data lock*/,
- &msg, 0))
+ if (mi->rli->init_relay_log_pos(mi->rli->get_group_relay_log_name(),
+ mi->rli->get_group_relay_log_pos(),
+ 0 /*no data lock*/,
+ &msg, 0))
{
my_error(ER_RELAY_LOG_INIT, MYF(0), msg);
ret= TRUE;
@@ -5854,27 +5683,27 @@ bool change_master(THD* thd, Master_info
''/0: we have lost all copies of the original good coordinates.
That's why we always save good coords in rli.
*/
- mi->rli.group_master_log_pos= mi->master_log_pos;
- DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
- strmake(mi->rli.group_master_log_name,mi->master_log_name,
- sizeof(mi->rli.group_master_log_name)-1);
-
- if (!mi->rli.group_master_log_name[0]) // uninitialized case
- mi->rli.group_master_log_pos=0;
+ mi->rli->set_group_master_log_pos(mi->get_master_log_pos());
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
+ mi->rli->set_group_master_log_name(mi->get_master_log_name());
+
+ var_group_master_log_name= const_cast<char *>(mi->rli->get_group_master_log_name());
+ if (!var_group_master_log_name[0]) // uninitialized case
+ mi->rli->set_group_master_log_pos(0);
- mysql_mutex_lock(&mi->rli.data_lock);
- mi->rli.abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */
+ mysql_mutex_lock(&mi->rli->data_lock);
+ mi->rli->abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */
/* Clear the errors, for a clean start */
- mi->rli.clear_error();
- mi->rli.clear_until_condition();
+ mi->rli->clear_error();
+ mi->rli->clear_until_condition();
sql_print_information("'CHANGE MASTER TO executed'. "
"Previous state master_host='%s', master_port='%u', master_log_file='%s', "
"master_log_pos='%ld'. "
"New state master_host='%s', master_port='%u', master_log_file='%s', "
"master_log_pos='%ld'.", saved_host, saved_port, saved_log_name,
- (ulong) saved_log_pos, mi->host, mi->port, mi->master_log_name,
- (ulong) mi->master_log_pos);
+ (ulong) saved_log_pos, mi->host, mi->port, mi->get_master_log_name(),
+ (ulong) mi->get_master_log_pos());
/*
If we don't write new coordinates to disk now, then old will remain in
@@ -5883,9 +5712,9 @@ bool change_master(THD* thd, Master_info
in-memory value at restart (thus causing errors, as the old relay log does
not exist anymore).
*/
- flush_relay_log_info(&mi->rli);
+ ret= mi->rli->flush_info(TRUE);
mysql_cond_broadcast(&mi->data_cond);
- mysql_mutex_unlock(&mi->rli.data_lock);
+ mysql_mutex_unlock(&mi->rli->data_lock);
err:
unlock_slave_threads(mi);
@@ -5899,5 +5728,63 @@ err:
/**
@} (end of group Replication)
*/
-
#endif /* HAVE_REPLICATION */
+
+Server_ids::Server_ids()
+{
+ my_init_dynamic_array(&server_ids, sizeof(::server_id), 16, 16);
+}
+
+Server_ids::~Server_ids()
+{
+ delete_dynamic(&server_ids);
+}
+
+bool Server_ids::unpack_server_ids(const char *param_server_ids)
+{
+ char *token, *last;
+ uint num_items;
+
+ DBUG_ENTER("Server_ids::unpack_server_ids");
+
+ token= strtok_r((char *)const_cast<const char*>(param_server_ids),
+ " ", &last);
+
+ if (token == NULL)
+ DBUG_RETURN(TRUE);
+
+ num_items= atoi(token);
+ for (uint i=0; i < num_items; i++)
+ {
+ token= strtok_r(NULL, " ", &last);
+ if (token == NULL)
+ DBUG_RETURN(TRUE);
+ else
+ {
+ ulong val= atol(token);
+ insert_dynamic(&server_ids, (uchar *) &val);
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
+bool Server_ids::pack_server_ids(char *buffer)
+{
+ DBUG_ENTER("Server_ids::pack_server_ids");
+
+ if (!buffer)
+ DBUG_RETURN(TRUE);
+
+ for (ulong i= 0, cur_len= sprintf(buffer,
+ "%u",
+ server_ids.elements);
+ i < server_ids.elements; i++)
+ {
+ ulong s_id;
+ get_dynamic(&server_ids, (uchar*) &s_id, i);
+ cur_len +=sprintf(buffer + cur_len,
+ " %lu", s_id);
+ }
+
+ DBUG_RETURN(FALSE);
+}
=== modified file 'sql/rpl_slave.h'
--- a/sql/rpl_slave.h 2010-07-27 14:04:13 +0000
+++ b/sql/rpl_slave.h 2010-08-06 18:09:14 +0000
@@ -145,11 +145,6 @@ extern ulonglong relay_log_space_limit;
#define MYSQL_SLAVE_RUN_NOT_CONNECT 1
#define MYSQL_SLAVE_RUN_CONNECT 2
-#define RPL_LOG_NAME (rli->group_master_log_name[0] ? rli->group_master_log_name :\
- "FIRST")
-#define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\
- "FIRST")
-
/*
If the following is set, if first gives an error, second will be
tried. Otherwise, if first fails, we fail.
@@ -164,13 +159,16 @@ int cmp_master_pos(const char* log_file_
int reset_slave(THD *thd, Master_info* mi);
int init_slave();
int init_recovery(Master_info* mi, const char** errmsg);
+int init_info(Master_info* mi, bool ignore_if_no_info, int thread_mask);
+void end_info(Master_info* mi);
+int reset_info(Master_info* mi);
+int flush_master_info(Master_info* mi, bool force);
void init_slave_skip_errors(const char* arg);
int register_slave_on_master(MYSQL* mysql);
int terminate_slave_threads(Master_info* mi, int thread_mask,
bool skip_lock = 0);
int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
- Master_info* mi, const char* master_info_fname,
- const char* slave_info_fname, int thread_mask);
+ Master_info* mi, int thread_mask);
/*
cond_lock is usually same as start_lock. It is needed for the case when
start_lock is 0 which happens if start_slave_thread() is called already
@@ -212,20 +210,14 @@ void init_thread_mask(int* mask,Master_i
void set_slave_thread_options(THD* thd);
void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli);
int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli);
-
-int init_longvar_from_file(long* var, IO_CACHE* f, long default_val);
-int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
-int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val);
-int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
- const char *default_val);
-int init_dynarray_intvar_from_file(DYNAMIC_ARRAY* arr, IO_CACHE* f);
+void rotate_relay_log(Master_info* mi);
pthread_handler_t handle_slave_io(void *arg);
pthread_handler_t handle_slave_sql(void *arg);
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 *active_mi; /* active_mi for multi-master */
extern LIST master_list;
extern my_bool replicate_same_server_id;
@@ -252,5 +244,4 @@ extern I_List<THD> threads;
/**
@} (end of group Replication)
*/
-
#endif
=== added file 'sql/server_ids.h'
--- a/sql/server_ids.h 1970-01-01 00:00:00 +0000
+++ b/sql/server_ids.h 2010-05-24 10:48:30 +0000
@@ -0,0 +1,19 @@
+#ifndef SERVER_ID_H
+
+#define SERVER_ID_H
+
+#include "my_sys.h"
+
+class Server_ids
+{
+ public:
+ DYNAMIC_ARRAY server_ids;
+
+ Server_ids();
+ ~Server_ids();
+
+ bool pack_server_ids(char *buffer);
+ bool unpack_server_ids(const char *param_server_ids);
+};
+
+#endif
=== modified file 'sql/sql_binlog.cc'
--- a/sql/sql_binlog.cc 2010-09-21 11:32:50 +0000
+++ b/sql/sql_binlog.cc 2010-10-04 10:16:31 +0000
@@ -17,7 +17,8 @@
#include "sql_binlog.h"
#include "sql_parse.h"
#include "sql_acl.h"
-#include "rpl_rli.h"
+#include "rpl_info.h"
+#include "rpl_info_factory.h"
#include "base64.h"
#include "rpl_slave.h" // apply_event_and_update_pos
#include "log_event.h" // Format_description_log_event,
@@ -146,12 +147,17 @@ void mysql_client_binlog_statement(THD*
/*
Allocation
*/
-
int err= 0;
- Relay_log_info *rli;
- rli= thd->rli_fake;
- if (!rli && (rli= thd->rli_fake= new Relay_log_info(FALSE)))
- rli->sql_thd= thd;
+ Relay_log_info *rli= thd->rli_fake;
+ if (!rli)
+ {
+ Rpl_info_factory::create_rli(RLI_REPOSITORY_FILE, FALSE, &rli);
+ if (rli)
+ {
+ thd->rli_fake= rli;
+ rli->info_thd= thd;
+ }
+ }
const char *error= 0;
char *buf= (char *) my_malloc(decoded_len, MYF(MY_WME));
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2010-10-03 23:42:39 +0000
+++ b/sql/sql_insert.cc 2010-10-08 14:35:24 +0000
@@ -804,7 +804,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
if (thd->slave_thread &&
(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(active_mi->rli, 24432, TRUE, NULL, NULL))
goto abort;
#endif
@@ -3306,7 +3306,7 @@ select_insert::prepare(List<Item> &value
if (thd->slave_thread &&
(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(active_mi->rli, 24432, TRUE, NULL, NULL))
DBUG_RETURN(1);
#endif
=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc 2010-08-16 06:58:42 +0000
+++ b/sql/sql_load.cc 2010-08-23 16:13:25 +0000
@@ -385,11 +385,11 @@ int mysql_load(THD *thd,sql_exchange *ex
if (thd->slave_thread)
{
#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(active_mi->rli->slave_patternload_file, name,
+ active_mi->rli->slave_patternload_file_size))
{
/*
- LOAD DATA INFILE in the slave SQL Thread can only read from
+ LOAD DATA INFILE in the slave SQL Thread can only read from
--slave-load-tmpdir". This should never happen. Please, report a bug.
*/
=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc 2010-10-11 16:43:09 +0000
+++ b/sql/sys_vars.cc 2010-10-25 13:46:20 +0000
@@ -36,6 +36,7 @@
#include <thr_alarm.h>
#include "rpl_slave.h"
#include "rpl_mi.h"
+#include "rpl_info_factory.h"
#include "transaction.h"
#include "mysqld.h"
#include "lock.h"
@@ -408,6 +409,25 @@ static Sys_var_mybool Sys_binlog_direct(
CMD_LINE(OPT_ARG), DEFAULT(FALSE),
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(binlog_direct_check));
+static const char *repository_names[]=
+{
+ "FILE", 0
+};
+
+ulong opt_mi_repository_id;
+static Sys_var_enum Sys_mi_repository(
+ "master_info_repository",
+ "Defines the type of the repository for the master information."
+ , READ_ONLY GLOBAL_VAR(opt_mi_repository_id), CMD_LINE(REQUIRED_ARG),
+ repository_names, DEFAULT(0));
+
+ulong opt_rli_repository_id;
+static Sys_var_enum Sys_rli_repository(
+ "relay_log_info_repository",
+ "Defines the type of the repository for the relay log information."
+ , READ_ONLY GLOBAL_VAR(opt_rli_repository_id), CMD_LINE(REQUIRED_ARG),
+ repository_names, DEFAULT(0));
+
static Sys_var_mybool Sys_binlog_rows_query(
"binlog_rows_query_log_events",
"Allow writing of Rows_query_log events into binary log.",
@@ -1104,7 +1124,7 @@ static bool fix_max_binlog_size(sys_var
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);
+ active_mi->rli->relay_log.set_max_size(max_binlog_size);
#endif
return false;
}
@@ -1238,7 +1258,7 @@ static Sys_var_ulong Sys_max_prepared_st
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 ?
+ active_mi->rli->relay_log.set_max_size(max_relay_log_size ?
max_relay_log_size: max_binlog_size);
#endif
return false;
@@ -3009,32 +3029,32 @@ static bool check_slave_skip_counter(sys
{
bool result= false;
mysql_mutex_lock(&LOCK_active_mi);
- mysql_mutex_lock(&active_mi->rli.run_lock);
- if (active_mi->rli.slave_running)
+ mysql_mutex_lock(&active_mi->rli->run_lock);
+ if (active_mi->rli->slave_running)
{
my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0));
result= true;
}
- mysql_mutex_unlock(&active_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_lock(&LOCK_active_mi);
- mysql_mutex_lock(&active_mi->rli.run_lock);
+ 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)
+ 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_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(&active_mi->rli->run_lock);
mysql_mutex_unlock(&LOCK_active_mi);
return 0;
}
Attachment: [text/bzr-bundle] bzr/marc.alff@oracle.com-20101025134620-e2qs25lvjmhakt3t.bundle
| Thread |
|---|
| • bzr commit into mysql-next-mr-wl4816 branch (marc.alff:3205) | Marc Alff | 25 Oct |