16 #include <my_global.h>
19 #include "rpl_info_factory.h"
24 Rpl_info_factory::struct_table_data Rpl_info_factory::rli_table_data;
25 Rpl_info_factory::struct_file_data Rpl_info_factory::rli_file_data;
26 Rpl_info_factory::struct_table_data Rpl_info_factory::mi_table_data;
27 Rpl_info_factory::struct_file_data Rpl_info_factory::mi_file_data;
28 Rpl_info_factory::struct_file_data Rpl_info_factory::worker_file_data;
29 Rpl_info_factory::struct_table_data Rpl_info_factory::worker_table_data;
47 bool Rpl_info_factory::create_coordinators(uint mi_option, Master_info **mi,
50 DBUG_ENTER(
"Rpl_info_factory::create_coordinators");
52 Rpl_info_factory::init_repository_metadata();
54 if (!((*mi)= Rpl_info_factory::create_mi(mi_option)))
57 if (!((*rli)= Rpl_info_factory::create_rli(rli_option, relay_log_recovery)))
67 (*mi)->set_relay_log_info(*rli);
68 (*rli)->set_master_info(*mi);
86 Master_info *Rpl_info_factory::create_mi(uint mi_option)
88 Master_info* mi= NULL;
89 Rpl_info_handler* handler_src= NULL;
90 Rpl_info_handler* handler_dest= NULL;
92 const char *
msg=
"Failed to allocate memory for the master info "
95 DBUG_ENTER(
"Rpl_info_factory::create_mi");
97 if (!(mi=
new Master_info(
98 #ifdef HAVE_PSI_INTERFACE
99 &key_master_info_run_lock,
100 &key_master_info_data_lock,
101 &key_master_info_sleep_lock,
102 &key_master_info_data_cond,
103 &key_master_info_start_cond,
104 &key_master_info_stop_cond,
105 &key_master_info_sleep_cond,
111 if(init_repositories(mi_table_data, mi_file_data, mi_option, instances,
112 &handler_src, &handler_dest, &msg))
115 if (decide_repository(mi, mi_option, &handler_src, &handler_dest, &msg))
129 mi->set_rpl_info_handler(NULL);
132 sql_print_error(
"Error creating master info: %s.", msg);
146 bool Rpl_info_factory::change_mi_repository(Master_info *mi,
150 Rpl_info_handler* handler_src= mi->get_rpl_info_handler();
151 Rpl_info_handler* handler_dest= NULL;
153 DBUG_ENTER(
"Rpl_info_factory::change_mi_repository");
155 DBUG_ASSERT(handler_src);
156 if (handler_src->get_rpl_info_type() == mi_option)
159 if (init_repositories(mi_table_data, mi_file_data, mi_option, instances,
160 NULL, &handler_dest, msg))
163 if (decide_repository(mi, mi_option, &handler_src, &handler_dest, msg))
172 sql_print_error(
"Error changing the type of master info's repository: %s.", *msg);
191 Relay_log_info *Rpl_info_factory::create_rli(uint rli_option,
bool is_slave_recovery)
194 Rpl_info_handler* handler_src= NULL;
195 Rpl_info_handler* handler_dest= NULL;
197 uint worker_repository= INVALID_INFO_REPOSITORY;
198 uint worker_instances= 1;
199 const char *msg= NULL;
200 const char *msg_alloc=
"Failed to allocate memory for the relay log info "
203 DBUG_ENTER(
"Rpl_info_factory::create_rli");
211 if (rli_option != INFO_REPOSITORY_DUMMY &&
212 scan_repositories(&worker_instances, &worker_repository,
213 worker_table_data, worker_file_data, &msg))
217 #ifdef HAVE_PSI_INTERFACE
218 ,&key_relay_log_info_run_lock,
219 &key_relay_log_info_data_lock,
220 &key_relay_log_info_sleep_lock,
221 &key_relay_log_info_data_cond,
222 &key_relay_log_info_start_cond,
223 &key_relay_log_info_stop_cond,
224 &key_relay_log_info_sleep_cond
233 if(init_repositories(rli_table_data, rli_file_data, rli_option, instances,
234 &handler_src, &handler_dest, &msg))
237 if (rli_option != INFO_REPOSITORY_DUMMY &&
238 worker_repository != INVALID_INFO_REPOSITORY &&
239 worker_repository != rli_option)
241 opt_rli_repository_id= rli_option= worker_repository;
242 sql_print_warning(
"It is not possible to change the type of the relay log "
243 "repository because there are workers repositories with "
244 "possible execution gaps. "
245 "The value of --relay_log_info_repository is altered to "
246 "one of the found Worker repositories. "
247 "The gaps have to be sorted out before resuming with "
249 std::swap(handler_src, handler_dest);
251 if (decide_repository(rli, rli_option, &handler_src, &handler_dest, &msg))
268 sql_print_error(
"Error creating relay log info: %s.", msg);
287 Rpl_info_handler* handler_dest= NULL;
289 DBUG_ENTER(
"Rpl_info_factory::change_rli_repository");
291 DBUG_ASSERT(handler_src != NULL);
293 if (handler_src->get_rpl_info_type() == rli_option)
296 if (init_repositories(rli_table_data, rli_file_data, rli_option,
297 instances, NULL, &handler_dest, msg))
300 if (decide_repository(rli, rli_option, &handler_src, &handler_dest,
310 sql_print_error(
"Error changing the type of relay log info's repository: %s.", *msg);
325 DBUG_ENTER(
"Rpl_info_factory::reset_workers");
327 if (rli->recovery_parallel_workers == 0)
330 if (Rpl_info_file::do_reset_info(Slave_worker::get_number_worker_fields(),
331 worker_file_data.pattern,
332 worker_file_data.name_indexed))
335 if (Rpl_info_table::do_reset_info(Slave_worker::get_number_worker_fields(),
336 MYSQL_SCHEMA_NAME.str, WORKER_INFO_NAME.str))
341 DBUG_EXECUTE_IF(
"mts_debug_reset_workers_fails", error=
true;);
345 sql_print_error(
"Could not delete from Slave Workers info repository.");
346 rli->recovery_parallel_workers= 0;
350 sql_print_error(
"Could not store the reset Slave Worker state into "
351 "the slave info repository.");
370 Slave_worker *Rpl_info_factory::create_worker(uint rli_option, uint worker_id,
372 bool is_gaps_collecting_phase)
374 Rpl_info_handler* handler_src= NULL;
375 Rpl_info_handler* handler_dest= NULL;
376 Slave_worker* worker= NULL;
377 const char *msg=
"Failed to allocate memory for the worker info "
380 DBUG_ENTER(
"Rpl_info_factory::create_worker");
385 char *pos= strmov(worker_file_data.name, worker_file_data.pattern);
386 sprintf(pos,
"%u", worker_id + 1);
388 if (!(worker=
new Slave_worker(rli
389 #ifdef HAVE_PSI_INTERFACE
390 ,&key_relay_log_info_run_lock,
391 &key_relay_log_info_data_lock,
392 &key_relay_log_info_sleep_lock,
393 &key_relay_log_info_data_cond,
394 &key_relay_log_info_start_cond,
395 &key_relay_log_info_stop_cond,
396 &key_relay_log_info_sleep_cond
403 if(init_repositories(worker_table_data, worker_file_data, rli_option,
404 worker_id + 1, &handler_src, &handler_dest, &msg))
407 if (decide_repository(worker, rli_option, &handler_src, &handler_dest, &msg))
410 if (worker->rli_init_info(is_gaps_collecting_phase))
412 msg=
"Failed to initialize the worker info structure";
416 if (rli->info_thd && rli->info_thd->is_error())
418 msg=
"Failed to initialize worker info table";
433 worker->set_rpl_info_handler(NULL);
436 sql_print_error(
"Error creating relay log info: %s.", msg);
440 static void build_worker_info_name(
char*
to,
447 pos= strmov(pos, path);
448 pos= strmov(pos,
"worker-");
449 pos= strmov(pos, fname);
456 void Rpl_info_factory::init_repository_metadata()
460 char* relay_log_info_file_name;
461 char relay_log_info_file_dirpart[FN_REFLEN];
464 dirname_part(relay_log_info_file_dirpart, relay_log_info_file, &len);
465 relay_log_info_file_name= relay_log_info_file + len;
467 rli_table_data.n_fields= Relay_log_info::get_number_info_rli_fields();
468 rli_table_data.schema= MYSQL_SCHEMA_NAME.str;
469 rli_table_data.name= RLI_INFO_NAME.str;
470 rli_file_data.n_fields= Relay_log_info::get_number_info_rli_fields();
471 strmov(rli_file_data.name, relay_log_info_file);
472 strmov(rli_file_data.pattern, relay_log_info_file);
473 rli_file_data.name_indexed=
false;
475 mi_table_data.n_fields= Master_info::get_number_info_mi_fields();
476 mi_table_data.schema= MYSQL_SCHEMA_NAME.str;
477 mi_table_data.name= MI_INFO_NAME.str;
478 mi_file_data.n_fields= Master_info::get_number_info_mi_fields();
479 strmov(mi_file_data.name, master_info_file);
480 strmov(mi_file_data.pattern, master_info_file);
481 rli_file_data.name_indexed=
false;
483 worker_table_data.n_fields= Slave_worker::get_number_worker_fields();
484 worker_table_data.schema= MYSQL_SCHEMA_NAME.str;
485 worker_table_data.name= WORKER_INFO_NAME.str;
486 worker_file_data.n_fields= Slave_worker::get_number_worker_fields();
487 build_worker_info_name(worker_file_data.name,
488 relay_log_info_file_dirpart,
489 relay_log_info_file_name);
490 build_worker_info_name(worker_file_data.pattern,
491 relay_log_info_file_dirpart,
492 relay_log_info_file_name);
493 worker_file_data.name_indexed=
true;
524 bool Rpl_info_factory::decide_repository(
Rpl_info *info, uint
option,
525 Rpl_info_handler **handler_src,
526 Rpl_info_handler **handler_dest,
530 enum_return_check return_check_src= ERROR_CHECKING_REPOSITORY;
531 enum_return_check return_check_dst= ERROR_CHECKING_REPOSITORY;
532 DBUG_ENTER(
"Rpl_info_factory::decide_repository");
534 if (option == INFO_REPOSITORY_DUMMY)
536 delete (*handler_src);
543 DBUG_ASSERT((*handler_src) != NULL && (*handler_dest) != NULL &&
544 (*handler_src) != (*handler_dest));
546 return_check_src= check_src_repository(info, option, handler_src);
547 return_check_dst= (*handler_dest)->do_check_info(info->get_internal_id());
549 if (return_check_src == ERROR_CHECKING_REPOSITORY ||
550 return_check_dst == ERROR_CHECKING_REPOSITORY)
556 DBUG_RETURN(check_error_repository(info, *handler_src, *handler_dest,
558 return_check_dst, msg));
562 if ((return_check_src == REPOSITORY_EXISTS &&
563 return_check_dst == REPOSITORY_DOES_NOT_EXIST) ||
564 (return_check_src == REPOSITORY_EXISTS &&
565 return_check_dst == REPOSITORY_EXISTS))
572 if (return_check_src == REPOSITORY_EXISTS &&
573 return_check_dst == REPOSITORY_EXISTS)
575 *msg=
"Multiple replication metadata repository instances "
576 "found with data in them. Unable to decide which is "
577 "the correct one to choose";
584 if (init_repositories(info, handler_src, handler_dest, msg))
595 if (info->copy_info(*handler_src, *handler_dest) ||
596 (*handler_dest)->flush_info(
true))
598 *msg=
"Error transfering information";
601 (*handler_src)->end_info();
602 if ((*handler_src)->remove_info())
604 *msg=
"Error removing old repository";
608 else if (return_check_src == REPOSITORY_DOES_NOT_EXIST &&
609 return_check_dst == REPOSITORY_EXISTS)
612 if ((*handler_dest)->do_init_info(info->get_internal_id()))
614 *msg=
"Error reading repository";
620 DBUG_ASSERT(return_check_src == REPOSITORY_DOES_NOT_EXIST &&
621 return_check_dst == REPOSITORY_DOES_NOT_EXIST);
624 delete (*handler_src);
647 Rpl_info_factory::check_src_repository(
Rpl_info *info,
649 Rpl_info_handler **handler_src)
651 enum_return_check return_check_src= ERROR_CHECKING_REPOSITORY;
660 return_check_src= (*handler_src)->do_check_info(info->get_internal_id());
668 if (ERROR_CHECKING_REPOSITORY == return_check_src &&
669 INFO_REPOSITORY_FILE == option &&
670 INFO_REPOSITORY_TABLE == (*handler_src)->do_get_rpl_info_type())
672 return_check_src= REPOSITORY_DOES_NOT_EXIST;
681 current_thd->clear_error();
694 return_check_src= (*handler_src)->do_check_info();
697 return return_check_src;
716 bool Rpl_info_factory::check_error_repository(
Rpl_info *info,
717 Rpl_info_handler *handler_src,
718 Rpl_info_handler *handler_dest,
719 enum_return_check err_src,
720 enum_return_check err_dst,
730 if (err_src == ERROR_CHECKING_REPOSITORY)
731 sql_print_error(
"Error in checking %s repository info type of %s.",
732 handler_src->get_description_info(),
733 handler_src->get_rpl_info_type_str());
734 if (err_dst == ERROR_CHECKING_REPOSITORY)
735 sql_print_error(
"Error in checking %s repository info type of %s.",
736 handler_dest->get_description_info(),
737 handler_dest->get_rpl_info_type_str());
738 *msg=
"Error checking repositories";
758 bool Rpl_info_factory::init_repositories(
Rpl_info *info,
759 Rpl_info_handler **handler_src,
760 Rpl_info_handler **handler_dest,
767 if ((*handler_src)->do_init_info(info->get_internal_id()) ||
768 (*handler_dest)->do_init_info(info->get_internal_id()))
770 *msg=
"Error transfering information";
776 if ((*handler_dest)->do_init_info(info->get_internal_id()))
778 *msg=
"Error transfering information";
805 bool Rpl_info_factory::init_repositories(
const struct_table_data table_data,
806 const struct_file_data file_data,
809 Rpl_info_handler **handler_src,
810 Rpl_info_handler **handler_dest,
814 *msg=
"Failed to allocate memory for master info repositories";
816 DBUG_ENTER(
"Rpl_info_factory::init_mi_repositories");
818 DBUG_ASSERT(handler_dest != NULL);
821 case INFO_REPOSITORY_FILE:
822 if (!(*handler_dest=
new Rpl_info_file(file_data.n_fields,
825 file_data.name_indexed)))
834 case INFO_REPOSITORY_TABLE:
840 !(*handler_src=
new Rpl_info_file(file_data.n_fields,
843 file_data.name_indexed)))
847 case INFO_REPOSITORY_DUMMY:
848 if (!(*handler_dest=
new Rpl_info_dummy(Master_info::get_number_info_mi_fields())))
861 bool Rpl_info_factory::scan_repositories(uint* found_instances,
862 uint* found_rep_option,
863 const struct_table_data table_data,
864 const struct_file_data file_data,
868 uint file_instances= 0;
869 uint table_instances= 0;
870 DBUG_ASSERT(found_rep_option != NULL);
872 DBUG_ENTER(
"Rpl_info_factory::scan_repositories");
874 if (Rpl_info_table::do_count_info(table_data.n_fields, table_data.schema,
875 table_data.name, &table_instances))
881 if (Rpl_info_file::do_count_info(file_data.n_fields, file_data.pattern,
882 file_data.name_indexed, &file_instances))
888 if (file_instances != 0 && table_instances != 0)
891 *msg=
"Multiple repository instances found with data in "
892 "them. Unable to decide which is the correct one to "
897 if (table_instances != 0)
899 *found_instances= table_instances;
900 *found_rep_option= INFO_REPOSITORY_TABLE;
902 else if (file_instances != 0)
904 *found_instances= file_instances;
905 *found_rep_option= INFO_REPOSITORY_FILE;
910 *found_rep_option= INVALID_INFO_REPOSITORY;