mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
5.2 merge
This commit is contained in:
@ -780,6 +780,88 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file,
|
||||
}
|
||||
|
||||
|
||||
static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev)
|
||||
{
|
||||
/*
|
||||
These events must be printed in base64 format, if printed.
|
||||
base64 format requires a FD event to be safe, so if no FD
|
||||
event has been printed, we give an error. Except if user
|
||||
passed --short-form, because --short-form disables printing
|
||||
row events.
|
||||
*/
|
||||
if (!print_event_info->printed_fd_event && !short_form &&
|
||||
opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
|
||||
{
|
||||
const char* type_str= ev->get_type_str();
|
||||
if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
|
||||
error("--base64-output=never specified, but binlog contains a "
|
||||
"%s event which must be printed in base64.",
|
||||
type_str);
|
||||
else
|
||||
error("malformed binlog: it does not contain any "
|
||||
"Format_description_log_event. I now found a %s event, which "
|
||||
"is not safe to process without a "
|
||||
"Format_description_log_event.",
|
||||
type_str);
|
||||
return 1;
|
||||
}
|
||||
ev->print(result_file, print_event_info);
|
||||
return print_event_info->head_cache.error == -1;
|
||||
}
|
||||
|
||||
|
||||
static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
|
||||
ulong table_id, bool is_stmt_end)
|
||||
{
|
||||
Table_map_log_event *ignored_map=
|
||||
print_event_info->m_table_map_ignored.get_table(table_id);
|
||||
bool skip_event= (ignored_map != NULL);
|
||||
|
||||
/*
|
||||
end of statement check:
|
||||
i) destroy/free ignored maps
|
||||
ii) if skip event, flush cache now
|
||||
*/
|
||||
if (is_stmt_end)
|
||||
{
|
||||
/*
|
||||
Now is safe to clear ignored map (clear_tables will also
|
||||
delete original table map events stored in the map).
|
||||
*/
|
||||
if (print_event_info->m_table_map_ignored.count() > 0)
|
||||
print_event_info->m_table_map_ignored.clear_tables();
|
||||
|
||||
/*
|
||||
If there is a kept Annotate event and all corresponding
|
||||
rbr-events were filtered away, the Annotate event was not
|
||||
freed and it is just the time to do it.
|
||||
*/
|
||||
free_annotate_event();
|
||||
|
||||
/*
|
||||
One needs to take into account an event that gets
|
||||
filtered but was last event in the statement. If this is
|
||||
the case, previous rows events that were written into
|
||||
IO_CACHEs still need to be copied from cache to
|
||||
result_file (as it would happen in ev->print(...) if
|
||||
event was not skipped).
|
||||
*/
|
||||
if (skip_event)
|
||||
{
|
||||
if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) ||
|
||||
copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file)))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip the event check */
|
||||
if (skip_event)
|
||||
return 0;
|
||||
|
||||
return print_base64(print_event_info, ev);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Print the given event, and either delete it or delegate the deletion
|
||||
to someone else.
|
||||
@ -1081,86 +1163,29 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
|
||||
error("Could not rewrite database name");
|
||||
goto err;
|
||||
}
|
||||
if (print_base64(print_event_info, ev))
|
||||
goto err;
|
||||
break;
|
||||
}
|
||||
case WRITE_ROWS_EVENT:
|
||||
case DELETE_ROWS_EVENT:
|
||||
case UPDATE_ROWS_EVENT:
|
||||
{
|
||||
Rows_log_event *e= (Rows_log_event*) ev;
|
||||
if (print_row_event(print_event_info, ev, e->get_table_id(),
|
||||
e->get_flags(Rows_log_event::STMT_END_F)))
|
||||
goto err;
|
||||
break;
|
||||
}
|
||||
case PRE_GA_WRITE_ROWS_EVENT:
|
||||
case PRE_GA_DELETE_ROWS_EVENT:
|
||||
case PRE_GA_UPDATE_ROWS_EVENT:
|
||||
{
|
||||
if (ev_type != TABLE_MAP_EVENT)
|
||||
{
|
||||
Rows_log_event *e= (Rows_log_event*) ev;
|
||||
Table_map_log_event *ignored_map=
|
||||
print_event_info->m_table_map_ignored.get_table(e->get_table_id());
|
||||
bool skip_event= (ignored_map != NULL);
|
||||
|
||||
/*
|
||||
end of statement check:
|
||||
i) destroy/free ignored maps
|
||||
ii) if skip event, flush cache now
|
||||
*/
|
||||
if (e->get_flags(Rows_log_event::STMT_END_F))
|
||||
{
|
||||
/*
|
||||
Now is safe to clear ignored map (clear_tables will also
|
||||
delete original table map events stored in the map).
|
||||
*/
|
||||
if (print_event_info->m_table_map_ignored.count() > 0)
|
||||
print_event_info->m_table_map_ignored.clear_tables();
|
||||
|
||||
/*
|
||||
If there is a kept Annotate event and all corresponding
|
||||
rbr-events were filtered away, the Annotate event was not
|
||||
freed and it is just the time to do it.
|
||||
*/
|
||||
free_annotate_event();
|
||||
|
||||
/*
|
||||
One needs to take into account an event that gets
|
||||
filtered but was last event in the statement. If this is
|
||||
the case, previous rows events that were written into
|
||||
IO_CACHEs still need to be copied from cache to
|
||||
result_file (as it would happen in ev->print(...) if
|
||||
event was not skipped).
|
||||
*/
|
||||
if (skip_event)
|
||||
{
|
||||
if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) ||
|
||||
copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file)))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip the event check */
|
||||
if (skip_event)
|
||||
goto end;
|
||||
}
|
||||
/*
|
||||
These events must be printed in base64 format, if printed.
|
||||
base64 format requires a FD event to be safe, so if no FD
|
||||
event has been printed, we give an error. Except if user
|
||||
passed --short-form, because --short-form disables printing
|
||||
row events.
|
||||
*/
|
||||
if (!print_event_info->printed_fd_event && !short_form &&
|
||||
opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
|
||||
{
|
||||
const char* type_str= ev->get_type_str();
|
||||
if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
|
||||
error("--base64-output=never specified, but binlog contains a "
|
||||
"%s event which must be printed in base64.",
|
||||
type_str);
|
||||
else
|
||||
error("malformed binlog: it does not contain any "
|
||||
"Format_description_log_event. I now found a %s event, which "
|
||||
"is not safe to process without a "
|
||||
"Format_description_log_event.",
|
||||
type_str);
|
||||
Old_rows_log_event *e= (Old_rows_log_event*) ev;
|
||||
if (print_row_event(print_event_info, ev, e->get_table_id(),
|
||||
e->get_flags(Old_rows_log_event::STMT_END_F)))
|
||||
goto err;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ev->print(result_file, print_event_info);
|
||||
|
@ -498,7 +498,8 @@ C_MODE_END
|
||||
#define compile_time_assert(X) \
|
||||
do \
|
||||
{ \
|
||||
typedef char compile_time_assert[(X) ? 1 : -1]; \
|
||||
typedef char compile_time_assert[(X) ? 1 : -1] \
|
||||
__attribute__((unused)); \
|
||||
} while(0)
|
||||
#endif
|
||||
|
||||
|
@ -31,6 +31,31 @@
|
||||
#define MYSQL50_TABLE_NAME_PREFIX_LENGTH (sizeof(MYSQL50_TABLE_NAME_PREFIX)-1)
|
||||
#define SAFE_NAME_LEN (NAME_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH)
|
||||
|
||||
/*
|
||||
MDEV-4088
|
||||
|
||||
MySQL (and MariaDB 5.x before the fix) was using the first character of the
|
||||
server version string (as sent in the first handshake protocol packet) to
|
||||
decide on the replication event formats. And for 10.x the first character
|
||||
is "1", which the slave thought comes from some ancient 1.x version
|
||||
(ignoring the fact that the first ever MySQL version was 3.x).
|
||||
|
||||
To support replication to these old clients, we fake the version in the
|
||||
first handshake protocol packet to start from "5.5.5-" (for example,
|
||||
it might be "5.5.5-10.0.1-MariaDB-debug-log".
|
||||
|
||||
On the client side we remove this fake version prefix to restore the
|
||||
correct server version. The version "5.5.5" did not support
|
||||
pluggable authentication, so any version starting from "5.5.5-" and
|
||||
claiming to support pluggable auth, must be using this fake prefix.
|
||||
*/
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
#define RPL_VERSION_HACK ""
|
||||
#else
|
||||
/* this version must be the one that *does not* support pluggable auth */
|
||||
#define RPL_VERSION_HACK "5.5.5-"
|
||||
#endif
|
||||
|
||||
#define SERVER_VERSION_LENGTH 60
|
||||
#define SQLSTATE_LENGTH 5
|
||||
#define LIST_PROCESS_HOST_LEN 64
|
||||
|
@ -2947,6 +2947,12 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
||||
strmov(mysql->server_version,(char*) net->read_pos+1);
|
||||
mysql->port=port;
|
||||
|
||||
/* remove the rpl hack from the version string, see RPL_VERSION_HACK comment */
|
||||
if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH &&
|
||||
strncmp(mysql->server_version, RPL_VERSION_HACK,
|
||||
sizeof(RPL_VERSION_HACK) - 1) == 0)
|
||||
mysql->server_version+= sizeof(RPL_VERSION_HACK) - 1;
|
||||
|
||||
if (pkt_end >= end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1)
|
||||
{
|
||||
/*
|
||||
|
@ -125,7 +125,12 @@
|
||||
|
||||
static int sel_cmp(Field *f,uchar *a,uchar *b,uint8 a_flag,uint8 b_flag);
|
||||
|
||||
static uchar is_null_string[2]= {1,0};
|
||||
/*
|
||||
this should be long enough so that any memcmp with a string that
|
||||
starts from '\0' won't cross is_null_string boundaries, even
|
||||
if the memcmp is optimized to compare 4- 8- or 16- bytes at once
|
||||
*/
|
||||
static uchar is_null_string[20]= {1,0};
|
||||
|
||||
class RANGE_OPT_PARAM;
|
||||
/*
|
||||
|
19
sql/slave.cc
19
sql/slave.cc
@ -874,6 +874,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
|
||||
int err_code= 0;
|
||||
MYSQL_RES *master_res= 0;
|
||||
MYSQL_ROW master_row;
|
||||
uint version= mysql_get_server_version(mysql) / 10000;
|
||||
DBUG_ENTER("get_master_version_and_clock");
|
||||
|
||||
/*
|
||||
@ -894,20 +895,20 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
|
||||
/*
|
||||
Note the following switch will bug when we have MySQL branch 30 ;)
|
||||
*/
|
||||
switch (*mysql->server_version)
|
||||
switch (version)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
errmsg = "Master reported unrecognized MySQL version";
|
||||
err_code= ER_SLAVE_FATAL_ERROR;
|
||||
sprintf(err_buff, ER(err_code), errmsg);
|
||||
break;
|
||||
case '3':
|
||||
case 3:
|
||||
mi->rli.relay_log.description_event_for_queue= new
|
||||
Format_description_log_event(1, mysql->server_version);
|
||||
break;
|
||||
case '4':
|
||||
case 4:
|
||||
mi->rli.relay_log.description_event_for_queue= new
|
||||
Format_description_log_event(3, mysql->server_version);
|
||||
break;
|
||||
@ -1113,10 +1114,10 @@ maybe it is a *VERY OLD MASTER*.");
|
||||
*/
|
||||
|
||||
/* redundant with rest of code but safer against later additions */
|
||||
if (*mysql->server_version == '3')
|
||||
if (version == 3)
|
||||
goto err;
|
||||
|
||||
if (*mysql->server_version == '4')
|
||||
if (version == 4)
|
||||
{
|
||||
master_res= NULL;
|
||||
if (!mysql_real_query(mysql,
|
||||
@ -1177,7 +1178,7 @@ inconsistency if replicated data deals with collation.");
|
||||
This check is only necessary for 4.x masters (and < 5.0.4 masters but
|
||||
those were alpha).
|
||||
*/
|
||||
if (*mysql->server_version == '4')
|
||||
if (version == 4)
|
||||
{
|
||||
master_res= NULL;
|
||||
if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) &&
|
||||
|
@ -4259,6 +4259,10 @@ static const char filename_safe_char[128]=
|
||||
|
||||
#define MY_FILENAME_ESCAPE '@'
|
||||
|
||||
/*
|
||||
note, that we cannot trust 'e' here, it's may be fake,
|
||||
see strconvert()
|
||||
*/
|
||||
static int
|
||||
my_mb_wc_filename(CHARSET_INFO *cs __attribute__((unused)),
|
||||
my_wc_t *pwc, const uchar *s, const uchar *e)
|
||||
@ -4280,7 +4284,7 @@ my_mb_wc_filename(CHARSET_INFO *cs __attribute__((unused)),
|
||||
return MY_CS_TOOSMALL3;
|
||||
|
||||
byte1= s[1];
|
||||
byte2= s[2];
|
||||
byte2= byte1 ? s[2] : 0;
|
||||
|
||||
if (byte1 >= 0x30 && byte1 <= 0x7F &&
|
||||
byte2 >= 0x30 && byte2 <= 0x7F)
|
||||
@ -4305,7 +4309,7 @@ my_mb_wc_filename(CHARSET_INFO *cs __attribute__((unused)),
|
||||
(byte2= hexlo(byte2)) >= 0)
|
||||
{
|
||||
int byte3= hexlo(s[3]);
|
||||
int byte4= hexlo(s[4]);
|
||||
int byte4= hexlo(s[3] ? s[4] : 0);
|
||||
if (byte3 >=0 && byte4 >=0)
|
||||
{
|
||||
*pwc= (byte1 << 12) + (byte2 << 8) + (byte3 << 4) + byte4;
|
||||
|
@ -5599,7 +5599,7 @@ static void test_date_dt()
|
||||
static void test_pure_coverage()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
MYSQL_BIND my_bind[1];
|
||||
MYSQL_BIND my_bind[2];
|
||||
int rc;
|
||||
ulong length;
|
||||
|
||||
@ -8275,7 +8275,7 @@ static void test_parse_error_and_bad_length()
|
||||
DIE_UNLESS(rc);
|
||||
if (!opt_silent)
|
||||
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
|
||||
rc= mysql_real_query(mysql, "SHOW DATABASES", 100);
|
||||
rc= mysql_real_query(mysql, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAAA"));
|
||||
DIE_UNLESS(rc);
|
||||
if (!opt_silent)
|
||||
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
|
||||
@ -8286,7 +8286,7 @@ static void test_parse_error_and_bad_length()
|
||||
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
DIE_UNLESS(stmt);
|
||||
rc= mysql_stmt_prepare(stmt, "SHOW DATABASES", 100);
|
||||
rc= mysql_stmt_prepare(stmt, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAA"));
|
||||
DIE_UNLESS(rc != 0);
|
||||
if (!opt_silent)
|
||||
fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
|
||||
@ -16272,7 +16272,8 @@ static void test_bug31669()
|
||||
rc= mysql_change_user(conn, "", "", "");
|
||||
DIE_UNLESS(rc);
|
||||
|
||||
memset(buff, 'a', sizeof(buff));
|
||||
memset(buff, 'a', sizeof(buff) - 1);
|
||||
buff[sizeof(buff) - 1]= 0;
|
||||
|
||||
mysql_close(conn);
|
||||
conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
|
||||
|
Reference in New Issue
Block a user