summaryrefslogtreecommitdiff
path: root/sql/sql_repl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_repl.cc')
-rw-r--r--sql/sql_repl.cc516
1 files changed, 313 insertions, 203 deletions
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 0ea61320a5a..5cf55d89d3e 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -51,7 +51,7 @@ extern TYPELIB binlog_checksum_typelib;
static int
fake_event_header(String* packet, Log_event_type event_type, ulong extra_len,
my_bool *do_checksum, ha_checksum *crc, const char** errmsg,
- uint8 checksum_alg_arg, uint32 end_pos)
+ enum enum_binlog_checksum_alg checksum_alg_arg, uint32 end_pos)
{
char header[LOG_EVENT_HEADER_LEN];
ulong event_len;
@@ -79,8 +79,7 @@ fake_event_header(String* packet, Log_event_type event_type, ulong extra_len,
}
if (*do_checksum)
{
- *crc= my_checksum(0L, NULL, 0);
- *crc= my_checksum(*crc, (uchar*)header, sizeof(header));
+ *crc= my_checksum(0, (uchar*)header, sizeof(header));
}
return 0;
}
@@ -133,7 +132,7 @@ struct binlog_send_info {
enum_gtid_skip_type gtid_skip_group;
enum_gtid_until_state gtid_until_group;
ushort flags;
- uint8 current_checksum_alg;
+ enum enum_binlog_checksum_alg current_checksum_alg;
bool slave_gtid_strict_mode;
bool send_fake_gtid_list;
bool slave_gtid_ignore_duplicates;
@@ -209,7 +208,7 @@ static int reset_transmit_packet(struct binlog_send_info *info, ushort flags,
*/
static int fake_rotate_event(binlog_send_info *info, ulonglong position,
- const char** errmsg, uint8 checksum_alg_arg)
+ const char** errmsg, enum enum_binlog_checksum_alg checksum_alg_arg)
{
DBUG_ENTER("fake_rotate_event");
ulong ev_offset;
@@ -405,11 +404,11 @@ inline void fix_checksum(String *packet, ulong ev_offset)
{
/* recalculate the crc for this event */
uint data_len = uint4korr(packet->ptr() + ev_offset + EVENT_LEN_OFFSET);
- ha_checksum crc= my_checksum(0L, NULL, 0);
+ ha_checksum crc;
DBUG_ASSERT(data_len ==
LOG_EVENT_MINIMAL_HEADER_LEN + FORMAT_DESCRIPTION_HEADER_LEN +
BINLOG_CHECKSUM_ALG_DESC_LEN + BINLOG_CHECKSUM_LEN);
- crc= my_checksum(crc, (uchar *)packet->ptr() + ev_offset, data_len -
+ crc= my_checksum(0, (uchar *)packet->ptr() + ev_offset, data_len -
BINLOG_CHECKSUM_LEN);
int4store(packet->ptr() + ev_offset + data_len - BINLOG_CHECKSUM_LEN, crc);
}
@@ -454,9 +453,9 @@ static bool is_slave_checksum_aware(THD * thd)
@c enum enum_binlog_checksum_alg
*/
-static uint8 get_binlog_checksum_value_at_connect(THD * thd)
+static enum enum_binlog_checksum_alg get_binlog_checksum_value_at_connect(THD * thd)
{
- uint8 ret;
+ enum enum_binlog_checksum_alg ret;
DBUG_ENTER("get_binlog_checksum_value_at_connect");
user_var_entry *entry= get_binlog_checksum_uservar(thd);
@@ -471,7 +470,8 @@ static uint8 get_binlog_checksum_value_at_connect(THD * thd)
uint dummy_errors;
str.copy(entry->value, entry->length, &my_charset_bin, &my_charset_bin,
&dummy_errors);
- ret= (uint8) find_type ((char*) str.ptr(), &binlog_checksum_typelib, 1) - 1;
+ ret= (enum_binlog_checksum_alg)
+ (find_type ((char*) str.ptr(), &binlog_checksum_typelib, 1) - 1);
DBUG_ASSERT(ret <= BINLOG_CHECKSUM_ALG_CRC32); // while it's just on CRC32 alg
}
DBUG_RETURN(ret);
@@ -559,7 +559,7 @@ bool purge_error_message(THD* thd, int res)
if ((errcode= purge_log_get_error_code(res)) != 0)
{
- my_message(errcode, ER(errcode), MYF(0));
+ my_message(errcode, ER_THD(thd, errcode), MYF(0));
return TRUE;
}
my_ok(thd);
@@ -644,6 +644,9 @@ void set_read_error(binlog_send_info *info, int error)
case LOG_READ_CHECKSUM_FAILURE:
info->errmsg= "event read from binlog did not pass crc check";
break;
+ case LOG_READ_DECRYPT:
+ info->errmsg= "event decryption failure";
+ break;
default:
info->errmsg= "unknown error reading log event on the master";
break;
@@ -775,7 +778,7 @@ get_slave_until_gtid(THD *thd, String *out_str)
static int send_heartbeat_event(binlog_send_info *info,
NET* net, String* packet,
const struct event_coordinates *coord,
- uint8 checksum_alg_arg)
+ enum enum_binlog_checksum_alg checksum_alg_arg)
{
DBUG_ENTER("send_heartbeat_event");
@@ -811,8 +814,7 @@ static int send_heartbeat_event(binlog_send_info *info,
if (do_checksum)
{
char b[BINLOG_CHECKSUM_LEN];
- ha_checksum crc= my_checksum(0L, NULL, 0);
- crc= my_checksum(crc, (uchar*) header, sizeof(header));
+ ha_checksum crc= my_checksum(0, (uchar*) header, sizeof(header));
crc= my_checksum(crc, (uchar*) p, ident_len);
int4store(b, crc);
packet->append(b, sizeof(b));
@@ -919,9 +921,14 @@ get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
typ= ev->get_type_code();
if (typ == GTID_LIST_EVENT)
break; /* Done, found it */
+ if (typ == START_ENCRYPTION_EVENT)
+ {
+ if (fdle->start_decryption((Start_encryption_log_event*) ev))
+ errormsg= "Could not set up decryption for binlog.";
+ }
delete ev;
if (typ == ROTATE_EVENT || typ == STOP_EVENT ||
- typ == FORMAT_DESCRIPTION_EVENT)
+ typ == FORMAT_DESCRIPTION_EVENT || typ == START_ENCRYPTION_EVENT)
continue; /* Continue looking */
/* We did not find any Gtid_list_log_event, must be old binlog. */
@@ -1396,7 +1403,7 @@ gtid_state_from_pos(const char *name, uint32 offset,
bool found_gtid_list_event= false;
bool found_format_description_event= false;
bool valid_pos= false;
- uint8 current_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
+ enum enum_binlog_checksum_alg current_checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
int err;
String packet;
Format_description_log_event *fdev= NULL;
@@ -1438,8 +1445,9 @@ gtid_state_from_pos(const char *name, uint32 offset,
break;
packet.length(0);
- err= Log_event::read_log_event(&cache, &packet, NULL,
- current_checksum_alg);
+ err= Log_event::read_log_event(&cache, &packet, fdev,
+ opt_master_verify_checksum ? current_checksum_alg
+ : BINLOG_CHECKSUM_ALG_OFF);
if (err)
{
errormsg= "Could not read binlog while searching for slave start "
@@ -1474,6 +1482,20 @@ gtid_state_from_pos(const char *name, uint32 offset,
delete fdev;
fdev= tmp;
}
+ else if (typ == START_ENCRYPTION_EVENT)
+ {
+ uint sele_len = packet.length();
+ if (current_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
+ {
+ sele_len -= BINLOG_CHECKSUM_LEN;
+ }
+ Start_encryption_log_event sele(packet.ptr(), sele_len, fdev);
+ if (fdev->start_decryption(&sele))
+ {
+ errormsg= "Could not start decryption of binlog.";
+ goto end;
+ }
+ }
else if (typ != FORMAT_DESCRIPTION_EVENT && !found_format_description_event)
{
errormsg= "Did not find format description log event while searching "
@@ -1647,7 +1669,7 @@ send_event_to_slave(binlog_send_info *info, Log_event_type event_type,
String* const packet= info->packet;
size_t len= packet->length();
int mariadb_slave_capability= info->mariadb_slave_capability;
- uint8 current_checksum_alg= info->current_checksum_alg;
+ enum enum_binlog_checksum_alg current_checksum_alg= info->current_checksum_alg;
slave_connection_state *gtid_state= &info->gtid_state;
slave_connection_state *until_gtid_state= info->until_gtid_state;
@@ -2073,18 +2095,6 @@ static int init_binlog_sender(binlog_send_info *info,
info->dbug_reconnect_counter= 22;
});
- /*
- We want to corrupt the first event, in Log_event::read_log_event().
- But we do not want the corruption to happen early, eg. when client does
- BINLOG_GTID_POS(). So test case sets a DBUG trigger which causes us to
- set the real DBUG injection here.
- */
- DBUG_EXECUTE_IF("corrupt_read_log_event2_set",
- {
- DBUG_SET("-d,corrupt_read_log_event2_set");
- DBUG_SET("+d,corrupt_read_log_event2");
- });
-
if (global_system_variables.log_warnings > 1)
sql_print_information(
"Start binlog_dump to slave_server(%lu), pos(%s, %lu)",
@@ -2194,10 +2204,8 @@ static int init_binlog_sender(binlog_send_info *info,
/**
* send format descriptor event for one binlog file
*/
-static int send_format_descriptor_event(binlog_send_info *info,
- IO_CACHE *log,
- LOG_INFO *linfo,
- my_off_t start_pos)
+static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log,
+ LOG_INFO *linfo, my_off_t start_pos)
{
int error;
ulong ev_offset;
@@ -2221,144 +2229,194 @@ static int send_format_descriptor_event(binlog_send_info *info,
return 1;
}
- do
+ /* reset transmit packet for the event read from binary log file */
+ if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg))
+ return 1;
+
+ /*
+ Try to find a Format_description_log_event at the beginning of
+ the binlog
+ */
+ info->last_pos= my_b_tell(log);
+ error= Log_event::read_log_event(log, packet, info->fdev,
+ opt_master_verify_checksum
+ ? info->current_checksum_alg
+ : BINLOG_CHECKSUM_ALG_OFF);
+ linfo->pos= my_b_tell(log);
+
+ if (error)
{
- /* reset transmit packet for the event read from binary log file */
- if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg))
- break;
+ set_read_error(info, error);
+ return 1;
+ }
- /*
- Try to find a Format_description_log_event at the beginning of
- the binlog
- */
- info->last_pos= my_b_tell(log);
- error= Log_event::read_log_event(log, packet, /* LOCK_log */ NULL,
- info->current_checksum_alg);
- linfo->pos= my_b_tell(log);
+ event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET+ev_offset]);
- if (error)
- {
- set_read_error(info, error);
- break;
- }
+ /*
+ The packet has offsets equal to the normal offsets in a
+ binlog event + ev_offset (the first ev_offset characters are
+ the header (default \0)).
+ */
+ DBUG_PRINT("info",
+ ("Looked for a Format_description_log_event, "
+ "found event type %d", (int)event_type));
- event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET+ev_offset]);
+ if (event_type != FORMAT_DESCRIPTION_EVENT)
+ {
+ info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ info->errmsg= "Failed to find format descriptor event in start of binlog";
+ sql_print_warning("Failed to find format descriptor event in "
+ "start of binlog: %s",
+ info->log_file_name);
+ return 1;
+ }
- /*
- The packet has offsets equal to the normal offsets in a
- binlog event + ev_offset (the first ev_offset characters are
- the header (default \0)).
- */
- DBUG_PRINT("info",
- ("Looked for a Format_description_log_event, "
- "found event type %d", (int)event_type));
+ info->current_checksum_alg= get_checksum_alg(packet->ptr() + ev_offset,
+ packet->length() - ev_offset);
- if (event_type != FORMAT_DESCRIPTION_EVENT)
- {
- info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
- info->errmsg= "Failed to find format descriptor event in start of binlog";
- sql_print_warning("Failed to find format descriptor event in "
- "start of binlog: %s",
- info->log_file_name);
- break;
- }
+ DBUG_ASSERT(info->current_checksum_alg == BINLOG_CHECKSUM_ALG_OFF ||
+ info->current_checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
+ info->current_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32);
- info->current_checksum_alg= get_checksum_alg(packet->ptr() + ev_offset,
- packet->length() - ev_offset);
+ if (!is_slave_checksum_aware(thd) &&
+ info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ {
+ info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ info->errmsg= "Slave can not handle replication events with the "
+ "checksum that master is configured to log";
+ sql_print_warning("Master is configured to log replication events "
+ "with checksum, but will not send such events to "
+ "slaves that cannot process them");
+ return 1;
+ }
- DBUG_ASSERT(info->current_checksum_alg == BINLOG_CHECKSUM_ALG_OFF ||
- info->current_checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
- info->current_checksum_alg == BINLOG_CHECKSUM_ALG_CRC32);
+ uint ev_len= packet->length() - ev_offset;
+ if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ ev_len-= BINLOG_CHECKSUM_LEN;
- if (!is_slave_checksum_aware(thd) &&
- info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
- info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
- {
- info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
- info->errmsg= "Slave can not handle replication events with the "
- "checksum that master is configured to log";
- sql_print_warning("Master is configured to log replication events "
- "with checksum, but will not send such events to "
- "slaves that cannot process them");
- break;
- }
+ Format_description_log_event *tmp;
+ if (!(tmp= new Format_description_log_event(packet->ptr() + ev_offset,
+ ev_len, info->fdev)))
+ {
+ info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ info->errmsg= "Corrupt Format_description event found "
+ "or out-of-memory";
+ return 1;
+ }
+ delete info->fdev;
+ info->fdev= tmp;
- Format_description_log_event *tmp;
- if (!(tmp= new Format_description_log_event(packet->ptr()+ev_offset,
- packet->length()-ev_offset,
- info->fdev)))
- {
- info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
- info->errmsg= "Corrupt Format_description event found "
- "or out-of-memory";
- break;
- }
- delete info->fdev;
- info->fdev= tmp;
+ (*packet)[FLAGS_OFFSET+ev_offset] &= ~LOG_EVENT_BINLOG_IN_USE_F;
- (*packet)[FLAGS_OFFSET+ev_offset] &= ~LOG_EVENT_BINLOG_IN_USE_F;
+ if (info->clear_initial_log_pos)
+ {
+ info->clear_initial_log_pos= false;
+ /*
+ mark that this event with "log_pos=0", so the slave
+ should not increment master's binlog position
+ (rli->group_master_log_pos)
+ */
+ int4store((char*) packet->ptr()+LOG_POS_OFFSET+ev_offset, (ulong) 0);
- if (info->clear_initial_log_pos)
- {
- info->clear_initial_log_pos= false;
- /*
- mark that this event with "log_pos=0", so the slave
- should not increment master's binlog position
- (rli->group_master_log_pos)
- */
- int4store((char*) packet->ptr()+LOG_POS_OFFSET+ev_offset, (ulong) 0);
+ /*
+ if reconnect master sends FD event with `created' as 0
+ to avoid destroying temp tables.
+ */
+ int4store((char*) packet->ptr()+LOG_EVENT_MINIMAL_HEADER_LEN+
+ ST_CREATED_OFFSET+ev_offset, (ulong) 0);
- /*
- if reconnect master sends FD event with `created' as 0
- to avoid destroying temp tables.
- */
+ /* fix the checksum due to latest changes in header */
+ if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ fix_checksum(packet, ev_offset);
+ }
+ else if (info->using_gtid_state)
+ {
+ /*
+ If this event has the field `created' set, then it will cause the
+ slave to delete all active temporary tables. This must not happen
+ if the slave received any later GTIDs in a previous connect, as
+ those GTIDs might have created new temporary tables that are still
+ needed.
+
+ So here, we check if the starting GTID position was already
+ reached before this format description event. If not, we clear the
+ `created' flag to preserve temporary tables on the slave. (If the
+ slave connects at a position past this event, it means that it
+ already received and handled it in a previous connect).
+ */
+ if (!info->gtid_state.is_pos_reached())
+ {
int4store((char*) packet->ptr()+LOG_EVENT_MINIMAL_HEADER_LEN+
ST_CREATED_OFFSET+ev_offset, (ulong) 0);
-
- /* fix the checksum due to latest changes in header */
if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
- info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
fix_checksum(packet, ev_offset);
}
- else if (info->using_gtid_state)
+ }
+
+ /* send it */
+ if (my_net_write(info->net, (uchar*) packet->ptr(), packet->length()))
+ {
+ info->errmsg= "Failed on my_net_write()";
+ info->error= ER_UNKNOWN_ERROR;
+ return 1;
+ }
+
+ /*
+ Read the following Start_encryption_log_event but don't send it to slave.
+ Slave doesn't need to know whether master's binlog is encrypted,
+ and if it'll want to encrypt its logs, it should generate its own
+ random nonce, not use the one from the master.
+ */
+ packet->length(0);
+ info->last_pos= linfo->pos;
+ error= Log_event::read_log_event(log, packet, info->fdev,
+ opt_master_verify_checksum
+ ? info->current_checksum_alg
+ : BINLOG_CHECKSUM_ALG_OFF);
+ linfo->pos= my_b_tell(log);
+
+ if (error)
+ {
+ set_read_error(info, error);
+ return 1;
+ }
+
+ event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET]);
+ if (event_type == START_ENCRYPTION_EVENT)
+ {
+ Start_encryption_log_event *sele= (Start_encryption_log_event *)
+ Log_event::read_log_event(packet->ptr(), packet->length(), &info->errmsg,
+ info->fdev, BINLOG_CHECKSUM_ALG_OFF);
+ if (!sele)
{
- /*
- If this event has the field `created' set, then it will cause the
- slave to delete all active temporary tables. This must not happen
- if the slave received any later GTIDs in a previous connect, as
- those GTIDs might have created new temporary tables that are still
- needed.
-
- So here, we check if the starting GTID position was already
- reached before this format description event. If not, we clear the
- `created' flag to preserve temporary tables on the slave. (If the
- slave connects at a position past this event, it means that it
- already received and handled it in a previous connect).
- */
- if (!info->gtid_state.is_pos_reached())
- {
- int4store((char*) packet->ptr()+LOG_EVENT_MINIMAL_HEADER_LEN+
- ST_CREATED_OFFSET+ev_offset, (ulong) 0);
- if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
- info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
- fix_checksum(packet, ev_offset);
- }
+ info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ return 1;
}
- /* send it */
- if (my_net_write(info->net, (uchar*) packet->ptr(), packet->length()))
+ if (info->fdev->start_decryption(sele))
{
- info->errmsg= "Failed on my_net_write()";
- info->error= ER_UNKNOWN_ERROR;
- break;
+ info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG;
+ info->errmsg= "Could not decrypt binlog: encryption key error";
+ return 1;
}
+ delete sele;
+ }
+ else if (start_pos == BIN_LOG_HEADER_SIZE)
+ {
+ /*
+ not Start_encryption_log_event - seek back. But only if
+ send_one_binlog_file() isn't going to seek anyway
+ */
+ my_b_seek(log, info->last_pos);
+ linfo->pos= info->last_pos;
+ }
- /** all done */
- return 0;
-
- } while (false);
- return 1;
+ /** all done */
+ return 0;
}
static bool should_stop(binlog_send_info *info)
@@ -2545,9 +2603,7 @@ static my_off_t get_binlog_end_pos(binlog_send_info *info,
* return 0 - OK
* else NOK
*/
-static int send_events(binlog_send_info *info,
- IO_CACHE* log,
- LOG_INFO* linfo,
+static int send_events(binlog_send_info *info, IO_CACHE* log, LOG_INFO* linfo,
my_off_t end_pos)
{
int error;
@@ -2568,14 +2624,15 @@ static int send_events(binlog_send_info *info,
return 1;
info->last_pos= linfo->pos;
- error = Log_event::read_log_event(log, packet, /* LOCK_log */ NULL,
- info->current_checksum_alg,
- NULL, NULL);
+ error= Log_event::read_log_event(log, packet, info->fdev,
+ opt_master_verify_checksum ? info->current_checksum_alg
+ : BINLOG_CHECKSUM_ALG_OFF);
linfo->pos= my_b_tell(log);
if (error)
{
- goto read_err;
+ set_read_error(info, error);
+ return 1;
}
Log_event_type event_type=
@@ -2618,8 +2675,9 @@ static int send_events(binlog_send_info *info,
});
#endif
- if ((info->errmsg= send_event_to_slave(info, event_type, log,
- ev_offset, &info->error_gtid)))
+ if (event_type != START_ENCRYPTION_EVENT &&
+ ((info->errmsg= send_event_to_slave(info, event_type, log,
+ ev_offset, &info->error_gtid))))
return 1;
if (unlikely(info->send_fake_gtid_list) &&
@@ -2661,11 +2719,6 @@ static int send_events(binlog_send_info *info,
}
return 0;
-
-read_err:
- set_read_error(info, error);
-
- return 1;
}
/**
@@ -2811,9 +2864,9 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
BINLOG_GTID_POS(). So test case sets a DBUG trigger which causes us to
set the real DBUG injection here.
*/
- DBUG_EXECUTE_IF("corrupt_read_log_event_to_slave_set",
+ DBUG_EXECUTE_IF("corrupt_read_log_event2_set",
{
- DBUG_SET("-d,corrupt_read_log_event_to_slave_set");
+ DBUG_SET("-d,corrupt_read_log_event2_set");
DBUG_SET("+d,corrupt_read_log_event2");
});
@@ -3047,8 +3100,6 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
}
else if (thd->lex->mi.relay_log_pos)
{
- if (thd->lex->mi.pos)
- slave_errno=ER_BAD_SLAVE_UNTIL_COND;
mi->rli.until_condition= Relay_log_info::UNTIL_RELAY_POS;
mi->rli.until_log_pos= thd->lex->mi.relay_log_pos;
strmake_buf(mi->rli.until_log_name, thd->lex->mi.relay_log_name);
@@ -3099,17 +3150,19 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
if (!opt_skip_slave_start)
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_MISSING_SKIP_SLAVE,
- ER(ER_MISSING_SKIP_SLAVE));
+ ER_THD(thd, ER_MISSING_SKIP_SLAVE));
}
mysql_mutex_unlock(&mi->rli.data_lock);
}
else if (thd->lex->mi.pos || thd->lex->mi.relay_log_pos)
- push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED,
- ER(ER_UNTIL_COND_IGNORED));
+ push_warning(thd,
+ Sql_condition::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED,
+ ER_THD(thd, ER_UNTIL_COND_IGNORED));
if (!slave_errno)
- slave_errno = start_slave_threads(0 /*no mutex */,
+ slave_errno = start_slave_threads(thd,
+ 0 /*no mutex */,
1 /* wait for start */,
mi,
master_info_file_tmp,
@@ -3123,7 +3176,7 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
{
/* no error if all threads are already started, only a warning */
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_RUNNING,
- ER(ER_SLAVE_WAS_RUNNING));
+ ER_THD(thd, ER_SLAVE_WAS_RUNNING));
}
err:
@@ -3190,14 +3243,14 @@ int stop_slave(THD* thd, Master_info* mi, bool net_report )
//no error if both threads are already stopped, only a warning
slave_errno= 0;
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_NOT_RUNNING,
- ER(ER_SLAVE_WAS_NOT_RUNNING));
+ ER_THD(thd, ER_SLAVE_WAS_NOT_RUNNING));
}
unlock_slave_threads(mi);
if (slave_errno)
{
if (net_report)
- my_message(slave_errno, ER(slave_errno), MYF(0));
+ my_message(slave_errno, ER_THD(thd, slave_errno), MYF(0));
DBUG_RETURN(1);
}
@@ -3590,7 +3643,8 @@ bool change_master(THD* thd, Master_info* mi, bool *master_info_added)
lex_mi->ssl_cert || lex_mi->ssl_cipher || lex_mi->ssl_key ||
lex_mi->ssl_verify_server_cert || lex_mi->ssl_crl || lex_mi->ssl_crlpath)
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_SLAVE_IGNORED_SSL_PARAMS, ER(ER_SLAVE_IGNORED_SSL_PARAMS));
+ ER_SLAVE_IGNORED_SSL_PARAMS,
+ ER_THD(thd, ER_SLAVE_IGNORED_SSL_PARAMS));
#endif
if (lex_mi->relay_log_name)
@@ -3770,16 +3824,19 @@ err:
@retval 0 success
@retval 1 error
*/
-int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len)
+int reset_master(THD* thd, rpl_gtid *init_state, uint32 init_state_len,
+ ulong next_log_number)
{
if (!mysql_bin_log.is_open())
{
my_message(ER_FLUSH_MASTER_BINLOG_CLOSED,
- ER(ER_FLUSH_MASTER_BINLOG_CLOSED), MYF(ME_BELL+ME_WAITTANG));
+ ER_THD(thd, ER_FLUSH_MASTER_BINLOG_CLOSED),
+ MYF(ME_BELL+ME_WAITTANG));
return 1;
}
- if (mysql_bin_log.reset_logs(thd, 1, init_state, init_state_len))
+ if (mysql_bin_log.reset_logs(thd, 1, init_state, init_state_len,
+ next_log_number))
return 1;
RUN_HOOK(binlog_transmit, after_reset_master, (thd, 0 /* flags */));
return 0;
@@ -3807,10 +3864,11 @@ bool mysql_show_binlog_events(THD* thd)
int old_max_allowed_packet= thd->variables.max_allowed_packet;
Master_info *mi= 0;
LOG_INFO linfo;
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
DBUG_ENTER("mysql_show_binlog_events");
- Log_event::init_show_field_list(&field_list);
+ Log_event::init_show_field_list(thd, &field_list);
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
@@ -3828,10 +3886,12 @@ bool mysql_show_binlog_events(THD* thd)
}
else /* showing relay log contents */
{
+ if (!lex_mi->connection_name.str)
+ lex_mi->connection_name= thd->variables.default_master_connection;
mysql_mutex_lock(&LOCK_active_mi);
if (!master_info_index ||
!(mi= master_info_index->
- get_master_info(&thd->variables.default_master_connection,
+ get_master_info(&lex_mi->connection_name,
Sql_condition::WARN_LEVEL_ERROR)))
{
mysql_mutex_unlock(&LOCK_active_mi);
@@ -3842,7 +3902,6 @@ bool mysql_show_binlog_events(THD* thd)
if (binary_log->is_open())
{
- LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
SELECT_LEX_UNIT *unit= &thd->lex->unit;
ha_rows event_count, limit_start, limit_end;
my_off_t pos = MY_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
@@ -3895,38 +3954,52 @@ bool mysql_show_binlog_events(THD* thd)
Read the first event in case it's a Format_description_log_event, to
know the format. If there's no such event, we are 3.23 or 4.x. This
code, like before, can't read 3.23 binlogs.
+ Also read the second event, in case it's a Start_encryption_log_event.
This code will fail on a mixed relay log (one which has Format_desc then
Rotate then Format_desc).
*/
- ev= Log_event::read_log_event(&log, (mysql_mutex_t*)0, description_event,
- opt_master_verify_checksum);
- if (ev)
+
+ my_off_t scan_pos = BIN_LOG_HEADER_SIZE;
+ while (scan_pos < pos)
{
+ ev= Log_event::read_log_event(&log, (mysql_mutex_t*)0, description_event,
+ opt_master_verify_checksum);
+ scan_pos = my_b_tell(&log);
+ if (ev == NULL || !ev->is_valid())
+ {
+ mysql_mutex_unlock(log_lock);
+ errmsg = "Wrong offset or I/O error";
+ goto err;
+ }
if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
{
delete description_event;
description_event= (Format_description_log_event*) ev;
}
else
+ {
+ if (ev->get_type_code() == START_ENCRYPTION_EVENT)
+ {
+ if (description_event->start_decryption((Start_encryption_log_event*) ev))
+ {
+ delete ev;
+ mysql_mutex_unlock(log_lock);
+ errmsg = "Could not initialize decryption of binlog.";
+ goto err;
+ }
+ }
delete ev;
+ break;
+ }
}
my_b_seek(&log, pos);
- if (!description_event->is_valid())
- {
- errmsg="Invalid Format_description event; could be out of memory";
- goto err;
- }
-
for (event_count = 0;
(ev = Log_event::read_log_event(&log, (mysql_mutex_t*) 0,
description_event,
opt_master_verify_checksum)); )
{
- if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
- description_event->checksum_alg= ev->checksum_alg;
-
if (event_count >= limit_start &&
ev->net_send(thd, protocol, linfo.log_file_name, pos))
{
@@ -3936,8 +4009,30 @@ bool mysql_show_binlog_events(THD* thd)
goto err;
}
+ if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
+ {
+ Format_description_log_event* new_fdle=
+ (Format_description_log_event*) ev;
+ new_fdle->copy_crypto_data(description_event);
+ delete description_event;
+ description_event= new_fdle;
+ }
+ else
+ {
+ if (ev->get_type_code() == START_ENCRYPTION_EVENT)
+ {
+ if (description_event->start_decryption((Start_encryption_log_event*) ev))
+ {
+ errmsg = "Error starting decryption";
+ delete ev;
+ mysql_mutex_unlock(log_lock);
+ goto err;
+ }
+ }
+ delete ev;
+ }
+
pos = my_b_tell(&log);
- delete ev;
if (++event_count >= limit_end)
break;
@@ -3994,13 +4089,23 @@ err:
bool show_binlog_info(THD* thd)
{
Protocol *protocol= thd->protocol;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("show_binlog_info");
+
List<Item> field_list;
- field_list.push_back(new Item_empty_string("File", FN_REFLEN));
- field_list.push_back(new Item_return_int("Position",20,
- MYSQL_TYPE_LONGLONG));
- field_list.push_back(new Item_empty_string("Binlog_Do_DB",255));
- field_list.push_back(new Item_empty_string("Binlog_Ignore_DB",255));
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "File", FN_REFLEN),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_return_int(thd, "Position", 20,
+ MYSQL_TYPE_LONGLONG),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Binlog_Do_DB", 255),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Binlog_Ignore_DB", 255),
+ mem_root);
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
@@ -4043,6 +4148,7 @@ bool show_binlogs(THD* thd)
uint length;
int cur_dir_len;
Protocol *protocol= thd->protocol;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("show_binlogs");
if (!mysql_bin_log.is_open())
@@ -4051,9 +4157,13 @@ bool show_binlogs(THD* thd)
DBUG_RETURN(TRUE);
}
- field_list.push_back(new Item_empty_string("Log_name", 255));
- field_list.push_back(new Item_return_int("File_size", 20,
- MYSQL_TYPE_LONGLONG));
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Log_name", 255),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_return_int(thd, "File_size", 20,
+ MYSQL_TYPE_LONGLONG),
+ mem_root);
if (protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
@@ -4313,7 +4423,7 @@ rpl_gtid_pos_check(THD *thd, char *str, size_t len)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_MASTER_GTID_POS_MISSING_DOMAIN,
- ER(ER_MASTER_GTID_POS_MISSING_DOMAIN),
+ ER_THD(thd, ER_MASTER_GTID_POS_MISSING_DOMAIN),
binlog_gtid->domain_id, binlog_gtid->domain_id,
binlog_gtid->server_id, binlog_gtid->seq_no);
gave_missing_warning= true;
@@ -4333,7 +4443,7 @@ rpl_gtid_pos_check(THD *thd, char *str, size_t len)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG,
- ER(ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG),
+ ER_THD(thd, ER_MASTER_GTID_POS_CONFLICTS_WITH_BINLOG),
slave_gtid->domain_id, slave_gtid->server_id,
slave_gtid->seq_no, binlog_gtid->domain_id,
binlog_gtid->server_id, binlog_gtid->seq_no);