Commit 0b36233a authored by unknown's avatar unknown

MDEV-26. Intermediate commit.

Implement CHANGE MASTER TO MASTER_GTID_POS=xxx.
parent bdbce30d
......@@ -77,6 +77,7 @@ static SYMBOL symbols[] = {
{ "AUTHORS", SYM(AUTHORS_SYM)},
{ "AUTO_INCREMENT", SYM(AUTO_INC)},
{ "AUTOEXTEND_SIZE", SYM(AUTOEXTEND_SIZE_SYM)},
{ "AUTO", SYM(AUTO_SYM)},
{ "AVG", SYM(AVG_SYM)},
{ "AVG_ROW_LENGTH", SYM(AVG_ROW_LENGTH)},
{ "BACKUP", SYM(BACKUP_SYM)},
......@@ -329,6 +330,7 @@ static SYMBOL symbols[] = {
{ "LOW_PRIORITY", SYM(LOW_PRIORITY)},
{ "MASTER", SYM(MASTER_SYM)},
{ "MASTER_CONNECT_RETRY", SYM(MASTER_CONNECT_RETRY_SYM)},
{ "MASTER_GTID_POS", SYM(MASTER_GTID_POS_SYM)},
{ "MASTER_HOST", SYM(MASTER_HOST_SYM)},
{ "MASTER_LOG_FILE", SYM(MASTER_LOG_FILE_SYM)},
{ "MASTER_LOG_POS", SYM(MASTER_LOG_POS_SYM)},
......
......@@ -6292,7 +6292,6 @@ rpl_slave_state::tostring(String *dest)
{
bool first= true;
uint32 i;
int err= 1;
lock();
......@@ -6303,9 +6302,8 @@ rpl_slave_state::tostring(String *dest)
element *e= (element *)my_hash_element(&hash, i);
list_element *l= e->list;
DBUG_ASSERT(l /* We should never have empty list in element. */);
if (!l)
goto err;
continue; /* Nothing here */
best_gtid.domain_id= e->domain_id;
best_gtid.server_id= l->server_id;
......@@ -6332,11 +6330,30 @@ rpl_slave_state::tostring(String *dest)
dest->append_ulonglong(best_gtid.seq_no);
}
err= 0;
unlock();
return 0;
}
err:
bool
rpl_slave_state::is_empty()
{
uint32 i;
bool result= true;
lock();
for (i= 0; i < hash.records; ++i)
{
element *e= (element *)my_hash_element(&hash, i);
if (e->list)
{
result= false;
break;
}
}
unlock();
return err;
return result;
}
......
......@@ -3009,6 +3009,7 @@ struct rpl_slave_state
bool in_transaction);
uint64 next_subid(uint32 domain_id);
int tostring(String *dest);
bool is_empty();
void lock() { DBUG_ASSERT(inited); mysql_mutex_lock(&LOCK_slave_state); }
void unlock() { DBUG_ASSERT(inited); mysql_mutex_unlock(&LOCK_slave_state); }
......
......@@ -37,7 +37,7 @@ Master_info::Master_info(LEX_STRING *connection_name_arg,
checksum_alg_before_fd(BINLOG_CHECKSUM_ALG_UNDEF),
connect_retry(DEFAULT_CONNECT_RETRY), inited(0), abort_slave(0),
slave_running(0), slave_run_id(0), sync_counter(0),
heartbeat_period(0), received_heartbeats(0), master_id(0)
heartbeat_period(0), received_heartbeats(0), master_id(0), gtid_pos_auto(0)
{
host[0] = 0; user[0] = 0; password[0] = 0;
ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
......@@ -172,8 +172,13 @@ enum {
LINE_FOR_MASTER_BIND = 17,
/* 6.0 added value of master_ignore_server_id */
LINE_FOR_REPLICATE_IGNORE_SERVER_IDS= 18,
/* Number of lines currently used when saving master info file */
LINES_IN_MASTER_INFO= LINE_FOR_REPLICATE_IGNORE_SERVER_IDS
/* MySQL 5.6 fixed-position lines. */
LINE_FOR_FIRST_MYSQL_5_6=19,
LINE_FOR_LAST_MYSQL_5_6=23,
/* Reserved lines for MySQL future versions. */
LINE_FOR_LAST_MYSQL_FUTURE=33,
/* Number of (fixed-position) lines used when saving master info file */
LINES_IN_MASTER_INFO= LINE_FOR_LAST_MYSQL_FUTURE
};
int init_master_info(Master_info* mi, const char* master_info_fname,
......@@ -301,7 +306,7 @@ file '%s')", fname);
int ssl= 0, ssl_verify_server_cert= 0;
float master_heartbeat_period= 0.0;
char *first_non_digit;
char dummy_buf[HOSTNAME_LENGTH+1];
char buf[HOSTNAME_LENGTH+1];
/*
Starting from 4.1.x master.info has new format. Now its
......@@ -395,7 +400,7 @@ file '%s')", fname);
(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, ""))
init_strvar_from_file(buf, sizeof(buf), &mi->file, ""))
goto errwithmsg;
/*
Starting from 6.0 list of server_id of ignorable servers might be
......@@ -407,6 +412,34 @@ file '%s')", fname);
sql_print_error("Failed to initialize master info ignore_server_ids");
goto errwithmsg;
}
/*
Starting with MariaDB 10.0, we use a key=value syntax, which is nicer
in several ways. But we leave a bunch of empty lines to accomodate
any future old-style additions in MySQL (this will make it easier for
users moving from MariaDB to MySQL, to not have MySQL try to
interpret a MariaDB key=value line.)
*/
if (lines >= LINE_FOR_LAST_MYSQL_FUTURE)
{
uint i;
/* Skip lines used by / reserved for MySQL >= 5.6. */
for (i= LINE_FOR_FIRST_MYSQL_5_6; i <= LINE_FOR_LAST_MYSQL_FUTURE; ++i)
{
if (init_strvar_from_file(buf, sizeof(buf), &mi->file, ""))
goto errwithmsg;
}
/*
Parse any extra key=value lines.
Ignore unknown lines, to facilitate downgrades.
*/
while (!init_strvar_from_file(buf, sizeof(buf), &mi->file, 0))
{
if (0 == strncmp(buf, STRING_WITH_LEN("gtid_pos_auto=")))
mi->gtid_pos_auto= (0 != atoi(buf + sizeof("gtid_pos_auto")));
}
}
}
#ifndef HAVE_OPENSSL
......@@ -546,14 +579,16 @@ int flush_master_info(Master_info* mi,
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",
"%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"
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
"gtid_pos_auto=%d\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);
heartbeat_buf, "", ignore_server_ids_buf, mi->gtid_pos_auto);
my_free(ignore_server_ids_buf);
err= flush_io_cache(file);
if (sync_masterinfo_period && !err &&
......
......@@ -126,6 +126,8 @@ class Master_info : public Slave_reporting_capability
ulonglong received_heartbeats; // counter of received heartbeat events
DYNAMIC_ARRAY ignore_server_ids;
ulong master_id;
/* If last CHANGE MASTER was MASTER_GTID_POS=AUTO. */
bool gtid_pos_auto;
};
int init_master_info(Master_info* mi, const char* master_info_fname,
const char* slave_info_fname,
......
......@@ -1786,8 +1786,7 @@ after_set_capability:
/* Request dump start from slave replication GTID state. */
/* ToDo: This needs to be configurable somehow in a useful way ... */
if (rpl_global_gtid_slave_state.count())
if (mi->gtid_pos_auto)
{
int rc;
char str_buf[256];
......@@ -2162,6 +2161,8 @@ static bool send_show_master_info_header(THD *thd, bool full)
10, MYSQL_TYPE_LONG));
field_list.push_back(new Item_float("Slave_heartbeat_period",
0.0, 3, 10));
field_list.push_back(new Item_return_int("Gtid_Pos_Auto", sizeof(ulong),
MYSQL_TYPE_LONG));
}
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
......@@ -2332,6 +2333,7 @@ static bool send_show_master_info_data(THD *thd, Master_info *mi, bool full)
protocol->store((uint32) mi->rli.executed_entries);
protocol->store((uint32) mi->received_heartbeats);
protocol->store((double) mi->heartbeat_period, 3, &tmp);
protocol->store((uint32) (mi->gtid_pos_auto != 0));
}
mysql_mutex_unlock(&mi->rli.err_lock);
......
......@@ -290,6 +290,8 @@ struct LEX_MASTER_INFO
char *relay_log_name;
LEX_STRING connection_name;
ulonglong pos;
LEX_STRING gtid_pos_str;
bool gtid_pos_auto;
ulong relay_log_pos;
ulong server_id;
uint port, connect_retry;
......@@ -313,6 +315,7 @@ struct LEX_MASTER_INFO
host= user= password= log_file_name= ssl_key= ssl_cert= ssl_ca=
ssl_capath= ssl_cipher= relay_log_name= 0;
pos= relay_log_pos= server_id= port= connect_retry= 0;
gtid_pos_auto= FALSE;
heartbeat_period= 0;
ssl= ssl_verify_server_cert= heartbeat_opt=
repl_ignore_server_ids_opt= LEX_MI_UNCHANGED;
......
......@@ -2236,6 +2236,13 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
mi->rli.group_relay_log_pos= mi->rli.event_relay_log_pos= lex_mi->relay_log_pos;
}
if (lex_mi->gtid_pos_auto)
mi->gtid_pos_auto= true;
else if (lex_mi->gtid_pos_str.str ||
lex_mi->log_file_name || lex_mi->pos ||
lex_mi->relay_log_name || lex_mi->relay_log_pos)
mi->gtid_pos_auto= false;
/*
If user did specify neither host nor port nor any log name nor any log
pos, i.e. he specified only user/password/master_connect_retry, he probably
......
......@@ -835,6 +835,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token AUTHORS_SYM
%token AUTOEXTEND_SIZE_SYM
%token AUTO_INC
%token AUTO_SYM
%token AVG_ROW_LENGTH
%token AVG_SYM /* SQL-2003-N */
%token BACKUP_SYM
......@@ -1094,6 +1095,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token LOW_PRIORITY
%token LT /* OPERATOR */
%token MASTER_CONNECT_RETRY_SYM
%token MASTER_GTID_POS_SYM
%token MASTER_HOST_SYM
%token MASTER_LOG_FILE_SYM
%token MASTER_LOG_POS_SYM
......@@ -2058,6 +2060,24 @@ master_file_def:
/* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
}
| MASTER_GTID_POS_SYM EQ TEXT_STRING_sys
{
if (Lex->mi.gtid_pos_str.str || Lex->mi.gtid_pos_auto)
{
my_error(ER_DUP_ARGUMENT, MYF(0), "MASTER_GTID_POS");
MYSQL_YYABORT;
}
Lex->mi.gtid_pos_str = $3;
}
| MASTER_GTID_POS_SYM EQ AUTO_SYM
{
if (Lex->mi.gtid_pos_str.str || Lex->mi.gtid_pos_auto)
{
my_error(ER_DUP_ARGUMENT, MYF(0), "MASTER_GTID_POS");
MYSQL_YYABORT;
}
Lex->mi.gtid_pos_auto = true;
}
;
optional_connection_name:
......@@ -13182,6 +13202,7 @@ keyword_sp:
| AUTHORS_SYM {}
| AUTO_INC {}
| AUTOEXTEND_SIZE_SYM {}
| AUTO_SYM {}
| AVG_ROW_LENGTH {}
| AVG_SYM {}
| BINLOG_SYM {}
......@@ -13292,6 +13313,7 @@ keyword_sp:
| MAX_ROWS {}
| MASTER_SYM {}
| MASTER_HEARTBEAT_PERIOD_SYM {}
| MASTER_GTID_POS_SYM {}
| MASTER_HOST_SYM {}
| MASTER_PORT_SYM {}
| MASTER_LOG_FILE_SYM {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment