MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rpl_info_factory.cc
1 /* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
16 #include <my_global.h>
17 #include "sql_priv.h"
18 #include "rpl_slave.h"
19 #include "rpl_info_factory.h"
20 
21 /*
22  Defines meta information on diferent repositories.
23 */
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;
30 
47 bool Rpl_info_factory::create_coordinators(uint mi_option, Master_info **mi,
48  uint rli_option, Relay_log_info **rli)
49 {
50  DBUG_ENTER("Rpl_info_factory::create_coordinators");
51 
52  Rpl_info_factory::init_repository_metadata();
53 
54  if (!((*mi)= Rpl_info_factory::create_mi(mi_option)))
55  DBUG_RETURN(TRUE);
56 
57  if (!((*rli)= Rpl_info_factory::create_rli(rli_option, relay_log_recovery)))
58  {
59  delete *mi;
60  *mi= NULL;
61  DBUG_RETURN(TRUE);
62  }
63 
64  /*
65  Setting the cross dependency used all over the code.
66  */
67  (*mi)->set_relay_log_info(*rli);
68  (*rli)->set_master_info(*mi);
69 
70  DBUG_RETURN(FALSE);
71 }
72 
86 Master_info *Rpl_info_factory::create_mi(uint mi_option)
87 {
88  Master_info* mi= NULL;
89  Rpl_info_handler* handler_src= NULL;
90  Rpl_info_handler* handler_dest= NULL;
91  uint instances= 1;
92  const char *msg= "Failed to allocate memory for the master info "
93  "structure";
94 
95  DBUG_ENTER("Rpl_info_factory::create_mi");
96 
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,
106 #endif
107  instances
108  )))
109  goto err;
110 
111  if(init_repositories(mi_table_data, mi_file_data, mi_option, instances,
112  &handler_src, &handler_dest, &msg))
113  goto err;
114 
115  if (decide_repository(mi, mi_option, &handler_src, &handler_dest, &msg))
116  goto err;
117 
118  DBUG_RETURN(mi);
119 
120 err:
121  delete handler_src;
122  delete handler_dest;
123  if (mi)
124  {
125  /*
126  The handler was previously deleted so we need to remove
127  any reference to it.
128  */
129  mi->set_rpl_info_handler(NULL);
130  delete mi;
131  }
132  sql_print_error("Error creating master info: %s.", msg);
133  DBUG_RETURN(NULL);
134 }
135 
146 bool Rpl_info_factory::change_mi_repository(Master_info *mi,
147  uint mi_option,
148  const char **msg)
149 {
150  Rpl_info_handler* handler_src= mi->get_rpl_info_handler();
151  Rpl_info_handler* handler_dest= NULL;
152  uint instances= 1;
153  DBUG_ENTER("Rpl_info_factory::change_mi_repository");
154 
155  DBUG_ASSERT(handler_src);
156  if (handler_src->get_rpl_info_type() == mi_option)
157  DBUG_RETURN(false);
158 
159  if (init_repositories(mi_table_data, mi_file_data, mi_option, instances,
160  NULL, &handler_dest, msg))
161  goto err;
162 
163  if (decide_repository(mi, mi_option, &handler_src, &handler_dest, msg))
164  goto err;
165 
166  DBUG_RETURN(FALSE);
167 
168 err:
169  delete handler_dest;
170  handler_dest= NULL;
171 
172  sql_print_error("Error changing the type of master info's repository: %s.", *msg);
173  DBUG_RETURN(TRUE);
174 }
175 
191 Relay_log_info *Rpl_info_factory::create_rli(uint rli_option, bool is_slave_recovery)
192 {
193  Relay_log_info *rli= NULL;
194  Rpl_info_handler* handler_src= NULL;
195  Rpl_info_handler* handler_dest= NULL;
196  uint instances= 1;
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 "
201  "structure";
202 
203  DBUG_ENTER("Rpl_info_factory::create_rli");
204 
205  /*
206  Returns how many occurrences of rli's repositories exist. For example,
207  if the repository is a table, this retrieves the number of rows in it.
208  Besides, it also returns the type of the repository where entries were
209  found.
210  */
211  if (rli_option != INFO_REPOSITORY_DUMMY &&
212  scan_repositories(&worker_instances, &worker_repository,
213  worker_table_data, worker_file_data, &msg))
214  goto err;
215 
216  if (!(rli= new Relay_log_info(is_slave_recovery
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
225 #endif
226  , instances
227  )))
228  {
229  msg= msg_alloc;
230  goto err;
231  }
232 
233  if(init_repositories(rli_table_data, rli_file_data, rli_option, instances,
234  &handler_src, &handler_dest, &msg))
235  goto err;
236 
237  if (rli_option != INFO_REPOSITORY_DUMMY &&
238  worker_repository != INVALID_INFO_REPOSITORY &&
239  worker_repository != rli_option)
240  {
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 "
248  "the type change.");
249  std::swap(handler_src, handler_dest);
250  }
251  if (decide_repository(rli, rli_option, &handler_src, &handler_dest, &msg))
252  goto err;
253 
254  DBUG_RETURN(rli);
255 
256 err:
257  delete handler_src;
258  delete handler_dest;
259  if (rli)
260  {
261  /*
262  The handler was previously deleted so we need to remove
263  any reference to it.
264  */
265  rli->set_rpl_info_handler(NULL);
266  delete rli;
267  }
268  sql_print_error("Error creating relay log info: %s.", msg);
269  DBUG_RETURN(NULL);
270 }
271 
282 bool Rpl_info_factory::change_rli_repository(Relay_log_info *rli,
283  uint rli_option,
284  const char **msg)
285 {
286  Rpl_info_handler* handler_src= rli->get_rpl_info_handler();
287  Rpl_info_handler* handler_dest= NULL;
288  uint instances= 1;
289  DBUG_ENTER("Rpl_info_factory::change_rli_repository");
290 
291  DBUG_ASSERT(handler_src != NULL);
292 
293  if (handler_src->get_rpl_info_type() == rli_option)
294  DBUG_RETURN(false);
295 
296  if (init_repositories(rli_table_data, rli_file_data, rli_option,
297  instances, NULL, &handler_dest, msg))
298  goto err;
299 
300  if (decide_repository(rli, rli_option, &handler_src, &handler_dest,
301  msg))
302  goto err;
303 
304  DBUG_RETURN(FALSE);
305 
306 err:
307  delete handler_dest;
308  handler_dest= NULL;
309 
310  sql_print_error("Error changing the type of relay log info's repository: %s.", *msg);
311  DBUG_RETURN(TRUE);
312 }
313 
321 bool Rpl_info_factory::reset_workers(Relay_log_info *rli)
322 {
323  bool error= true;
324 
325  DBUG_ENTER("Rpl_info_factory::reset_workers");
326 
327  if (rli->recovery_parallel_workers == 0)
328  DBUG_RETURN(0);
329 
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))
333  goto err;
334 
335  if (Rpl_info_table::do_reset_info(Slave_worker::get_number_worker_fields(),
336  MYSQL_SCHEMA_NAME.str, WORKER_INFO_NAME.str))
337  goto err;
338 
339  error= false;
340 
341  DBUG_EXECUTE_IF("mts_debug_reset_workers_fails", error= true;);
342 
343 err:
344  if (error)
345  sql_print_error("Could not delete from Slave Workers info repository.");
346  rli->recovery_parallel_workers= 0;
347  if (rli->flush_info(true))
348  {
349  error= true;
350  sql_print_error("Could not store the reset Slave Worker state into "
351  "the slave info repository.");
352  }
353  DBUG_RETURN(error);
354 }
355 
370 Slave_worker *Rpl_info_factory::create_worker(uint rli_option, uint worker_id,
371  Relay_log_info *rli,
372  bool is_gaps_collecting_phase)
373 {
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 "
378  "structure";
379 
380  DBUG_ENTER("Rpl_info_factory::create_worker");
381 
382  /*
383  Define the name of the worker and its repository.
384  */
385  char *pos= strmov(worker_file_data.name, worker_file_data.pattern);
386  sprintf(pos, "%u", worker_id + 1);
387 
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
397 #endif
398  , worker_id
399  )))
400  goto err;
401 
402 
403  if(init_repositories(worker_table_data, worker_file_data, rli_option,
404  worker_id + 1, &handler_src, &handler_dest, &msg))
405  goto err;
406 
407  if (decide_repository(worker, rli_option, &handler_src, &handler_dest, &msg))
408  goto err;
409 
410  if (worker->rli_init_info(is_gaps_collecting_phase))
411  {
412  msg= "Failed to initialize the worker info structure";
413  goto err;
414  }
415 
416  if (rli->info_thd && rli->info_thd->is_error())
417  {
418  msg= "Failed to initialize worker info table";
419  goto err;
420  }
421 
422  DBUG_RETURN(worker);
423 
424 err:
425  delete handler_src;
426  delete handler_dest;
427  if (worker)
428  {
429  /*
430  The handler was previously deleted so we need to remove
431  any reference to it.
432  */
433  worker->set_rpl_info_handler(NULL);
434  delete worker;
435  }
436  sql_print_error("Error creating relay log info: %s.", msg);
437  DBUG_RETURN(NULL);
438 }
439 
440 static void build_worker_info_name(char* to,
441  const char* path,
442  const char* fname)
443 {
444  DBUG_ASSERT(to);
445  char* pos= to;
446  if (path[0])
447  pos= strmov(pos, path);
448  pos= strmov(pos, "worker-");
449  pos= strmov(pos, fname);
450  strmov(pos, ".");
451 }
452 
456 void Rpl_info_factory::init_repository_metadata()
457 {
458  /* Needed for the file names and paths for worker info files. */
459  size_t len;
460  char* relay_log_info_file_name;
461  char relay_log_info_file_dirpart[FN_REFLEN];
462 
463  /* Extract the directory name from relay_log_info_file */
464  dirname_part(relay_log_info_file_dirpart, relay_log_info_file, &len);
465  relay_log_info_file_name= relay_log_info_file + len;
466 
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;
474 
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;
482 
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;
494 }
495 
496 
524 bool Rpl_info_factory::decide_repository(Rpl_info *info, uint option,
525  Rpl_info_handler **handler_src,
526  Rpl_info_handler **handler_dest,
527  const char **msg)
528 {
529  bool error= true;
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");
533 
534  if (option == INFO_REPOSITORY_DUMMY)
535  {
536  delete (*handler_src);
537  *handler_src= NULL;
538  info->set_rpl_info_handler(*handler_dest);
539  error = false;
540  goto err;
541  }
542 
543  DBUG_ASSERT((*handler_src) != NULL && (*handler_dest) != NULL &&
544  (*handler_src) != (*handler_dest));
545 
546  return_check_src= check_src_repository(info, option, handler_src);
547  return_check_dst= (*handler_dest)->do_check_info(info->get_internal_id());
548 
549  if (return_check_src == ERROR_CHECKING_REPOSITORY ||
550  return_check_dst == ERROR_CHECKING_REPOSITORY)
551  {
552  /*
553  If there is a problem with one of the repositories we print out
554  more information and exit.
555  */
556  DBUG_RETURN(check_error_repository(info, *handler_src, *handler_dest,
557  return_check_src,
558  return_check_dst, msg));
559  }
560  else
561  {
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))
566  {
567  /*
568  If there is no error, we can proceed with the normal operation.
569  However, if both repositories are set an error will be printed
570  out.
571  */
572  if (return_check_src == REPOSITORY_EXISTS &&
573  return_check_dst == REPOSITORY_EXISTS)
574  {
575  *msg= "Multiple replication metadata repository instances "
576  "found with data in them. Unable to decide which is "
577  "the correct one to choose";
578  goto err;
579  }
580 
581  /*
582  Do a low-level initialization to be able to do a state transfer.
583  */
584  if (init_repositories(info, handler_src, handler_dest, msg))
585  goto err;
586 
587  /*
588  Transfer information from source to destination and delete the
589  source. Note this is not fault-tolerant and a crash before removing
590  source may cause the next restart to fail as is_src and is_dest may
591  be true. Moreover, any failure in removing the source may lead to
592  the same.
593  /Alfranio
594  */
595  if (info->copy_info(*handler_src, *handler_dest) ||
596  (*handler_dest)->flush_info(true))
597  {
598  *msg= "Error transfering information";
599  goto err;
600  }
601  (*handler_src)->end_info();
602  if ((*handler_src)->remove_info())
603  {
604  *msg= "Error removing old repository";
605  goto err;
606  }
607  }
608  else if (return_check_src == REPOSITORY_DOES_NOT_EXIST &&
609  return_check_dst == REPOSITORY_EXISTS)
610  {
611  DBUG_ASSERT(info->get_rpl_info_handler() == NULL);
612  if ((*handler_dest)->do_init_info(info->get_internal_id()))
613  {
614  *msg= "Error reading repository";
615  goto err;
616  }
617  }
618  else
619  {
620  DBUG_ASSERT(return_check_src == REPOSITORY_DOES_NOT_EXIST &&
621  return_check_dst == REPOSITORY_DOES_NOT_EXIST);
622  }
623 
624  delete (*handler_src);
625  *handler_src= NULL;
626  info->set_rpl_info_handler(*handler_dest);
627  error= false;
628  }
629 
630 err:
631  DBUG_RETURN(error);
632 }
633 
634 
646 enum_return_check
647 Rpl_info_factory::check_src_repository(Rpl_info *info,
648  uint option,
649  Rpl_info_handler **handler_src)
650 {
651  enum_return_check return_check_src= ERROR_CHECKING_REPOSITORY;
652  bool live_migration = info->get_rpl_info_handler() != NULL;
653 
654  if (!live_migration)
655  {
656  /*
657  This is not a live migration and we don't know whether the repository
658  exists or not.
659  */
660  return_check_src= (*handler_src)->do_check_info(info->get_internal_id());
661 
662  /*
663  Since this is not a live migration, if we are using file repository
664  and there is some error on table repository (for instance, engine
665  disabled) we can ignore it instead of stopping replication.
666  A warning saying that table is not ready to be used was logged.
667  */
668  if (ERROR_CHECKING_REPOSITORY == return_check_src &&
669  INFO_REPOSITORY_FILE == option &&
670  INFO_REPOSITORY_TABLE == (*handler_src)->do_get_rpl_info_type())
671  {
672  return_check_src= REPOSITORY_DOES_NOT_EXIST;
673  /*
674  If a already existent thread was used to access info tables,
675  current_thd will point to it and we must clear access error on
676  it. If a temporary thread was used, then there is nothing to
677  clean because the thread was already deleted.
678  See Rpl_info_table_access::create_thd().
679  */
680  if (current_thd)
681  current_thd->clear_error();
682  }
683  }
684  else
685  {
686  /*
687  This is a live migration as the repository is already associated to.
688  However, we cannot assume that it really exists, for instance, if a
689  file was really created.
690 
691  This situation may happen when we start a slave for the first time
692  but skips its initialization and tries to migrate it.
693  */
694  return_check_src= (*handler_src)->do_check_info();
695  }
696 
697  return return_check_src;
698 }
699 
700 
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,
721  const char **msg)
722 {
723  bool error = true;
724 
725  /*
726  If there is an error in any of the source or destination
727  repository checks, the normal operation can't be proceeded.
728  The runtime repository won't be initialized.
729  */
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";
739  return error;
740 }
741 
742 
758 bool Rpl_info_factory::init_repositories(Rpl_info *info,
759  Rpl_info_handler **handler_src,
760  Rpl_info_handler **handler_dest,
761  const char **msg)
762 {
763  bool live_migration = info->get_rpl_info_handler() != NULL;
764 
765  if (!live_migration)
766  {
767  if ((*handler_src)->do_init_info(info->get_internal_id()) ||
768  (*handler_dest)->do_init_info(info->get_internal_id()))
769  {
770  *msg= "Error transfering information";
771  return true;
772  }
773  }
774  else
775  {
776  if ((*handler_dest)->do_init_info(info->get_internal_id()))
777  {
778  *msg= "Error transfering information";
779  return true;
780  }
781  }
782  return false;
783 }
784 
785 
805 bool Rpl_info_factory::init_repositories(const struct_table_data table_data,
806  const struct_file_data file_data,
807  uint rep_option,
808  uint instance,
809  Rpl_info_handler **handler_src,
810  Rpl_info_handler **handler_dest,
811  const char **msg)
812 {
813  bool error= TRUE;
814  *msg= "Failed to allocate memory for master info repositories";
815 
816  DBUG_ENTER("Rpl_info_factory::init_mi_repositories");
817 
818  DBUG_ASSERT(handler_dest != NULL);
819  switch (rep_option)
820  {
821  case INFO_REPOSITORY_FILE:
822  if (!(*handler_dest= new Rpl_info_file(file_data.n_fields,
823  file_data.pattern,
824  file_data.name,
825  file_data.name_indexed)))
826  goto err;
827  if (handler_src &&
828  !(*handler_src= new Rpl_info_table(table_data.n_fields,
829  table_data.schema,
830  table_data.name)))
831  goto err;
832  break;
833 
834  case INFO_REPOSITORY_TABLE:
835  if (!(*handler_dest= new Rpl_info_table(table_data.n_fields,
836  table_data.schema,
837  table_data.name)))
838  goto err;
839  if (handler_src &&
840  !(*handler_src= new Rpl_info_file(file_data.n_fields,
841  file_data.pattern,
842  file_data.name,
843  file_data.name_indexed)))
844  goto err;
845  break;
846 
847  case INFO_REPOSITORY_DUMMY:
848  if (!(*handler_dest= new Rpl_info_dummy(Master_info::get_number_info_mi_fields())))
849  goto err;
850  break;
851 
852  default:
853  DBUG_ASSERT(0);
854  }
855  error= FALSE;
856 
857 err:
858  DBUG_RETURN(error);
859 }
860 
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,
865  const char **msg)
866 {
867  bool error= false;
868  uint file_instances= 0;
869  uint table_instances= 0;
870  DBUG_ASSERT(found_rep_option != NULL);
871 
872  DBUG_ENTER("Rpl_info_factory::scan_repositories");
873 
874  if (Rpl_info_table::do_count_info(table_data.n_fields, table_data.schema,
875  table_data.name, &table_instances))
876  {
877  error= true;
878  goto err;
879  }
880 
881  if (Rpl_info_file::do_count_info(file_data.n_fields, file_data.pattern,
882  file_data.name_indexed, &file_instances))
883  {
884  error= true;
885  goto err;
886  }
887 
888  if (file_instances != 0 && table_instances != 0)
889  {
890  error= true;
891  *msg= "Multiple repository instances found with data in "
892  "them. Unable to decide which is the correct one to "
893  "choose";
894  goto err;
895  }
896 
897  if (table_instances != 0)
898  {
899  *found_instances= table_instances;
900  *found_rep_option= INFO_REPOSITORY_TABLE;
901  }
902  else if (file_instances != 0)
903  {
904  *found_instances= file_instances;
905  *found_rep_option= INFO_REPOSITORY_FILE;
906  }
907  else
908  {
909  *found_instances= 0;
910  *found_rep_option= INVALID_INFO_REPOSITORY;
911  }
912 
913 err:
914  DBUG_RETURN(error);
915 }