Li Bing, hello.
So #support is indeed unhappy about the current version of
SHOW SLAVE HOSTS incl behaviour of --report-host.
I am okay with your current patch.
In order this work to converge in something very good we need to
create We need to create a WL addressing #support guys'
items and where --report-host will be a part of.
But approving does not have to depend on the new
WL. This feature has to go away.
Please find attached my discussion on #support. If you will find time to compose
a WL out of it and your expirence with the source code, please go ahead.
Thanks for working on it!
Andrei
<andrei> Guys, esp those who are into replication, HarrisonF, Jorgen,
Oli, Sveta, Axel, Susanne - there is Bug#13963 which claims to
change the current behavior of --report-host server
param/global var. Personally I would not do that unless there
was consensus of the fixer and you. The essence is the bug
reporter offered to display in `SHOW SLAVE HOSTS' all
connected slaves whereas the docs specify only ones that
started with --report-host. What
<andrei> would you say?
[16:13]<HarrisonF> andrei, i think a decision needs to be made about the SHOW
SLAVE HOSTS command
<HarrisonF> andrei, the way it is currently, it is pretty useless
<andrei> HarrisonF, what specifically?
<HarrisonF> andrei, the above behavior is the primary thing
<axel> andrei: this feature request makes much sense IMHO. I'd like
SHOW SLAVE HOSTS to show a) all connected slaves, regardless if
they have report-host set or not. Both the real host/ip and the
reported should be shown. And optionally b) slaves that
connected earlier but are disconnected ATM
<Leith> axel++
[16:17]<HarrisonF> andrei, SHOW SLAVE HOSTS really is very rare in usage
<HarrisonF> andrei, it just doesn't really do anything useful right now
<axel> andrei: "SHOW SLAVE HOSTS really is very rare in usage" <- I
think this is because it is so useless, as it is now
<HarrisonF> andrei, if it gave more information, such as list all
slaves, show their binary log coordinates for downloading,
show some stats regarding connections, speed, etc... it
would be useful, but in it's current incarnation it isn't
very useful
[16:19]<HarrisonF> andrei, so that is why i said a decision needs to be made
whether to make it useful or not, since it seems like a lot
more work than just making all slaves show up there
<axel> andrei: SHOW SLAVE HOSTS would be helpful for MEM and related
monitoring tools. But then it must show *all* connected
slaves. And preferrably it should display a reason why a slave
is disconnected (AFAIU this is not possible)
[16:20]<andrei> HarrisonF, axel: i got it. You are for making it be more
informative.
* axel gives andrei a cookie
> Li Bing, hello.
>
>
>> #At file:///home/anders/work/bzrwork/September/bug13963/mysql-next-bugfixing/
> based on revid:alik@stripped
>>
>> 2818 Li-Bing.Song@stripped 2009-09-28
>> Bug #13963 SHOW SLAVE HOSTS is unreliable
>>
>> Before the patch, slaves only appear in the output of SHOW SLAVE HOSTS
>> when report-host option is set. If an expected slave does not appear in
>> the list, nobody knows whether the slave does not connect or has started
>> without the "report-host" option. The output also contains a strange
>> field "Rpl_recovery_rank" which has never been implemented and the manual
>> of MySQL6.0 declares that the field has been removed from MySQL6.0.
>>
>
> While the writing above makes sense I still can not make up my mind about
> the issue.
> Indeed, I am not sure if `report-host' is designed on purpose to allow or disallow
> a slave server to particiapte in the `SHOW SLAVE HOSTS' report as
> lines of the docs clarify:
>
> * `--report-host=HOST_NAME'
>
> The host name or IP number of the slave to be reported to the
> master during slave registration. This value appears in the output
> of *note `SHOW SLAVE HOSTS': show-slave-hosts. on the master
> server. Leave the value unset if you do not want the slave to
> register itself with the master
>
>
> SHOW SLAVE HOSTS
>
> Displays a list of replication slaves currently registered with the
> master. Only slaves started with the `--report-host=HOST_NAME' option
> are visible in this list.
>
>
> In order to distinguish between
> ` the slave does not connect or has started without the "report-host" option'
> i wonder why not to start all slaves with --report-host?
> The docs say the report-host-not-supplied slave won't go into the list.
> Maybe some users like to have "invisible" slave too?
>
> I suggest to ask people on #support to make sure we are not overdoing something.
>
>
> cheers,
>
> Andrei
>
>
>> This patch is done with these,
>> According to the manual of MySQL5.4, "Rpl_recovery_rank" is removed.
>> Slaves will register themself to master no matter if report_host option is
> set
>> or not. When slaves are registering themselves, their Server_ids,
> report_host
>> and other information are together sent to master. Sever_ids are never null
>
>> and is unique in one replication group. Slaves always can be identified
> with
>> different Server_ids no matter if report_host exists.
>> @ mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result
>> 'Rpl_recovery_rank' field has been removed.
>> @ sql/repl_failsafe.cc
>> rpl_recovery_rank has been removed.
>> @ sql/slave.cc
>>
>>
>> added:
>> mysql-test/suite/rpl/r/rpl_show_slave_hosts.result
>> mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf
>> mysql-test/suite/rpl/t/rpl_show_slave_hosts.test
>> modified:
>> mysql-test/include/wait_show_condition.inc
>> mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result
>> sql/repl_failsafe.cc
>> sql/slave.cc
>> === modified file 'mysql-test/include/wait_show_condition.inc'
>> --- a/mysql-test/include/wait_show_condition.inc 2009-04-30 10:42:50 +0000
>> +++ b/mysql-test/include/wait_show_condition.inc 2009-09-28 14:24:36 +0000
>> @@ -2,20 +2,23 @@
>> #
>> # SUMMARY
>> #
>> -# Waits until the show statement ($show_statement) has at least within one
> of
>> -# the rows of the result set for the field ($field) a value which fulfils
>> +# Waits until the show statement ($show_statement) has one or all of the
>> +# rows of the result set for the field ($field) a value which fulfils
>> # a condition ($condition), or the operation times out.
>> #
>> #
>> # USAGE
>> #
>> +# All rows of the result must fulfil the condition if $all_rows_fulfil is 1
>> +# else at least one of the result must fulfil the condition.
>> +# let $all_rows_fulfil= 1;
>> # let $show_statement= SHOW PROCESSLIST;
>> # let $field= State;
>> # let $condition= = 'Updating';
>> # --source include/wait_show_condition.inc
>> #
>> # OR
>> -#
>> +#
>> # let $wait_timeout= 60; # Override default of 30 seconds with 60.
>> # let $show_statement= SHOW PROCESSLIST;
>> # let $field= State;
>> @@ -33,8 +36,9 @@ if ($wait_timeout)
>> {
>> let $max_run_time= $wait_timeout;
>> }
>> -# Reset $wait_timeout so that its value won't be used on subsequent
>> -# calls, and default will be used instead.
>> +
>> +# Reset $wait_timeout so that its value won't be used on subsequent calls, and
>> +# default will be used instead.
>> let $wait_timeout= 0;
>>
>> # The smallest timespan till UNIX_TIMESTAMP() gets incremented is ~0 seconds.
>> @@ -46,27 +50,56 @@ inc $max_run_time;
>>
>> let $found= 0;
>> let $max_end_time= `SELECT UNIX_TIMESTAMP() + $max_run_time`;
>> -while (`SELECT UNIX_TIMESTAMP() <= $max_end_time AND $found = 0`)
>> +
>> +if (`SELECT '$all_rows_fulfil' != '1'`)
>> +{
>> + while (`SELECT UNIX_TIMESTAMP() <= $max_end_time AND $found = 0`)
>> + {
>> + # Sleep a bit to avoid too heavy load.
>> + real_sleep 0.2;
>> + let $rowno= 1;
>> + let $process_result= 1;
>> + while (`SELECT $process_result = 1 AND $found = 0`)
>> + {
>> + let $field_value= query_get_value($show_statement, $field, $rowno);
>> + if (`SELECT '$field_value' $condition`)
>> + {
>> + let $found= 1;
>> + }
>> + if (`SELECT '$field_value' = 'No such row'`)
>> + {
>> + # We are behind the last row of the result set.
>> + let $process_result= 0;
>> + }
>> + inc $rowno;
>> + }
>> + }
>> +}
>> +
>> +if (`SELECT '$all_rows_fulfil' = '1'`)
>> {
>> - # Sleep a bit to avoid too heavy load.
>> - real_sleep 0.2;
>> - let $rowno= 1;
>> - let $process_result= 1;
>> - while (`SELECT $process_result = 1 AND $found = 0`)
>> - {
>> + while (`SELECT UNIX_TIMESTAMP() <= $max_end_time AND $found = 0`)
>> + {
>> + # Sleep a bit to avoid too heavy load.
>> + real_sleep 0.2;
>> + let $rowno= 1;
>> + let $process_result= 1;
>> + while (`SELECT $process_result = 1 AND $found = 0`)
>> + {
>> let $field_value= query_get_value($show_statement, $field, $rowno);
>> - if (`SELECT '$field_value' $condition`)
>> + if (`SELECT '$field_value' = 'No such row'`)
>> {
>> - let $found= 1;
>> + let $found= 1;
>> }
>> - if (`SELECT '$field_value' = 'No such row'`)
>> + if (`SELECT $found = 0 AND NOT '$field_value' $condition`)
>> {
>> - # We are behind the last row of the result set.
>> - let $process_result= 0;
>> + let process_result= 0;
>> }
>> inc $rowno;
>> - }
>> + }
>> + }
>> }
>> +
>> if (!$found)
>> {
>> echo # Timeout in include/wait_show_condition.inc for $wait_condition;
>>
>> === modified file 'mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result'
>> --- a/mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result 2008-11-04 17:07:14 +0000
>> +++ b/mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result 2009-09-28 14:24:36 +0000
>> @@ -13,8 +13,8 @@ n
>> 2001
>> 2002
>> show slave hosts;
>> -Server_id Host Port Rpl_recovery_rank Master_id
>> -2 127.0.0.1 9999 0 1
>> +Server_id Host Port Master_id
>> +2 127.0.0.1 9999 1
>> drop table t1;
>> stop slave;
>> create table t2(id int auto_increment primary key, created datetime);
>>
>> === added file 'mysql-test/suite/rpl/r/rpl_show_slave_hosts.result'
>> --- a/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result 1970-01-01 00:00:00
> +0000
>> +++ b/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result 2009-09-28 14:24:36
> +0000
>> @@ -0,0 +1,17 @@
>> +stop slave;
>> +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
>> +reset master;
>> +reset slave;
>> +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
>> +start slave;
>> +RESET SLAVE;
>> +CHANGE MASTER TO master_host='127.0.0.1',master_port=13000,master_user='root';
>> +START SLAVE IO_THREAD;
>> +SHOW SLAVE HOSTS;
>> +Server_id Host Port Master_id
>> +3 slave2 3306 1
>> +2 13001 1
>> +STOP SLAVE IO_THREAD;
>> +SHOW SLAVE HOSTS;
>> +Server_id Host Port Master_id
>> +2 13001 1
>>
>> === added file 'mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf'
>> --- a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf 1970-01-01 00:00:00 +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.cnf 2009-09-28 14:24:36 +0000
>> @@ -0,0 +1,23 @@
>> +!include ../my.cnf
>> +
>> +[mysqld.1]
>> +server_id=1
>> +mysql-backup=1
>> +
>> +[mysqld.2]
>> +server_id=2
>> +mysql-backup=1
>> +report-host=
>> +report-user=
>> +
>> +[mysqld.3]
>> +server_id=3
>> +mysql-backup=1
>> +report-host=slave2
>> +slave-net-timeout=5
>> +
>> +[ENV]
>> +SLAVE_MYPORT2= @mysqld.3.port
>> +SLAVE_MYSOCK2= @mysqld.3.socket
>> +
>> +
>>
>> === added file 'mysql-test/suite/rpl/t/rpl_show_slave_hosts.test'
>> --- a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test 1970-01-01 00:00:00 +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test 2009-09-28 14:24:36 +0000
>> @@ -0,0 +1,44 @@
>> +###############################################################################
>> +# Bug#13963 SHOW SLAVE HOSTS is unreliable
>> +#
>> +# Slaves only appear in the output of SHOW SLAVE HOSTS when report-host option
>> +# is set. If an expected slave does not appear in the list, nobody knows
>> +# whether the slave does not connect or has started without the "report-host"
>> +# option.
>> +#
>> +# Remove the "Rpl_recovery_rank" column from SHOW SLAVE HOSTS, It is not
>> +# implemented.
>> +#######################################################################
>> +source include/master-slave.inc;
>> +connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT2,);
>> +
>> +connection slave2;
>> +RESET SLAVE;
>> +--eval CHANGE MASTER TO
> master_host='127.0.0.1',master_port=$MASTER_MYPORT,master_user='root'
>> +START SLAVE IO_THREAD;
>> +source include/wait_for_slave_io_to_start.inc;
>> +
>> +connection master;
>> +let $show_statement= SHOW SLAVE HOSTS;
>> +let $field= Server_id;
>> +# 3 is server_id of slave2.
>> +let $connection= ='3';
>> +source include/wait_show_condition.inc;
>> +SHOW SLAVE HOSTS;
>> +
>> +connection slave2;
>> +STOP SLAVE IO_THREAD;
>> +source include/wait_for_slave_io_to_stop.inc;
>> +
>> +connection master;
>> +let $show_statement= SHOW SLAVE HOSTS;
>> +let $field= Server_id;
>> +# 3 is server_id of slave2.
>> +let $condition= <> '3';
>> +# All rows of 'SHOW SLAVE HOSTS' are not equal to 3. It mean that master has
>> +# knew the leave of slave2 and has unregistered it.
>> +let $all_rows_fulfil= 1;
>> +source include/wait_show_condition.inc;
>> +SHOW SLAVE HOSTS;
>> +
>> +source include/master-slave-end.inc;
>>
>> === modified file 'sql/repl_failsafe.cc'
>> --- a/sql/repl_failsafe.cc 2009-05-15 13:45:06 +0000
>> +++ b/sql/repl_failsafe.cc 2009-09-28 14:24:36 +0000
>> @@ -183,12 +183,11 @@ int register_slave(THD* thd, uchar* pack
>> 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'");
>> - if (p+10 > p_end)
>> + /*6 is the total length of port and master_id*/
>> + if (p+6 != p_end)
>> goto err;
>> si->port= uint2korr(p);
>> p += 2;
>> - si->rpl_recovery_rank= uint4korr(p);
>> - p += 4;
>> if (!(si->master_id= uint4korr(p)))
>> si->master_id= server_id;
>> si->thd= thd;
>> @@ -670,8 +669,6 @@ bool show_slave_hosts(THD* thd)
>> field_list.push_back(new Item_empty_string("Password",20));
>> }
>> field_list.push_back(new Item_return_int("Port", 7, MYSQL_TYPE_LONG));
>> - field_list.push_back(new Item_return_int("Rpl_recovery_rank", 7,
>> - MYSQL_TYPE_LONG));
>> field_list.push_back(new Item_return_int("Master_id", 10,
>> MYSQL_TYPE_LONG));
>>
>> @@ -693,7 +690,6 @@ bool show_slave_hosts(THD* thd)
>> protocol->store(si->password, &my_charset_bin);
>> }
>> protocol->store((uint32) si->port);
>> - protocol->store((uint32) si->rpl_recovery_rank);
>> protocol->store((uint32) si->master_id);
>> if (protocol->write())
>> {
>>
>> === modified file 'sql/slave.cc'
>> --- a/sql/slave.cc 2009-09-14 16:03:38 +0000
>> +++ b/sql/slave.cc 2009-09-28 14:24:36 +0000
>> @@ -1672,28 +1672,48 @@ int register_slave_on_master(MYSQL* mysq
>> bool *suppress_warnings)
>> {
>> uchar buf[1024], *pos= buf;
>> - uint report_host_len, report_user_len=0, report_password_len=0;
>> + uint report_host_len=0, report_user_len=0, report_password_len=0;
>> DBUG_ENTER("register_slave_on_master");
>>
>> *suppress_warnings= FALSE;
>> - if (!report_host)
>> + if (report_host)
>> + report_host_len= strlen(report_host);
>> + if (report_host_len > HOSTNAME_LENGTH)
>> + {
>> + sql_print_warning("The length of report_host is %d. "
>> + "It is larger than the max length(%d), so this "
>> + "slave cannot be registered to the master.",
>> + report_host_len, HOSTNAME_LENGTH);
>> DBUG_RETURN(0);
>> - report_host_len= strlen(report_host);
>> + }
>> +
>> if (report_user)
>> report_user_len= strlen(report_user);
>> + if (report_user_len > USERNAME_LENGTH)
>> + {
>> + sql_print_warning("The length of report_user is %d. "
>> + "It is larger than the max length(%d), so this "
>> + "slave cannot be registered to the master.",
>> + report_user_len, USERNAME_LENGTH);
>> + DBUG_RETURN(0);
>> + }
>> +
>> if (report_password)
>> report_password_len= strlen(report_password);
>> - /* 30 is a good safety margin */
>> - if (report_host_len + report_user_len + report_password_len + 30 >
>> - sizeof(buf))
>> - DBUG_RETURN(0); // safety
>> + if (report_password_len > MAX_PASSWORD_LENGTH)
>> + {
>> + sql_print_warning("The length of report_password is %d. "
>> + "It is larger than the max length(%d), so this "
>> + "slave cannot be registered to the master.",
>> + report_password_len, MAX_PASSWORD_LENGTH);
>> + DBUG_RETURN(0);
>> + }
>>
>> int4store(pos, server_id); pos+= 4;
>> pos= net_store_data(pos, (uchar*) report_host, report_host_len);
>> 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;
>> - int4store(pos, rpl_recovery_rank); pos+= 4;
>> /* The master will fill in master_id */
>> int4store(pos, 0); pos+= 4;
>>
>>
>>
>> # Bazaar merge directive format 2 (Bazaar 0.90)
>> # revision_id: li-bing.song@stripped
>> # target_branch: file:///home/anders/work/bzrwork/September/bug13963\
>> # /mysql-next-bugfixing/
>> # testament_sha1: b720703fab11b87412b57c590694c3aca54ba1e1
>> # timestamp: 2009-09-28 22:24:49 +0800
>> # base_revision_id: alik@stripped
>> #
>> # Begin bundle
>> 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
>> hIVQx45A