From: Andrei Elkin Date: November 30 2010 2:39pm Subject: bzr commit into mysql-next-mr.crash-safe branch (andrei.elkin:3222) WL#5569 WL#5599 List-Archive: http://lists.mysql.com/commits/125513 Message-Id: <201011301440.oAUEe4RU007301@mysql1000.dsl.inet.fi> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0320098389==" --===============0320098389== 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 3222 Andrei Elkin 2010-11-30 [merge] merging from from wl#5569 repo containing wl#5599 integration modified: sql/binlog.cc sql/log_event.cc sql/rpl_constants.h sql/rpl_info.cc sql/rpl_info.h sql/rpl_info_dummy.cc sql/rpl_info_dummy.h sql/rpl_info_factory.cc sql/rpl_info_factory.h sql/rpl_mi.cc sql/rpl_mi.h sql/rpl_rli.cc sql/rpl_rli.h sql/rpl_rli_pdb.cc sql/rpl_rli_pdb.h sql/rpl_slave.cc === modified file 'sql/binlog.cc' --- a/sql/binlog.cc 2010-11-11 11:53:01 +0000 +++ b/sql/binlog.cc 2010-11-30 02:08:01 +0000 @@ -2140,8 +2140,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay } /* Store where we are in the new file for the execution thread */ - /* Andrei needs to guarantee that there is no worker using the current relay log. */ - rli->flush_info(key_info_idx, key_info_size, TRUE); + rli->flush_info(TRUE); DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_ABORT();); === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2010-11-30 14:02:15 +0000 +++ b/sql/log_event.cc 2010-11-30 14:39:40 +0000 @@ -2665,6 +2665,8 @@ int slave_worker_exec_job(Slave_worker * if (ev->starts_group()) { w->curr_group_seen_begin= TRUE; // The current group is started with B-event + // ANDREI ---- + // w->configure_position(rli); } else { @@ -2698,6 +2700,7 @@ int slave_worker_exec_job(Slave_worker * if (ev->ends_group() || !w->curr_group_seen_begin) { w->slave_worker_ends_group(ev->mts_group_cnt, error); /* last done sets post exec */ + w->checkpoint(w->w_rli); } mysql_mutex_lock(&w->jobs_lock); @@ -4209,8 +4212,7 @@ int Query_log_event::do_update_pos(Relay DBUG_EXECUTE_IF("crash_after_commit_and_update_pos", if (!strcmp("COMMIT", query)) { - /* Alfranio needs to update the coordinator and workers. */ - rli->flush_info(key_info_idx, key_info_size, TRUE); + rli->flush_info(TRUE); DBUG_ABORT(); } ); @@ -5860,11 +5862,8 @@ int Rotate_log_event::do_update_pos(Rela rli->get_group_master_log_name(), (ulong) rli->get_group_master_log_pos())); mysql_mutex_unlock(&rli->data_lock); - /* - Andrei to investigate if it is necessary to guarantee that - this done in sequential mode. - */ - rli->flush_info(key_info_idx, key_info_size, TRUE); + + rli->flush_info(TRUE); /* Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of @@ -6272,8 +6271,7 @@ int Xid_log_event::do_apply_event(Relay_ rli_ptr->set_group_master_log_pos(log_pos); } - /* Alfranio needs to update the coordinator and workers. */ - if ((error= rli_ptr->flush_info(key_info_idx, key_info_size, TRUE))) + if ((error= rli_ptr->flush_info(TRUE))) goto err; } @@ -6944,11 +6942,7 @@ int Stop_log_event::do_update_pos(Relay_ else { rli->inc_group_relay_log_pos(0); - /* - Andrei to investigate if it is necessary to guarantee that - this done in sequential mode. - */ - rli->flush_info(key_info_idx, key_info_size, TRUE); + rli->flush_info(TRUE); } return 0; } === modified file 'sql/rpl_constants.h' --- a/sql/rpl_constants.h 2010-11-11 11:53:01 +0000 +++ b/sql/rpl_constants.h 2010-11-30 02:08:01 +0000 @@ -15,14 +15,4 @@ enum Incident { INCIDENT_COUNT }; -#define NUMBER_OF_FIELDS_TO_IDENTIFY_MASTER 1 -#define NUMBER_OF_MASTERS 1 -/* - We assume here a single master and uses slave's id to identify - entries in a system table, if there is any. This code needs to - be changed when we start handling multi-master replication. -*/ -extern ulong key_info_idx[]; -extern uint key_info_size; - #endif /* RPL_CONSTANTS_H */ === modified file 'sql/rpl_info.cc' --- a/sql/rpl_info.cc 2010-11-23 09:03:37 +0000 +++ b/sql/rpl_info.cc 2010-11-30 02:08:01 +0000 @@ -17,20 +17,10 @@ #include #include "rpl_info.h" -/* - We assume here a single master and uses slave's id to identify - entries in a system table, if there is any. This code needs to - be changed when we start handling multi-master replication. - - Most likely, server_id is zero when key_info_idx is defined. - For that reason, it is reset in Rpl_info_factory. -*/ -ulong key_info_idx[]= { server_id }; -uint key_info_size= NUMBER_OF_FIELDS_TO_IDENTIFY_MASTER; - Rpl_info::Rpl_info(const char* type) : Slave_reporting_capability(type), - info_thd(0), inited(0), abort_slave(0), + info_thd(0), uidx(0), nidx(0), + inited(0), abort_slave(0), slave_running(0), slave_run_id(0), handler(0) { @@ -39,6 +29,9 @@ Rpl_info::Rpl_info(const char* type) Rpl_info::~Rpl_info() { + if (uidx) + delete []uidx; + if (handler) delete handler; } === modified file 'sql/rpl_info.h' --- a/sql/rpl_info.h 2010-11-23 09:03:37 +0000 +++ b/sql/rpl_info.h 2010-11-30 02:08:01 +0000 @@ -27,6 +27,10 @@ class Rpl_info : public Slave_reporting_ public: THD *info_thd; + ulong *uidx; + + uint nidx; + bool inited; volatile bool abort_slave; volatile uint slave_running; @@ -35,12 +39,12 @@ public: Rpl_info(const char *type); virtual ~Rpl_info(); - int check_info(const ulong *uidx, const uint nidx) + int check_info() { return (handler->check_info(uidx, nidx)); } - int remove_info(const ulong *uidx, const uint nidx) + int remove_info() { return (handler->remove_info(uidx, nidx)); } @@ -50,6 +54,12 @@ public: return (handler->is_transactional()); } + void set_idx_info(ulong *param_uidx, uint param_nidx) + { + uidx= param_uidx; + nidx= param_nidx; + } + char *get_description_info() { return (handler->get_description_info()); === modified file 'sql/rpl_info_dummy.cc' --- a/sql/rpl_info_dummy.cc 2010-11-23 09:03:37 +0000 +++ b/sql/rpl_info_dummy.cc 2010-11-30 02:08:01 +0000 @@ -16,8 +16,8 @@ #include #include "rpl_info_dummy.h" -Rpl_info_dummy::Rpl_info_dummy(bool param_abort) - :Rpl_info_handler(0), abort(param_abort) +Rpl_info_dummy::Rpl_info_dummy() + :Rpl_info_handler(0) { } === modified file 'sql/rpl_info_dummy.h' --- a/sql/rpl_info_dummy.h 2010-11-23 09:03:37 +0000 +++ b/sql/rpl_info_dummy.h 2010-11-30 02:08:01 +0000 @@ -30,7 +30,7 @@ class Rpl_info_dummy : public Rpl_info_handler { public: - Rpl_info_dummy(bool param_abort); + Rpl_info_dummy(); virtual ~Rpl_info_dummy() { }; private: @@ -61,7 +61,7 @@ private: char* do_get_description_info(); bool do_is_transactional(); - bool abort; + static const bool abort= FALSE; Rpl_info_dummy& operator=(const Rpl_info_dummy& info); Rpl_info_dummy(const Rpl_info_dummy& info); === modified file 'sql/rpl_info_factory.cc' --- a/sql/rpl_info_factory.cc 2010-11-23 09:03:37 +0000 +++ b/sql/rpl_info_factory.cc 2010-11-30 02:08:01 +0000 @@ -25,6 +25,10 @@ #define master_info_engine NULL #define relay_log_info_engine NULL +#define NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR 1 +#define NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER 2 + + /** Creates both a Master info and a Relay log info repository whose types are defined as parameters. @@ -82,6 +86,7 @@ Master_info *Rpl_info_factory::create_mi Master_info* mi= NULL; Rpl_info_file* mi_file= NULL; Rpl_info_table* mi_table= NULL; + ulong *key_info_idx= NULL; const char *msg= "Failed to allocate memory for the master info " "structure"; @@ -91,35 +96,50 @@ Master_info *Rpl_info_factory::create_mi !(mi->registered_mutexes)) 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(), + if (!(key_info_idx= new ulong[NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR])) + goto err; + key_info_idx[0]= server_id; + mi->set_idx_info(key_info_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR); + + DBUG_ASSERT(mi_option == MI_REPOSITORY_FILE || + mi_option == MI_REPOSITORY_TABLE || + mi_option == MI_REPOSITORY_DUMMY); + + if (mi_option == MI_REPOSITORY_FILE || + mi_option == MI_REPOSITORY_TABLE) + { + /* + 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; + goto err; - if (!(mi_table= new Rpl_info_table(mi->get_number_info_mi_fields() + 1, + if (!(mi_table= new Rpl_info_table(mi->get_number_info_mi_fields() + 1, MI_SCHEMA, MI_TABLE))) - goto err; - - DBUG_ASSERT(mi_option == MI_REPOSITORY_FILE || - mi_option == MI_REPOSITORY_TABLE); + goto err; - /* - In a multi-master envinroment, we need to make sure that both master - info and relay log info are prepared to handle events from all - masters. In such case, we need to execute the code below for each - master and correctly set the key_info_idx. /Alfranio - */ - if (decide_repository(mi, key_info_idx, key_info_size, &mi_table, &mi_file, + /* + In a multi-master envinroment, we need to make sure that both master + info and relay log info are prepared to handle events from all + masters. In such case, we need to execute the code below for each + master and correctly set the key_info_idx. /Alfranio + */ + if (decide_repository(mi, &mi_table, &mi_file, mi_option == MI_REPOSITORY_TABLE, &msg)) - goto err; + goto err; - if ((mi_option == MI_REPOSITORY_TABLE) && - change_engine(static_cast(mi_table), - master_info_engine, &msg)) + if ((mi_option == MI_REPOSITORY_TABLE) && + change_engine(static_cast(mi_table), + master_info_engine, &msg)) + goto err; + + DBUG_RETURN(mi); + } + + if (Rpl_info_factory::create_info_dummy(mi)) goto err; DBUG_RETURN(mi); @@ -127,6 +147,11 @@ Master_info *Rpl_info_factory::create_mi err: if (mi_file) delete mi_file; if (mi_table) delete mi_table; + if (key_info_idx) + { + delete []key_info_idx; + mi->set_idx_info(NULL, 0); + } if (mi) { /* @@ -161,6 +186,7 @@ Relay_log_info *Rpl_info_factory::create Relay_log_info *rli= NULL; Rpl_info_file* rli_file= NULL; Rpl_info_table* rli_table= NULL; + ulong *key_info_idx= NULL; const char *msg= "Failed to allocate memory for the relay log info " "structure"; @@ -170,36 +196,50 @@ Relay_log_info *Rpl_info_factory::create !(rli->registered_mutexes)) 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_SCHEMA, RLI_TABLE))) - goto err; + if (!(key_info_idx= new ulong[NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR])) + goto err; + key_info_idx[0]= server_id; + rli->set_idx_info(key_info_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR); DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE || - rli_option == RLI_REPOSITORY_TABLE); + rli_option == RLI_REPOSITORY_TABLE || + rli_option == RLI_REPOSITORY_DUMMY); - /* - In a multi-master envinroment, we need to make sure that both master - info and relay log info are prepared to handle events from all - masters. In such case, we need to execute the code below for each - master and correctly set the key_info_idx. /Alfranio - */ - if (decide_repository(rli, key_info_idx, key_info_size, - &rli_table, &rli_file, - rli_option == RLI_REPOSITORY_TABLE, &msg)) - goto err; + if (rli_option == RLI_REPOSITORY_FILE || + rli_option == RLI_REPOSITORY_TABLE) + { + /* + 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_option == RLI_REPOSITORY_TABLE) && - change_engine(static_cast(rli_table), - relay_log_info_engine, &msg)) + if (!(rli_table= new Rpl_info_table(rli->get_number_info_rli_fields() + 1, + RLI_SCHEMA, RLI_TABLE))) + goto err; + + /* + In a multi-master envinroment, we need to make sure that both master + info and relay log info are prepared to handle events from all + masters. In such case, we need to execute the code below for each + master and correctly set the key_info_idx. /Alfranio + */ + if (decide_repository(rli, &rli_table, &rli_file, + rli_option == RLI_REPOSITORY_TABLE, &msg)) + goto err; + + if ((rli_option == RLI_REPOSITORY_TABLE) && + change_engine(static_cast(rli_table), + relay_log_info_engine, &msg)) + goto err; + + DBUG_RETURN(rli); + } + + if (Rpl_info_factory::create_info_dummy(rli)) goto err; DBUG_RETURN(rli); @@ -207,6 +247,11 @@ Relay_log_info *Rpl_info_factory::create err: if (rli_file) delete rli_file; if (rli_table) delete rli_table; + if (key_info_idx) + { + delete []key_info_idx; + rli->set_idx_info(NULL, 0); + } if (rli) { /* @@ -258,7 +303,6 @@ err: @retval TRUE Failure */ bool Rpl_info_factory::decide_repository(Rpl_info *info, - ulong *uidx, uint nidx, Rpl_info_table **table, Rpl_info_file **file, bool is_table, const char **msg) @@ -267,8 +311,8 @@ bool Rpl_info_factory::decide_repository DBUG_ENTER("Rpl_info_factory::decide_repository"); bool error= TRUE; - bool is_t= !((*table)->check_info(uidx, nidx)); - bool is_f= !((*file)->check_info(uidx, nidx)); + bool is_t= !((*table)->check_info(info->uidx, info->nidx)); + bool is_f= !((*file)->check_info(info->uidx, info->nidx)); if (is_t && is_f) { @@ -282,7 +326,8 @@ bool Rpl_info_factory::decide_repository { if (!is_t && is_f) { - if ((*table)->init_info(uidx, nidx) || (*file)->init_info(uidx, nidx)) + if ((*table)->init_info(info->uidx, info->nidx) || + (*file)->init_info(info->uidx, info->nidx)) { *msg= "Error transfering information from a file to a table."; goto err; @@ -294,8 +339,9 @@ bool Rpl_info_factory::decide_repository This process is not atomic and if the server crashes before removing the file, the user needs to manualy remove it. */ - if (info->copy_info(*file, *table) || (*table)->flush_info(uidx, nidx, TRUE) - || (*file)->remove_info(uidx, nidx)) + if (info->copy_info(*file, *table) || + (*table)->flush_info(info->uidx, info->nidx, TRUE) + || (*file)->remove_info(info->uidx, info->nidx)) { *msg= "Error transfering information from a file to a table."; goto err; @@ -310,7 +356,8 @@ bool Rpl_info_factory::decide_repository { if (is_t && !is_f) { - if ((*table)->init_info(uidx, nidx) || (*file)->init_info(uidx, nidx)) + if ((*table)->init_info(info->uidx, info->nidx) || + (*file)->init_info(info->uidx, info->nidx)) { *msg= "Error transfering information from a file to a table."; goto err; @@ -325,8 +372,9 @@ bool Rpl_info_factory::decide_repository repeat the process. Note that we assuming here single master rep. This process needs to be changed if there are multi-masters. */ - if (info->copy_info(*table, *file) || (*file)->flush_info(uidx, nidx, TRUE) - || (*table)->remove_info(uidx, nidx)) + if (info->copy_info(*table, *file) || + (*file)->flush_info(info->uidx, info->nidx, TRUE) + || (*table)->remove_info(info->uidx, info->nidx)) { *msg= "Error transfering information from a table to a file."; goto err; @@ -355,7 +403,7 @@ err: bool Rpl_info_factory::change_engine(Rpl_info_table *table, const char *engine, const char **msg) { - DBUG_ENTER("Rpl_info_factory::decide_engine"); + DBUG_ENTER("Rpl_info_factory::change_engine"); if (engine && table->change_engine(engine)) { @@ -374,8 +422,8 @@ Slave_worker *Rpl_info_factory::create_w char info_name[FN_REFLEN]; Rpl_info_file* w_file= NULL; Rpl_info_table* w_table= NULL; + ulong *key_info_idx= NULL; Slave_worker *worker= NULL; - ulong idx[]= {server_id, worker_id}; const char *msg= "Failed to allocate memory for the Slave worker info " "structure"; @@ -390,7 +438,18 @@ Slave_worker *Rpl_info_factory::create_w if (!(worker= new Slave_worker(info_name))) goto err; - if (rli) + if (!(key_info_idx= new ulong[NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER])) + goto err; + key_info_idx[0]= server_id; + key_info_idx[1]= worker_id; + worker->set_idx_info(key_info_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER); + + DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE || + rli_option == RLI_REPOSITORY_TABLE || + rli_option == RLI_REPOSITORY_DUMMY); + + if (rli_option == RLI_REPOSITORY_FILE || + rli_option == RLI_REPOSITORY_TABLE) { /* Now we instantiate all info repos and later decide which one to take, @@ -405,15 +464,12 @@ Slave_worker *Rpl_info_factory::create_w WORKER_SCHEMA, WORKER_TABLE))) goto err; - DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE || - rli_option == RLI_REPOSITORY_TABLE); - /* 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, + if (decide_repository(worker, &w_table, &w_file, rli_option == MI_REPOSITORY_TABLE, &msg)) goto err; @@ -421,13 +477,23 @@ Slave_worker *Rpl_info_factory::create_w change_engine(static_cast(w_table), relay_log_info_engine, &msg)) goto err; + + DBUG_RETURN(worker); } + if (Rpl_info_factory::create_info_dummy(rli)) + goto err; + DBUG_RETURN(worker); err: if (w_file) delete w_file; if (w_table) delete w_table; + if (key_info_idx) + { + delete []key_info_idx; + worker->set_idx_info(NULL, 0); + } if (worker) { /* @@ -440,3 +506,17 @@ err: sql_print_error("%s", msg); DBUG_RETURN(NULL); } + +bool Rpl_info_factory::create_info_dummy(Rpl_info *rpl) +{ + DBUG_ENTER("Rpl_info_factory::create_info_dummy"); + + Rpl_info_dummy* rpl_dummy= NULL; + + if (!(rpl_dummy= new Rpl_info_dummy())) + DBUG_RETURN(TRUE); + + rpl->set_rpl_info_handler(rpl_dummy); + + DBUG_RETURN(FALSE); +} === modified file 'sql/rpl_info_factory.h' --- a/sql/rpl_info_factory.h 2010-11-11 11:53:01 +0000 +++ b/sql/rpl_info_factory.h 2010-11-30 02:08:01 +0000 @@ -22,19 +22,22 @@ #include "rpl_rli_pdb.h" #include "rpl_info_file.h" #include "rpl_info_table.h" +#include "rpl_info_dummy.h" #include "rpl_info_handler.h" enum enum_mi_repository { MI_REPOSITORY_FILE= 0, - MI_REPOSITORY_TABLE= 1 + MI_REPOSITORY_TABLE= 1, + MI_REPOSITORY_DUMMY= 2 }; extern ulong opt_mi_repository_id; enum enum_rli_repository { RLI_REPOSITORY_FILE= 0, - RLI_REPOSITORY_TABLE= 1 + RLI_REPOSITORY_TABLE= 1, + RLI_REPOSITORY_DUMMY= 2 }; extern ulong opt_rli_repository_id; @@ -58,11 +61,11 @@ class Rpl_info_factory static Master_info *create_mi(uint rli_option); static Relay_log_info *create_rli(uint rli_option, bool is_slave_recovery); static bool decide_repository(Rpl_info *info, - ulong *uidx, uint nidx, Rpl_info_table **table, Rpl_info_file **file, bool is_table, const char **msg); static bool change_engine(Rpl_info_table *table, const char *engine, const char **msg); + static bool create_info_dummy(Rpl_info *rpl); }; #endif === modified file 'sql/rpl_mi.cc' --- a/sql/rpl_mi.cc 2010-11-23 09:03:37 +0000 +++ b/sql/rpl_mi.cc 2010-11-30 02:08:01 +0000 @@ -156,7 +156,7 @@ void Master_info::init_master_log_pos() DBUG_VOID_RETURN; } -void Master_info::end_info(ulong *uidx, uint nidx) +void Master_info::end_info() { DBUG_ENTER("Master_info::end_info"); @@ -199,7 +199,7 @@ void Master_info::end_info(ulong *uidx, @todo Change the log file information to a binary format to avoid calling longlong2str. */ -int Master_info::flush_info(ulong *uidx, uint nidx, bool force) +int Master_info::flush_info(bool force) { DBUG_ENTER("Master_info::flush_info"); DBUG_PRINT("enter",("master_pos: %lu", (ulong) master_log_pos)); @@ -230,7 +230,7 @@ void Master_info::set_relay_log_info(Rel rli= info; } -int Master_info::init_info(ulong *uidx, uint nidx) +int Master_info::init_info() { DBUG_ENTER("Master_info::init_info"); @@ -242,7 +242,7 @@ int Master_info::init_info(ulong *uidx, from the repository, in order to initialize the Master_info. */ mysql= 0; file_id= 1; - int necessary_to_configure= check_info(uidx, nidx); + int necessary_to_configure= check_info(); if (handler->init_info(uidx, nidx)) goto err; @@ -256,7 +256,7 @@ int Master_info::init_info(ulong *uidx, goto err; end: - if (flush_info(uidx, nidx, TRUE)) + if (flush_info(TRUE)) goto err; inited= 1; === modified file 'sql/rpl_mi.h' --- a/sql/rpl_mi.h 2010-11-23 09:03:37 +0000 +++ b/sql/rpl_mi.h 2010-11-30 02:08:01 +0000 @@ -97,9 +97,9 @@ class Master_info : public Rpl_info_coor ulong retry_count; char master_uuid[UUID_LENGTH+1]; - int init_info(ulong *uidx, uint nidx); - void end_info(ulong *uidx, uint nidx); - int flush_info(ulong *uidx, uint nidx, bool force= FALSE); + int init_info(); + void end_info(); + int flush_info(bool force= FALSE); void set_relay_log_info(Relay_log_info *info); bool shall_ignore_server_id(ulong s_id); === modified file 'sql/rpl_rli.cc' --- a/sql/rpl_rli.cc 2010-11-30 14:02:15 +0000 +++ b/sql/rpl_rli.cc 2010-11-30 14:39:40 +0000 @@ -1016,17 +1016,7 @@ void Relay_log_info::stmt_done(my_off_t /* Alfranio needs to update the coordinator and workers. */ if ((w= get_current_worker()) == NULL) - flush_info(key_info_idx, key_info_size, is_transactional() ? TRUE : FALSE); - - // 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 - { - // ulong key_worker_idx[]= { server_id, w->id }; - // w->flush_info(key_worker_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER, - // is_transactional() ? TRUE : FALSE); - } + flush_info(is_transactional() ? TRUE : FALSE); } } @@ -1150,7 +1140,7 @@ bool mysql_show_relaylog_events(THD* thd #endif -int Relay_log_info::init_info(ulong *uidx, uint nidx) +int Relay_log_info::init_info() { int error= 0; const char *msg= NULL; @@ -1296,7 +1286,7 @@ a file name for --relay-log-index option will be values to be read. Please, do not move this call after the handler->init_info(). */ - int necessary_to_configure= check_info(uidx, nidx); + int necessary_to_configure= check_info(); if ((error= handler->init_info(uidx, nidx))) { msg= "Error reading relay log configuration"; @@ -1356,7 +1346,7 @@ a file name for --relay-log-index option #endif } - if ((error= flush_info(uidx, nidx, TRUE))) + if ((error= flush_info(TRUE))) { msg= "Error reading relay log configuration"; error= 1; @@ -1380,7 +1370,7 @@ err: DBUG_RETURN(error); } -void Relay_log_info::end_info(ulong *uidx, uint nidx) +void Relay_log_info::end_info() { DBUG_ENTER("Relay_log_info::end_info"); @@ -1480,7 +1470,7 @@ void Relay_log_info::set_master_info(Mas @return 0 on success, 1 on error. */ -int Relay_log_info::flush_info(ulong *uidx, uint nidx, const bool force) +int Relay_log_info::flush_info(const bool force) { DBUG_ENTER("Relay_log_info::flush_info"); === modified file 'sql/rpl_rli.h' --- a/sql/rpl_rli.h 2010-11-30 14:02:15 +0000 +++ b/sql/rpl_rli.h 2010-11-30 14:39:40 +0000 @@ -517,9 +517,9 @@ public: int count_relay_log_space(); - int init_info(ulong *uidx, uint nidx); - void end_info(ulong *uidx, uint nidx); - int flush_info(ulong *uidx, uint nidx, bool force= FALSE); + int init_info(); + void end_info(); + int flush_info(bool force= FALSE); int flush_current_log(); void set_master_info(Master_info *info); === modified file 'sql/rpl_rli_pdb.cc' --- a/sql/rpl_rli_pdb.cc 2010-11-30 14:02:15 +0000 +++ b/sql/rpl_rli_pdb.cc 2010-11-30 14:39:40 +0000 @@ -28,7 +28,7 @@ Slave_worker::~Slave_worker() } -int Slave_worker::init_info(ulong *uidx, uint nidx) +int Slave_worker::init_info() { DBUG_ENTER("Slave_worker::init_info"); @@ -39,7 +39,7 @@ int Slave_worker::init_info(ulong *uidx, The init_info() is used to either create or read information from the repository, in order to initialize the Slave_worker. */ - int necessary_to_configure= check_info(uidx, nidx); + int necessary_to_configure= check_info(); if (handler->init_info(uidx, nidx)) goto err; @@ -47,7 +47,7 @@ int Slave_worker::init_info(ulong *uidx, if (!necessary_to_configure && read_info(handler)) goto err; - if (flush_info(uidx, nidx, TRUE)) + if (flush_info(TRUE)) goto err; inited= 1; @@ -58,7 +58,7 @@ err: DBUG_RETURN(1); } -void Slave_worker::end_info(ulong *uidx, uint nidx) +void Slave_worker::end_info() { DBUG_ENTER("Slave_worker::end_info"); @@ -72,7 +72,7 @@ void Slave_worker::end_info(ulong *uidx, DBUG_VOID_RETURN; } -int Slave_worker::flush_info(ulong *uidx, uint nidx, const bool force) +int Slave_worker::flush_info(const bool force) { DBUG_ENTER("Slave_worker::flush_info"); @@ -153,6 +153,26 @@ size_t Slave_worker::get_number_worker_f return sizeof(info_slave_worker_fields)/sizeof(info_slave_worker_fields[0]); } +bool Slave_worker::checkpoint(Relay_log_info *info) +{ + DBUG_ENTER("Relay_coordinator::checkpoint_worker"); + + bool error= FALSE; + + group_relay_log_pos= info->get_group_relay_log_pos(); + strmake(group_relay_log_name, info->get_group_relay_log_name(), + sizeof(group_relay_log_name)-1); + + group_master_log_pos= info->get_group_master_log_pos(); + strmake(group_master_log_name, info->get_group_master_log_name(), + sizeof(group_master_log_name)-1); + + error= flush_info(TRUE); + + DBUG_RETURN(error); +} + + static HASH mapping_db_to_worker; static bool inited_hash_workers= FALSE; === modified file 'sql/rpl_rli_pdb.h' --- a/sql/rpl_rli_pdb.h 2010-11-30 14:02:15 +0000 +++ b/sql/rpl_rli_pdb.h 2010-11-30 14:39:40 +0000 @@ -210,14 +210,16 @@ public: char group_master_log_name[FN_REFLEN]; ulonglong group_master_log_pos; - int init_info(ulong *uidx, uint nidx); - void end_info(ulong *uidx, uint nidx); - int flush_info(ulong *uidx, uint nidx, bool force= FALSE); + int init_info(); + void end_info(); + int flush_info(bool force= FALSE); size_t get_number_worker_fields(); void slave_worker_ends_group(ulong, int); // CGEP walk through to upd APH + bool checkpoint(Relay_log_info *rli); + private: bool read_info(Rpl_info_handler *from); bool write_info(Rpl_info_handler *to); === modified file 'sql/rpl_slave.cc' --- a/sql/rpl_slave.cc 2010-11-30 14:02:15 +0000 +++ b/sql/rpl_slave.cc 2010-11-30 14:39:40 +0000 @@ -408,21 +408,21 @@ int init_info(Master_info* mi, bool igno In a multi-master envinroment, we need to make sure that both master info and relay log info are prepared to handle events from all masters. In such case, we need to execute the code below for each - master and correctly set the key_info_idx. + master and correctly set the key_info_idx. /Alfranio */ - necessary_to_configure= mi->check_info(key_info_idx, key_info_size); + necessary_to_configure= mi->check_info(); if (!(ignore_if_no_info && necessary_to_configure)) { if ((thread_mask & SLAVE_IO) != 0 && - mi->init_info(key_info_idx, key_info_size)) + mi->init_info()) error= 1; } - necessary_to_configure= mi->rli->check_info(key_info_idx, key_info_size); + necessary_to_configure= mi->rli->check_info(); if (!(ignore_if_no_info && necessary_to_configure)) { if (((thread_mask & SLAVE_SQL) != 0 || !(mi->rli->inited)) - && mi->rli->init_info(key_info_idx, key_info_size)) + && mi->rli->init_info()) error= 1; } @@ -446,8 +446,8 @@ void end_info(Master_info* mi) masters. In such case, we need to execute the code below for each master and correctly set the key_info_idx. /Alfranio */ - mi->end_info(key_info_idx, key_info_size); - mi->rli->end_info(key_info_idx, key_info_size); + mi->end_info(); + mi->rli->end_info(); DBUG_VOID_RETURN; } @@ -477,11 +477,11 @@ int remove_info(Master_info* mi) masters. In such case, we need to execute the code below for each master and correctly set the key_info_idx. /Alfranio */ - mi->end_info(key_info_idx, key_info_size); - mi->rli->end_info(key_info_idx, key_info_size); + mi->end_info(); + mi->rli->end_info(); - if (mi->remove_info(key_info_idx, key_info_size) || - mi->rli->remove_info(key_info_idx, key_info_size)) + if (mi->remove_info() || + mi->rli->remove_info()) error= 1; DBUG_RETURN(error); @@ -522,7 +522,7 @@ int flush_master_info(Master_info* mi, b master and correctly set the key_info_idx. /Alfranio */ int err= (mi->rli->flush_current_log() || - mi->flush_info(key_info_idx, key_info_size, force)); + mi->flush_info(force)); mysql_mutex_unlock(log_lock); @@ -678,7 +678,7 @@ int terminate_slave_threads(Master_info* masters. In such case, we need to execute the code below for each master and correctly set the key_info_idx. /Alfranio */ - if (mi->flush_info(key_info_idx, key_info_size, TRUE)) + if (mi->flush_info(TRUE)) DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); /* @@ -714,7 +714,7 @@ int terminate_slave_threads(Master_info* masters. In such case, we need to execute the code below for each master and correctly set the key_info_idx. /Alfranio */ - if (mi->rli->flush_info(key_info_idx, key_info_size, TRUE)) + if (mi->rli->flush_info(TRUE)) DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS); mysql_mutex_unlock(log_lock); @@ -3644,10 +3644,9 @@ 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); - Rpl_info_dummy *dummy_handler= new Rpl_info_dummy(TRUE); + Rpl_info_dummy *dummy_handler= new Rpl_info_dummy(); 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); + w->init_info(); w->relay_log_change_notified= FALSE; // the 1st group to contain relaylog name @@ -3791,8 +3790,7 @@ 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); + w->end_info(); mysql_mutex_lock(&w->jobs_lock); while (w->jobs.len != rli->slave_pending_jobs_max + 1) @@ -5378,7 +5376,7 @@ static Log_event* next_event(Relay_log_i We may update the worker here but this is not extremlly necessary. /Alfranio */ - rli->flush_info(key_info_idx, key_info_size); + rli->flush_info(); } /* Reset the relay-log-change-notified status of Slave Workers */ @@ -6200,7 +6198,7 @@ bool change_master(THD* thd, Master_info Andrei needs to guarantee that this done in sequential mode. */ - ret= mi->rli->flush_info(key_info_idx, key_info_size, TRUE); + ret= mi->rli->flush_info(TRUE); mysql_cond_broadcast(&mi->data_cond); mysql_mutex_unlock(&mi->rli->data_lock); --===============0320098389== 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: 6d42ff2471267b9fd2e73523183bdad217d0d589 # timestamp: 2010-11-30 16:40:04 +0200 # base_revision_id: andrei.elkin@stripped\ # 2sj37wwx8sdq8cz4 # # Begin bundle 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 gA== --===============0320098389==--