summaryrefslogtreecommitdiff
path: root/sql/slave.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/slave.cc')
-rw-r--r--sql/slave.cc401
1 files changed, 21 insertions, 380 deletions
diff --git a/sql/slave.cc b/sql/slave.cc
index 5c8db6f2c56..86180af8aed 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -160,7 +160,6 @@ failed read"
typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
static int process_io_rotate(Master_info* mi, Rotate_log_event* rev);
-static int process_io_create_file(Master_info* mi, Create_file_log_event* cev);
static bool wait_for_relay_log_space(Relay_log_info* rli);
static bool io_slave_killed(Master_info* mi);
static bool sql_slave_killed(rpl_group_info *rgi);
@@ -1487,20 +1486,6 @@ bool net_request_file(NET* net, const char* fname)
(uchar*) "", 0));
}
-/*
- From other comments and tests in code, it looks like
- sometimes Query_log_event and Load_log_event can have db == 0
- (see rewrite_db() above for example)
- (cases where this happens are unclear; it may be when the master is 3.23).
-*/
-
-const char *print_slave_db_safe(const char* db)
-{
- DBUG_ENTER("*print_slave_db_safe");
-
- DBUG_RETURN((db ? db : ""));
-}
-
#endif /* HAVE_REPLICATION */
bool Sql_cmd_show_slave_status::execute(THD *thd)
@@ -1785,6 +1770,8 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
case 0:
case 1:
case 2:
+ case 3:
+ case 4:
errmsg= err_buff2;
snprintf(err_buff2, sizeof(err_buff2),
"Master reported unrecognized MariaDB version: %s",
@@ -1792,14 +1779,6 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
err_code= ER_SLAVE_FATAL_ERROR;
sprintf(err_buff, ER_DEFAULT(err_code), err_buff2);
break;
- case 3:
- 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
- Format_description_log_event(3, mysql->server_version);
- break;
default:
/*
Master is MySQL >=5.0. Give a default Format_desc event, so that we can
@@ -4877,28 +4856,25 @@ connected:
goto connected;
}
- if (mi->rli.relay_log.description_event_for_queue->binlog_version > 1)
+ /*
+ Register ourselves with the master.
+ */
+ THD_STAGE_INFO(thd, stage_registering_slave_on_master);
+ if (register_slave_on_master(mysql, mi, &suppress_warnings))
{
- /*
- Register ourselves with the master.
- */
- THD_STAGE_INFO(thd, stage_registering_slave_on_master);
- if (register_slave_on_master(mysql, mi, &suppress_warnings))
+ if (!check_io_slave_killed(mi, "Slave I/O thread killed "
+ "while registering slave on master"))
{
- if (!check_io_slave_killed(mi, "Slave I/O thread killed "
- "while registering slave on master"))
- {
- sql_print_error("Slave I/O thread couldn't register on master");
- if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
- reconnect_messages[SLAVE_RECON_ACT_REG]))
- goto err;
- }
- else
+ sql_print_error("Slave I/O thread couldn't register on master");
+ if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
+ reconnect_messages[SLAVE_RECON_ACT_REG]))
goto err;
- goto connected;
}
- DBUG_EXECUTE_IF("fail_com_register_slave", goto err;);
+ else
+ goto err;
+ goto connected;
}
+ DBUG_EXECUTE_IF("fail_com_register_slave", goto err;);
DBUG_PRINT("info",("Starting reading binary log from master"));
thd->set_command(COM_SLAVE_IO);
@@ -5874,115 +5850,6 @@ err_during_init:
/*
- process_io_create_file()
-*/
-
-static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
-{
- int error = 1;
- ulong num_bytes;
- bool cev_not_written;
- THD *thd = mi->io_thd;
- NET *net = &mi->mysql->net;
- DBUG_ENTER("process_io_create_file");
-
- if (unlikely(!cev->is_valid()))
- DBUG_RETURN(1);
-
- if (!mi->rpl_filter->db_ok(cev->db))
- {
- skip_load_data_infile(net);
- DBUG_RETURN(0);
- }
- DBUG_ASSERT(cev->inited_from_old);
- thd->file_id = cev->file_id = mi->file_id++;
- thd->variables.server_id = cev->server_id;
- cev_not_written = 1;
-
- if (unlikely(net_request_file(net,cev->fname)))
- {
- sql_print_error("Slave I/O: failed requesting download of '%s'",
- cev->fname);
- goto err;
- }
-
- /*
- This dummy block is so we could instantiate Append_block_log_event
- once and then modify it slightly instead of doing it multiple times
- in the loop
- */
- {
- Append_block_log_event aev(thd,0,0,0,0);
-
- for (;;)
- {
- if (unlikely((num_bytes=my_net_read(net)) == packet_error))
- {
- sql_print_error("Network read error downloading '%s' from master",
- cev->fname);
- goto err;
- }
- if (unlikely(!num_bytes)) /* eof */
- {
- /* 3.23 master wants it */
- net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0);
- /*
- If we wrote Create_file_log_event, then we need to write
- Execute_load_log_event. If we did not write Create_file_log_event,
- then this is an empty file and we can just do as if the LOAD DATA
- INFILE had not existed, i.e. write nothing.
- */
- if (unlikely(cev_not_written))
- break;
- Execute_load_log_event xev(thd,0,0);
- xev.log_pos = cev->log_pos;
- if (unlikely(mi->rli.relay_log.append(&xev)))
- {
- mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
- ER_THD(thd, 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);
- break;
- }
- if (unlikely(cev_not_written))
- {
- cev->block = net->read_pos;
- cev->block_len = num_bytes;
- if (unlikely(mi->rli.relay_log.append(cev)))
- {
- mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
- ER_THD(thd, ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
- "error writing Create_file event to relay log");
- goto err;
- }
- cev_not_written=0;
- 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)))
- {
- mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, NULL,
- ER_THD(thd, 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) ;
- }
- }
- }
- error=0;
-err:
- DBUG_RETURN(error);
-}
-
-
-/*
Start using a new binary log on the master
SYNOPSIS
@@ -6026,25 +5893,10 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
mi->events_till_disconnect++;
#endif
- /*
- If description_event_for_queue is format <4, there is conversion in the
- relay log to the slave's format (4). And Rotate can mean upgrade or
- nothing. If upgrade, it's to 5.0 or newer, so we will get a Format_desc, so
- 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).
- */
+ /* this prevents a redundant FDLE in the relay log */
if (mi->rli.relay_log.description_event_for_queue->binlog_version >= 4)
- {
- DBUG_ASSERT(mi->rli.relay_log.description_event_for_queue->checksum_alg ==
- mi->rli.relay_log.relay_log_checksum_alg);
-
- 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
- Format_description_log_event(3);
- mi->rli.relay_log.description_event_for_queue->checksum_alg=
- mi->rli.relay_log.relay_log_checksum_alg;
- }
+ mi->rli.relay_log.description_event_for_queue->binlog_version= 3;
+
/*
Rotate the relay log makes binlog format detection easier (at next slave
start or mysqlbinlog)
@@ -6053,216 +5905,9 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
}
/*
- Reads a 3.23 event and converts it to the slave's format. This code was
- copied from MySQL 4.0.
-*/
-static int queue_binlog_ver_1_event(Master_info *mi, const uchar *buf,
- ulong event_len)
-{
- const char *errmsg = 0;
- ulong inc_pos;
- bool ignore_event= 0;
- uchar *tmp_buf = 0;
- Relay_log_info *rli= &mi->rli;
- DBUG_ENTER("queue_binlog_ver_1_event");
-
- /*
- If we get Load event, we need to pass a non-reusable buffer
- to read_log_event, so we do a trick
- */
- if ((uchar)buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
- {
- if (unlikely(!(tmp_buf= (uchar*) my_malloc(key_memory_binlog_ver_1_event,
- event_len+1, MYF(MY_WME)))))
- {
- mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, NULL,
- ER(ER_SLAVE_FATAL_ERROR), "Memory allocation failed");
- DBUG_RETURN(1);
- }
- memcpy(tmp_buf,buf,event_len);
- /*
- Create_file constructor wants a 0 as last char of buffer, this 0 will
- serve as the string-termination char for the file's name (which is at the
- end of the buffer)
- We must increment event_len, otherwise the event constructor will not see
- this end 0, which leads to segfault.
- */
- tmp_buf[event_len++]=0;
- int4store(tmp_buf+EVENT_LEN_OFFSET, event_len);
- buf= tmp_buf;
- }
- /*
- This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to
- send the loaded file, and write it to the relay log in the form of
- Append_block/Exec_load (the SQL thread needs the data, as that thread is not
- connected to the master).
- */
- Log_event *ev=
- Log_event::read_log_event(buf, event_len, &errmsg,
- mi->rli.relay_log.description_event_for_queue, 0);
- 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);
- DBUG_RETURN(1);
- }
-
- mysql_mutex_lock(&mi->data_lock);
- ev->log_pos= mi->master_log_pos; /* 3.23 events don't contain log_pos */
- switch (ev->get_type_code()) {
- case STOP_EVENT:
- ignore_event= 1;
- inc_pos= event_len;
- break;
- case ROTATE_EVENT:
- if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
- {
- delete ev;
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(1);
- }
- inc_pos= 0;
- break;
- case CREATE_FILE_EVENT:
- /*
- Yes it's possible to have CREATE_FILE_EVENT here, even if we're in
- queue_old_event() which is for 3.23 events which don't comprise
- CREATE_FILE_EVENT. This is because read_log_event() above has just
- transformed LOAD_EVENT into CREATE_FILE_EVENT.
- */
- {
- /* We come here when and only when tmp_buf != 0 */
- DBUG_ASSERT(tmp_buf != 0);
- inc_pos=event_len;
- 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));
- mysql_mutex_unlock(&mi->data_lock);
- my_free(tmp_buf);
- DBUG_RETURN(error);
- }
- default:
- inc_pos= event_len;
- break;
- }
- if (likely(!ignore_event))
- {
- if (ev->log_pos)
- /*
- Don't do it for fake Rotate events (see comment in
- Log_event::Log_event(const char* buf...) in log_event.cc).
- */
- ev->log_pos+= event_len; /* make log_pos be the pos of the end of the event */
- if (unlikely(rli->relay_log.append(ev)))
- {
- delete ev;
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(1);
- }
- 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));
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(0);
-}
-
-/*
- Reads a 4.0 event and converts it to the slave's format. This code was copied
- from queue_binlog_ver_1_event(), with some affordable simplifications.
-*/
-static int queue_binlog_ver_3_event(Master_info *mi, const uchar *buf,
- ulong event_len)
-{
- const char *errmsg = 0;
- ulong inc_pos;
- char *tmp_buf = 0;
- 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, 0);
- 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);
- DBUG_RETURN(1);
- }
- mysql_mutex_lock(&mi->data_lock);
- switch (ev->get_type_code()) {
- case STOP_EVENT:
- goto err;
- case ROTATE_EVENT:
- if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
- {
- delete ev;
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(1);
- }
- inc_pos= 0;
- break;
- default:
- inc_pos= event_len;
- break;
- }
-
- if (unlikely(rli->relay_log.append(ev)))
- {
- delete ev;
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(1);
- }
- rli->relay_log.harvest_bytes_written(&rli->log_space_total);
- delete ev;
- mi->master_log_pos+= inc_pos;
-err:
- DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
- mysql_mutex_unlock(&mi->data_lock);
- DBUG_RETURN(0);
-}
-
-/*
- queue_old_event()
-
- Writes a 3.23 or 4.0 event to the relay log, after converting it to the 5.0
- (exactly, slave's) format. To do the conversion, we create a 5.0 event from
- the 3.23/4.0 bytes, then write this event to the relay log.
-
- TODO:
- Test this code before release - it has to be tested on a separate
- setup with 3.23 master or 4.0 master
-*/
-
-static int queue_old_event(Master_info *mi, const uchar *buf, ulong event_len)
-{
- DBUG_ENTER("queue_old_event");
-
- switch (mi->rli.relay_log.description_event_for_queue->binlog_version) {
- case 1:
- DBUG_RETURN(queue_binlog_ver_1_event(mi,buf,event_len));
- case 3:
- 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));
- DBUG_RETURN(1);
- }
-}
-
-/*
queue_event()
- If the event is 3.23/4.0, passes it to queue_old_event() which will convert
- it. Otherwise, writes a 5.0 (or newer) event to the relay log. Then there is
+ Writes a 5.0 (or newer) event to the relay log. Then there is
no format conversion, it's pure read/write of bytes.
So a 5.0.0 slave's relay log can contain events in the slave's format or in
any >=5.0.0 format.
@@ -6350,10 +5995,6 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
}
DBUG_ASSERT(((uchar) buf[FLAGS_OFFSET] & LOG_EVENT_ACCEPT_OWN_F) == 0);
- 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));
-
#ifdef ENABLED_DEBUG_SYNC
/*
A (+d,dbug.rows_events_to_delay_relay_logging)-test is supposed to
@@ -6617,7 +6258,7 @@ static int queue_event(Master_info* mi, const uchar *buf, ulong event_len)
*/
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;