#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#12334346 | Alfranio Correia | 26 May |