Commit 845d7e1e authored by Luis Soares's avatar Luis Soares

BUG#49259: Slave I/O thread could not register on master

The slave thread changed the format of the information it used to
connect to the master after patch for BUG 13963.  This resulted
in old master getting confused, thence rejecting the slave
connection attempt.

In particular, patch for BUG 13963 removed the rpl_recovery_rank
variable which was, at that time, packed together with the rest
of the information which the slave would use to register itself
on the master. Based on this data, the master would then assert
that the number of bytes received in the connection command was
consistent to what it was expecting. 

Therefore, given that a slave, patched with the aforementioned
patch, would not pack the four bytes related to the
rpl_recovery_rank variable, the old master would reject the
connection attempt. It would assume that the data was
inconsistent (fewer bytes than it was expecting) and return 
an error.

We fix this by faking an rpl_recovery_rank variable when
registering the slave on the master. In practice this reverts a
small part of patch for BUG 13963, the one related to the slave
connecting to the master.
parent 0758893a
......@@ -183,11 +183,18 @@ int register_slave(THD* thd, uchar* packet, uint packet_length)
get_object(p,si->host, "Failed to register slave: too long 'report-host'");
get_object(p,si->user, "Failed to register slave: too long 'report-user'");
get_object(p,si->password, "Failed to register slave; too long 'report-password'");
/*6 is the total length of port and master_id*/
if (p+6 != p_end)
if (p+10 > p_end)
goto err;
si->port= uint2korr(p);
p += 2;
/*
We need to by pass the bytes used in the fake rpl_recovery_rank
variable. It was removed in patch for BUG#13963. But this would
make a server with that patch unable to connect to an old master.
See: BUG#49259
*/
// si->rpl_recovery_rank= uint4korr(p);
p += 4;
if (!(si->master_id= uint4korr(p)))
si->master_id= server_id;
si->thd= thd;
......
......@@ -1612,6 +1612,12 @@ int register_slave_on_master(MYSQL* mysql, Master_info *mi,
pos= net_store_data(pos, (uchar*) report_user, report_user_len);
pos= net_store_data(pos, (uchar*) report_password, report_password_len);
int2store(pos, (uint16) report_port); pos+= 2;
/*
Fake rpl_recovery_rank, which was removed in BUG#13963,
so that this server can register itself on old servers,
see BUG#49259.
*/
int4store(pos, /* rpl_recovery_rank */ 0); pos+= 4;
/* The master will fill in master_id */
int4store(pos, 0); pos+= 4;
......
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