List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:May 26 2011 11:30am
Subject:bzr commit into mysql-trunk branch (alfranio.correia:3115) Bug#12334346
View as plain text  
#At file:///home/acorreia/workspace.oracle/repository.mysql/bzrwork/bug-12334346/mysql-trunk/ based on revid:dmitry.shulga@stripped

 3115 Alfranio Correia	2011-05-26
      BUG#12334346
      
      Master_Id in the slave_master_info and slave_relay_log_info tables was
      wrongly refering to the slave's id. 
      
      To fix this problem, we have removed the Master_Id from both tables. In
      the master info table, we have used the host and port to uniquely point
      to a row. We also have identified that there is no need bind the relay
      log info table to a master and we have decided to use an internal id to
      uniquely point to a row.
     @ mysql-test/suite/funcs_1/r/is_columns_mysql.result
        Updated test case after changing the slave_master_info and slave_relay_log_info.
     @ mysql-test/suite/funcs_1/r/is_key_column_usage.result
        Updated test case after changing the slave_master_info and slave_relay_log_info.
     @ mysql-test/suite/funcs_1/r/is_statistics.result
        Updated test case after changing the slave_master_info and slave_relay_log_info.
     @ mysql-test/suite/funcs_1/r/is_statistics_mysql.result
        Updated test case after changing the slave_master_info and slave_relay_log_info.
     @ mysql-test/suite/rpl/r/rpl_migration_crash_safe.result
        Updated the test case to test if it is possible use START SLAVE,
        STOP SLAVE, RESET or CHANGE MASTER when by mistake a wrong
        repository was manually introduced.
     @ mysql-test/suite/rpl/r/rpl_row_crash_safe.result
        Updated test case after changing the slave_master_info and slave_relay_log_info.
     @ mysql-test/suite/rpl/r/rpl_stm_mixed_crash_safe.result
        Updated test case after changing the slave_master_info and slave_relay_log_info.
     @ mysql-test/suite/rpl/t/rpl_migration_crash_safe.test
        Updated the test case to test if it is possible use START SLAVE,
        STOP SLAVE, RESET or CHANGE MASTER when by mistake a wrong
        repository was manually introduced.
     @ mysql-test/suite/sys_vars/r/master_info_repository_basic.result
        Updated test case that replication is not configured.
     @ mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result
        Updated test case that replication is not configured.
     @ mysql-test/suite/sys_vars/t/master_info_repository_basic.test
        Updated test case that replication is not configured.
     @ mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test
        Updated test case that replication is not configured.
     @ scripts/mysql_system_tables.sql
        Changed slave_master_info:
        
           . Master_id was removed.
           . Host has changed from TEXT to CHAR(64).
           . The primary key is (Host, Port).
        
        Changed the slave_relay_log_info:
        
           . Master_id was removed.
           . The field Id, an artificial key was introduced.
           . The primary key is (Id).
     @ sql/rpl_info.h
        This files has:
          Changed INVALID_INFO_REPOSITORY to a positive value as it is
          manipulated as an unsigned integer.
        
          . Introduced a function to clean up the repository without dropping it.
            For example, if the repository is a table, rows will be delete but
            the table will not be dropped.
     @ sql/rpl_info_factory.cc
        Introduced functions to scan the master info and relay log info
        repositories and retrieve the number of instances and correctly
        initialize the repositories based on such information.
     @ sql/rpl_info_factory.h
        Introduced functions to scan the master info and relay log info
        repositories and retrieve the number of instances.
     @ sql/rpl_info_file.cc
        This file has:
          . Introduced a function to count the number of files used as
            repositories. Currently, it should be at most one file.
          . Introduced a function to truncate a file.
     @ sql/rpl_info_file.h
        This file has:
          . Introduced a function to count the number of files used as
            repositories. Currently, it should be at most one file.
          . Introduced a function to truncate a file.
     @ sql/rpl_info_handler.h
        Introduced a function to clean up the repository without dropping it.
        For example, if the repository is a table, rows will be delete but
        the table will not be dropped.
     @ sql/rpl_info_table.cc
        This file has:
          . Introduced a function to count the number of rows in a table.
          . Introduced a function to remove rows without dropping the
            table.
          . The function do_remove_info() should remove rows and drop
            the table but we have decide to not do so, as currently such
            tables belong to the mysql schema.
          . Removed field_idx as the primary key is automatically discovered
            after this patch.
          . Introduced instance which indicates what is the row that shall
            be retrieved through the table scan.
        
        In particular, cursor was set to 1 to skip retrieving the Master_Id
        in the tables as it was set by the application, i.e. relay log info
        and master info and were not really members. This not necessary
        anymore.
     @ sql/rpl_info_table.h
        This file has:
          . Introduced a function to count the number of rows in a table.
          . Introduced a function to remove rows without dropping the
            table.
          . The function do_remove_info() should remove rows and drop
            the table but we have decide to not do so, as currently such
            tables belong to the mysql schema.
          . Removed field_idx as the primary key is automatically discovered
            after this patch.
          . Introduced instance which indicates what is the row that shall
            be retrieved through the table scan.
     @ sql/rpl_info_table_access.cc
        This file has:
          . Introduced a function to return a pointer to a row through
            a table scan.
          . Introduced a function to count the number of rows in a table.
          . Changed the find_info that returns a pointer to a row through
            a table scan.
        
        In particular, the find_info, automatically figures out what is
        the primary key in place, and uses it to fetch a pointer to the
        correspondent row.
     @ sql/rpl_info_table_access.h
        This file has:
          . Introduced a function to return a pointer to a row through
            a table scan.
          . Introduced a function to count the number of rows in a table.
          . Changed the signature of find_info that returns a pointer to
            a row through a table scan.
     @ sql/rpl_info_values.h
        Transformed the comment in a doxygen comment.
     @ sql/rpl_mi.h
        Transformed get_number_info_mi_fields() in a static method.
     @ sql/rpl_rli.cc
        This file has:
          . Introduced an internal_id that uniquely identifies a relay
            log instance/entry.
          . Moved LINES_IN_RELAY_LOG_INFO_WITH_DELAY to an enum anonymous.
     @ sql/rpl_rli.h
        This file has:
          . Transformed get_number_info_rli_fields() in a static method.
          . Introduced an internal_id that uniquely identifies a relay
            log instance/entry.
          . Moved LINES_IN_RELAY_LOG_INFO_WITH_DELAY to an enum anonymous
            at rpl_rli.cc
     @ sql/rpl_slave.cc
        We need to clean the respository otherwise there will be different
        entries as the key is about to change.
        
        Reset information in the repository without dropping the repository
        what may happen if we had called remove_info(). This is necessary
        because the primary key, i.e. host or port, has changed.
        
        The repository does not support direct changes on the primary key,
        so the row is dropped and re-inserted with a new primary key. If we
        don't do that, the master info repository we will end up with several
        rows. While the server was on-line this would not be a problem but
        after a server restart most likely replication would fail.
        
        Note that CHANGE MASTER is this case is not atomic and if a crash
        happens before flush_info() is called, there will be no entries in
        the repository.

    modified:
      mysql-test/suite/funcs_1/r/is_columns_mysql.result
      mysql-test/suite/funcs_1/r/is_key_column_usage.result
      mysql-test/suite/funcs_1/r/is_statistics.result
      mysql-test/suite/funcs_1/r/is_statistics_mysql.result
      mysql-test/suite/rpl/r/rpl_migration_crash_safe.result
      mysql-test/suite/rpl/r/rpl_row_crash_safe.result
      mysql-test/suite/rpl/r/rpl_stm_mixed_crash_safe.result
      mysql-test/suite/rpl/t/rpl_migration_crash_safe.test
      mysql-test/suite/sys_vars/r/master_info_repository_basic.result
      mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result
      mysql-test/suite/sys_vars/t/master_info_repository_basic.test
      mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test
      scripts/mysql_system_tables.sql
      sql/rpl_info.h
      sql/rpl_info_factory.cc
      sql/rpl_info_factory.h
      sql/rpl_info_file.cc
      sql/rpl_info_file.h
      sql/rpl_info_handler.h
      sql/rpl_info_table.cc
      sql/rpl_info_table.h
      sql/rpl_info_table_access.cc
      sql/rpl_info_table_access.h
      sql/rpl_info_values.h
      sql/rpl_mi.h
      sql/rpl_rli.cc
      sql/rpl_rli.h
      sql/rpl_slave.cc
=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result	2011-05-05 22:46:07 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result	2011-05-26 11:29:59 +0000
@@ -150,34 +150,33 @@ def	mysql	servers	Server_name	1		NO	char
 def	mysql	servers	Socket	7		NO	char	64	192	NULL	NULL	utf8	utf8_general_ci	char(64)			select,insert,update,references	
 def	mysql	servers	Username	4		NO	char	64	192	NULL	NULL	utf8	utf8_general_ci	char(64)			select,insert,update,references	
 def	mysql	servers	Wrapper	8		NO	char	64	192	NULL	NULL	utf8	utf8_general_ci	char(64)			select,insert,update,references	
-def	mysql	slave_master_info	Bind	18	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	Displays which interface is employed when connecting to the MySQL server
-def	mysql	slave_master_info	Connect_retry	9	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references	The period (in seconds) that the slave will wait before trying to reconnect to the master.
-def	mysql	slave_master_info	Enabled_ssl	10	NULL	NO	tinyint	NULL	NULL	3	0	NULL	NULL	tinyint(1)			select,insert,update,references	Indicates whether the server supports SSL connections.
-def	mysql	slave_master_info	Heartbeat	17	NULL	NO	float	NULL	NULL	12	NULL	NULL	NULL	float			select,insert,update,references	
-def	mysql	slave_master_info	Host	5	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The host name of the master.
-def	mysql	slave_master_info	Ignored_server_ids	19	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The number of server IDs to be ignored, followed by the actual server IDs
-def	mysql	slave_master_info	Master_id	1	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned	PRI		select,insert,update,references	
-def	mysql	slave_master_info	Master_log_name	3	NULL	NO	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the master binary log currently being read from the master.
-def	mysql	slave_master_info	Master_log_pos	4	NULL	NO	bigint	NULL	NULL	20	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references	The master log position of the last read event.
-def	mysql	slave_master_info	Number_of_lines	2	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references	Number of lines in the file.
-def	mysql	slave_master_info	Port	8	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references	The network port used to connect to the master.
-def	mysql	slave_master_info	Retry_count	21	NULL	NO	bigint	NULL	NULL	20	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references	Number of reconnect attempts, to the master, before giving up.
-def	mysql	slave_master_info	Ssl_ca	11	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The file used for the Certificate Authority (CA) certificate.
-def	mysql	slave_master_info	Ssl_capath	12	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The path to the Certificate Authority (CA) certificates.
-def	mysql	slave_master_info	Ssl_cert	13	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the SSL certificate file.
-def	mysql	slave_master_info	Ssl_cipher	14	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the cipher in use for the SSL connection.
-def	mysql	slave_master_info	Ssl_key	15	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the SSL key file.
-def	mysql	slave_master_info	Ssl_verify_server_cert	16	NULL	NO	tinyint	NULL	NULL	3	0	NULL	NULL	tinyint(1)			select,insert,update,references	Whether to verify the server certificate.
-def	mysql	slave_master_info	User_name	6	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The user name used to connect to the master.
-def	mysql	slave_master_info	User_password	7	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The password used to connect to the master.
-def	mysql	slave_master_info	Uuid	20	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The master server uuid.
-def	mysql	slave_relay_log_info	Master_id	1	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned	PRI		select,insert,update,references	
-def	mysql	slave_relay_log_info	Master_log_name	5	NULL	NO	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the master binary log file from which the events in the relay log file were read.
-def	mysql	slave_relay_log_info	Master_log_pos	6	NULL	NO	bigint	NULL	NULL	20	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references	The master log position of the last executed event.
-def	mysql	slave_relay_log_info	Number_of_lines	2	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references	Number of lines in the file or rows in the table. Used to version table definitions.
-def	mysql	slave_relay_log_info	Relay_log_name	3	NULL	NO	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the current relay log file.
-def	mysql	slave_relay_log_info	Relay_log_pos	4	NULL	NO	bigint	NULL	NULL	20	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references	The relay log position of the last executed event.
-def	mysql	slave_relay_log_info	Sql_delay	7	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(11)			select,insert,update,references	The number of seconds that the slave must lag behind the master.
+def	mysql	slave_master_info	Bind	17	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	Displays which interface is employed when connecting to the MySQL server
+def	mysql	slave_master_info	Connect_retry	8	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references	The period (in seconds) that the slave will wait before trying to reconnect to the master.
+def	mysql	slave_master_info	Enabled_ssl	9	NULL	NO	tinyint	NULL	NULL	3	0	NULL	NULL	tinyint(1)			select,insert,update,references	Indicates whether the server supports SSL connections.
+def	mysql	slave_master_info	Heartbeat	16	NULL	NO	float	NULL	NULL	12	NULL	NULL	NULL	float			select,insert,update,references	
+def	mysql	slave_master_info	Host	4		NO	char	64	192	NULL	NULL	utf8	utf8_bin	char(64)	PRI		select,insert,update,references	The host name of the master.
+def	mysql	slave_master_info	Ignored_server_ids	18	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The number of server IDs to be ignored, followed by the actual server IDs
+def	mysql	slave_master_info	Master_log_name	2	NULL	NO	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the master binary log currently being read from the master.
+def	mysql	slave_master_info	Master_log_pos	3	NULL	NO	bigint	NULL	NULL	20	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references	The master log position of the last read event.
+def	mysql	slave_master_info	Number_of_lines	1	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references	Number of lines in the file.
+def	mysql	slave_master_info	Port	7	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned	PRI		select,insert,update,references	The network port used to connect to the master.
+def	mysql	slave_master_info	Retry_count	20	NULL	NO	bigint	NULL	NULL	20	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references	Number of reconnect attempts, to the master, before giving up.
+def	mysql	slave_master_info	Ssl_ca	10	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The file used for the Certificate Authority (CA) certificate.
+def	mysql	slave_master_info	Ssl_capath	11	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The path to the Certificate Authority (CA) certificates.
+def	mysql	slave_master_info	Ssl_cert	12	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the SSL certificate file.
+def	mysql	slave_master_info	Ssl_cipher	13	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the cipher in use for the SSL connection.
+def	mysql	slave_master_info	Ssl_key	14	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the SSL key file.
+def	mysql	slave_master_info	Ssl_verify_server_cert	15	NULL	NO	tinyint	NULL	NULL	3	0	NULL	NULL	tinyint(1)			select,insert,update,references	Whether to verify the server certificate.
+def	mysql	slave_master_info	User_name	5	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The user name used to connect to the master.
+def	mysql	slave_master_info	User_password	6	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The password used to connect to the master.
+def	mysql	slave_master_info	Uuid	19	NULL	YES	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The master server uuid.
+def	mysql	slave_relay_log_info	Id	7	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned	PRI		select,insert,update,references	Internal Id that uniquely identifies this record.
+def	mysql	slave_relay_log_info	Master_log_name	4	NULL	NO	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the master binary log file from which the events in the relay log file were read.
+def	mysql	slave_relay_log_info	Master_log_pos	5	NULL	NO	bigint	NULL	NULL	20	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references	The master log position of the last executed event.
+def	mysql	slave_relay_log_info	Number_of_lines	1	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(10) unsigned			select,insert,update,references	Number of lines in the file or rows in the table. Used to version table definitions.
+def	mysql	slave_relay_log_info	Relay_log_name	2	NULL	NO	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references	The name of the current relay log file.
+def	mysql	slave_relay_log_info	Relay_log_pos	3	NULL	NO	bigint	NULL	NULL	20	0	NULL	NULL	bigint(20) unsigned			select,insert,update,references	The relay log position of the last executed event.
+def	mysql	slave_relay_log_info	Sql_delay	6	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(11)			select,insert,update,references	The number of seconds that the slave must lag behind the master.
 def	mysql	slow_log	db	7	NULL	NO	varchar	512	1536	NULL	NULL	utf8	utf8_general_ci	varchar(512)			select,insert,update,references	
 def	mysql	slow_log	insert_id	9	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(11)			select,insert,update,references	
 def	mysql	slow_log	last_insert_id	8	NULL	NO	int	NULL	NULL	10	0	NULL	NULL	int(11)			select,insert,update,references	
@@ -473,11 +472,10 @@ NULL	mysql	servers	Port	int	NULL	NULL	NU
 3.0000	mysql	servers	Socket	char	64	192	utf8	utf8_general_ci	char(64)
 3.0000	mysql	servers	Wrapper	char	64	192	utf8	utf8_general_ci	char(64)
 3.0000	mysql	servers	Owner	char	64	192	utf8	utf8_general_ci	char(64)
-NULL	mysql	slave_master_info	Master_id	int	NULL	NULL	NULL	NULL	int(10) unsigned
 NULL	mysql	slave_master_info	Number_of_lines	int	NULL	NULL	NULL	NULL	int(10) unsigned
 1.0000	mysql	slave_master_info	Master_log_name	text	65535	65535	utf8	utf8_bin	text
 NULL	mysql	slave_master_info	Master_log_pos	bigint	NULL	NULL	NULL	NULL	bigint(20) unsigned
-1.0000	mysql	slave_master_info	Host	text	65535	65535	utf8	utf8_bin	text
+3.0000	mysql	slave_master_info	Host	char	64	192	utf8	utf8_bin	char(64)
 1.0000	mysql	slave_master_info	User_name	text	65535	65535	utf8	utf8_bin	text
 1.0000	mysql	slave_master_info	User_password	text	65535	65535	utf8	utf8_bin	text
 NULL	mysql	slave_master_info	Port	int	NULL	NULL	NULL	NULL	int(10) unsigned
@@ -494,13 +492,13 @@ NULL	mysql	slave_master_info	Heartbeat	f
 1.0000	mysql	slave_master_info	Ignored_server_ids	text	65535	65535	utf8	utf8_bin	text
 1.0000	mysql	slave_master_info	Uuid	text	65535	65535	utf8	utf8_bin	text
 NULL	mysql	slave_master_info	Retry_count	bigint	NULL	NULL	NULL	NULL	bigint(20) unsigned
-NULL	mysql	slave_relay_log_info	Master_id	int	NULL	NULL	NULL	NULL	int(10) unsigned
 NULL	mysql	slave_relay_log_info	Number_of_lines	int	NULL	NULL	NULL	NULL	int(10) unsigned
 1.0000	mysql	slave_relay_log_info	Relay_log_name	text	65535	65535	utf8	utf8_bin	text
 NULL	mysql	slave_relay_log_info	Relay_log_pos	bigint	NULL	NULL	NULL	NULL	bigint(20) unsigned
 1.0000	mysql	slave_relay_log_info	Master_log_name	text	65535	65535	utf8	utf8_bin	text
 NULL	mysql	slave_relay_log_info	Master_log_pos	bigint	NULL	NULL	NULL	NULL	bigint(20) unsigned
 NULL	mysql	slave_relay_log_info	Sql_delay	int	NULL	NULL	NULL	NULL	int(11)
+NULL	mysql	slave_relay_log_info	Id	int	NULL	NULL	NULL	NULL	int(10) unsigned
 NULL	mysql	slow_log	start_time	timestamp	NULL	NULL	NULL	NULL	timestamp
 1.0000	mysql	slow_log	user_host	mediumtext	16777215	16777215	utf8	utf8_general_ci	mediumtext
 NULL	mysql	slow_log	query_time	time	NULL	NULL	NULL	NULL	time

=== modified file 'mysql-test/suite/funcs_1/r/is_key_column_usage.result'
--- a/mysql-test/suite/funcs_1/r/is_key_column_usage.result	2010-12-17 11:28:59 +0000
+++ b/mysql-test/suite/funcs_1/r/is_key_column_usage.result	2011-05-26 11:29:59 +0000
@@ -111,8 +111,9 @@ def	mysql	PRIMARY	def	mysql	proxies_priv
 def	mysql	PRIMARY	def	mysql	proxies_priv	Proxied_host
 def	mysql	PRIMARY	def	mysql	proxies_priv	Proxied_user
 def	mysql	PRIMARY	def	mysql	servers	Server_name
-def	mysql	PRIMARY	def	mysql	slave_master_info	Master_id
-def	mysql	PRIMARY	def	mysql	slave_relay_log_info	Master_id
+def	mysql	PRIMARY	def	mysql	slave_master_info	Host
+def	mysql	PRIMARY	def	mysql	slave_master_info	Port
+def	mysql	PRIMARY	def	mysql	slave_relay_log_info	Id
 def	mysql	PRIMARY	def	mysql	tables_priv	Host
 def	mysql	PRIMARY	def	mysql	tables_priv	Db
 def	mysql	PRIMARY	def	mysql	tables_priv	User

=== modified file 'mysql-test/suite/funcs_1/r/is_statistics.result'
--- a/mysql-test/suite/funcs_1/r/is_statistics.result	2010-12-17 11:28:59 +0000
+++ b/mysql-test/suite/funcs_1/r/is_statistics.result	2011-05-26 11:29:59 +0000
@@ -125,6 +125,7 @@ def	mysql	proxies_priv	mysql	PRIMARY
 def	mysql	proxies_priv	mysql	Grantor
 def	mysql	servers	mysql	PRIMARY
 def	mysql	slave_master_info	mysql	PRIMARY
+def	mysql	slave_master_info	mysql	PRIMARY
 def	mysql	slave_relay_log_info	mysql	PRIMARY
 def	mysql	tables_priv	mysql	PRIMARY
 def	mysql	tables_priv	mysql	PRIMARY

=== modified file 'mysql-test/suite/funcs_1/r/is_statistics_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_statistics_mysql.result	2010-12-17 11:28:59 +0000
+++ b/mysql-test/suite/funcs_1/r/is_statistics_mysql.result	2011-05-26 11:29:59 +0000
@@ -46,8 +46,9 @@ def	mysql	proxies_priv	0	mysql	PRIMARY	2
 def	mysql	proxies_priv	0	mysql	PRIMARY	3	Proxied_host	A	#CARD#	NULL	NULL		BTREE		
 def	mysql	proxies_priv	0	mysql	PRIMARY	4	Proxied_user	A	#CARD#	NULL	NULL		BTREE		
 def	mysql	servers	0	mysql	PRIMARY	1	Server_name	A	#CARD#	NULL	NULL		BTREE		
-def	mysql	slave_master_info	0	mysql	PRIMARY	1	Master_id	A	#CARD#	NULL	NULL		BTREE		
-def	mysql	slave_relay_log_info	0	mysql	PRIMARY	1	Master_id	A	#CARD#	NULL	NULL		BTREE		
+def	mysql	slave_master_info	0	mysql	PRIMARY	1	Host	A	#CARD#	NULL	NULL		BTREE		
+def	mysql	slave_master_info	0	mysql	PRIMARY	2	Port	A	#CARD#	NULL	NULL		BTREE		
+def	mysql	slave_relay_log_info	0	mysql	PRIMARY	1	Id	A	#CARD#	NULL	NULL		BTREE		
 def	mysql	tables_priv	1	mysql	Grantor	1	Grantor	A	#CARD#	NULL	NULL		BTREE		
 def	mysql	tables_priv	0	mysql	PRIMARY	1	Host	A	#CARD#	NULL	NULL		BTREE		
 def	mysql	tables_priv	0	mysql	PRIMARY	2	Db	A	#CARD#	NULL	NULL		BTREE		

=== modified file 'mysql-test/suite/rpl/r/rpl_migration_crash_safe.result'
--- a/mysql-test/suite/rpl/r/rpl_migration_crash_safe.result	2011-03-23 23:28:49 +0000
+++ b/mysql-test/suite/rpl/r/rpl_migration_crash_safe.result	2011-05-26 11:29:59 +0000
@@ -8,6 +8,19 @@ include/rpl_restart_server.inc [server_n
 SET @@GLOBAL.relay_log_info_repository= "TABLE";
 SET @@GLOBAL.relay_log_info_repository= "FILE";
 SET @@GLOBAL.relay_log_info_repository= "FILE";
+SET @@GLOBAL.relay_log_info_repository= "TABLE";
+include/start_slave.inc
+include/stop_slave.inc
+line one for the file
+line two for the file
+RESET SLAVE;
+line one for the file
+line two for the file
+change master to master_host='127.0.0.1', master_port=MASTER_PORT, master_user='root';
+line one for the file
+line two for the file
+SET @@GLOBAL.relay_log_info_repository= "FILE";
+DROP TABLE IF EXISTS test;
 include/start_slave.inc
 SET @@GLOBAL.relay_log_info_repository= "TABLE";
 ERROR HY000: This operation cannot be performed with a running slave; run STOP SLAVE first

=== modified file 'mysql-test/suite/rpl/r/rpl_row_crash_safe.result'
--- a/mysql-test/suite/rpl/r/rpl_row_crash_safe.result	2011-05-05 22:46:07 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_crash_safe.result	2011-05-26 11:29:59 +0000
@@ -14,27 +14,27 @@ include/stop_slave.inc
 SHOW CREATE TABLE mysql.slave_relay_log_info;
 Table	Create Table
 slave_relay_log_info	CREATE TABLE `slave_relay_log_info` (
-  `Master_id` int(10) unsigned NOT NULL,
   `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
   `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
   `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
   `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
   `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
   `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
-  PRIMARY KEY (`Master_id`)
+  `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
+  PRIMARY KEY (`Id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Relay Log Information'
 ALTER TABLE mysql.slave_relay_log_info ENGINE= Innodb;
 SHOW CREATE TABLE mysql.slave_relay_log_info;
 Table	Create Table
 slave_relay_log_info	CREATE TABLE `slave_relay_log_info` (
-  `Master_id` int(10) unsigned NOT NULL,
   `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
   `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
   `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
   `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
   `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
   `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
-  PRIMARY KEY (`Master_id`)
+  `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
+  PRIMARY KEY (`Id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Relay Log Information'
 include/start_slave.inc
 SET SQL_LOG_BIN=0;

=== modified file 'mysql-test/suite/rpl/r/rpl_stm_mixed_crash_safe.result'
--- a/mysql-test/suite/rpl/r/rpl_stm_mixed_crash_safe.result	2011-05-05 22:46:07 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stm_mixed_crash_safe.result	2011-05-26 11:29:59 +0000
@@ -14,27 +14,27 @@ include/stop_slave.inc
 SHOW CREATE TABLE mysql.slave_relay_log_info;
 Table	Create Table
 slave_relay_log_info	CREATE TABLE `slave_relay_log_info` (
-  `Master_id` int(10) unsigned NOT NULL,
   `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
   `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
   `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
   `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
   `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
   `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
-  PRIMARY KEY (`Master_id`)
+  `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
+  PRIMARY KEY (`Id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Relay Log Information'
 ALTER TABLE mysql.slave_relay_log_info ENGINE= Innodb;
 SHOW CREATE TABLE mysql.slave_relay_log_info;
 Table	Create Table
 slave_relay_log_info	CREATE TABLE `slave_relay_log_info` (
-  `Master_id` int(10) unsigned NOT NULL,
   `Number_of_lines` int(10) unsigned NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.',
   `Relay_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.',
   `Relay_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The relay log position of the last executed event.',
   `Master_log_name` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.',
   `Master_log_pos` bigint(20) unsigned NOT NULL COMMENT 'The master log position of the last executed event.',
   `Sql_delay` int(11) NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.',
-  PRIMARY KEY (`Master_id`)
+  `Id` int(10) unsigned NOT NULL COMMENT 'Internal Id that uniquely identifies this record.',
+  PRIMARY KEY (`Id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Relay Log Information'
 include/start_slave.inc
 SET SQL_LOG_BIN=0;

=== modified file 'mysql-test/suite/rpl/t/rpl_migration_crash_safe.test'
--- a/mysql-test/suite/rpl/t/rpl_migration_crash_safe.test	2011-03-23 23:28:49 +0000
+++ b/mysql-test/suite/rpl/t/rpl_migration_crash_safe.test	2011-05-26 11:29:59 +0000
@@ -42,10 +42,16 @@
 #   6.1. SET @GLOBAL.relay_log_info_repository=FILE is executed.
 #   6.2. Assertions AF1 and AF2 are verified.
 #
-# 7. Migration while slave is running by using SET
-#   7.1  Slave is started.
-#   7.2. SET @GLOBAL.relay_log_info_repository=FILE is executed and fails.
-#   7.3. Assertions AF1 and AF2 are verified.
+# 7. Migration from FILE TO TABLE/TABLE to FILE with duplicated repositories.
+#   7.1. SET @GLOBAL.relay_log_info_repository=TABLE is executed.
+#   7.2. Assertions AT1 and AT2 are verified.
+#   7.3. SET @GLOBAL.relay_log_info_repository=FILE is executed.
+#   7.4. Assertions AF1 and AF2 are verified.
+#
+# 8. Migration while slave is running by using SET
+#   8.1  Slave is started.
+#   8.2. SET @GLOBAL.relay_log_info_repository=FILE is executed and fails.
+#   8.3. Assertions AF1 and AF2 are verified.
 #
 # 8. Check consistency
 #   8.1. The replication is started and the master is compared to the slave.
@@ -61,12 +67,14 @@
 --connection slave
 
 let $MYSQLD_DATADIR= `SELECT @@datadir`;
+let $has_information= "The mysql.slave_relay_log_info has information and this is not expected.";
+let $has_no_information= "The mysql.slave_relay_log_info has no information and this is not expected.";
 
 let $exp_slave= 0;
 let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
 if ($got_slave != $exp_slave)
 {
-  --echo "The mysql.slave_relay_log_info has information and this is not expected."
+  --echo $has_information
   --die
 }
 file_exists $MYSQLD_DATADIR/relay-log.info;
@@ -91,7 +99,7 @@ let $exp_slave= 1;
 let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
 if ($got_slave != $exp_slave)
 {
-  --echo "The mysql.slave_relay_log_info has no information and this is not expected."
+  --echo $has_no_information
   --die
 }
 --error 1
@@ -110,7 +118,7 @@ let $exp_slave= 0;
 let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
 if ($got_slave != $exp_slave)
 {
-  --echo "The mysql.slave_relay_log_info has information and this is not expected."
+  --echo $has_information
   --die
 }
 file_exists $MYSQLD_DATADIR/relay-log.info;
@@ -126,7 +134,7 @@ let $exp_slave= 1;
 let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
 if ($got_slave != $exp_slave)
 {
-  --echo "The mysql.slave_relay_log_info has no information and this is not expected."
+  --echo $has_no_information
   --die
 }
 --error 1
@@ -143,7 +151,7 @@ let $exp_slave= 0;
 let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
 if ($got_slave != $exp_slave)
 {
-  --echo "The mysql.slave_relay_log_info has information and this is not expected."
+  --echo $has_information
   --die
 }
 file_exists $MYSQLD_DATADIR/relay-log.info;
@@ -159,13 +167,107 @@ let $exp_slave= 0;
 let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
 if ($got_slave != $exp_slave)
 {
-  --echo "The mysql.slave_relay_log_info has information and this is not expected."
+  --echo $has_information
   --die
 }
 file_exists $MYSQLD_DATADIR/relay-log.info;
 
 ########################################################################################
-# 7. Migration while slave is running by using SET
+# 7. Migration FROM FILE TO TABLE/TABLE TO FILE by using SET with dup. repositories
+########################################################################################
+--connection slave
+
+#
+# This change the repository from FILE to TABLE.
+#
+SET @@GLOBAL.relay_log_info_repository= "TABLE";
+
+let $exp_slave= 1;
+let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
+if ($got_slave != $exp_slave)
+{
+  --echo $has_no_information
+  --die
+}
+--error 1
+file_exists $MYSQLD_DATADIR/relay-log.info;
+
+#
+# We simulate that a relay-log.info is copied by mistake.
+#
+write_file $MYSQL_$MYSQLD_DATADIR/relay-log.info;
+line one for the file
+line two for the file
+EOF
+
+#
+# Although there is a duplicate repository, this fact will be ingored
+# by an on-line server. The variable @@GLOBAL.relay_log_info_repository
+# determines the current repository and the other is simply ignored.
+#
+# So START, STOP, RESET and CHANGE MASTER will work as expected. Note
+# that the file repository is not updated.
+#
+--source include/start_slave.inc
+--source include/stop_slave.inc
+
+let $exp_slave= 1;
+let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
+if ($got_slave != $exp_slave)
+{
+  --echo $has_no_information
+  --die
+}
+cat_file $MYSQL_$MYSQLD_DATADIR/relay-log.info;
+
+RESET SLAVE;
+
+let $exp_slave= 0;
+let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
+if ($got_slave != $exp_slave)
+{
+  --echo $has_information
+  --die
+}
+cat_file $MYSQL_$MYSQLD_DATADIR/relay-log.info;
+
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval change master to master_host='127.0.0.1', master_port=$MASTER_MYPORT, master_user='root';
+
+let $exp_slave= 1;
+let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
+if ($got_slave != $exp_slave)
+{
+  --echo $has_no_information
+  --die
+}
+cat_file $MYSQL_$MYSQLD_DATADIR/relay-log.info;
+
+#
+# This change the repository from FILE to TABLE.
+#
+SET @@GLOBAL.relay_log_info_repository= "FILE";
+
+let $exp_slave= 0;
+let $got_slave= `SELECT COUNT(*) FROM mysql.slave_relay_log_info`;
+if ($got_slave != $exp_slave)
+{
+  --echo $has_information
+  --die
+}
+file_exists $MYSQLD_DATADIR/relay-log.info;
+
+#
+# It would be great if we could directly update mysql.slave_relay_log_info.
+# Please, change this test case after fixing BUG#60902.
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS test;
+--enable_warnings
+
+########################################################################################
+# 8. Migration while slave is running by using SET
 ########################################################################################
 --connection slave
 
@@ -175,7 +277,7 @@ file_exists $MYSQLD_DATADIR/relay-log.in
 SET @@GLOBAL.relay_log_info_repository= "TABLE";
 
 ########################################################################################
-# 8. Check consistency
+# 9. Check consistency
 ########################################################################################
 --connection master
 

=== modified file 'mysql-test/suite/sys_vars/r/master_info_repository_basic.result'
--- a/mysql-test/suite/sys_vars/r/master_info_repository_basic.result	2011-03-23 23:28:49 +0000
+++ b/mysql-test/suite/sys_vars/r/master_info_repository_basic.result	2011-05-26 11:29:59 +0000
@@ -1,3 +1,4 @@
+CALL mtr.add_suppression("The master info repository is not configured properly. Please, fix this before using replication.");
 '#---------------------BS_STVARS_002_01----------------------#'
 SELECT @@GLOBAL.master_info_repository;
 @@GLOBAL.master_info_repository

=== modified file 'mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result'
--- a/mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result	2011-03-23 23:28:49 +0000
+++ b/mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result	2011-05-26 11:29:59 +0000
@@ -1,3 +1,4 @@
+CALL mtr.add_suppression("The relay log info repository is not configured properly. Please, fix this before using replication.");
 '#---------------------BS_STVARS_002_01----------------------#'
 SELECT @@GLOBAL.relay_log_info_repository;
 @@GLOBAL.relay_log_info_repository

=== modified file 'mysql-test/suite/sys_vars/t/master_info_repository_basic.test'
--- a/mysql-test/suite/sys_vars/t/master_info_repository_basic.test	2011-03-23 23:28:49 +0000
+++ b/mysql-test/suite/sys_vars/t/master_info_repository_basic.test	2011-05-26 11:29:59 +0000
@@ -21,6 +21,8 @@
 ###############################################################################
 --source include/not_master_info_table.inc
 
+CALL mtr.add_suppression("The master info repository is not configured properly. Please, fix this before using replication.");
+
 --echo '#---------------------BS_STVARS_002_01----------------------#'
 ####################################################################
 #   Displaying default value                                       #

=== modified file 'mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test'
--- a/mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test	2011-03-23 23:28:49 +0000
+++ b/mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test	2011-05-26 11:29:59 +0000
@@ -21,6 +21,8 @@
 ###############################################################################
 --source include/not_relay_log_info_table.inc
 
+CALL mtr.add_suppression("The relay log info repository is not configured properly. Please, fix this before using replication.");
+
 --echo '#---------------------BS_STVARS_002_01----------------------#'
 ####################################################################
 #   Displaying default value                                       #

=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql	2011-05-05 22:46:07 +0000
+++ b/scripts/mysql_system_tables.sql	2011-05-26 11:29:59 +0000
@@ -100,9 +100,9 @@ CREATE TABLE IF NOT EXISTS event ( db ch
 
 CREATE TABLE IF NOT EXISTS ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;
 
-CREATE TABLE IF NOT EXISTS slave_relay_log_info (Master_id INTEGER UNSIGNED NOT NULL, Number_of_lines INTEGER UNSIGNED NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.', Relay_log_name TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.', Relay_log_pos BIGINT UNSIGNED NOT NULL COMMENT 'The relay log position of the last executed event.', Master_log_name TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.', Master_log_pos BIGINT UNSIGNED NOT NULL COMMENT 'The master log position of the last executed event.', Sql_delay INTEGER NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.', PRIMARY KEY(Master_id)) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT 'Relay Log Information';
+CREATE TABLE IF NOT EXISTS slave_relay_log_info (Number_of_lines INTEGER UNSIGNED NOT NULL COMMENT 'Number of lines in the file or rows in the table. Used to version table definitions.', Relay_log_name TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the current relay log file.', Relay_log_pos BIGINT UNSIGNED NOT NULL COMMENT 'The relay log position of the last executed event.', Master_log_name TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log file from which the events in the relay log file were read.', Master_log_pos BIGINT UNSIGNED NOT NULL COMMENT 'The master log position of the last executed event.', Sql_delay INTEGER NOT NULL COMMENT 'The number of seconds that the slave must lag behind the master.', Id INTEGER UNSIGNED NOT NULL COMMENT 'Internal Id that uniquely identifies this record.', PRIMARY KEY(Id)) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT 'Relay Log Information';
 
-CREATE TABLE IF NOT EXISTS slave_master_info (Master_id INTEGER UNSIGNED NOT NULL, Number_of_lines INTEGER UNSIGNED NOT NULL COMMENT 'Number of lines in the file.', Master_log_name TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log currently being read from the master.', Master_log_pos BIGINT UNSIGNED NOT NULL COMMENT 'The master log position of the last read event.', Host TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The host name of the master.', User_name TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The user name used to connect to the master.', User_password TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The password used to connect to the master.', Port INTEGER UNSIGNED NOT NULL COMMENT 'The network port used to connect to the master.', Connect_retry INTEGER UNSIGNED NOT NULL COMMENT 'The period (in seconds) that the slave will wait before trying to reconnect to the master.', Enabled_ssl BOOLEAN NOT NULL COMMENT 'In!
 dicates whether the server supports SSL connections.', Ssl_ca TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The file used for the Certificate Authority (CA) certificate.', Ssl_capath TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The path to the Certificate Authority (CA) certificates.', Ssl_cert TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the SSL certificate file.', Ssl_cipher TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the cipher in use for the SSL connection.', Ssl_key TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the SSL key file.', Ssl_verify_server_cert BOOLEAN NOT NULL COMMENT 'Whether to verify the server certificate.', Heartbeat FLOAT NOT NULL COMMENT '', Bind TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'Displays which interface is employed when connecting to the MySQL server', Ignored_server_ids TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The number of server IDs to be ignored, followed by the a!
 ctual server IDs', Uuid TEXT CHARACTER SET utf8 COLLATE utf8_bin COMME
NT 'The master server uuid.', Retry_count BIGINT UNSIGNED NOT NULL COMMENT 'Number of reconnect attempts, to the master, before giving up.', PRIMARY KEY(Master_id)) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT 'Master Information';
+CREATE TABLE IF NOT EXISTS slave_master_info (Number_of_lines INTEGER UNSIGNED NOT NULL COMMENT 'Number of lines in the file.', Master_log_name TEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'The name of the master binary log currently being read from the master.', Master_log_pos BIGINT UNSIGNED NOT NULL COMMENT 'The master log position of the last read event.', Host CHAR(64) CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The host name of the master.', User_name TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The user name used to connect to the master.', User_password TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The password used to connect to the master.', Port INTEGER UNSIGNED NOT NULL COMMENT 'The network port used to connect to the master.', Connect_retry INTEGER UNSIGNED NOT NULL COMMENT 'The period (in seconds) that the slave will wait before trying to reconnect to the master.', Enabled_ssl BOOLEAN NOT NULL COMMENT 'Indicates whether the server suppor!
 ts SSL connections.', Ssl_ca TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The file used for the Certificate Authority (CA) certificate.', Ssl_capath TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The path to the Certificate Authority (CA) certificates.', Ssl_cert TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the SSL certificate file.', Ssl_cipher TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the cipher in use for the SSL connection.', Ssl_key TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The name of the SSL key file.', Ssl_verify_server_cert BOOLEAN NOT NULL COMMENT 'Whether to verify the server certificate.', Heartbeat FLOAT NOT NULL COMMENT '', Bind TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'Displays which interface is employed when connecting to the MySQL server', Ignored_server_ids TEXT CHARACTER SET utf8 COLLATE utf8_bin COMMENT 'The number of server IDs to be ignored, followed by the actual server IDs', Uuid TEXT CHAR!
 ACTER SET utf8 COLLATE utf8_bin COMMENT 'The master server uuid.', Ret
ry_count BIGINT UNSIGNED NOT NULL COMMENT 'Number of reconnect attempts, to the master, before giving up.', PRIMARY KEY(Host, Port)) ENGINE=MYISAM DEFAULT CHARSET=utf8 COMMENT 'Master Information';
 
 --
 -- PERFORMANCE SCHEMA INSTALLATION

=== modified file 'sql/rpl_info.h'
--- a/sql/rpl_info.h	2011-04-28 16:50:10 +0000
+++ b/sql/rpl_info.h	2011-05-26 11:29:59 +0000
@@ -23,9 +23,13 @@
 
 enum enum_info_repository
 {
-  INVALID_INFO_REPOSITORY= -1,
   INFO_REPOSITORY_FILE= 0,
-  INFO_REPOSITORY_TABLE= 1
+  INFO_REPOSITORY_TABLE= 1,
+  /*
+    Add new types of repository before this
+    entry.
+  */
+  INVALID_INFO_REPOSITORY
 };
 
 class Rpl_info : public Slave_reporting_capability
@@ -115,6 +119,11 @@ public:
     return (handler->remove_info());
   }
 
+  int clean_info()
+  {
+    return (handler->clean_info());
+  }
+
   bool is_transactional()
   {
     return (handler->is_transactional());

=== modified file 'sql/rpl_info_factory.cc'
--- a/sql/rpl_info_factory.cc	2011-04-28 16:50:10 +0000
+++ b/sql/rpl_info_factory.cc	2011-05-26 11:29:59 +0000
@@ -18,6 +18,15 @@
 #include "rpl_slave.h"
 #include "rpl_info_factory.h"
 
+/*
+  This class has duplicated logic and code that should be removed after
+  the code becomes GA. Maybe we should simply the code while introducing
+  MTS what will require additional repositories and will generate more
+  duplicated code we one follows the current pattern.
+
+  / Alfranio
+*/
+
 /**
   Creates both a Master info and a Relay log info repository whose types are
   defined as parameters.
@@ -75,11 +84,20 @@ Master_info *Rpl_info_factory::create_mi
   Master_info* mi= NULL;
   Rpl_info_handler*  handler_src= NULL;
   Rpl_info_handler*  handler_dest= NULL;
+  uint instances= 0;
   const char *msg= "Failed to allocate memory for the master info "
                    "structure";
 
   DBUG_ENTER("Rpl_info_factory::create_mi");
 
+  /*
+    Checks how many occurrences of mi's repositories exist. For
+    example, if the repository is a table, this retrieves the
+    number of rows in it.
+  */
+  if (scan_mi_repositories(&instances, INVALID_INFO_REPOSITORY))
+    goto err;
+
   if (!(mi= new Master_info(
 #ifdef HAVE_PSI_INTERFACE
                             &key_master_info_run_lock,
@@ -93,7 +111,8 @@ Master_info *Rpl_info_factory::create_mi
                            )))
     goto err;
 
-  if(init_mi_repositories(mi, mi_option, &handler_src, &handler_dest, &msg))
+  if(init_mi_repositories(mi, mi_option, instances, &handler_src,
+                          &handler_dest, &msg))
     goto err;
 
   if (decide_repository(mi, mi_option, &handler_src, &handler_dest, &msg))
@@ -136,11 +155,20 @@ bool Rpl_info_factory::change_mi_reposit
 
   Rpl_info_handler*  handler_src= mi->get_rpl_info_handler();
   Rpl_info_handler*  handler_dest= NULL;
+  uint instances= 0;
 
   if (mi->get_rpl_info_type()  == mi_option)
     DBUG_RETURN(FALSE);
 
-  if (init_mi_repositories(mi, mi_option, NULL, &handler_dest, msg))
+  /*
+    Checks how many occurrences of mi's repositories exist. For
+    example, if the repository is a table, this retrieves the
+    number of rows in it.
+  */
+  if (scan_mi_repositories(&instances, mi->get_rpl_info_type()))
+    goto err;
+
+  if (init_mi_repositories(mi, mi_option, instances, NULL, &handler_dest, msg))
     goto err;
 
   if (change_repository(mi, mi_option, &handler_src, &handler_dest, msg))
@@ -176,11 +204,20 @@ Relay_log_info *Rpl_info_factory::create
   Relay_log_info *rli= NULL;
   Rpl_info_handler* handler_src= NULL;
   Rpl_info_handler* handler_dest= NULL;
+  uint instances= 0;
   const char *msg= "Failed to allocate memory for the relay log info "
                    "structure";
 
   DBUG_ENTER("Rpl_info_factory::create_rli");
 
+  /*
+    Checks how many occurrences of rli's repositories exist. For
+    example, if the repository is a table, this retrieves the
+    number of rows in it.
+  */
+  if (scan_rli_repositories(&instances, INVALID_INFO_REPOSITORY))
+    goto err;
+
   if (!(rli= new Relay_log_info(is_slave_recovery
 #ifdef HAVE_PSI_INTERFACE
                                 ,&key_relay_log_info_run_lock,
@@ -189,12 +226,14 @@ Relay_log_info *Rpl_info_factory::create
                                 &key_relay_log_info_data_cond,
                                 &key_relay_log_info_start_cond,
                                 &key_relay_log_info_stop_cond,
-                                &key_relay_log_info_sleep_cond
+                                &key_relay_log_info_sleep_cond,
 #endif
+                                static_cast<int>(instances)
                                )))
     goto err;
 
-  if(init_rli_repositories(rli, rli_option, &handler_src, &handler_dest, &msg))
+  if(init_rli_repositories(rli, rli_option, instances, &handler_src,
+                           &handler_dest, &msg))
     goto err;
 
   if (decide_repository(rli, rli_option, &handler_src, &handler_dest, &msg))
@@ -237,11 +276,21 @@ bool Rpl_info_factory::change_rli_reposi
 
   Rpl_info_handler*  handler_src= rli->get_rpl_info_handler();
   Rpl_info_handler*  handler_dest= NULL;
+  uint instances= 0;
 
   if (rli->get_rpl_info_type()  == rli_option)
     DBUG_RETURN(FALSE);
 
-  if (init_rli_repositories(rli, rli_option, NULL, &handler_dest, msg))
+  /*
+    Checks how many occurrences of rli's repositories exist. For
+    example, if the repository is a table, this retrieves the
+    number of rows in it.
+  */
+  if (scan_rli_repositories(&instances, rli->get_rpl_info_type()))
+    goto err;
+
+  if (init_rli_repositories(rli, rli_option, instances, NULL, &handler_dest,
+                            msg))
     goto err;
 
   if (change_repository(rli, rli_option, &handler_src, &handler_dest, msg))
@@ -290,10 +339,11 @@ bool Rpl_info_factory::decide_repository
                                          Rpl_info_handler **handler_dest,
                                          const char **msg)
 {
+  bool error= TRUE;
 
   DBUG_ENTER("Rpl_info_factory::decide_repository");
  
-  bool error= TRUE;
+  DBUG_ASSERT((*handler_dest) != NULL && (*handler_dest) != NULL);
   /*
     check_info() returns FALSE if the repository exists. If a FILE, 
     for example, this means that FALSE is returned if a file exists.
@@ -308,21 +358,9 @@ bool Rpl_info_factory::decide_repository
       . is_src  == TRUE, means that the source repository exists.
       . is_dest == TRUE, means that the destination repository
         exists.
-
-    /Alfranio
   */
   bool is_src= !((*handler_src)->check_info());
   bool is_dest= !((*handler_dest)->check_info());
-
-  DBUG_ASSERT((*handler_dest) != NULL && (*handler_dest) != NULL);
-  if (is_src && is_dest)
-  {
-    *msg= "Multiple replication metadata repository instances "
-          "found with data in them. Unable to decide which is "
-          "the correct one to choose";
-    DBUG_RETURN(error);
-  }
-
   if (!is_dest && is_src)
   {
     if ((*handler_src)->init_info() || (*handler_dest)->init_info())
@@ -445,8 +483,10 @@ err:
   Creates repositories that will be associated to the master info.
 
   @param[in] mi            Pointer to the class Master info.
-  @param[in] rli_option    Identifies the type of the repository that will
+  @param[in] mi_option     Identifies the type of the repository that will
                            be used, i.e., destination repository.
+  @param[in] mi_instance   Identifies the instance of the repository that
+                           will be used.
   @param[out] handler_src  Source repository from where information is
                            copied into the destination repository.
   @param[out] handler_dest Destination repository to where informaiton is
@@ -458,6 +498,7 @@ err:
 */
 bool Rpl_info_factory::init_mi_repositories(Master_info *mi,
                                             uint mi_option,
+                                            uint instance,
                                             Rpl_info_handler **handler_src,
                                             Rpl_info_handler **handler_dest,
                                             const char **msg)
@@ -471,22 +512,24 @@ bool Rpl_info_factory::init_mi_repositor
   switch (mi_option)
   {
     case INFO_REPOSITORY_FILE:
-      if (!(*handler_dest= new Rpl_info_file(mi->get_number_info_mi_fields(),
-                                             master_info_file)))
+      if (!(*handler_dest= new Rpl_info_file(Master_info::get_number_info_mi_fields(),
+                                             master_info_file, instance)))
         goto err;
       if (handler_src &&
-          !(*handler_src= new Rpl_info_table(mi->get_number_info_mi_fields() + 1,
-                                             MI_FIELD_ID, MYSQL_SCHEMA_NAME.str, MI_INFO_NAME.str)))
+          !(*handler_src= new Rpl_info_table(Master_info::get_number_info_mi_fields(),
+                                             MYSQL_SCHEMA_NAME.str,
+                                             MI_INFO_NAME.str, instance)))
         goto err;
     break;
 
     case INFO_REPOSITORY_TABLE:
-      if (!(*handler_dest= new Rpl_info_table(mi->get_number_info_mi_fields() + 1,
-                                              MI_FIELD_ID, MYSQL_SCHEMA_NAME.str, MI_INFO_NAME.str)))
+      if (!(*handler_dest= new Rpl_info_table(Master_info::get_number_info_mi_fields(),
+                                              MYSQL_SCHEMA_NAME.str,
+                                              MI_INFO_NAME.str, instance)))
         goto err;
       if (handler_src &&
-          !(*handler_src= new Rpl_info_file(mi->get_number_info_mi_fields(),
-                                            master_info_file)))
+          !(*handler_src= new Rpl_info_file(Master_info::get_number_info_mi_fields(),
+                                            master_info_file, instance)))
         goto err;
     break;
     default:
@@ -504,6 +547,8 @@ err:
   @param[in] rli           Pointer to the class Relay_log_info.
   @param[in] rli_option    Identifies the type of the repository that will
                            be used, i.e., destination repository.
+  @param[in] mi_instance   Identifies the instance of the repository that
+                           will be used.
   @param[out] handler_src  Source repository from where information is
                            copied into the destination repository.
   @param[out] handler_dest Destination repository to where informaiton is
@@ -515,6 +560,7 @@ err:
 */
 bool Rpl_info_factory::init_rli_repositories(Relay_log_info *rli,
                                              uint rli_option,
+                                             uint instance,
                                              Rpl_info_handler **handler_src,
                                              Rpl_info_handler **handler_dest,
                                              const char **msg)
@@ -528,22 +574,24 @@ bool Rpl_info_factory::init_rli_reposito
   switch (rli_option)
   {
     case INFO_REPOSITORY_FILE:
-      if (!(*handler_dest= new Rpl_info_file(rli->get_number_info_rli_fields(),
-                                             relay_log_info_file)))
+      if (!(*handler_dest= new Rpl_info_file(Relay_log_info::get_number_info_rli_fields(),
+                                             relay_log_info_file, instance)))
         goto err;
       if (handler_src &&
-          !(*handler_src= new Rpl_info_table(rli->get_number_info_rli_fields() + 1,
-                                             RLI_FIELD_ID, MYSQL_SCHEMA_NAME.str, RLI_INFO_NAME.str)))
+          !(*handler_src= new Rpl_info_table(Relay_log_info::get_number_info_rli_fields(),
+                                             MYSQL_SCHEMA_NAME.str,
+                                             RLI_INFO_NAME.str, instance)))
         goto err;
     break;
 
     case INFO_REPOSITORY_TABLE:
-      if (!(*handler_dest= new Rpl_info_table(rli->get_number_info_rli_fields() + 1,
-                                              RLI_FIELD_ID, MYSQL_SCHEMA_NAME.str, RLI_INFO_NAME.str)))
+      if (!(*handler_dest= new Rpl_info_table(Relay_log_info::get_number_info_rli_fields(),
+                                              MYSQL_SCHEMA_NAME.str,
+                                              RLI_INFO_NAME.str, instance)))
         goto err;
       if (handler_src &&
-          !(*handler_src= new Rpl_info_file(rli->get_number_info_rli_fields(),
-                                            relay_log_info_file)))
+          !(*handler_src= new Rpl_info_file(Relay_log_info::get_number_info_rli_fields(),
+                                            relay_log_info_file, instance)))
         goto err;
     break;
     default:
@@ -553,4 +601,170 @@ bool Rpl_info_factory::init_rli_reposito
 
 err:
   DBUG_RETURN(error);
+}
+
+bool Rpl_info_factory::scan_mi_repositories(uint* instances, uint mi_option)
+{
+  bool error= FALSE;
+  uint file_instances= 0;
+  uint table_instances= 0;
+  Rpl_info_table* table= NULL;
+  Rpl_info_file* file= NULL;
+
+  DBUG_ENTER("Rpl_info_fact ry::scan_mi_repositories");
+
+  if (!(table= new Rpl_info_table(Master_info::get_number_info_mi_fields(),
+                                  MYSQL_SCHEMA_NAME.str, MI_INFO_NAME.str, 0)))
+  {
+    error= TRUE;
+    goto err;
+  }
+  if ((error= table->do_count_info(&table_instances)))
+    goto err;
+
+  if (!(file= new Rpl_info_file(Master_info::get_number_info_mi_fields(),
+                                master_info_file, 0)))
+  {
+    error= TRUE;
+    goto err;
+  }
+  if ((error= file->do_count_info(&file_instances)))
+    goto err;
+
+  switch (mi_option)
+  {
+    case INVALID_INFO_REPOSITORY:
+      if (file_instances != 0 && table_instances != 0)
+      {
+        sql_print_error("Multiple master info repository instances "
+                        "found with data in them. Unable to decide which is "
+                        "the correct one to use.");
+        error= TRUE;
+        goto err;
+      }
+      /*
+        It is not possible to have different repositories with information.
+        So, we just pick the one that may have information.
+      */
+      *instances= file_instances != 0 ? file_instances : table_instances;
+      /*
+        If there is no repository with information, we force instances
+        to be one, thus guaranteeing that a repository will eventually
+        be populated with one entry.
+      */
+      *instances= *instances != 0 ? *instances : 1; 
+    break;
+
+    case INFO_REPOSITORY_TABLE:
+      *instances= table_instances;
+    break;
+
+    case INFO_REPOSITORY_FILE:
+      *instances= file_instances;
+    break;
+  }
+
+  if (*instances != 1)
+  {
+    /* 
+      For non-multi-source replication, the retrieved value, i.e.
+      instances, must be equal to 1.
+          
+      If this situation happens, this means that one directly and
+      wrongly updated the repository. However, we cannot throw an
+      error message at this point because this would shut down the
+      server.
+
+      So, we only print out a warning message and give the user
+      the chance to fix the issue.
+    */
+
+    sql_print_warning("The master info repository is not configured properly. "
+                      "Please, fix this before using replication.");
+  }
+
+err:
+  DBUG_RETURN(error);
+}
+
+bool Rpl_info_factory::scan_rli_repositories(uint* instances, uint rli_option)
+{
+  bool error= FALSE;
+  uint file_instances= 0;
+  uint table_instances= 0;
+  Rpl_info_table* table= NULL;
+  Rpl_info_file* file= NULL;
+
+  DBUG_ENTER("Rpl_info_factory::scan_rli_repositories");
+
+  if (!(table= new Rpl_info_table(Relay_log_info::get_number_info_rli_fields(),
+                                  MYSQL_SCHEMA_NAME.str, RLI_INFO_NAME.str, 0)))
+  {
+    error= TRUE;
+    goto err;
+  }
+  if ((error= table->do_count_info(&table_instances)))
+    goto err;
+
+  if (!(file= new Rpl_info_file(Relay_log_info::get_number_info_rli_fields(),
+                                relay_log_info_file, 0)))
+  {
+    error= TRUE;
+    goto err;
+  }
+  if ((error= file->do_count_info(&file_instances)))
+    goto err;
+
+  switch (rli_option)
+  {
+    case INVALID_INFO_REPOSITORY:
+      if (file_instances != 0 && table_instances != 0)
+      {
+        sql_print_error ("Multiple relay log info repository instances "
+                         "found with data in them. Unable to decide which is "
+                         "the correct one to choose");
+        error= TRUE;
+        goto err;
+      }
+      /*
+        It is not possible to have different repositories with information.
+        So, we just pick the one that may have information.
+      */
+      *instances= file_instances != 0 ? file_instances : table_instances;
+      /*
+        If there is no repository with information, we force *instances
+        to be one, thus guaranteeing that a repository will eventually
+        be populated with one entry.
+      */
+      *instances= *instances != 0 ? *instances : 1;
+    break;
+
+    case INFO_REPOSITORY_TABLE:
+      *instances= table_instances;
+    break;
+
+    case INFO_REPOSITORY_FILE:
+      *instances= file_instances;
+    break;
+  }
+
+  if (*instances != 1)
+  {
+    /* 
+      The retrieved value, i.e. instances, must be equal to 1.
+          
+      If this situation happens, this means that one directly and
+      wrongly updated the repository. However, we cannot throw an
+      error message at this point because this would shut down the
+      server.
+
+      So, we only print out a warning message and give the user
+      the chance to fix the issue.
+    */
+    sql_print_warning("The relay log info repository is not configured "
+                      "properly. Please, fix this before using replication.");
+  }
+
+err:
+  DBUG_RETURN(error);
 }

=== modified file 'sql/rpl_info_factory.h'
--- a/sql/rpl_info_factory.h	2011-04-14 12:25:14 +0000
+++ b/sql/rpl_info_factory.h	2011-05-26 11:29:59 +0000
@@ -54,13 +54,17 @@ private:
                                 const char **msg);
   static bool init_mi_repositories(Master_info *mi,
                                    uint mi_option,
+                                   uint instance,
                                    Rpl_info_handler **handler_src,
                                    Rpl_info_handler **handler_dest,
                                    const char **msg);
   static bool init_rli_repositories(Relay_log_info *rli,
                                     uint rli_option,
+                                    uint instance,
                                     Rpl_info_handler **handler_src,
                                     Rpl_info_handler **handler_dest,
                                     const char **msg);
+  static bool scan_mi_repositories(uint* instances, uint mi_option);
+  static bool scan_rli_repositories(uint* instances, uint rli_option);
 };
 #endif

=== modified file 'sql/rpl_info_file.cc'
--- a/sql/rpl_info_file.cc	2011-05-16 17:26:11 +0000
+++ b/sql/rpl_info_file.cc	2011-05-26 11:29:59 +0000
@@ -28,7 +28,8 @@ int init_floatvar_from_file(float* var,
 bool init_dynarray_intvar_from_file(char *buffer, size_t size, 
                                     char **buffer_act, IO_CACHE* f);
 
-Rpl_info_file::Rpl_info_file(const int nparam, const char* param_info_fname)
+Rpl_info_file::Rpl_info_file(const int nparam, const char* param_info_fname,
+                             uint instance __attribute__((unused)))
   :Rpl_info_handler(nparam), info_fd(-1)
 {
   DBUG_ENTER("Rpl_info_file::Rpl_info_file");
@@ -148,6 +149,35 @@ int Rpl_info_file::do_check_info()
   return my_access(info_fname, F_OK);
 }
 
+bool Rpl_info_file::do_count_info(uint* counter)
+{
+  uint i= 0;
+  struct st_my_dir *dir_info= NULL;
+  struct fileinfo *file_info= NULL;
+  char dir_name[FN_REFLEN];
+  size_t dir_size= 0;
+  char* file_name= NULL;
+  size_t file_size= 0;
+
+  DBUG_ENTER("Rpl_info_file::do_count_info");
+
+  file_name= info_fname + dirname_part(dir_name, info_fname, &dir_size);
+  file_size= strlen(file_name);
+
+  if (!(dir_info= my_dir(dir_name, MYF(MY_DONT_SORT))))
+    DBUG_RETURN(TRUE);
+
+  file_info= dir_info->dir_entry;
+  for (i= dir_info->number_off_files ; i-- ; file_info++)
+  {
+    if (!strncmp(file_info->name, file_name, file_size))
+      (*counter)++;
+  }
+  my_dirend(dir_info);
+
+  DBUG_RETURN(FALSE);
+}
+
 int Rpl_info_file::do_flush_info(const bool force)
 {
   int error= 0;
@@ -196,6 +226,15 @@ int Rpl_info_file::do_remove_info()
   DBUG_RETURN(error);
 }
 
+int Rpl_info_file::do_clean_info()
+{
+  /*
+    There is nothing to do here. Maybe we can truncate the
+    file in the future. Howerver, for now, there is no need.
+  */
+  return 0;
+}
+
 bool Rpl_info_file::do_set_info(const int pos, const char *value)
 {
   return (my_b_printf(&info_file, "%s\n", value) > (size_t) 0 ?

=== modified file 'sql/rpl_info_file.h'
--- a/sql/rpl_info_file.h	2011-03-23 23:28:49 +0000
+++ b/sql/rpl_info_file.h	2011-05-26 11:29:59 +0000
@@ -49,6 +49,8 @@ private:
   void do_end_info();
   int do_flush_info(const bool force);
   int do_remove_info();
+  int do_clean_info();
+  bool do_count_info(uint* counter);
 
   int do_prepare_info_for_read();
   int do_prepare_info_for_write();
@@ -68,12 +70,14 @@ private:
   bool do_get_info(const int pos, Server_ids *value,
                    const Server_ids *default_value);
   char* do_get_description_info();
+
   bool do_is_transactional();
   bool do_update_is_transactional();
 
-  Rpl_info_file(int const nparam, const char* param_info_fname);
-  Rpl_info_file(const Rpl_info_file& info);
+  Rpl_info_file(int const nparam, const char* param_info_fname,
+                uint instance);
 
+  Rpl_info_file(const Rpl_info_file& info);
   Rpl_info_file& operator=(const Rpl_info_file& info);
 };
 #endif /* RPL_INFO_FILE_H */

=== modified file 'sql/rpl_info_handler.h'
--- a/sql/rpl_info_handler.h	2011-03-23 23:28:49 +0000
+++ b/sql/rpl_info_handler.h	2011-05-26 11:29:59 +0000
@@ -73,7 +73,9 @@ public:
   }
 
   /**
-    Deletes any information in the repository.
+    Deletes any information in it and in some cases the repository.
+    The decision to remove the repository is delegated to the
+    developer.
 
     @retval FALSE No error
     @retval TRUE  Failure
@@ -84,6 +86,18 @@ public:
   }
 
   /**
+    Deletes any information in the repository. In contrast to the
+    @code remove_info() method, the repository cannot be removed.
+
+    @retval FALSE No error
+    @retval TRUE  Failure
+  */
+  int clean_info()
+  {
+    return do_clean_info();
+  }
+
+  /**
     Closes access to the repository.
 
     @retval FALSE No error
@@ -310,6 +324,7 @@ private:
   virtual int do_check_info()= 0;
   virtual int do_flush_info(const bool force)= 0;
   virtual int do_remove_info()= 0;
+  virtual int do_clean_info()= 0;
   virtual void do_end_info()= 0;
   virtual int do_prepare_info_for_read()= 0;
   virtual int do_prepare_info_for_write()= 0;

=== modified file 'sql/rpl_info_table.cc'
--- a/sql/rpl_info_table.cc	2011-04-04 10:06:13 +0000
+++ b/sql/rpl_info_table.cc	2011-05-26 11:29:59 +0000
@@ -16,10 +16,11 @@
 #include "rpl_info_table.h"
 #include "rpl_utility.h"
 
-Rpl_info_table::Rpl_info_table(uint nparam, uint param_field_idx,
+Rpl_info_table::Rpl_info_table(uint nparam,
                                const char* param_schema,
-                               const char *param_table)
-:Rpl_info_handler(nparam), field_idx(param_field_idx),
+                               const char *param_table,
+                               uint param_instance)
+:Rpl_info_handler(nparam), instance(param_instance),
  is_transactional(FALSE)
 {
   str_schema.str= str_table.str= NULL;
@@ -85,16 +86,14 @@ int Rpl_info_table::do_init_info()
     goto end;
 
   /*
-    Points the cursor at the row to be read where the master_id equals to
-    the server_id.
+    Points the cursor at the row to be read according to the
+    keys.
   */
-  if ((res= access->find_info_for_server_id(server_id, field_idx,
-                                            field_values, table)) == FOUND_ID)
+  if ((res= access->scan_info(table, instance)) == FOUND_ID)
   {
     /*
       Reads the information stored in the rpl_info table into a
       set of variables. If there is a failure, an error is returned.
-      Then executes some initialization routines.
     */
     if (access->load_info_values(get_number_info(), table->field,
                                  field_values))
@@ -141,12 +140,10 @@ int Rpl_info_table::do_flush_info(const
     goto end;
 
   /*
-    Points the cursor at the row to be read where the master_id
-    equals to the server_id. If the row is not found an error is
-    reported.
+    Points the cursor at the row to be read according to the
+    keys. If the row is not found an error is reported.
   */
-  if ((res= access->find_info_for_server_id(server_id, field_idx,
-                                            field_values, table)) == NOT_FOUND_ID)
+  if ((res= access->find_info(field_values, table)) == NOT_FOUND_ID)
   {
     /*
       Prepares the information to be stored before calling ha_write_row.
@@ -212,6 +209,15 @@ end:
 
 int Rpl_info_table::do_remove_info()
 {
+  /*
+    There is no need to remove the table as the current design
+    uses system tables.
+  */
+  return do_clean_info();
+}
+
+int Rpl_info_table::do_clean_info()
+{
   int error= 1;
   enum enum_return_id res= FOUND_ID;
   TABLE *table= NULL;
@@ -234,12 +240,10 @@ int Rpl_info_table::do_remove_info()
     goto end;
 
   /*
-    Points the cursor at the row to be deleted where the the master_id
-    equals to the server_id. If the row is not found, the execution
-    proceeds normally.
+    Points the cursor at the row to be deleted according to the
+    keys. If the row is not found, the execution proceeds normally.
   */
-  if ((res= access->find_info_for_server_id(server_id, field_idx,
-                                            field_values, table)) == FOUND_ID)
+  if ((res= access->find_info(field_values, table)) == FOUND_ID)
   {
     /*
       Deletes a row in the rpl_info table.
@@ -289,12 +293,10 @@ int Rpl_info_table::do_check_info()
   }
 
   /*
-    Points the cursor at the row to be deleted where the the master_id
-    equals to the server_id. If the row is not found, an error is
-    reported.
+    Points the cursor at the row to be read according to the
+    keys.
   */
-  if (access->find_info_for_server_id(server_id, field_idx,
-                                      field_values, table) != FOUND_ID)
+  if (access->scan_info(table, instance) != FOUND_ID)
   {
     /* 
        We cannot simply call my_error here because it does not
@@ -305,6 +307,57 @@ int Rpl_info_table::do_check_info()
   }
   error= 0;
 
+
+end:
+  /*
+    Unlocks and closes the rpl_info table.
+  */
+  access->close_table(thd, table, &backup, error);
+  thd->variables.sql_mode= saved_mode;
+  access->drop_thd(thd);
+  DBUG_RETURN(error);
+}
+
+bool Rpl_info_table::do_count_info(uint* counter)
+{
+  int error= 1;
+  TABLE *table= NULL;
+  ulong saved_mode;
+  Open_tables_backup backup;
+
+  DBUG_ENTER("Rpl_info_table::do_count_info");
+
+  THD *thd= access->create_thd();
+
+  saved_mode= thd->variables.sql_mode;
+
+  /*
+    Opens and locks the rpl_info table before accessing it.
+  */
+  if (access->open_table(thd, str_schema, str_table,
+                         get_number_info(), TL_READ,
+                         &table, &backup))
+  {
+    /*
+      We cannot simply print out a warning message at this
+      point because this may represent a bootstrap.
+    */
+    error= 0;
+    goto end;
+  }
+
+  /*
+    Counts entries in the rpl_info table.
+  */
+  if (access->count_info(table, counter))
+  {
+    sql_print_warning("Info table is not ready to be used. Table "
+                      "'%s.%s' cannot be scanned.", str_schema.str,
+                      str_table.str);
+    goto end;
+  }
+  error= 0;
+
 end:
   /*
     Unlocks and closes the rpl_info table.
@@ -324,7 +377,7 @@ int Rpl_info_table::do_prepare_info_for_
   if (!field_values)
     return TRUE;
 
-  cursor= 1;
+  cursor= 0;
 
   return FALSE;
 }

=== modified file 'sql/rpl_info_table.h'
--- a/sql/rpl_info_table.h	2011-03-23 23:28:49 +0000
+++ b/sql/rpl_info_table.h	2011-05-26 11:29:59 +0000
@@ -19,8 +19,6 @@
 #include "rpl_info_handler.h"
 #include "rpl_info_table_access.h"
 
-class Rpl_info_factory;
-
 class Rpl_info_table : public Rpl_info_handler
 {
   friend class Rpl_info_factory;
@@ -29,36 +27,38 @@ public:
   virtual ~Rpl_info_table();
 
 private:
-  /*
+  /**
     This property identifies the name of the schema where a
     replication table is created.
   */
   LEX_STRING str_schema;
 
-  /*
+  /**
     This property identifies the name of a replication
     table.
   */
   LEX_STRING str_table;
 
-  /*
-    This property indentifies the id/position of the field that is
-    used as primary key.
-  */
-  uint field_idx;
-  /*
+  /**
     This property represents a description of the repository.
     Speciffically, "schema"."table".
   */
   char *description;
 
-  /*
+  /**
     This is a pointer to a class that facilitates manipulation
     of replication tables.
   */
   Rpl_info_table_access *access;
 
-  /*
+  /**
+    This identifies which entry in table the object is associated
+    with. This is only used during startup routine and users must
+    ensure that different objects have different instance values.
+  */
+  uint instance;
+
+  /**
     Identifies if a table is transactional or non-transactional.
     This is used to provide a crash-safe behaviour.
   */
@@ -69,6 +69,8 @@ private:
   void do_end_info();
   int do_flush_info(const bool force);
   int do_remove_info();
+  int do_clean_info();
+  bool do_count_info(uint* counter);
 
   int do_prepare_info_for_read();
   int do_prepare_info_for_write();
@@ -88,13 +90,16 @@ private:
   bool do_get_info(const int pos, Server_ids *value,
                    const Server_ids *default_value);
   char* do_get_description_info();
+
   bool do_is_transactional();
   bool do_update_is_transactional();
 
-  Rpl_info_table(uint nparam, uint param_field_id, const char* param_schema,
-                 const char *param_table);
-  Rpl_info_table(const Rpl_info_table& info);
+  Rpl_info_table(uint nparam,
+                 const char* param_schema,
+                 const char *param_table,
+                 uint instance);
 
+  Rpl_info_table(const Rpl_info_table& info);
   Rpl_info_table& operator=(const Rpl_info_table& info);
 };
 #endif /* RPL_INFO_TABLE_H */

=== modified file 'sql/rpl_info_table_access.cc'
--- a/sql/rpl_info_table_access.cc	2011-03-23 23:28:49 +0000
+++ b/sql/rpl_info_table_access.cc	2011-05-26 11:29:59 +0000
@@ -155,13 +155,11 @@ bool Rpl_info_table_access::close_table(
 }
 
 /**
-  Positions the internal pointer of `table` to the place where (id)
-  is stored.
+  Positions the internal pointer of `table` according to the primary
+  key.
 
-  In case search succeeded, the table cursor points to the found row.
+  If the search succeeds, the table cursor points to the found row.
 
-  @param[in]      server_id    Server id
-  @param[in]      idx          Index field
   @param[in,out]  field_values The sequence of values
   @param[in,out]  table        Table
 
@@ -170,27 +168,43 @@ bool Rpl_info_table_access::close_table(
     @retval NOT_FOUND The row was not found.
     @retval ERROR     There was a failure.
 */
-enum enum_return_id Rpl_info_table_access::find_info_for_server_id(ulong server_id,
-                                                                   uint idx,
-                                                                   Rpl_info_values *field_values,
-                                                                   TABLE *table)
+enum enum_return_id Rpl_info_table_access::find_info(Rpl_info_values *field_values,
+                                                     TABLE *table)
 {
+  KEY* keyinfo= NULL;
   uchar key[MAX_KEY_LENGTH];
-  DBUG_ENTER("Rpl_info_table_access::find_info_for_server_id");
 
-  field_values->value[idx].set_int(server_id, TRUE, &my_charset_bin);
+  DBUG_ENTER("Rpl_info_table_access::find_info");
 
-  if (field_values->value[idx].length() > table->field[idx]->field_length)
+  /*
+    Checks if the table has a primary key as expected.
+  */
+  if (table->s->primary_key >= MAX_KEY &&
+      table->s->keys_in_use.is_set(table->s->primary_key))
+  {
+    /*
+      This is not supposed to happen and means that someone
+      has changed the table or disabled the keys.
+    */
     DBUG_RETURN(ERROR_ID);
+  }
 
-  table->field[idx]->store(field_values->value[idx].c_ptr_safe(),
-                           field_values->value[idx].length(),
-                           &my_charset_bin);
-
-  if (!(table->field[idx]->flags & PRI_KEY_FLAG) &&
-      table->s->keys_in_use.is_set(0))
-    DBUG_RETURN(ERROR_ID);
+  keyinfo= table->s->key_info + (uint) table->s->primary_key;
+  for (uint idx= 0; idx < keyinfo->key_parts; idx++)
+  {
+    uint fieldnr= keyinfo->key_part[idx].fieldnr - 1;
 
+    /*
+      The size of the field must be great to store data.
+    */
+    if (field_values->value[fieldnr].length() >
+        table->field[fieldnr]->field_length)
+      DBUG_RETURN(ERROR_ID);
+
+    table->field[fieldnr]->store(field_values->value[fieldnr].c_ptr_safe(),
+                                 field_values->value[fieldnr].length(),
+                                 &my_charset_bin);
+  }
   key_copy(key, table->record[0], table->key_info, table->key_info->key_length);
 
   if (table->file->ha_index_read_idx_map(table->record[0], 0, key, HA_WHOLE_KEY,
@@ -203,6 +217,107 @@ enum enum_return_id Rpl_info_table_acces
 }
 
 /**
+  Positions the internal pointer of `table` to the n-instance row.
+
+  @param[in,out]  field_values The sequence of values
+  @param[in,out]  table        Table
+
+  @return
+    @retval FOUND     The row was found.
+    @retval NOT_FOUND The row was not found.
+    @retval ERROR     There was a failure.
+*/
+enum enum_return_id Rpl_info_table_access::scan_info(TABLE* table,
+                                                     uint instance)
+{
+  int error= 0;
+  uint counter= 0;
+  enum enum_return_id ret= NOT_FOUND_ID;
+
+  DBUG_ENTER("Rpl_info_table_access::scan_info");
+
+  if ((error= table->file->ha_rnd_init(TRUE)))
+    DBUG_RETURN(ERROR_ID);
+
+  do
+  {
+    error= table->file->ha_rnd_next(table->record[0]);
+    switch (error)
+    {
+      case 0:
+        counter++;
+        if (counter == instance)
+        {
+          ret= FOUND_ID;
+          error= HA_ERR_END_OF_FILE;
+        }
+      break;
+
+      case HA_ERR_END_OF_FILE:
+        ret= NOT_FOUND_ID;
+      break;
+
+      default:
+        DBUG_PRINT("info", ("Failed to get next record"
+                            " (ha_rnd_next returns %d)", error));
+        ret= ERROR_ID;
+      break;
+    }
+  }
+  while (!error);
+
+  table->file->ha_rnd_end();
+
+  DBUG_RETURN(ret);
+}
+
+/**
+  Counts the number of rows in `table`.
+
+  @param[in]  table   Table
+  @param[out] counter Registers the number of rows
+
+  @return
+    @retval FALSE No error
+    @retval TRUE  Failure
+*/
+bool Rpl_info_table_access::count_info(TABLE* table, uint* counter)
+{
+  bool end= FALSE;
+  int error= 0;
+
+  DBUG_ENTER("Rpl_info_table_access::count_info");
+
+  if ((error= table->file->ha_rnd_init(TRUE)))
+    DBUG_RETURN(TRUE);
+
+  do
+  {
+    error= table->file->ha_rnd_next(table->record[0]);
+    switch (error) 
+    {
+      case 0:
+        (*counter)++;
+      break;
+
+      case HA_ERR_END_OF_FILE:
+        end= TRUE;
+      break;
+
+      default:
+        DBUG_PRINT("info", ("Failed to get next record"
+                            " (ha_rnd_next returns %d)", error));
+      break;
+    }
+  }
+  while (!error);
+
+  table->file->ha_rnd_end();
+
+  DBUG_RETURN(end ? FALSE : TRUE);
+}
+
+/**
   Reads information from a sequence of fields into a set of LEX_STRING
   structures, where the sequence of values is specified through the object
   Rpl_info_values.
@@ -214,7 +329,7 @@ enum enum_return_id Rpl_info_table_acces
   @return
     @retval FALSE No error
     @retval TRUE  Failure
- */
+*/
 bool Rpl_info_table_access::load_info_values(uint max_num_field, Field **fields,
                                              Rpl_info_values *field_values)
 {
@@ -227,7 +342,7 @@ bool Rpl_info_table_access::load_info_va
   {
     fields[field_idx]->val_str(&str);
     field_values->value[field_idx].copy(str.c_ptr_safe(), str.length(),
-                                             &my_charset_bin);
+                                        &my_charset_bin);
     field_idx++;
   }
 

=== modified file 'sql/rpl_info_table_access.h'
--- a/sql/rpl_info_table_access.h	2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_table_access.h	2011-05-26 11:29:59 +0000
@@ -36,8 +36,9 @@ public:
                   TABLE** table, Open_tables_backup* backup);
   bool close_table(THD* thd, TABLE* table, Open_tables_backup* backup,
                    bool error);
-  enum enum_return_id find_info_for_server_id(ulong server_id, uint idx, Rpl_info_values *,
-                                              TABLE *table);
+  enum enum_return_id find_info(Rpl_info_values *field_values, TABLE *table);
+  enum enum_return_id scan_info(TABLE *table, uint instance);
+  bool count_info(TABLE *table, uint* counter);
   bool load_info_values(uint max_num_field, Field **fields,
                         Rpl_info_values *field_values);
   bool store_info_values(uint max_num_field, Field **fields,
@@ -51,5 +52,4 @@ private:
   Rpl_info_table_access& operator=(const Rpl_info_table_access& info);
   Rpl_info_table_access(const Rpl_info_table_access& info);
 };
-
 #endif /* RPL_INFO_TABLE_ACCESS_H */

=== modified file 'sql/rpl_info_values.h'
--- a/sql/rpl_info_values.h	2010-10-27 09:04:21 +0000
+++ b/sql/rpl_info_values.h	2011-05-26 11:29:59 +0000
@@ -29,7 +29,9 @@ public:
 
   bool init();
 
-  /* Sequence of values to be read from or stored into a repository. */
+  /** 
+    Sequence of values to be read from or stored into a repository.
+  */
   String *value;
 
 private:

=== modified file 'sql/rpl_mi.h'
--- a/sql/rpl_mi.h	2011-04-28 16:50:10 +0000
+++ b/sql/rpl_mi.h	2011-05-26 11:29:59 +0000
@@ -134,7 +134,7 @@ public:
   {
     return (master_log_name[0] ? master_log_name : "FIRST");
   }
-  size_t get_number_info_mi_fields();
+  static size_t get_number_info_mi_fields();
 
 private:
   bool read_info(Rpl_info_handler *from);

=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc	2011-05-23 23:34:47 +0000
+++ b/sql/rpl_rli.cc	2011-05-26 11:29:59 +0000
@@ -30,6 +30,24 @@
 #include <mysql/plugin.h>
 #include <mysql/service_thd_wait.h>
 
+enum 
+{
+  /*
+    Before the MASTER_DELAY parameter was added (WL#344), relay_log.info
+    had 5 lines. Now it has 6 lines.
+  */
+  LINES_IN_RELAY_LOG_INFO_WITH_DELAY= 6,
+
+  /*
+    Before the Id was added (BUG#2334346), relay_log.info
+    had 6 lines. Now it has 7 lines.
+  */
+  LINES_IN_RELAY_LOG_INFO_WITH_ID= 7,
+
+  /* Number of lines currently used when saving relay log info file */
+  LINES_IN_RELAY_LOG_INFO= LINES_IN_RELAY_LOG_INFO_WITH_ID
+};
+
 /*
   Please every time you add a new field to the relay log info, update
   what follows. For now, this is just used to get the number of
@@ -42,7 +60,8 @@ const char* info_rli_fields[]=
   "group_relay_log_pos",
   "group_master_log_name",
   "group_master_log_pos",
-  "sql_delay"
+  "sql_delay",
+  "id"
 };
 
 Relay_log_info::Relay_log_info(bool is_slave_recovery
@@ -53,8 +72,9 @@ Relay_log_info::Relay_log_info(bool is_s
                                PSI_mutex_key *param_key_info_data_cond,
                                PSI_mutex_key *param_key_info_start_cond,
                                PSI_mutex_key *param_key_info_stop_cond,
-                               PSI_mutex_key *param_key_info_sleep_cond
+                               PSI_mutex_key *param_key_info_sleep_cond,
 #endif
+                               int param_id
                               )
    :Rpl_info("SQL"
 #ifdef HAVE_PSI_INTERFACE
@@ -76,7 +96,7 @@ Relay_log_info::Relay_log_info(bool is_s
    tables_to_lock(0), tables_to_lock_count(0),
    rows_query_ev(NULL), last_event_start_time(0),
    sql_delay(0), sql_delay_end(0),
-   m_flags(0)
+   m_flags(0), internal_id(param_id)
 {
   DBUG_ENTER("Relay_log_info::Relay_log_info");
 
@@ -1489,7 +1509,13 @@ bool Relay_log_info::read_info(Rpl_info_
 
   if (lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY)
   {
-    if (from->get_info((int *) &temp_sql_delay,(int) 0))
+    if (from->get_info((int *) &temp_sql_delay, (int) 0))
+      DBUG_RETURN(TRUE);
+  }
+
+  if (lines >= LINES_IN_RELAY_LOG_INFO_WITH_ID)
+  {
+    if (from->get_info(&internal_id, (int) 0))
       DBUG_RETURN(TRUE);
   }
 
@@ -1511,12 +1537,13 @@ bool Relay_log_info::write_info(Rpl_info
   //DBUG_ASSERT(!belongs_to_client());
 
   if (to->prepare_info_for_write() ||
-      to->set_info((int) LINES_IN_RELAY_LOG_INFO_WITH_DELAY) ||
+      to->set_info((int) LINES_IN_RELAY_LOG_INFO) ||
       to->set_info(group_relay_log_name) ||
       to->set_info((ulong) group_relay_log_pos) ||
       to->set_info(group_master_log_name) ||
       to->set_info((ulong) group_master_log_pos) ||
-      to->set_info((int) sql_delay))
+      to->set_info((int) sql_delay) ||
+      to->set_info(internal_id))
     DBUG_RETURN(TRUE);
 
   if (to->flush_info(force))

=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h	2011-05-13 13:59:55 +0000
+++ b/sql/rpl_rli.h	2011-05-26 11:29:59 +0000
@@ -548,7 +548,7 @@ public:
   }
 #endif
 
-  size_t get_number_info_rli_fields();
+  static size_t get_number_info_rli_fields();
 
   /**
     Indicate that a delay starts.
@@ -599,11 +599,11 @@ private:
   time_t sql_delay_end;
 
   uint32 m_flags;
+
   /*
-    Before the MASTER_DELAY parameter was added (WL#344), relay_log.info
-    had 4 lines. Now it has 5 lines.
+    Uniquely identifies a relay log info entry.
   */
-  static const int LINES_IN_RELAY_LOG_INFO_WITH_DELAY= 5;
+  int internal_id;
 
   bool read_info(Rpl_info_handler *from);
   bool write_info(Rpl_info_handler *to, bool force);
@@ -616,8 +616,9 @@ private:
                  PSI_mutex_key *param_key_info_data_cond,
                  PSI_mutex_key *param_key_info_start_cond,
                  PSI_mutex_key *param_key_info_stop_cond,
-                 PSI_mutex_key *param_key_info_sleep_cond
+                 PSI_mutex_key *param_key_info_sleep_cond,
 #endif
+                 int param_id
                 );
   Relay_log_info(const Relay_log_info& info);
 

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2011-05-21 08:25:33 +0000
+++ b/sql/rpl_slave.cc	2011-05-26 11:29:59 +0000
@@ -5813,6 +5813,29 @@ bool change_master(THD* thd, Master_info
   if ((lex_mi->host && strcmp(lex_mi->host, mi->host)) ||
       (lex_mi->port && lex_mi->port != mi->port))
   {
+    /*
+      We need to clean the respository otherwise there will be different
+      entries as the key is about to change.
+
+      Reset information in the repository without dropping the repository
+      what may happen if we had called remove_info(). This is necessary
+      because the primary key, i.e. host or port, has changed.
+
+      The repository does not support direct changes on the primary key,
+      so the row is dropped and re-inserted with a new primary key. If we
+      don't do that, the master info repository we will end up with several
+      rows. While the server was on-line this would not be a problem but
+      after a server restart most likely replication would fail.
+
+      Note that CHANGE MASTER is this case is not atomic and if a crash
+      happens before flush_info() is called, there will be no entries in
+      the repository.
+    */
+    if (mi->clean_info())
+    {
+      ret= TRUE;
+      goto err;
+    }
     mi->master_uuid[0]= 0;
     mi->master_id= 0;
   }


Attachment: [text/bzr-bundle] bzr/alfranio.correia@oracle.com-20110526112959-po0cdr468vhtlg68.bundle
Thread
bzr commit into mysql-trunk branch (alfranio.correia:3115) Bug#12334346Alfranio Correia26 May