From: Andrei Elkin Date: November 25 2010 9:04am Subject: bzr commit into mysql-next-mr.crash-safe branch (andrei.elkin:3217) WL#5569 WL#5599 List-Archive: http://lists.mysql.com/commits/124986 Message-Id: <201011250904.oAP949nQ007172@mysql1000.dsl.inet.fi> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0494418659==" --===============0494418659== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///home/andrei/MySQL/BZR/2a-23May/WL/mysql-next-mr-wl5569/ based on revid:andrei.elkin@stripped 3217 Andrei Elkin 2010-11-25 [merge] wl#5569 merging with wl#5599 piece of code added: mysql-test/suite/rpl/t/rpl_parallel-slave.opt mysql-test/suite/rpl/t/rpl_parallel_start_stop-slave.opt sql/rpl_info_dummy.cc sql/rpl_info_dummy.h modified: sql/CMakeLists.txt sql/Makefile.am sql/mysqld.cc sql/rpl_info.cc sql/rpl_info.h sql/rpl_info_factory.cc sql/rpl_mi.cc sql/rpl_mi.h sql/rpl_rli.cc sql/rpl_rli.h sql/rpl_rli_pdb.h sql/rpl_slave.cc === added file 'mysql-test/suite/rpl/t/rpl_parallel-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_parallel-slave.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/t/rpl_parallel-slave.opt 2010-11-23 09:03:37 +0000 @@ -0,0 +1 @@ +--relay-log-info-repository=FILE === added file 'mysql-test/suite/rpl/t/rpl_parallel_start_stop-slave.opt' --- a/mysql-test/suite/rpl/t/rpl_parallel_start_stop-slave.opt 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/rpl/t/rpl_parallel_start_stop-slave.opt 2010-11-23 09:03:37 +0000 @@ -0,0 +1 @@ +--relay-log-info-repository=FILE === modified file 'sql/CMakeLists.txt' --- a/sql/CMakeLists.txt 2010-11-09 13:04:14 +0000 +++ b/sql/CMakeLists.txt 2010-11-23 09:03:37 +0000 @@ -106,7 +106,8 @@ ADD_DEPENDENCIES(master GenError) SET (SLAVE_SOURCE rpl_slave.cc rpl_reporting.cc rpl_mi.cc rpl_rli.cc rpl_info_handler.cc rpl_info_file.cc rpl_info_table.cc rpl_info_values.cc rpl_info.cc rpl_info_factory.cc - rpl_info_table_access.cc server_ids.h rpl_rli_pdb.cc) + rpl_info_table_access.cc server_ids.h rpl_rli_pdb.cc + rpl_info_dummy.cc) ADD_LIBRARY(slave ${SLAVE_SOURCE}) ADD_DEPENDENCIES(slave GenError) ADD_LIBRARY(sqlgunitlib mdl.cc sql_list.cc sql_string.cc thr_malloc.cc) === modified file 'sql/Makefile.am' --- a/sql/Makefile.am 2010-11-09 13:04:14 +0000 +++ b/sql/Makefile.am 2010-11-23 09:03:37 +0000 @@ -110,7 +110,7 @@ noinst_HEADERS = item.h item_func.h item rpl_info_handler.h \ log.h sql_show.h rpl_info.h rpl_info_file.h \ rpl_info_table.h rpl_rli.h rpl_mi.h rpl_info_values.h \ - rpl_info_table_access.h \ + rpl_info_table_access.h rpl_info_dummy.h \ rpl_info_factory.h server_ids.h rpl_rli_pdb.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h \ lex.h lex_symbol.h sql_acl.h sql_crypt.h sql_base.h \ @@ -196,7 +196,7 @@ librpl_la_SOURCES = rpl_handler.cc r libmaster_la_SOURCES = rpl_master.cc libslave_la_SOURCES = rpl_slave.cc rpl_reporting.cc rpl_rli.cc rpl_mi.cc \ rpl_info.cc rpl_info_factory.cc rpl_info_file.cc \ - rpl_info_handler.cc rpl_info_table.cc \ + rpl_info_handler.cc rpl_info_table.cc rpl_info_dummy.cc \ rpl_info_table_access.cc rpl_info_values.cc rpl_rli_pdb.cc libndb_la_CPPFLAGS= @ndbcluster_includes@ libndb_la_SOURCES= ha_ndbcluster.cc \ === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2010-11-09 13:04:14 +0000 +++ b/sql/mysqld.cc 2010-11-23 09:03:37 +0000 @@ -7836,9 +7836,8 @@ PSI_mutex_key key_BINLOG_LOCK_index, key key_LOCK_server_started, key_LOCK_status, key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data, key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log, - key_master_info_data_lock, key_master_info_run_lock, - key_mutex_slave_reporting_capability_err_lock, key_relay_log_info_data_lock, - key_relay_log_info_log_space_lock, key_relay_log_info_run_lock, + key_mutex_slave_reporting_capability_err_lock, + key_relay_log_info_log_space_lock, key_structure_guard_mutex, key_TABLE_SHARE_LOCK_ha_data, key_LOCK_error_messages, key_LOG_INFO_lock, key_LOCK_thread_count, key_PARTITION_LOCK_auto_inc; @@ -7880,12 +7879,8 @@ static PSI_mutex_info all_server_mutexes { &key_LOCK_user_conn, "LOCK_user_conn", PSI_FLAG_GLOBAL}, { &key_LOCK_uuid_generator, "LOCK_uuid_generator", PSI_FLAG_GLOBAL}, { &key_LOG_LOCK_log, "LOG::LOCK_log", 0}, - { &key_master_info_data_lock, "Master_info::data_lock", 0}, - { &key_master_info_run_lock, "Master_info::run_lock", 0}, { &key_mutex_slave_reporting_capability_err_lock, "Slave_reporting_capability::err_lock", 0}, - { &key_relay_log_info_data_lock, "Relay_log_info::data_lock", 0}, { &key_relay_log_info_log_space_lock, "Relay_log_info::log_space_lock", 0}, - { &key_relay_log_info_run_lock, "Relay_log_info::run_lock", 0}, { &key_structure_guard_mutex, "Query_cache::structure_guard_mutex", 0}, { &key_TABLE_SHARE_LOCK_ha_data, "TABLE_SHARE::LOCK_ha_data", 0}, { &key_LOCK_error_messages, "LOCK_error_messages", PSI_FLAG_GLOBAL}, @@ -7919,10 +7914,8 @@ PSI_cond_key key_BINLOG_COND_prep_xids, key_COND_cache_status_changed, key_COND_global_read_lock, key_COND_manager, key_COND_server_started, key_delayed_insert_cond, key_delayed_insert_cond_client, - key_item_func_sleep_cond, key_master_info_data_cond, - key_master_info_start_cond, key_master_info_stop_cond, - key_relay_log_info_data_cond, key_relay_log_info_log_space_cond, - key_relay_log_info_start_cond, key_relay_log_info_stop_cond, + key_item_func_sleep_cond, + key_relay_log_info_log_space_cond, key_TABLE_SHARE_cond, key_user_level_lock_cond, key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache; @@ -7945,13 +7938,7 @@ static PSI_cond_info all_server_conds[]= { &key_delayed_insert_cond, "Delayed_insert::cond", 0}, { &key_delayed_insert_cond_client, "Delayed_insert::cond_client", 0}, { &key_item_func_sleep_cond, "Item_func_sleep::cond", 0}, - { &key_master_info_data_cond, "Master_info::data_cond", 0}, - { &key_master_info_start_cond, "Master_info::start_cond", 0}, - { &key_master_info_stop_cond, "Master_info::stop_cond", 0}, - { &key_relay_log_info_data_cond, "Relay_log_info::data_cond", 0}, { &key_relay_log_info_log_space_cond, "Relay_log_info::log_space_cond", 0}, - { &key_relay_log_info_start_cond, "Relay_log_info::start_cond", 0}, - { &key_relay_log_info_stop_cond, "Relay_log_info::stop_cond", 0}, { &key_TABLE_SHARE_cond, "TABLE_SHARE::cond", 0}, { &key_user_level_lock_cond, "User_level_lock::cond", 0}, { &key_COND_thread_count, "COND_thread_count", PSI_FLAG_GLOBAL}, === modified file 'sql/rpl_info.cc' --- a/sql/rpl_info.cc 2010-11-11 11:53:01 +0000 +++ b/sql/rpl_info.cc 2010-11-23 09:03:37 +0000 @@ -48,36 +48,101 @@ void Rpl_info::set_rpl_info_handler(Rpl_ handler= param_handler; } -Rpl_info_coordinator::Rpl_info_coordinator(const char* type, - 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) - : Rpl_info(type), - key_info_run_lock(param_key_info_run_lock), - key_info_data_lock(param_key_info_data_lock), - key_info_data_cond(param_key_info_data_cond), - key_info_start_cond(param_key_info_start_cond), - key_info_stop_cond(param_key_info_stop_cond) +Rpl_info_coordinator::Rpl_info_coordinator(const char* type) + : Rpl_info(type) +{ + register_mutexes(type); +} + +bool Rpl_info_coordinator::register_mutexes(const char* description) { - mysql_mutex_init(*key_info_run_lock, &run_lock, MY_MUTEX_INIT_FAST); - mysql_mutex_init(*key_info_data_lock, - &data_lock, MY_MUTEX_INIT_FAST); - mysql_cond_init(*key_info_data_cond, &data_cond, NULL); - mysql_cond_init(*key_info_start_cond, &start_cond, NULL); - mysql_cond_init(*key_info_stop_cond, &stop_cond, NULL); + PSI_mutex_info *mutex_info= NULL; + PSI_cond_info *cond_info= NULL; + PSI_mutex_key *key_mutex_info= NULL; + PSI_cond_key *key_cond_info= NULL; + + const int NUMBER_MUTEX_INFO= 2; + const int RUN_LOCK_IDX= 0; + const int DATA_LOCK_IDX= 1; + + const int NUMBER_COND_INFO= 3; + const int DATA_COND_IDX= 0; + const int START_COND_IDX= 1; + const int STOP_COND_IDX= 2; + + if (!(key_mutex_info= new PSI_mutex_key[NUMBER_MUTEX_INFO]) || + !(key_cond_info= new PSI_cond_key[NUMBER_COND_INFO]) || + !(mutex_info= new PSI_mutex_info[NUMBER_MUTEX_INFO]) || + !(cond_info= new PSI_cond_info[NUMBER_COND_INFO])) + goto err; + + mutex_info[RUN_LOCK_IDX].m_key= (PSI_mutex_key *) &(key_mutex_info[RUN_LOCK_IDX]); + mutex_info[RUN_LOCK_IDX].m_name= "Rpl_info_coordinator::run_lock"; + mutex_info[RUN_LOCK_IDX].m_flags= 0; + mutex_info[DATA_LOCK_IDX].m_key= (PSI_mutex_key *) &(key_mutex_info[DATA_LOCK_IDX]); + mutex_info[DATA_LOCK_IDX].m_name= "Rpl_info_coordinator::data_lock"; + mutex_info[DATA_LOCK_IDX].m_flags= 0; + + cond_info[DATA_COND_IDX].m_key= (PSI_cond_key *) &(key_cond_info[DATA_COND_IDX]); + cond_info[DATA_COND_IDX].m_name= "Rpl_info_coordinator::data_cond"; + cond_info[DATA_COND_IDX].m_flags= 0; + cond_info[START_COND_IDX].m_key= (PSI_cond_key *) &(key_cond_info[START_COND_IDX]); + cond_info[START_COND_IDX].m_name= "Rpl_info_coordinator::start_cond"; + cond_info[START_COND_IDX].m_flags= 0; + cond_info[STOP_COND_IDX].m_key= (PSI_cond_key *) &(key_cond_info[STOP_COND_IDX]); + cond_info[STOP_COND_IDX].m_name= "Rpl_info_coordinator::stop_cond"; + cond_info[STOP_COND_IDX].m_flags= 0; + + if (PSI_server) + { + PSI_server->register_mutex(description, mutex_info, + NUMBER_MUTEX_INFO); + + PSI_server->register_cond(description, cond_info, + NUMBER_MUTEX_INFO); + } + + mysql_mutex_init(key_mutex_info[RUN_LOCK_IDX], &run_lock, + MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_mutex_info[DATA_LOCK_IDX], &data_lock, + MY_MUTEX_INIT_FAST); + + mysql_cond_init(key_cond_info[DATA_COND_IDX], &data_cond, NULL); + mysql_cond_init(key_cond_info[START_COND_IDX], &start_cond, NULL); + mysql_cond_init(key_cond_info[STOP_COND_IDX], &stop_cond, NULL); + + registered_mutexes= TRUE; + + return (FALSE); + +err: + if (key_mutex_info) + delete []key_mutex_info; + + if (key_cond_info) + delete []key_cond_info; + + if (mutex_info) + delete []mutex_info; + + if (mutex_info) + delete []mutex_info; + + return (TRUE); } Rpl_info_coordinator::~Rpl_info_coordinator() { DBUG_ENTER("Rpl_info_coordinator::~Rpl_info_coordinator"); - mysql_mutex_destroy(&run_lock); - mysql_mutex_destroy(&data_lock); - mysql_cond_destroy(&data_cond); - mysql_cond_destroy(&start_cond); - mysql_cond_destroy(&stop_cond); + if (registered_mutexes) + { + mysql_mutex_destroy(&run_lock); + mysql_mutex_destroy(&data_lock); + mysql_cond_destroy(&data_cond); + mysql_cond_destroy(&start_cond); + mysql_cond_destroy(&stop_cond); + } DBUG_VOID_RETURN; } === modified file 'sql/rpl_info.h' --- a/sql/rpl_info.h 2010-11-11 11:53:01 +0000 +++ b/sql/rpl_info.h 2010-11-23 09:03:37 +0000 @@ -89,6 +89,7 @@ public: run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index */ mysql_mutex_t data_lock,run_lock; + /* start_cond is broadcast when SQL thread is started stop_cond - when stopped @@ -96,22 +97,31 @@ public: */ mysql_cond_t data_cond, start_cond, stop_cond; - PSI_mutex_key *key_info_run_lock, *key_info_data_lock; - - PSI_mutex_key *key_info_data_cond, *key_info_start_cond, *key_info_stop_cond; - #ifndef DBUG_OFF int events_until_exit; #endif - Rpl_info_coordinator(const char* type, - 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); + Rpl_info_coordinator(const char* type); virtual ~Rpl_info_coordinator(); + /** + Identifies if mutexes and condition variables were successfuly + created and registered. + */ + bool registered_mutexes; + +protected: + /** + Registers mutexes and condition variables in the performance + schema. + + @param description identifier to ease its localization in + the peformance schema. + + @return FALSE if success, TRUE if error. + */ + bool register_mutexes(const char* description); + private: Rpl_info_coordinator& operator=(const Rpl_info_coordinator& info); Rpl_info_coordinator(const Rpl_info_coordinator& info); === added file 'sql/rpl_info_dummy.cc' --- a/sql/rpl_info_dummy.cc 1970-01-01 00:00:00 +0000 +++ b/sql/rpl_info_dummy.cc 2010-11-23 09:03:37 +0000 @@ -0,0 +1,156 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include "rpl_info_dummy.h" + +Rpl_info_dummy::Rpl_info_dummy(bool param_abort) + :Rpl_info_handler(0), abort(param_abort) +{ +} + +int Rpl_info_dummy::do_init_info(const ulong *uidx __attribute__((unused)), + const uint nidx __attribute__((unused))) +{ + return 0; +} + +int Rpl_info_dummy::do_prepare_info_for_read() +{ + if (abort) DBUG_ASSERT(0); + return 0; +} + +int Rpl_info_dummy::do_prepare_info_for_write() +{ + if (abort) DBUG_ASSERT(0); + return 0; +} + +int Rpl_info_dummy::do_check_info(const ulong *uidx __attribute__((unused)), + const uint nidx __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return 0; +} + +int Rpl_info_dummy::do_flush_info(const ulong *uidx __attribute__((unused)), + const uint nidx __attribute__((unused)), + const bool force __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return 0; +} + +void Rpl_info_dummy::do_end_info(const ulong *uidx __attribute__((unused)), + const uint nidx __attribute__((unused))) +{ + return; +} + +int Rpl_info_dummy::do_remove_info(const ulong *uidx __attribute__((unused)), + const uint nidx __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return 0; +} + +bool Rpl_info_dummy::do_set_info(const int pos __attribute__((unused)), + const char *value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_set_info(const int pos __attribute__((unused)), + const ulong value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_set_info(const int pos __attribute__((unused)), + const int value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_set_info(const int pos __attribute__((unused)), + const float value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_set_info(const int pos __attribute__((unused)), + const Server_ids *value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_get_info(const int pos __attribute__((unused)), + char *value __attribute__((unused)), + const size_t size __attribute__((unused)), + const char *default_value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_get_info(const int pos __attribute__((unused)), + ulong *value __attribute__((unused)), + const ulong default_value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_get_info(const int pos __attribute__((unused)), + int *value __attribute__((unused)), + const int default_value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_get_info(const int pos __attribute__((unused)), + float *value __attribute__((unused)), + const float default_value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +bool Rpl_info_dummy::do_get_info(const int pos __attribute__((unused)), + Server_ids *value __attribute__((unused)), + const Server_ids *default_value __attribute__((unused))) +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} + +char* Rpl_info_dummy::do_get_description_info() +{ + if (abort) DBUG_ASSERT(0); + return NULL; +} + +bool Rpl_info_dummy::do_is_transactional() +{ + if (abort) DBUG_ASSERT(0); + return FALSE; +} === added file 'sql/rpl_info_dummy.h' --- a/sql/rpl_info_dummy.h 1970-01-01 00:00:00 +0000 +++ b/sql/rpl_info_dummy.h 2010-11-23 09:03:37 +0000 @@ -0,0 +1,69 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef RPL_INFO_DUMMY_H +#define RPL_INFO_DUMMY_H + +#include +#include +#include "rpl_info_handler.h" + +/** + Defines a dummy handler that should only be internally accessed. + This class is useful for debugging and performance tests. + + The flag abort indicates if the execution should abort if some + methods are called. See the code for further details. +*/ +class Rpl_info_dummy : public Rpl_info_handler +{ +public: + Rpl_info_dummy(bool param_abort); + virtual ~Rpl_info_dummy() { }; + +private: + int do_init_info(const ulong *uidx, const uint nidx); + int do_check_info(const ulong *uidx, const uint nidx); + void do_end_info(const ulong *uidx, const uint nidx); + int do_flush_info(const ulong *uidx, const uint nidx, + const bool force); + int do_remove_info(const ulong *uidx, const uint nidx); + + int do_prepare_info_for_read(); + int do_prepare_info_for_write(); + bool do_set_info(const int pos, const char *value); + bool do_set_info(const int pos, const int value); + bool do_set_info(const int pos, const ulong value); + bool do_set_info(const int pos, const float value); + bool do_set_info(const int pos, const Server_ids *value); + bool do_get_info(const int pos, char *value, const size_t size, + const char *default_value); + bool do_get_info(const int pos, int *value, + const int default_value); + bool do_get_info(const int pos, ulong *value, + const ulong default_value); + bool do_get_info(const int pos, float *value, + const float default_value); + 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 abort; + + Rpl_info_dummy& operator=(const Rpl_info_dummy& info); + Rpl_info_dummy(const Rpl_info_dummy& info); +}; +#endif /* RPL_INFO_DUMMY_H */ === modified file 'sql/rpl_info_factory.cc' --- a/sql/rpl_info_factory.cc 2010-11-12 17:58:12 +0000 +++ b/sql/rpl_info_factory.cc 2010-11-23 09:03:37 +0000 @@ -87,11 +87,8 @@ Master_info *Rpl_info_factory::create_mi DBUG_ENTER("Rpl_info_factory::create_mi"); - if (!(mi= new Master_info(&key_master_info_run_lock, - &key_master_info_data_lock, - &key_master_info_data_cond, - &key_master_info_start_cond, - &key_master_info_stop_cond))) + if (!(mi= new Master_info()) || + !(mi->registered_mutexes)) goto err; /* @@ -169,12 +166,8 @@ Relay_log_info *Rpl_info_factory::create DBUG_ENTER("Rpl_info_factory::create_rli"); - if (!(rli= new Relay_log_info(is_slave_recovery, - &key_relay_log_info_run_lock, - &key_relay_log_info_data_lock, - &key_relay_log_info_data_cond, - &key_relay_log_info_start_cond, - &key_relay_log_info_stop_cond))) + if (!(rli= new Relay_log_info(is_slave_recovery)) || + !(rli->registered_mutexes)) goto err; /* @@ -397,35 +390,38 @@ Slave_worker *Rpl_info_factory::create_w if (!(worker= new Slave_worker(info_name))) 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 (!(w_file= new Rpl_info_file(worker->get_number_worker_fields(), - info_fname))) - goto err; - - if (!(w_table= new Rpl_info_table(worker->get_number_worker_fields() + 1, - WORKER_SCHEMA, WORKER_TABLE))) - goto err; - - DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE || - rli_option == RLI_REPOSITORY_TABLE); + if (rli) + { + /* + 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 (!(w_file= new Rpl_info_file(worker->get_number_worker_fields(), + info_fname))) + goto err; + + if (!(w_table= new Rpl_info_table(worker->get_number_worker_fields() + 1, + WORKER_SCHEMA, WORKER_TABLE))) + goto err; - /* - Check if this is conceptually right and what happens in case of - partial failures. Problems will not happen if we decide to use - only TABLES as repositories. /Alfranio - */ - if (decide_repository(worker, idx, sizeof(idx), &w_table, &w_file, - rli_option == MI_REPOSITORY_TABLE, &msg)) - goto err; + DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE || + rli_option == RLI_REPOSITORY_TABLE); - if ((rli_option == RLI_REPOSITORY_TABLE) && - change_engine(static_cast(w_table), - relay_log_info_engine, &msg)) - goto err; + /* + Check if this is conceptually right and what happens in case of + partial failures. Problems will not happen if we decide to use + only TABLES as repositories. /Alfranio + */ + if (decide_repository(worker, idx, sizeof(idx), &w_table, &w_file, + rli_option == MI_REPOSITORY_TABLE, &msg)) + goto err; + + if ((rli_option == RLI_REPOSITORY_TABLE) && + change_engine(static_cast(w_table), + relay_log_info_engine, &msg)) + goto err; + } DBUG_RETURN(worker); === modified file 'sql/rpl_mi.cc' --- a/sql/rpl_mi.cc 2010-11-11 11:53:01 +0000 +++ b/sql/rpl_mi.cc 2010-11-23 09:03:37 +0000 @@ -76,15 +76,8 @@ const char *info_mi_fields []= "retry_count" }; -Master_info::Master_info(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) - :Rpl_info_coordinator("I/O", - param_key_info_run_lock, param_key_info_data_lock, - param_key_info_data_cond, param_key_info_start_cond, - param_key_info_stop_cond), +Master_info::Master_info() + :Rpl_info_coordinator("I/O"), ssl(0), ssl_verify_server_cert(0), port(MYSQL_PORT), connect_retry(DEFAULT_CONNECT_RETRY), clock_diff_with_master(0), heartbeat_period(0), === modified file 'sql/rpl_mi.h' --- a/sql/rpl_mi.h 2010-11-11 11:53:01 +0000 +++ b/sql/rpl_mi.h 2010-11-23 09:03:37 +0000 @@ -63,11 +63,7 @@ typedef struct st_mysql MYSQL; class Master_info : public Rpl_info_coordinator { public: - Master_info(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); + Master_info(); virtual ~Master_info(); /* the variables below are needed because we can change masters on the fly */ === modified file 'sql/rpl_rli.cc' --- a/sql/rpl_rli.cc 2010-11-25 08:47:39 +0000 +++ b/sql/rpl_rli.cc 2010-11-25 09:03:54 +0000 @@ -55,16 +55,8 @@ PSI_mutex_key key_mutex_slave_parallel_p PSI_cond_key *key_cond_slave_parallel_worker= NULL; PSI_cond_key key_cond_slave_parallel_pend_jobs; -Relay_log_info::Relay_log_info(bool is_slave_recovery, - 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) - :Rpl_info_coordinator("SQL", - param_key_info_run_lock, param_key_info_data_lock, - param_key_info_data_cond, param_key_info_start_cond, - param_key_info_stop_cond), +Relay_log_info::Relay_log_info(bool is_slave_recovery) + :Rpl_info_coordinator("SQL"), replicate_same_server_id(::replicate_same_server_id), cur_log_fd(-1), relay_log(&sync_relaylog_period), is_relay_log_recovery(is_slave_recovery), @@ -115,10 +107,10 @@ Relay_log_info::Relay_log_info(bool is_s for (wi= 0; wi < slave_parallel_workers; wi++) { worker_mutexes[wi].m_key= (PSI_mutex_key *) &(key_mutex_slave_parallel_worker[wi]); - worker_mutexes[wi].m_name= "struct slave_worker::jobs_lock"; + worker_mutexes[wi].m_name= "Slave_worker::jobs_lock"; worker_mutexes[wi].m_flags= 0; worker_conds[wi].m_key= (PSI_cond_key *) &(key_cond_slave_parallel_worker[wi]); - worker_conds[wi].m_name= "struct slave_worker::jobs_cond"; + worker_conds[wi].m_name= "Slave_worker::jobs_cond"; worker_conds[wi].m_flags= 0; } if (PSI_server) @@ -1030,8 +1022,12 @@ void Relay_log_info::stmt_done(my_off_t // Andrei: tried testing the worker's method but got a segfault // because in to->set_info(group_relay_log_name) the arg is NULL. - //else - // w->flush_info(key_info_idx, key_info_size, is_transactional() ? TRUE : FALSE); + else + { + // ulong key_worker_idx[]= { server_id, w->id }; + // w->flush_info(key_worker_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER, + // is_transactional() ? TRUE : FALSE); + } } } === modified file 'sql/rpl_rli.h' --- a/sql/rpl_rli.h 2010-11-25 08:47:39 +0000 +++ b/sql/rpl_rli.h 2010-11-25 09:03:54 +0000 @@ -327,12 +327,7 @@ public: char slave_patternload_file[FN_REFLEN]; size_t slave_patternload_file_size; - Relay_log_info(bool is_slave_recovery, - 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); + Relay_log_info(bool is_slave_recovery); virtual ~Relay_log_info(); /** === modified file 'sql/rpl_rli_pdb.h' --- a/sql/rpl_rli_pdb.h 2010-11-25 08:47:39 +0000 +++ b/sql/rpl_rli_pdb.h 2010-11-25 09:03:54 +0000 @@ -28,6 +28,8 @@ Slave_worker *get_least_occupied_worker( #define SLAVE_WORKER_QUEUE_SIZE 8096 #define SLAVE_INIT_DBS_IN_GROUP 4 // initial allocation for CGEP dynarray +#define NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER 2 + typedef struct slave_job_item { void *data; === modified file 'sql/rpl_slave.cc' --- a/sql/rpl_slave.cc 2010-11-25 08:47:39 +0000 +++ b/sql/rpl_slave.cc 2010-11-25 09:03:54 +0000 @@ -41,6 +41,7 @@ #include #include #include "rpl_handler.h" +#include "rpl_info_dummy.h" #include #include #include @@ -3626,12 +3627,14 @@ int slave_start_single_worker(Relay_log_ // fixme: experimenting to make Workers to run ev->update_pos(w->w_rli) // fixme: a real hack! part of Rpl_info_factory::create_rli(RLI_REPOSITORY_FILE, FALSE); - w->w_rli= new Relay_log_info(FALSE, - &key_relay_log_info_run_lock, - &key_relay_log_info_data_lock, - &key_relay_log_info_data_cond, - &key_relay_log_info_start_cond, - &key_relay_log_info_stop_cond); + w->w_rli= new Relay_log_info(FALSE); + Rpl_info_dummy *dummy_handler= new Rpl_info_dummy(FALSE); + w->w_rli->set_rpl_info_handler(dummy_handler); + ulong key_worker_idx[]= { server_id, w->id }; + w->init_info(key_worker_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER); + + // ALFRANIO --> The recovery procedure must be introduced here. + w->w_rli->workers= rli->workers; // shallow copying is sufficient w->w_rli->this_worker= w; @@ -3663,6 +3666,7 @@ int slave_start_single_worker(Relay_log_ my_init_dynamic_array(&w->curr_group_exec_parts, NAME_LEN, SLAVE_INIT_DBS_IN_GROUP, 1); w->curr_group_seen_begin= FALSE; + if (pthread_create(&th, &connection_attrib, handle_slave_worker, (void*) w)) { @@ -3760,6 +3764,9 @@ void slave_stop_workers(Relay_log_info * Slave_worker *w; get_dynamic((DYNAMIC_ARRAY*)&rli->workers, (uchar*) &w, i); + ulong key_worker_idx[]= { server_id, w->id }; + w->end_info(key_worker_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER); + mysql_mutex_lock(&w->jobs_lock); while (w->jobs.len != rli->slave_pending_jobs_max + 1) { --===============0494418659== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/andrei.elkin@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: andrei.elkin@stripped # target_branch: file:///home/andrei/MySQL/BZR/2a-23May/WL/mysql-next-\ # mr-wl5569/ # testament_sha1: 5de198649ec558c97d109c9c2832188f209d2329 # timestamp: 2010-11-25 11:04:09 +0200 # base_revision_id: andrei.elkin@stripped\ # m413cpf2n9kzfntl # # Begin bundle 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 --===============0494418659==--