#At file:///home/acorreia/workspace.oracle/repository.mysql/bzrwork/bug-58897/mysql-trunk.merge/ based on revid:alfranio.correia@stripped
3357 Alfranio Correia 2011-04-04 [merge]
merge mysql-trunk (local) --> mysql-trunk
Conflicts:
. sql/share/errmsg-utf8.txt
modified:
mysql-test/include/mtr_warnings.sql
mysql-test/suite/rpl/r/rpl_migration_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_install_db.pl.in
scripts/mysql_install_db.sh
sql/rpl_info.cc
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.cc
sql/rpl_info_handler.h
sql/rpl_info_table.cc
sql/rpl_info_table.h
sql/rpl_info_table_access.cc
sql/rpl_info_values.cc
sql/rpl_mi.h
sql/rpl_rli.h
sql/rpl_slave.cc
sql/rpl_slave.h
sql/share/errmsg-utf8.txt
sql/sql_binlog.cc
sql/sql_class.h
sql/sys_vars.cc
sql/table.h
=== modified file 'mysql-test/include/mtr_warnings.sql'
--- a/mysql-test/include/mtr_warnings.sql 2011-02-23 20:01:27 +0000
+++ b/mysql-test/include/mtr_warnings.sql 2011-03-23 23:28:49 +0000
@@ -240,6 +240,12 @@ INSERT INTO global_suppressions VALUES
*/
("Found lock of type 6 that is write and read locked"),
+ /*
+ Warning message is printed out whenever a slave is started with
+ a configuration that is not crash-safe.
+ */
+ (".*If a crash happens this configuration does not guarantee.*"),
+
("THE_LAST_SUPPRESSION")||
=== modified file 'mysql-test/suite/rpl/r/rpl_migration_crash_safe.result'
--- a/mysql-test/suite/rpl/r/rpl_migration_crash_safe.result 2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/rpl/r/rpl_migration_crash_safe.result 2011-03-23 23:28:49 +0000
@@ -5,5 +5,10 @@ CREATE TABLE test(id INTEGER NOT NULL PR
INSERT INTO test VALUES (1), (2), (3);
include/rpl_restart_server.inc [server_number=2 parameters: --relay-log-info-repository=TABLE --skip-slave-start]
include/rpl_restart_server.inc [server_number=2 parameters: --relay-log-info-repository=FILE --skip-slave-start]
+SET @@GLOBAL.relay_log_info_repository= "TABLE";
+SET @@GLOBAL.relay_log_info_repository= "FILE";
+SET @@GLOBAL.relay_log_info_repository= "FILE";
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
DROP TABLE test;
=== modified file 'mysql-test/suite/rpl/t/rpl_migration_crash_safe.test'
--- a/mysql-test/suite/rpl/t/rpl_migration_crash_safe.test 2010-12-20 14:27:17 +0000
+++ b/mysql-test/suite/rpl/t/rpl_migration_crash_safe.test 2011-03-23 23:28:49 +0000
@@ -22,16 +22,33 @@
# if data is replicated correctly.
# 1.3. Assertions AF1 and AF2 are verified.
#
-# 2. Migration from FILE to TABLE
+# 2. Migration from FILE to TABLE by restarting the SERVER
# 2.1. The slave is stopped and restarted with --relay-log-info-repository=TABLE
# 2.2. Assertions AT1 and AT2 are verified.
#
-# 3. Migration from TABLE to FILE with success
+# 3. Migration from TABLE to FILE by restarting the SERVER
# 4.1. The slave is stopped and restarted with --relay-log-info-repository=FILE
# 4.2. Assertions AF1 and AF2 are verified.
#
-# 4. Check consistency
-# 4.1. The replication is started and the master is compared to the slave.
+# 4. Migration from FILE to TALBE by using SET
+# 4.1. SET @GLOBAL.relay_log_info_repository=TABLE is exectued.
+# 4.2. Assertions AT1 and AT2 are verified.
+#
+# 5. Migration from TABLE to FILE by using SET
+# 5.1. SET @GLOBAL.relay_log_info_repository=FILE is executed.
+# 5.2. Assertions AF1 and AF2 are verified.
+#
+# 6. Migration from FILE to FILE by using SET
+# 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.
+#
+# 8. Check consistency
+# 8.1. The replication is started and the master is compared to the slave.
########################################################################################
########################################################################################
# 1. Preparation
@@ -62,7 +79,7 @@ CREATE TABLE test(id INTEGER NOT NULL PR
INSERT INTO test VALUES (1), (2), (3);
########################################################################################
-# 2. Migration from FILE to TABLE
+# 2. Migration from FILE to TABLE by restarting the SERVER
########################################################################################
--connection slave
@@ -74,15 +91,16 @@ 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 information and this is not expected."
+ --echo "The mysql.slave_relay_log_info has no information and this is not expected."
--die
}
--error 1
file_exists $MYSQLD_DATADIR/relay-log.info;
########################################################################################
-# 3. Migration from TABLE to FILE
+# 3. Migration from TABLE to FILE by restarting the SERVER
########################################################################################
+--connection slave
--let $rpl_server_number= 2
--let $rpl_server_parameters= --relay-log-info-repository=FILE --skip-slave-start
@@ -98,12 +116,67 @@ if ($got_slave != $exp_slave)
file_exists $MYSQLD_DATADIR/relay-log.info;
########################################################################################
-# 4. Check consistency
+# 4. Migration FROM FILE TO TABLE by using SET
+########################################################################################
+--connection slave
+
+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 "The mysql.slave_relay_log_info has no information and this is not expected."
+ --die
+}
+--error 1
+file_exists $MYSQLD_DATADIR/relay-log.info;
+
+########################################################################################
+# 5. Migration FROM TABLE TO FILE by using SET
+########################################################################################
+--connection slave
+
+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 "The mysql.slave_relay_log_info has information and this is not expected."
+ --die
+}
+file_exists $MYSQLD_DATADIR/relay-log.info;
+
+########################################################################################
+# 6. Migration FROM FILE TO FILE by using SET
+########################################################################################
+--connection slave
+
+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 "The mysql.slave_relay_log_info has information and this is not expected."
+ --die
+}
+file_exists $MYSQLD_DATADIR/relay-log.info;
+
+########################################################################################
+# 7. Migration while slave is running by using SET
########################################################################################
--connection slave
--source include/start_slave.inc
+--error ER_SLAVE_MUST_STOP
+SET @@GLOBAL.relay_log_info_repository= "TABLE";
+
+########################################################################################
+# 8. Check consistency
+########################################################################################
--connection master
sync_slave_with_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 2010-07-06 22:01:07 +0000
+++ b/mysql-test/suite/sys_vars/r/master_info_repository_basic.result 2011-03-23 23:28:49 +0000
@@ -10,10 +10,9 @@ SELECT COUNT(@@SESSION.master_info_repos
ERROR HY000: Variable 'master_info_repository' is a GLOBAL variable
'#---------------------BS_STVARS_002_02----------------------#'
SET @@GLOBAL.master_info_repository= "TABLE";
-ERROR HY000: Variable 'master_info_repository' is a read only variable
SELECT @@GLOBAL.master_info_repository;
@@GLOBAL.master_info_repository
-FILE
+TABLE
'#---------------------BS_STVARS_002_03----------------------#'
SELECT @@GLOBAL.master_info_repository = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -42,3 +41,5 @@ SELECT COUNT(@@GLOBAL.master_info_reposi
COUNT(@@GLOBAL.master_info_repository)
1
1 Expected
+'#---------------------BS_STVARS_002_06----------------------#'
+SET @@GLOBAL.master_info_repository= "FILE";
=== 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 2010-07-06 22:01:07 +0000
+++ b/mysql-test/suite/sys_vars/r/relay_log_info_repository_basic.result 2011-03-23 23:28:49 +0000
@@ -10,10 +10,9 @@ SELECT COUNT(@@SESSION.relay_log_info_re
ERROR HY000: Variable 'relay_log_info_repository' is a GLOBAL variable
'#---------------------BS_STVARS_002_02----------------------#'
SET @@GLOBAL.relay_log_info_repository= "TABLE";
-ERROR HY000: Variable 'relay_log_info_repository' is a read only variable
SELECT @@GLOBAL.relay_log_info_repository;
@@GLOBAL.relay_log_info_repository
-FILE
+TABLE
'#---------------------BS_STVARS_002_03----------------------#'
SELECT @@GLOBAL.relay_log_info_repository = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -42,3 +41,5 @@ SELECT COUNT(@@GLOBAL.relay_log_info_rep
COUNT(@@GLOBAL.relay_log_info_repository)
1
1 Expected
+'#---------------------BS_STVARS_002_06----------------------#'
+SET @@GLOBAL.relay_log_info_repository= "FILE";
=== 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 2010-10-25 10:39:01 +0000
+++ b/mysql-test/suite/sys_vars/t/master_info_repository_basic.test 2011-03-23 23:28:49 +0000
@@ -37,7 +37,6 @@ SELECT COUNT(@@SESSION.master_info_repos
####################################################################
# Check if Value can set #
####################################################################
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
SET @@GLOBAL.master_info_repository= "TABLE";
SELECT @@GLOBAL.master_info_repository;
@@ -74,3 +73,10 @@ SELECT COUNT(@@local.master_info_reposit
SELECT COUNT(@@GLOBAL.master_info_repository);
--echo 1 Expected
+
+
+--echo '#---------------------BS_STVARS_002_06----------------------#'
+################################################################################
+# Clean up #
+################################################################################
+SET @@GLOBAL.master_info_repository= "FILE";
=== 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 2010-10-25 10:39:01 +0000
+++ b/mysql-test/suite/sys_vars/t/relay_log_info_repository_basic.test 2011-03-23 23:28:49 +0000
@@ -37,7 +37,6 @@ SELECT COUNT(@@SESSION.relay_log_info_re
####################################################################
# Check if Value can set #
####################################################################
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
SET @@GLOBAL.relay_log_info_repository= "TABLE";
SELECT @@GLOBAL.relay_log_info_repository;
@@ -74,3 +73,10 @@ SELECT COUNT(@@local.relay_log_info_repo
SELECT COUNT(@@GLOBAL.relay_log_info_repository);
--echo 1 Expected
+
+
+--echo '#---------------------BS_STVARS_002_06----------------------#'
+################################################################################
+# Clean up #
+################################################################################
+SET @@GLOBAL.relay_log_info_repository= "FILE";
=== modified file 'scripts/mysql_install_db.pl.in'
--- a/scripts/mysql_install_db.pl.in 2010-10-25 10:39:01 +0000
+++ b/scripts/mysql_install_db.pl.in 2011-03-23 23:28:49 +0000
@@ -79,11 +79,6 @@ Usage: $0 [OPTIONS]
user. You must be root to use this option. By default
mysqld runs using your current login name and files and
directories that it creates will be owned by you.
- --rpl-engine=engine The storage engine used for the mysql.slave_master_info and
- mysql.slave_relay_log_info tables. By default, both tables are
- created using the MyISAM storage engine. However, any storage
- engine available to the server may be used. If a crash-safe
- slave is required, the storage engine must be transactional.
All other options are passed to the mysqld program
@@ -122,7 +117,6 @@ sub parse_arguments
"builddir=s", # FIXME not documented
"srcdir=s",
"ldata|datadir=s",
- "rpl-engine=s",
# Note that the user will be passed to mysqld so that it runs
# as 'user' (crucial e.g. if log-bin=/some_other_path/
@@ -459,29 +453,6 @@ if ( open(PIPE, "| $mysqld_install_cmd_l
report_verbose($opt,"OK");
# ----------------------------------------------------------------------
- # Pipe ALTER TABLE mysql.slave_master_info|slave_relay_log_info to "mysqld --bootstrap"
- # ----------------------------------------------------------------------
-
- if ($opt->{'rpl-engine'})
- {
- report_verbose_wait($opt,"Setting engine for mysql.slave_master_info mysql.slave_relay_log_info tables...");
- if ( open(PIPE, "| $mysqld_install_cmd_line") )
- {
- print PIPE "use mysql;\n";
- print PIPE "ALTER TABLE mysql.slave_master_info ENGINE= " . $opt->{'rpl-engine'} . ";\n";
- print PIPE "ALTER TABLE mysql.slave_relay_log_info ENGINE= " . $opt->{'$rpl-engine'} . ";\n";
- close PIPE;
-
- report_verbose($opt,"OK");
- }
- else
- {
- warning($opt,"CRASH-SAFE SLAVE IS NOT COMPLETELY CONFIGURED!",
- "The \"CRASH-SAFE SLAVE\" might not work properly.");
- }
- }
-
- # ----------------------------------------------------------------------
# Pipe fill_help_tables.sql to "mysqld --bootstrap"
# ----------------------------------------------------------------------
=== modified file 'scripts/mysql_install_db.sh'
--- a/scripts/mysql_install_db.sh 2010-10-25 10:39:01 +0000
+++ b/scripts/mysql_install_db.sh 2011-03-23 23:28:49 +0000
@@ -63,11 +63,6 @@ Usage: $0 [OPTIONS]
user. You must be root to use this option. By default
mysqld runs using your current login name and files and
directories that it creates will be owned by you.
- --rpl-engine=engine The storage engine used for the mysql.slave_master_info and
- mysql.slave_relay_log_info tables. By default, both tables are
- created using the MyISAM storage engine. However, any storage
- engine available to the server may be used. If a crash-safe
- slave is required, the storage engine must be transactional.
All other options are passed to the mysqld program
@@ -120,8 +115,6 @@ parse_arguments()
--no-defaults|--defaults-file=*|--defaults-extra-file=*)
defaults="$arg" ;;
- --rpl-engine=*) rpl_engine=`parse_arg "$arg"` ;;
-
--cross-bootstrap|--windows)
# Used when building the MySQL system tables on a different host than
# the target. The platform-independent files that are created in
@@ -434,19 +427,6 @@ else
exit 1
fi
-if test -n "$rpl_engine"
-then
- s_echo "Setting engine for mysql.slave_master_info mysql.slave_relay_log_info tables..."
- if { echo "use mysql;"; echo "ALTER TABLE mysql.slave_master_info ENGINE= $rpl_engine;"; echo "ALTER TABLE mysql.slave_relay_log_info ENGINE= $rpl_engine;"; } | $mysqld_install_cmd_line > /dev/null
- then
- s_echo "OK"
- else
- echo
- echo "WARNING: CRASH-SAFE SLAVE IS NOT COMPLETELY CONFIGURED!"
- echo "The \"CRASH-SAFE SLAVE\" might not work properly."
- fi
-fi
-
s_echo "Filling help tables..."
if { echo "use mysql;"; cat $fill_help_tables; } | $mysqld_install_cmd_line > /dev/null
then
=== modified file 'sql/rpl_info.cc'
--- a/sql/rpl_info.cc 2010-12-21 09:33:41 +0000
+++ b/sql/rpl_info.cc 2011-03-23 23:28:49 +0000
@@ -36,7 +36,7 @@ Rpl_info::Rpl_info(const char* type
#endif
info_thd(0), inited(0), abort_slave(0),
slave_running(0), slave_run_id(0),
- handler(0)
+ handler(0), rpl_info_type(INVALID_INFO_REPOSITORY)
{
#ifdef HAVE_PSI_INTERFACE
mysql_mutex_init(*key_info_run_lock,
@@ -65,13 +65,7 @@ Rpl_info::~Rpl_info()
mysql_cond_destroy(&start_cond);
mysql_cond_destroy(&stop_cond);
- if (handler)
- delete handler;
+ delete handler;
DBUG_VOID_RETURN;
}
-
-void Rpl_info::set_rpl_info_handler(Rpl_info_handler * param_handler)
-{
- handler= param_handler;
-}
=== modified file 'sql/rpl_info.h'
--- a/sql/rpl_info.h 2010-12-21 09:33:41 +0000
+++ b/sql/rpl_info.h 2011-03-23 23:28:49 +0000
@@ -21,9 +21,18 @@
#include "rpl_info_handler.h"
#include "rpl_reporting.h"
+enum enum_info_repository
+{
+ INVALID_INFO_REPOSITORY= -1,
+ INFO_REPOSITORY_FILE= 0,
+ INFO_REPOSITORY_TABLE= 1
+};
+
class Rpl_info : public Slave_reporting_capability
{
public:
+ virtual ~Rpl_info();
+
/*
standard lock acquisition order to avoid deadlocks:
run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index
@@ -53,16 +62,45 @@ public:
int events_until_exit;
#endif
- Rpl_info(const char* type
-#ifdef HAVE_PSI_INTERFACE
- ,PSI_mutex_key *param_key_info_run_lock,
- PSI_mutex_key *param_key_info_data_lock,
- PSI_mutex_key *param_key_info_data_cond,
- PSI_mutex_key *param_key_info_start_cond,
- PSI_mutex_key *param_key_info_stop_cond
-#endif
- );
- virtual ~Rpl_info();
+ /**
+ Defines the type of the repository that is used.
+
+ @param param_rpl_info_type Type of repository.
+ */
+ void set_rpl_info_type(uint param_rpl_info_type)
+ {
+ rpl_info_type= param_rpl_info_type;
+ }
+
+ /**
+ Gets the type of the repository that is used.
+
+ @return Type of repository.
+ */
+ uint get_rpl_info_type()
+ {
+ return(rpl_info_type);
+ }
+
+ /**
+ Sets the persistency component/handler.
+
+ @param[in] hanlder Pointer to the handler.
+ */
+ void set_rpl_info_handler(Rpl_info_handler * param_handler)
+ {
+ handler= param_handler;
+ }
+
+ /**
+ Gets the persistency component/handler.
+
+ @return the handler if there is one.
+ */
+ Rpl_info_handler *get_rpl_info_handler()
+ {
+ return (handler);
+ }
int check_info()
{
@@ -79,6 +117,11 @@ public:
return (handler->is_transactional());
}
+ bool update_is_transactional()
+ {
+ return (handler->update_is_transactional());
+ }
+
char *get_description_info()
{
return (handler->get_description_info());
@@ -92,21 +135,26 @@ public:
return(FALSE);
}
- /**
- Sets the persistency component/handler.
-
- @param[in] hanlder Pointer to the handler.
- */
- void set_rpl_info_handler(Rpl_info_handler * handler);
-
protected:
Rpl_info_handler *handler;
+ uint rpl_info_type;
+
+ Rpl_info(const char* type
+#ifdef HAVE_PSI_INTERFACE
+ ,PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond
+#endif
+ );
+
private:
virtual bool read_info(Rpl_info_handler *from)= 0;
virtual bool write_info(Rpl_info_handler *to, bool force)= 0;
- Rpl_info& operator=(const Rpl_info& info);
Rpl_info(const Rpl_info& info);
+ Rpl_info& operator=(const Rpl_info& info);
};
#endif /* RPL_INFO_H */
=== modified file 'sql/rpl_info_factory.cc'
--- a/sql/rpl_info_factory.cc 2010-12-21 09:33:41 +0000
+++ b/sql/rpl_info_factory.cc 2011-03-23 23:28:49 +0000
@@ -18,13 +18,6 @@
#include "rpl_slave.h"
#include "rpl_info_factory.h"
-/*
- We need to replace these definitions by an option that states the
- engine one wants to use in the master info repository.
-*/
-#define master_info_engine NULL
-#define relay_log_info_engine NULL
-
/**
Creates both a Master info and a Relay log info repository whose types are
defined as parameters.
@@ -42,7 +35,7 @@
bool Rpl_info_factory::create(uint mi_option, Master_info **mi,
uint rli_option, Relay_log_info **rli)
{
- DBUG_ENTER("Rpl_info_factory::Rpl_info_factory");
+ DBUG_ENTER("Rpl_info_factory::create");
if (!((*mi)= Rpl_info_factory::create_mi(mi_option)))
DBUG_RETURN(TRUE);
@@ -80,12 +73,12 @@ bool Rpl_info_factory::create(uint mi_op
Master_info *Rpl_info_factory::create_mi(uint mi_option)
{
Master_info* mi= NULL;
- Rpl_info_file* mi_file= NULL;
- Rpl_info_table* mi_table= NULL;
+ Rpl_info_handler* handler_src= NULL;
+ Rpl_info_handler* handler_dest= NULL;
const char *msg= "Failed to allocate memory for the master info "
"structure";
- DBUG_ENTER("Rpl_info_factory::Rpl_info_factory");
+ DBUG_ENTER("Rpl_info_factory::create_mi");
if (!(mi= new Master_info(
#ifdef HAVE_PSI_INTERFACE
@@ -98,36 +91,17 @@ Master_info *Rpl_info_factory::create_mi
)))
goto err;
- /*
- Now we instantiate all info repos and later decide which one to take,
- but not without first checking if there is already existing data for
- a repo different from the one that is being requested.
- */
- if (!(mi_file= new Rpl_info_file(mi->get_number_info_mi_fields(),
- master_info_file)))
- goto err;
-
- if (!(mi_table= new Rpl_info_table(mi->get_number_info_mi_fields() + 1,
- MI_FIELD_ID, MI_SCHEMA, MI_TABLE)))
- goto err;
-
- DBUG_ASSERT(mi_option == MI_REPOSITORY_FILE ||
- mi_option == MI_REPOSITORY_TABLE);
-
- if (decide_repository(mi, &mi_table, &mi_file,
- mi_option == MI_REPOSITORY_TABLE, &msg))
+ if(init_mi_repositories(mi, mi_option, &handler_src, &handler_dest, &msg))
goto err;
- if ((mi_option == MI_REPOSITORY_TABLE) &&
- change_engine(static_cast<Rpl_info_table *>(mi_table),
- master_info_engine, &msg))
+ if (decide_repository(mi, mi_option, &handler_src, &handler_dest, &msg))
goto err;
DBUG_RETURN(mi);
err:
- if (mi_file) delete mi_file;
- if (mi_table) delete mi_table;
+ delete handler_src;
+ delete handler_dest;
if (mi)
{
/*
@@ -135,13 +109,51 @@ err:
any reference to it.
*/
mi->set_rpl_info_handler(NULL);
- delete (mi);
+ mi->set_rpl_info_type(INVALID_INFO_REPOSITORY);
+ delete mi;
}
- sql_print_error("%s", msg);
+ sql_print_error("Error creating master info: %s.", msg);
DBUG_RETURN(NULL);
}
/**
+ Allows to change the master info repository after startup.
+
+ @param[in] mi Pointer to Master_info.
+ @param[in] mi_option Type of the repository, e.g. FILE TABLE.
+ @param[out] msg Error message if something goes wrong.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+*/
+bool Rpl_info_factory::change_mi_repository(Master_info *mi,
+ const uint mi_option,
+ const char **msg)
+{
+ DBUG_ENTER("Rpl_info_factory::change_mi_repository");
+
+ Rpl_info_handler* handler_src= mi->get_rpl_info_handler();
+ Rpl_info_handler* handler_dest= NULL;
+
+ if (mi->get_rpl_info_type() == mi_option)
+ DBUG_RETURN(FALSE);
+
+ if (init_mi_repositories(mi, mi_option, NULL, &handler_dest, msg))
+ goto err;
+
+ if (change_repository(mi, mi_option, &handler_src, &handler_dest, msg))
+ goto err;
+
+ DBUG_RETURN(FALSE);
+
+err:
+ delete handler_dest;
+
+ sql_print_error("Error changing the type of master info's repository: %s.", *msg);
+ DBUG_RETURN(TRUE);
+}
+
+/**
Creates a Relay log info repository whose type is defined as a parameter.
@param[in] rli_option Type of the Relay log info repository
@@ -160,8 +172,8 @@ err:
Relay_log_info *Rpl_info_factory::create_rli(uint rli_option, bool is_slave_recovery)
{
Relay_log_info *rli= NULL;
- Rpl_info_file* rli_file= NULL;
- Rpl_info_table* rli_table= NULL;
+ Rpl_info_handler* handler_src= NULL;
+ Rpl_info_handler* handler_dest= NULL;
const char *msg= "Failed to allocate memory for the relay log info "
"structure";
@@ -178,36 +190,17 @@ Relay_log_info *Rpl_info_factory::create
)))
goto err;
- /*
- Now we instantiate all info repos and later decide which one to take,
- but not without first checking if there is already existing data for
- a repo different from the one that is being requested.
- */
- if (!(rli_file= new Rpl_info_file(rli->get_number_info_rli_fields(),
- relay_log_info_file)))
- goto err;
-
- if (!(rli_table= new Rpl_info_table(rli->get_number_info_rli_fields() + 1,
- RLI_FIELD_ID, RLI_SCHEMA, RLI_TABLE)))
- goto err;
-
- DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE ||
- rli_option == RLI_REPOSITORY_TABLE);
-
- if (decide_repository(rli, &rli_table, &rli_file,
- rli_option == RLI_REPOSITORY_TABLE, &msg))
+ if(init_rli_repositories(rli, rli_option, &handler_src, &handler_dest, &msg))
goto err;
- if ((rli_option == RLI_REPOSITORY_TABLE) &&
- change_engine(static_cast<Rpl_info_table *>(rli_table),
- relay_log_info_engine, &msg))
+ if (decide_repository(rli, rli_option, &handler_src, &handler_dest, &msg))
goto err;
DBUG_RETURN(rli);
err:
- if (rli_file) delete rli_file;
- if (rli_table) delete rli_table;
+ delete handler_src;
+ delete handler_dest;
if (rli)
{
/*
@@ -215,142 +208,341 @@ err:
any reference to it.
*/
rli->set_rpl_info_handler(NULL);
- delete (rli);
+ rli->set_rpl_info_type(INVALID_INFO_REPOSITORY);
+ delete rli;
}
- sql_print_error("%s", msg);
+ sql_print_error("Error creating relay log info: %s.", msg);
DBUG_RETURN(NULL);
}
/**
- Decides what repository will be used based on the following decision table:
+ Allows to change the relay log info repository after startup.
- \code
- |--------------+-----------------------+-----------------------|
- | Exists \ Opt | TABLE | FILE |
- |--------------+-----------------------+-----------------------|
- | ~is_t, is_f | Update T and delete F | Read F |
- | is_t, is_f | ERROR | ERROR |
- | ~is_t, ~is_f | Fill in T | Create and Fill in F |
- | is_t, ~is_f | Read T | Update F and delete T |
- |--------------+-----------------------+-----------------------|
- \endcode
+ @param[in] mi Pointer to Relay_log_info.
+ @param[in] mi_option Type of the repository, e.g. FILE TABLE.
+ @param[out] msg Error message if something goes wrong.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+*/
+bool Rpl_info_factory::change_rli_repository(Relay_log_info *rli,
+ const uint rli_option,
+ const char **msg)
+{
+ DBUG_ENTER("Rpl_info_factory::change_rli_repository");
- <ul>
- \li F --> file
+ Rpl_info_handler* handler_src= rli->get_rpl_info_handler();
+ Rpl_info_handler* handler_dest= NULL;
- \li T --> table
+ if (rli->get_rpl_info_type() == rli_option)
+ DBUG_RETURN(FALSE);
- \li is_t --> table with data
+ if (init_rli_repositories(rli, rli_option, NULL, &handler_dest, msg))
+ goto err;
- \li is_f --> file with data
+ if (change_repository(rli, rli_option, &handler_src, &handler_dest, msg))
+ goto err;
- \li ~is_t --> no data in the table
+ DBUG_RETURN(FALSE);
- \li ~is_f --> no file
- </ul>
+err:
+ delete handler_dest;
+ handler_dest= NULL;
- @param[in] info Either master info or relay log info.
- @param[in] table Table handler.
- @param[in] file File handler.
- @param[in] is_table True if a table handler was requested.
- @param[out] msg Message specifying what went wrong, if there is any error.
+ sql_print_error("Error changing the type of relay log info's repository: %s.", *msg);
+ DBUG_RETURN(TRUE);
+}
+
+/**
+ Decides during startup what repository will be used based on the following
+ decision table:
+
+ \code
+ |--------------+-----------------------+-----------------------|
+ | Exists \ Opt | SOURCE | DESTINATION |
+ |--------------+-----------------------+-----------------------|
+ | ~is_s, ~is_d | - | Create/Update D |
+ | ~is_s, is_d | - | Continue with D |
+ | is_s, ~is_d | Copy S into D | Create/Update D |
+ | is_s, is_d | Error | Error |
+ |--------------+-----------------------+-----------------------|
+ \endcode
+
+ @param[in] info Either master info or relay log info.
+ @param[in] option Identifies the type of the repository that will
+ be used, i.e., destination repository.
+ @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
+ copied.
+ @param[out] msg Error message if something goes wrong.
@retval FALSE No error
@retval TRUE Failure
*/
-bool Rpl_info_factory::decide_repository(Rpl_info *info, Rpl_info_table **table,
- Rpl_info_file **file, bool is_table,
+bool Rpl_info_factory::decide_repository(Rpl_info *info,
+ uint option,
+ Rpl_info_handler **handler_src,
+ Rpl_info_handler **handler_dest,
const char **msg)
{
DBUG_ENTER("Rpl_info_factory::decide_repository");
bool error= TRUE;
- bool is_t= !((*table)->check_info());
- bool is_f= !((*file)->check_info());
+ /*
+ check_info() returns FALSE if the repository exists. If a FILE,
+ for example, this means that FALSE is returned if a file exists.
+ If a TABLE, for example, this means that FALSE is returned if
+ the table exists and is populated. Otherwise, TRUE is returned.
+
+ The check_info() behavior is odd and we are going to fix this
+ in the future.
+
+ So,
- if (is_t && is_f)
+ . 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.";
+ "the correct one to choose";
DBUG_RETURN(error);
}
- if (is_table)
+ if (!is_dest && is_src)
{
- if (!is_t && is_f)
+ if ((*handler_src)->init_info() || (*handler_dest)->init_info())
{
- if ((*table)->init_info() || (*file)->init_info())
- {
- *msg= "Error transfering information from a file to a table.";
- goto err;
- }
- /*
- Transfer the information from the file to the table and delete the
- file, i.e. Update the table (T) and delete the file (F).
- */
- if (info->copy_info(*file, *table) || (*file)->remove_info())
- {
- *msg= "Error transfering information from a file to a table.";
- goto err;
- }
+ *msg= "Error transfering information";
+ goto err;
+ }
+ /*
+ Transfer the information from source to destination and delete the
+ source. Note this is not fault-tolerant and a crash before removing
+ source may cause the next restart to fail as is_src and is_dest may
+ be true. Moreover, any failure in removing the source may lead to
+ the same.
+
+ /Alfranio
+ */
+ if (info->copy_info(*handler_src, *handler_dest) || (*handler_src)->remove_info())
+ {
+ *msg= "Error transfering information";
+ goto err;
+ }
+ }
+
+ delete (*handler_src);
+ *handler_src= NULL;
+ info->set_rpl_info_handler(*handler_dest);
+ info->set_rpl_info_type(option);
+ error= FALSE;
+
+err:
+ DBUG_RETURN(error);
+}
+
+/**
+ Changes the type of the repository after startup based on the following
+ decision table:
+
+ \code
+ |--------------+-----------------------+-----------------------|
+ | Exists \ Opt | SOURCE | DESTINATION |
+ |--------------+-----------------------+-----------------------|
+ | ~is_s, ~is_d | - | Create/Update D |
+ | ~is_s, is_d | - | Continue with D |
+ | is_s, ~is_d | Copy S into D | Create/Update D |
+ | is_s, is_d | Copy S into D | Continue with D |
+ |--------------+-----------------------+-----------------------|
+ \endcode
+
+ @param[in] info Either master info or relay log info.
+ @param[in] option Identifies the type of the repository that will
+ be used, i.e., destination repository.
+ @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
+ copied.
+ @param[out] msg Error message if something goes wrong.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+*/
+bool Rpl_info_factory::change_repository(Rpl_info *info,
+ uint option,
+ Rpl_info_handler **handler_src,
+ Rpl_info_handler **handler_dest,
+ const char **msg)
+{
+ bool error= TRUE;
+
+ DBUG_ENTER("Rpl_info_factory::change_repository");
+
+ DBUG_ASSERT((*handler_dest) != NULL && (*handler_dest) != NULL);
+ if (!(*handler_src)->check_info())
+ {
+ if ((*handler_dest)->init_info())
+ {
+ *msg= "Error initializing new repository";
+ goto err;
+ }
+
+ /*
+ Transfer the information from source to destination and delete the
+ source. Note this is not fault-tolerant and a crash before removing
+ source may cause the next restart to fail as is_src and is_dest may
+ be true. Moreover, any failure in removing the source may lead to
+ the same.
+
+ /Alfranio
+ */
+ if (info->copy_info(*handler_src, *handler_dest) || (*handler_src)->remove_info())
+ {
+ *msg= "Error transfering information";
+ goto err;
}
- delete (*file);
- info->set_rpl_info_handler(*table);
- error= FALSE;
- *file= NULL;
}
else
{
- if (is_t && !is_f)
+ if ((*handler_src)->remove_info())
{
- if ((*table)->init_info() || (*file)->init_info())
- {
- *msg= "Error transfering information from a file to a table.";
+ *msg= "Error removing old repository";
+ goto err;
+ }
+ }
+
+ info->set_rpl_info_handler(NULL);
+ delete (*handler_src);
+ *handler_src= NULL;
+ info->set_rpl_info_handler(*handler_dest);
+ info->set_rpl_info_type(option);
+ error= FALSE;
+
+err:
+ DBUG_RETURN(error);
+}
+
+/**
+ 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
+ be used, i.e., destination repository.
+ @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
+ copied.
+ @param[out] msg Error message if something goes wrong.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+*/
+bool Rpl_info_factory::init_mi_repositories(Master_info *mi,
+ uint mi_option,
+ Rpl_info_handler **handler_src,
+ Rpl_info_handler **handler_dest,
+ const char **msg)
+{
+ bool error= TRUE;
+ *msg= "Failed to allocate memory for master info repositories";
+
+ DBUG_ENTER("Rpl_info_factory::init_mi_repositories");
+
+ DBUG_ASSERT(handler_dest != NULL);
+ switch (mi_option)
+ {
+ case INFO_REPOSITORY_FILE:
+ if (!(*handler_dest= new Rpl_info_file(mi->get_number_info_mi_fields(),
+ master_info_file)))
goto err;
- }
- /*
- Transfer the information from the table to the file and delete
- entries in the table, i.e. Update the file (F) and delete the
- table (T).
- */
- if (info->copy_info(*table, *file) || (*table)->remove_info())
- {
- *msg= "Error transfering information from a table to a file.";
+ 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)))
goto err;
- }
- }
- delete (*table);
- info->set_rpl_info_handler(*file);
- error= FALSE;
- *table= NULL;
+ 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)))
+ goto err;
+ if (handler_src &&
+ !(*handler_src= new Rpl_info_file(mi->get_number_info_mi_fields(),
+ master_info_file)))
+ goto err;
+ break;
+ default:
+ DBUG_ASSERT(0);
}
+ error= FALSE;
err:
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/**
- Changes the engine in use by a handler.
-
- @param[in] handler Reference to a handler.
- @param[in] engine Type of the engine, e.g. Innodb, MyIsam.
- @param[out] msg Message specifying what went wrong, if there is any error.
+ Creates repositories that will be associated to the relay log info.
+
+ @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[out] handler_src Source repository from where information is
+ copied into the destination repository.
+ @param[out] handler_dest Destination repository to where informaiton is
+ copied.
+ @param[out] msg Error message if something goes wrong.
@retval FALSE No error
@retval TRUE Failure
*/
-bool Rpl_info_factory::change_engine(Rpl_info_table *table, const char *engine,
- const char **msg)
+bool Rpl_info_factory::init_rli_repositories(Relay_log_info *rli,
+ uint rli_option,
+ Rpl_info_handler **handler_src,
+ Rpl_info_handler **handler_dest,
+ const char **msg)
{
- DBUG_ENTER("Rpl_info_factory::decide_engine");
+ bool error= TRUE;
+ *msg= "Failed to allocate memory for relay log info repositories";
+
+ DBUG_ENTER("Rpl_info_factory::init_rli_repositories");
- if (engine && table->change_engine(engine))
+ DBUG_ASSERT(handler_dest != NULL);
+ switch (rli_option)
{
- *msg= "Error changing the engine for a respository.";
- DBUG_RETURN(TRUE);
+ case INFO_REPOSITORY_FILE:
+ if (!(*handler_dest= new Rpl_info_file(rli->get_number_info_rli_fields(),
+ relay_log_info_file)))
+ 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)))
+ 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)))
+ goto err;
+ if (handler_src &&
+ !(*handler_src= new Rpl_info_file(rli->get_number_info_rli_fields(),
+ relay_log_info_file)))
+ goto err;
+ break;
+ default:
+ DBUG_ASSERT(0);
}
+ error= FALSE;
- DBUG_RETURN(FALSE);
+err:
+ DBUG_RETURN(error);
}
=== modified file 'sql/rpl_info_factory.h'
--- a/sql/rpl_info_factory.h 2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_factory.h 2011-03-23 23:28:49 +0000
@@ -16,6 +16,7 @@
#ifndef RPL_INFO_FACTORY_H
#define RPL_INFO_FACTORY_H
+#include "table.h"
#include "rpl_info.h"
#include "rpl_mi.h"
#include "rpl_rli.h"
@@ -23,42 +24,43 @@
#include "rpl_info_table.h"
#include "rpl_info_handler.h"
-enum enum_mi_repository
-{
- MI_REPOSITORY_FILE= 0,
- MI_REPOSITORY_TABLE= 1
-};
extern ulong opt_mi_repository_id;
-
-enum enum_rli_repository
-{
- RLI_REPOSITORY_FILE= 0,
- RLI_REPOSITORY_TABLE= 1
-};
extern ulong opt_rli_repository_id;
#define MI_FIELD_ID 0
-
-#define MI_SCHEMA "mysql"
-#define MI_TABLE "slave_master_info"
-
#define RLI_FIELD_ID 0
-#define RLI_SCHEMA "mysql"
-#define RLI_TABLE "slave_relay_log_info"
-
class Rpl_info_factory
{
- public:
-
+public:
static bool create(uint mi_option, Master_info **mi,
uint rli_option, Relay_log_info **rli);
static Master_info *create_mi(uint rli_option);
+ static bool change_mi_repository(Master_info *mi, uint mi_option,
+ const char **msg);
static Relay_log_info *create_rli(uint rli_option, bool is_slave_recovery);
- static bool decide_repository(Rpl_info *info, Rpl_info_table **table,
- Rpl_info_file **file, bool is_table,
+ static bool change_rli_repository(Relay_log_info *mi, uint mi_option,
+ const char **msg);
+private:
+ static bool decide_repository(Rpl_info *info,
+ uint option,
+ Rpl_info_handler **handler_src,
+ Rpl_info_handler **handler_dest,
+ const char **msg);
+ static bool change_repository(Rpl_info *info,
+ uint option,
+ Rpl_info_handler **handler_src,
+ Rpl_info_handler **handler_dest,
const char **msg);
- static bool change_engine(Rpl_info_table *table, const char *engine,
- const char **msg);
+ static bool init_mi_repositories(Master_info *mi,
+ uint mi_option,
+ 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,
+ Rpl_info_handler **handler_src,
+ Rpl_info_handler **handler_dest,
+ const char **msg);
};
#endif
=== modified file 'sql/rpl_info_file.cc'
--- a/sql/rpl_info_file.cc 2011-04-04 09:42:22 +0000
+++ b/sql/rpl_info_file.cc 2011-04-04 10:06:13 +0000
@@ -313,6 +313,11 @@ bool Rpl_info_file::do_is_transactional(
return FALSE;
}
+bool Rpl_info_file::do_update_is_transactional()
+{
+ return FALSE;
+}
+
int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
const char *default_val)
{
=== modified file 'sql/rpl_info_file.h'
--- a/sql/rpl_info_file.h 2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_file.h 2011-03-23 23:28:49 +0000
@@ -20,13 +20,16 @@
#include <sql_priv.h>
#include "rpl_info_handler.h"
+class Rpl_info_factory;
+
/**
Defines a file hander.
*/
class Rpl_info_file : public Rpl_info_handler
{
+ friend class Rpl_info_factory;
+
public:
- Rpl_info_file(int const nparam, const char* param_info_fname);
virtual ~Rpl_info_file() { };
private:
@@ -66,8 +69,11 @@ private:
const Server_ids *default_value);
char* do_get_description_info();
bool do_is_transactional();
+ bool do_update_is_transactional();
- Rpl_info_file& operator=(const Rpl_info_file& info);
+ Rpl_info_file(int const nparam, const char* param_info_fname);
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.cc'
--- a/sql/rpl_info_handler.cc 2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_handler.cc 2011-03-23 23:28:49 +0000
@@ -35,10 +35,7 @@ Rpl_info_handler::Rpl_info_handler(const
Rpl_info_handler::~Rpl_info_handler()
{
- if (field_values)
- {
- delete field_values;
- }
+ delete field_values;
}
void Rpl_info_handler::set_sync_period(uint period)
=== modified file 'sql/rpl_info_handler.h'
--- a/sql/rpl_info_handler.h 2011-02-04 11:55:17 +0000
+++ b/sql/rpl_info_handler.h 2011-03-23 23:28:49 +0000
@@ -23,9 +23,6 @@
class Rpl_info_handler
{
public:
- Rpl_info_handler(const int nparam);
- virtual ~Rpl_info_handler();
-
/**
After creating an object and assembling components, this method is
used to initialize internal structures. Everything that does not
@@ -260,6 +257,21 @@ public:
*/
bool is_transactional() { return do_is_transactional(); }
+ /**
+ Updates the value returned by the member function is_transactional()
+ because it may be expensive to compute it whenever is_transactional()
+ is called.
+
+ In the current implementation, the type of the repository can only be
+ changed when replication, i.e. slave, is stopped. For that reason,
+ this member function, i.e. update_is__transactional(), must be called
+ when slave is starting.
+
+ @retval FALSE No error
+ @retval TRUE Failure
+ */
+ bool update_is_transactional() { return do_update_is_transactional(); }
+
/*
Pre-store information before writing it to the repository and if
necessary after reading it from the repository. The decision is
@@ -267,6 +279,8 @@ public:
*/
Rpl_info_values *field_values;
+ virtual ~Rpl_info_handler();
+
protected:
/* Number of fields to be stored in the repository. */
int ninfo;
@@ -289,6 +303,8 @@ protected:
*/
uint sync_period;
+ Rpl_info_handler(const int nparam);
+
private:
virtual int do_init_info()= 0;
virtual int do_check_info()= 0;
@@ -315,8 +331,10 @@ private:
const Server_ids *default_value)= 0;
virtual char* do_get_description_info()= 0;
virtual bool do_is_transactional()= 0;
+ virtual bool do_update_is_transactional()= 0;
- Rpl_info_handler& operator=(const Rpl_info_handler& handler);
Rpl_info_handler(const Rpl_info_handler& handler);
+
+ Rpl_info_handler& operator=(const Rpl_info_handler& handler);
};
#endif /* RPL_INFO_HANDLER_H */
=== modified file 'sql/rpl_info_table.cc'
--- a/sql/rpl_info_table.cc 2011-04-04 09:42:22 +0000
+++ b/sql/rpl_info_table.cc 2011-04-04 10:06:13 +0000
@@ -15,12 +15,12 @@
#include "rpl_info_table.h"
#include "rpl_utility.h"
-#include "sql_parse.h"
Rpl_info_table::Rpl_info_table(uint nparam, uint param_field_idx,
const char* param_schema,
const char *param_table)
-:Rpl_info_handler(nparam), field_idx(param_field_idx)
+:Rpl_info_handler(nparam), field_idx(param_field_idx),
+ is_transactional(FALSE)
{
str_schema.str= str_table.str= NULL;
str_schema.length= str_table.length= 0;
@@ -52,17 +52,13 @@ Rpl_info_table::Rpl_info_table(uint npar
Rpl_info_table::~Rpl_info_table()
{
- if (access)
- delete access;
+ delete access;
- if (description)
- my_free(description);
+ my_free(description);
- if (str_table.str)
- my_free(str_table.str);
+ my_free(str_table.str);
- if (str_schema.str)
- my_free(str_schema.str);
+ my_free(str_schema.str);
}
int Rpl_info_table::do_init_info()
@@ -452,47 +448,35 @@ char* Rpl_info_table::do_get_description
bool Rpl_info_table::do_is_transactional()
{
- ulong saved_mode;
- TABLE *table= NULL;
- Open_tables_backup backup;
- bool is_trans= FALSE;
-
- DBUG_ENTER("Rpl_info_table::do_is_transactional");
-
- 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))
- is_trans= table->file->has_transactions();
-
- access->close_table(thd, table, &backup, 0);
- thd->variables.sql_mode= saved_mode;
- access->drop_thd(thd);
- DBUG_RETURN(is_trans);
+ return is_transactional;
}
-bool Rpl_info_table::change_engine(const char *engine)
+bool Rpl_info_table::do_update_is_transactional()
{
bool error= TRUE;
ulong saved_mode;
-
- DBUG_ENTER("Rpl_info_table::do_check_info");
+ TABLE *table= NULL;
+ Open_tables_backup backup;
+
+ DBUG_ENTER("Rpl_info_table::do_update_is_transactional");
THD *thd= access->create_thd();
-
saved_mode= thd->variables.sql_mode;
tmp_disable_binlog(thd);
- /* TODO: Change the engine using internal functions */
-
+ /*
+ 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))
+ goto end;
+
+ is_transactional= table->file->has_transactions();
error= FALSE;
+end:
+ access->close_table(thd, table, &backup, 0);
reenable_binlog(thd);
thd->variables.sql_mode= saved_mode;
access->drop_thd(thd);
=== modified file 'sql/rpl_info_table.h'
--- a/sql/rpl_info_table.h 2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_table.h 2011-03-23 23:28:49 +0000
@@ -19,22 +19,15 @@
#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;
+
public:
- Rpl_info_table(uint nparam, uint param_field_id, const char* param_schema,
- const char *param_table);
virtual ~Rpl_info_table();
- /*
- This enables to change the engine in use by internally executing
- an ALTER TABLE ENGINE= engine.
-
- @param[in] engine Type of the engine, e.g. Innodb, MyIsam.
- @retval FALSE No error
- @retval TRUE Failure
- */
- bool change_engine(const char* engine);
private:
/*
This property identifies the name of the schema where a
@@ -65,6 +58,12 @@ private:
*/
Rpl_info_table_access *access;
+ /*
+ Identifies if a table is transactional or non-transactional.
+ This is used to provide a crash-safe behaviour.
+ */
+ bool is_transactional;
+
int do_init_info();
int do_check_info();
void do_end_info();
@@ -90,9 +89,12 @@ private:
const Server_ids *default_value);
char* do_get_description_info();
bool do_is_transactional();
+ bool do_update_is_transactional();
- Rpl_info_table& operator=(const Rpl_info_table& info);
+ 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& 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 2010-10-27 11:20:32 +0000
+++ b/sql/rpl_info_table_access.cc 2011-03-23 23:28:49 +0000
@@ -288,6 +288,8 @@ THD *Rpl_info_table_access::create_thd()
thd= new THD;
thd->thread_stack= (char*) &thd;
thd->store_globals();
+ thd->security_ctx->skip_grants();
+ thd->system_thread= SYSTEM_THREAD_INFO_REPOSITORY;
}
else
thd= current_thd;
=== modified file 'sql/rpl_info_values.cc'
--- a/sql/rpl_info_values.cc 2010-10-27 09:04:21 +0000
+++ b/sql/rpl_info_values.cc 2011-03-23 23:28:49 +0000
@@ -39,8 +39,5 @@ bool Rpl_info_values::init()
Rpl_info_values::~Rpl_info_values()
{
- for (int pos= 0; pos < ninfo; pos++)
- value[pos].~String();
-
delete [] value;
}
=== modified file 'sql/rpl_mi.h'
--- a/sql/rpl_mi.h 2010-12-21 09:33:41 +0000
+++ b/sql/rpl_mi.h 2011-03-23 23:28:49 +0000
@@ -27,6 +27,7 @@
#include "my_sys.h"
typedef struct st_mysql MYSQL;
+class Rpl_info_factory;
/*****************************************************************************
Replication IO Thread
@@ -62,18 +63,9 @@ typedef struct st_mysql MYSQL;
class Master_info : public Rpl_info
{
- public:
- Master_info(
-#ifdef HAVE_PSI_INTERFACE
- PSI_mutex_key *param_key_info_run_lock,
- PSI_mutex_key *param_key_info_data_lock,
- PSI_mutex_key *param_key_info_data_cond,
- PSI_mutex_key *param_key_info_start_cond,
- PSI_mutex_key *param_key_info_stop_cond
-#endif
- );
- virtual ~Master_info();
+ friend class Rpl_info_factory;
+public:
/* the variables below are needed because we can change masters on the fly */
char host[HOSTNAME_LENGTH+1];
char user[USERNAME_LENGTH+1];
@@ -120,6 +112,8 @@ class Master_info : public Rpl_info
bool shall_ignore_server_id(ulong s_id);
+ virtual ~Master_info();
+
protected:
char master_log_name[FN_REFLEN];
my_off_t master_log_pos;
@@ -146,8 +140,18 @@ private:
bool read_info(Rpl_info_handler *from);
bool write_info(Rpl_info_handler *to, bool force);
- Master_info& operator=(const Master_info& info);
+ Master_info(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond
+#endif
+ );
Master_info(const Master_info& info);
+
+ Master_info& operator=(const Master_info& info);
};
int change_master_server_id_cmp(ulong *id1, ulong *id2);
=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h 2010-12-21 09:33:41 +0000
+++ b/sql/rpl_rli.h 2011-03-23 23:28:49 +0000
@@ -28,6 +28,7 @@
struct RPL_TABLE_LIST;
class Master_info;
+class Rpl_info_factory;
extern uint sql_slave_skip_counter;
/*******************************************************************************
@@ -104,6 +105,8 @@ tables along with the --relay-log-recove
*******************************************************************************/
class Relay_log_info : public Rpl_info
{
+ friend class Rpl_info_factory;
+
public:
/**
Flags for the state of the replication.
@@ -328,17 +331,6 @@ public:
char slave_patternload_file[FN_REFLEN];
size_t slave_patternload_file_size;
- Relay_log_info(bool is_slave_recovery
-#ifdef HAVE_PSI_INTERFACE
- ,PSI_mutex_key *param_key_info_run_lock,
- PSI_mutex_key *param_key_info_data_lock,
- PSI_mutex_key *param_key_info_data_cond,
- PSI_mutex_key *param_key_info_start_cond,
- PSI_mutex_key *param_key_info_stop_cond
-#endif
- );
- virtual ~Relay_log_info();
-
/**
Invalidates cached until_log_name and group_relay_log_name comparison
result. Should be called after any update of group_realy_log_name if
@@ -585,8 +577,9 @@ public:
void set_sql_delay(time_t _sql_delay) { sql_delay= _sql_delay; }
time_t get_sql_delay_end() { return sql_delay_end; }
-private:
+ virtual ~Relay_log_info();
+private:
/**
Delay slave SQL thread by this amount, compared to master (in
seconds). This is set with CHANGE MASTER TO MASTER_DELAY=X.
@@ -610,6 +603,7 @@ 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.
@@ -619,10 +613,18 @@ private:
bool read_info(Rpl_info_handler *from);
bool write_info(Rpl_info_handler *to, bool force);
- Relay_log_info& operator=(const Relay_log_info& info);
+ Relay_log_info(bool is_slave_recovery
+#ifdef HAVE_PSI_INTERFACE
+ ,PSI_mutex_key *param_key_info_run_lock,
+ PSI_mutex_key *param_key_info_data_lock,
+ PSI_mutex_key *param_key_info_data_cond,
+ PSI_mutex_key *param_key_info_start_cond,
+ PSI_mutex_key *param_key_info_stop_cond
+#endif
+ );
Relay_log_info(const Relay_log_info& info);
- uint32 m_flags;
+ Relay_log_info& operator=(const Relay_log_info& info);
};
bool mysql_show_relaylog_events(THD* thd);
=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc 2011-04-04 08:47:25 +0000
+++ b/sql/rpl_slave.cc 2011-04-04 10:06:13 +0000
@@ -141,8 +141,6 @@ failed read"
};
-typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
-
static int process_io_rotate(Master_info* mi, Rotate_log_event* rev);
static int process_io_create_file(Master_info* mi, Create_file_log_event* cev);
static bool wait_for_relay_log_space(Relay_log_info* rli);
@@ -3534,7 +3532,7 @@ pthread_handler_t handle_slave_sql(void
Relay_log_info* rli = ((Master_info*)arg)->rli;
const char *errmsg;
-
+
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
my_thread_init();
DBUG_ENTER("handle_slave_sql");
@@ -3596,6 +3594,20 @@ pthread_handler_t handle_slave_sql(void
*/
rli->clear_error();
+ if (rli->update_is_transactional())
+ {
+ mysql_cond_broadcast(&rli->start_cond);
+ mysql_mutex_unlock(&rli->run_lock);
+ rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+ "Error checking if the relay log repository is transactional.");
+ goto err;
+ }
+
+ if (!rli->is_transactional())
+ rli->report(WARNING_LEVEL, 0,
+ "If a crash happens this configuration does not guarantee that the relay "
+ "log info will be consistent");
+
mysql_mutex_unlock(&rli->run_lock);
mysql_cond_broadcast(&rli->start_cond);
=== modified file 'sql/rpl_slave.h'
--- a/sql/rpl_slave.h 2011-03-28 13:19:08 +0000
+++ b/sql/rpl_slave.h 2011-04-04 10:06:13 +0000
@@ -16,6 +16,8 @@
#ifndef RPL_SLAVE_H
#define RPL_SLAVE_H
+typedef enum {SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
+
/**
MASTER_DELAY can be at most (1 << 31) - 1.
*/
=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt 2011-03-25 14:35:13 +0000
+++ b/sql/share/errmsg-utf8.txt 2011-04-04 10:06:13 +0000
@@ -6495,3 +6495,6 @@ ER_TABLE_NEEDS_REBUILD
WARN_OPTION_BELOW_LIMIT
eng "The value of '%s' should be no less than the value of '%s'"
+
+ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE
+ eng "Failure while changing the type of replication repository: %s."
=== modified file 'sql/sql_binlog.cc'
--- a/sql/sql_binlog.cc 2010-12-02 13:44:21 +0000
+++ b/sql/sql_binlog.cc 2011-03-23 23:28:49 +0000
@@ -158,7 +158,7 @@ void mysql_client_binlog_statement(THD*
Relay_log_info *rli= thd->rli_fake;
if (!rli)
{
- if ((rli= Rpl_info_factory::create_rli(RLI_REPOSITORY_FILE, FALSE)))
+ if ((rli= Rpl_info_factory::create_rli(INFO_REPOSITORY_FILE, FALSE)))
{
thd->rli_fake= rli;
rli->info_thd= thd;
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2011-03-24 08:00:03 +0000
+++ b/sql/sql_class.h 2011-04-04 10:06:13 +0000
@@ -1193,7 +1193,8 @@ enum enum_thread_type
SYSTEM_THREAD_SLAVE_SQL= 4,
SYSTEM_THREAD_NDBCLUSTER_BINLOG= 8,
SYSTEM_THREAD_EVENT_SCHEDULER= 16,
- SYSTEM_THREAD_EVENT_WORKER= 32
+ SYSTEM_THREAD_EVENT_WORKER= 32,
+ SYSTEM_THREAD_INFO_REPOSITORY= 64
};
inline char const *
@@ -1209,6 +1210,7 @@ show_system_thread(enum_thread_type thre
RETURN_NAME_AS_STRING(SYSTEM_THREAD_NDBCLUSTER_BINLOG);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_SCHEDULER);
RETURN_NAME_AS_STRING(SYSTEM_THREAD_EVENT_WORKER);
+ RETURN_NAME_AS_STRING(SYSTEM_THREAD_INFO_REPOSITORY);
default:
sprintf(buf, "<UNKNOWN SYSTEM THREAD: %d>", thread);
return buf;
=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc 2011-03-25 14:35:13 +0000
+++ b/sql/sys_vars.cc 2011-04-04 10:06:13 +0000
@@ -36,6 +36,8 @@
#include <thr_alarm.h>
#include "rpl_slave.h"
#include "rpl_mi.h"
+#include "rpl_rli.h"
+#include "rpl_slave.h"
#include "rpl_info_factory.h"
#include "transaction.h"
#include "mysqld.h"
@@ -490,6 +492,73 @@ static Sys_var_mybool Sys_binlog_direct(
CMD_LINE(OPT_ARG), DEFAULT(FALSE),
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(binlog_direct_check));
+static bool repository_check(sys_var *self, THD *thd, set_var *var, SLAVE_THD_TYPE thread_mask)
+{
+ bool ret= FALSE;
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
+ {
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+ return TRUE;
+ }
+#endif
+#ifdef HAVE_REPLICATION
+ int running= 0;
+ const char *msg= NULL;
+ mysql_mutex_lock(&LOCK_active_mi);
+ if (active_mi)
+ {
+ lock_slave_threads(active_mi);
+ init_thread_mask(&running, active_mi, FALSE);
+ if(!running)
+ {
+ switch (thread_mask)
+ {
+ case SLAVE_THD_IO:
+ if (Rpl_info_factory::change_mi_repository(active_mi,
+ var->save_result.ulonglong_value,
+ &msg))
+ {
+ ret= TRUE;
+ my_error(ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE, MYF(0), msg);
+ }
+ break;
+ case SLAVE_THD_SQL:
+ if (Rpl_info_factory::change_rli_repository(active_mi->rli,
+ var->save_result.ulonglong_value,
+ &msg))
+ {
+ ret= TRUE;
+ my_error(ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE, MYF(0), msg);
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ else
+ {
+ ret= TRUE;
+ my_error(ER_SLAVE_MUST_STOP, MYF(0));
+ }
+ unlock_slave_threads(active_mi);
+ }
+ mysql_mutex_unlock(&LOCK_active_mi);
+#endif
+ return ret;
+}
+
+static bool relay_log_info_repository_check(sys_var *self, THD *thd, set_var *var)
+{
+ return repository_check(self, thd, var, SLAVE_THD_SQL);
+}
+
+static bool master_info_repository_check(sys_var *self, THD *thd, set_var *var)
+{
+ return repository_check(self, thd, var, SLAVE_THD_IO);
+}
+
static const char *repository_names[]=
{
"FILE", "TABLE", 0
@@ -499,15 +568,19 @@ ulong opt_mi_repository_id;
static Sys_var_enum Sys_mi_repository(
"master_info_repository",
"Defines the type of the repository for the master information."
- , READ_ONLY GLOBAL_VAR(opt_mi_repository_id), CMD_LINE(REQUIRED_ARG),
- repository_names, DEFAULT(0));
+ ,GLOBAL_VAR(opt_mi_repository_id), CMD_LINE(REQUIRED_ARG),
+ repository_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(master_info_repository_check),
+ ON_UPDATE(0));
ulong opt_rli_repository_id;
static Sys_var_enum Sys_rli_repository(
"relay_log_info_repository",
"Defines the type of the repository for the relay log information."
- , READ_ONLY GLOBAL_VAR(opt_rli_repository_id), CMD_LINE(REQUIRED_ARG),
- repository_names, DEFAULT(0));
+ ,GLOBAL_VAR(opt_rli_repository_id), CMD_LINE(REQUIRED_ARG),
+ repository_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(relay_log_info_repository_check),
+ ON_UPDATE(0));
static Sys_var_mybool Sys_binlog_rows_query(
"binlog_rows_query_log_events",
=== modified file 'sql/table.h'
--- a/sql/table.h 2011-04-01 14:04:52 +0000
+++ b/sql/table.h 2011-04-04 10:06:13 +0000
@@ -2203,6 +2203,10 @@ extern LEX_STRING SLOW_LOG_NAME;
extern LEX_STRING INFORMATION_SCHEMA_NAME;
extern LEX_STRING MYSQL_SCHEMA_NAME;
+/* replication's tables */
+extern LEX_STRING RLI_INFO_NAME;
+extern LEX_STRING MI_INFO_NAME;
+
inline bool is_infoschema_db(const char *name, size_t len)
{
return (INFORMATION_SCHEMA_NAME.length == len &&
No bundle (reason: revision is a merge).
| Thread |
|---|
| • bzr commit into mysql-trunk branch (alfranio.correia:3357) | Alfranio Correia | 4 Apr |