diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-04-04 11:35:10 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-04-04 11:35:10 +0200 |
commit | 87a452f6d5839f9702d41d00137350fe9a38a774 (patch) | |
tree | 03c9915b730fc88c5f2ff3c06b82d9be98286b77 | |
parent | e70ce465b7f4daf7124f442c95425ad66b92b527 (diff) | |
download | mariadb-git-87a452f6d5839f9702d41d00137350fe9a38a774.tar.gz |
MDEV-4088 Replication 10.0 -> 5.5 fails
update 5.1 to replicate from 10.0 and
to show the server version (as of 10.0) correctly
sql-common/client.c:
mdev:4088
sql/slave.cc:
use the version number, not just the first character of the version string
(we want 10 > 4 not "10" < "4").
-rw-r--r-- | include/mysql_com.h | 27 | ||||
-rw-r--r-- | sql-common/client.c | 6 | ||||
-rw-r--r-- | sql/slave.cc | 19 |
3 files changed, 43 insertions, 9 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h index 96eb8f21d3f..d39414bbea6 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -27,6 +27,31 @@ #define NAME_LEN (NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN) #define USERNAME_LENGTH (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN) +/* + 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 @@ -145,6 +170,8 @@ enum enum_server_command #define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ #define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ +#define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */ + #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) #define CLIENT_REMEMBER_OPTIONS (1UL << 31) diff --git a/sql-common/client.c b/sql-common/client.c index 53642b65be7..a1f3909c023 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2264,6 +2264,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; + /* Part 2: format and send client info to the server for access check */ diff --git a/sql/slave.cc b/sql/slave.cc index 1a5dd9c4395..d401eacc9df 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -872,6 +872,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"); /* @@ -892,20 +893,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; @@ -1069,10 +1070,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, @@ -1133,7 +1134,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")) && |