2 Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 All of the functions defined in this file which are not used (the ones to
22 handle failsafe) are not used; their code has not been updated for more
23 than one year now so should be considered as BADLY BROKEN. Do not enable
24 it. The used functions (to handle LOAD DATA FROM MASTER, plus some small
25 functions like register_slave()) are working.
28 #include "mysql_priv.h"
29 #ifdef HAVE_REPLICATION
31 #include "repl_failsafe.h"
35 #include "rpl_filter.h"
36 #include "log_event.h"
39 #define SLAVE_LIST_CHUNK 128
40 #define SLAVE_ERRMSG_SIZE (FN_REFLEN+64)
43 RPL_STATUS rpl_status
=RPL_NULL
;
44 pthread_mutex_t LOCK_rpl_status
;
45 pthread_cond_t COND_rpl_status
;
48 const char *rpl_role_type
[] = {"MASTER","SLAVE",NullS
};
49 TYPELIB rpl_role_typelib
= {array_elements(rpl_role_type
)-1,"",
52 const char* rpl_status_type
[]=
54 "AUTH_MASTER","ACTIVE_SLAVE","IDLE_SLAVE", "LOST_SOLDIER","TROOP_SOLDIER",
55 "RECOVERY_CAPTAIN","NULL",NullS
57 TYPELIB rpl_status_typelib
= {array_elements(rpl_status_type
)-1,"",
58 rpl_status_type
, NULL
};
61 static Slave_log_event
* find_slave_event(IO_CACHE
* log
,
62 const char* log_file_name
,
66 All of the functions defined in this file which are not used (the ones to
67 handle failsafe) are not used; their code has not been updated for more than
68 one year now so should be considered as BADLY BROKEN. Do not enable it.
69 The used functions (to handle LOAD DATA FROM MASTER, plus some small
70 functions like register_slave()) are working.
74 static int init_failsafe_rpl_thread(THD
* thd
)
76 DBUG_ENTER("init_failsafe_rpl_thread");
77 thd
->system_thread
= SYSTEM_THREAD_DELAYED_INSERT
;
79 thd->bootstrap is to report errors barely to stderr; if this code is
80 enable again one day, one should check if bootstrap is still needed (maybe
81 this thread has no other error reporting method).
84 thd
->security_ctx
->skip_grants();
85 my_net_init(&thd
->net
, 0);
86 thd
->net
.read_timeout
= slave_net_timeout
;
87 thd
->max_client_packet_length
=thd
->net
.max_packet
;
88 pthread_mutex_lock(&LOCK_thread_count
);
89 thd
->thread_id
= thd
->variables
.pseudo_thread_id
= thread_id
++;
90 pthread_mutex_unlock(&LOCK_thread_count
);
92 if (init_thr_lock() || thd
->store_globals())
94 /* purecov: begin inspected */
95 close_connection(thd
, ER_OUT_OF_RESOURCES
, 1); // is this needed?
96 statistic_increment(aborted_connects
,&LOCK_status
);
97 one_thread_per_connection_end(thd
,0);
102 thd
->mem_root
->free
= thd
->mem_root
->used
= 0;
103 if (thd
->variables
.max_join_size
== HA_POS_ERROR
)
104 thd
->options
|= OPTION_BIG_SELECTS
;
106 thd_proc_info(thd
, "Thread initialized");
107 thd
->version
=refresh_version
;
113 void change_rpl_status(RPL_STATUS from_status
, RPL_STATUS to_status
)
115 pthread_mutex_lock(&LOCK_rpl_status
);
116 if (rpl_status
== from_status
|| rpl_status
== RPL_ANY
)
117 rpl_status
= to_status
;
118 pthread_cond_signal(&COND_rpl_status
);
119 pthread_mutex_unlock(&LOCK_rpl_status
);
123 #define get_object(p, obj, msg) \
125 uint len = (uint)*p++; \
126 if (p + len > p_end || len >= sizeof(obj)) \
131 strmake(obj,(char*) p,len); \
136 static inline int cmp_master_pos(Slave_log_event* sev, LEX_MASTER_INFO* mi)
138 return cmp_master_pos(sev
->master_log
, sev
->master_pos
, mi
->log_file_name
,
143 void unregister_slave(THD
* thd
, bool only_mine
, bool need_mutex
)
148 pthread_mutex_lock(&LOCK_slave_list
);
151 if ((old_si
= (SLAVE_INFO
*)hash_search(&slave_list
,
152 (uchar
*)&thd
->server_id
, 4)) &&
153 (!only_mine
|| old_si
->thd
== thd
))
154 hash_delete(&slave_list
, (uchar
*)old_si
);
157 pthread_mutex_unlock(&LOCK_slave_list
);
163 Register slave in 'slave_list' hash table.
168 1 Error. Error message sent to client
171 int register_slave(THD
* thd
, uchar
* packet
, uint packet_length
)
175 uchar
*p
= packet
, *p_end
= packet
+ packet_length
;
176 const char *errmsg
= "Wrong parameters to function register_slave";
178 if (check_access(thd
, REPL_SLAVE_ACL
, any_db
,0,0,0,0))
180 if (!(si
= (SLAVE_INFO
*)my_malloc(sizeof(SLAVE_INFO
), MYF(MY_WME
))))
183 thd
->server_id
= si
->server_id
= uint4korr(p
);
185 get_object(p
,si
->host
, "Failed to register slave: too long 'report-host'");
186 get_object(p
,si
->user
, "Failed to register slave: too long 'report-user'");
187 get_object(p
,si
->password
, "Failed to register slave; too long 'report-password'");
190 si
->port
= uint2korr(p
);
192 si
->rpl_recovery_rank
= uint4korr(p
);
194 if (!(si
->master_id
= uint4korr(p
)))
195 si
->master_id
= server_id
;
198 pthread_mutex_lock(&LOCK_slave_list
);
199 unregister_slave(thd
,0,0);
200 res
= my_hash_insert(&slave_list
, (uchar
*) si
);
201 pthread_mutex_unlock(&LOCK_slave_list
);
205 my_free(si
, MYF(MY_WME
));
206 my_message(ER_UNKNOWN_ERROR
, errmsg
, MYF(0)); /* purecov: inspected */
212 *slave_list_key(SLAVE_INFO
* si
, size_t *len
,
213 my_bool not_used
__attribute__((unused
)))
216 return &si
->server_id
;
219 extern "C" void slave_info_free(void *s
)
221 my_free(s
, MYF(MY_WME
));
224 void init_slave_list()
226 hash_init(&slave_list
, system_charset_info
, SLAVE_LIST_CHUNK
, 0, 0,
227 (hash_get_key
) slave_list_key
, (hash_free_key
) slave_info_free
, 0);
228 pthread_mutex_init(&LOCK_slave_list
, MY_MUTEX_INIT_FAST
);
231 void end_slave_list()
233 /* No protection by a mutex needed as we are only called at shutdown */
234 if (hash_inited(&slave_list
))
236 hash_free(&slave_list
);
237 pthread_mutex_destroy(&LOCK_slave_list
);
241 static int find_target_pos(LEX_MASTER_INFO
*mi
, IO_CACHE
*log
, char *errmsg
)
243 my_off_t log_pos
= (my_off_t
) mi
->pos
;
244 uint32 target_server_id
= mi
->server_id
;
249 if (!(ev
= Log_event::read_log_event(log
, (pthread_mutex_t
*) 0, 0)))
252 strmov(errmsg
, "Binary log truncated in the middle of event");
253 else if (log
->error
< 0)
254 strmov(errmsg
, "I/O error reading binary log");
256 strmov(errmsg
, "Could not find target event in the binary log");
260 if (ev
->log_pos
>= log_pos
&& ev
->server_id
== target_server_id
)
263 mi
->pos
= my_b_tell(log
);
273 Before 4.0.15 we had a member of THD called log_pos, it was meant for
274 failsafe replication code in repl_failsafe.cc which is disabled until
275 it is reworked. Event's log_pos used to be preserved through
276 log-slave-updates to make code in repl_failsafe.cc work (this
277 function, SHOW NEW MASTER); but on the other side it caused unexpected
278 values in Exec_Master_Log_Pos in A->B->C replication setup,
279 synchronization problems in master_pos_wait(), ... So we
280 (Dmitri & Guilhem) removed it.
282 So for now this function is broken.
285 int translate_master(THD
* thd
, LEX_MASTER_INFO
* mi
, char* errmsg
)
288 char last_log_name
[FN_REFLEN
];
290 File file
= -1, last_file
= -1;
291 pthread_mutex_t
*log_lock
;
292 const char* errmsg_p
;
293 Slave_log_event
* sev
= 0;
294 my_off_t last_pos
= 0;
298 DBUG_ENTER("translate_master");
300 if (!mysql_bin_log
.is_open())
302 strmov(errmsg
,"Binary log is not open");
306 if (!server_id_supplied
)
308 strmov(errmsg
, "Misconfigured master - server id was not set");
312 if (mysql_bin_log
.find_log_pos(&linfo
, NullS
, 1))
314 strmov(errmsg
,"Could not find first log");
317 thd
->current_linfo
= &linfo
;
319 bzero((char*) &log
,sizeof(log
));
320 log_lock
= mysql_bin_log
.get_log_lock();
321 pthread_mutex_lock(log_lock
);
325 if ((file
=open_binlog(&log
, linfo
.log_file_name
, &errmsg_p
)) < 0)
327 strmov(errmsg
, errmsg_p
);
331 if (!(sev
= find_slave_event(&log
, linfo
.log_file_name
, errmsg
)))
334 cmp_res
= cmp_master_pos(sev
, mi
);
340 fn_format(mi
->log_file_name
, linfo
.log_file_name
, "","",1);
341 mi
->pos
= my_b_tell(&log
);
344 else if (cmp_res
> 0)
349 "Slave event in first log points past the target position");
353 (void) my_close(file
, MYF(MY_WME
));
354 if (init_io_cache(&log
, (file
= last_file
), IO_SIZE
, READ_CACHE
, 0, 0,
363 strmov(last_log_name
, linfo
.log_file_name
);
364 last_pos
= my_b_tell(&log
);
366 switch (mysql_bin_log
.find_next_log(&linfo
, 1)) {
369 (void)my_close(last_file
, MYF(MY_WME
));
375 strmov(errmsg
, "Error reading log index");
381 (void) my_close(last_file
, MYF(MY_WME
));
386 my_b_seek(&log
, last_pos
);
387 if (find_target_pos(mi
,&log
,errmsg
))
389 fn_format(mi
->log_file_name
, last_log_name
, "","",1); /* Copy basename */
394 pthread_mutex_unlock(log_lock
);
396 pthread_mutex_lock(&LOCK_thread_count
);
397 thd
->current_linfo
= 0;
398 pthread_mutex_unlock(&LOCK_thread_count
);
400 (void) my_close(file
, MYF(MY_WME
));
401 if (last_file
>= 0 && last_file
!= file
)
402 (void) my_close(last_file
, MYF(MY_WME
));
409 Caller must delete result when done.
412 static Slave_log_event
* find_slave_event(IO_CACHE
* log
,
413 const char* log_file_name
,
418 bool slave_event_found
= 0;
421 for (i
= 0; i
< 2; i
++)
423 if (!(ev
= Log_event::read_log_event(log
, (pthread_mutex_t
*)0, 0)))
425 my_snprintf(errmsg
, SLAVE_ERRMSG_SIZE
,
426 "Error reading event in log '%s'",
427 (char*)log_file_name
);
430 if (ev
->get_type_code() == SLAVE_EVENT
)
432 slave_event_found
= 1;
437 if (!slave_event_found
)
439 my_snprintf(errmsg
, SLAVE_ERRMSG_SIZE
,
440 "Could not find slave event in log '%s'",
441 (char*)log_file_name
);
445 return (Slave_log_event
*)ev
;
449 This function is broken now.
451 @seealso translate_master()
454 bool show_new_master(THD
* thd
)
456 Protocol
*protocol
= thd
->protocol
;
457 DBUG_ENTER("show_new_master");
458 List
<Item
> field_list
;
459 char errmsg
[SLAVE_ERRMSG_SIZE
];
460 LEX_MASTER_INFO
* lex_mi
= &thd
->lex
->mi
;
462 errmsg
[0]=0; // Safety
463 if (translate_master(thd
, lex_mi
, errmsg
))
466 my_error(ER_ERROR_WHEN_EXECUTING_COMMAND
, MYF(0),
467 "SHOW NEW MASTER", errmsg
);
472 field_list
.push_back(new Item_empty_string("Log_name", 20));
473 field_list
.push_back(new Item_return_int("Log_pos", 10,
474 MYSQL_TYPE_LONGLONG
));
475 if (protocol
->send_fields(&field_list
,
476 Protocol::SEND_NUM_ROWS
| Protocol::SEND_EOF
))
478 protocol
->prepare_for_resend();
479 protocol
->store(lex_mi
->log_file_name
, &my_charset_bin
);
480 protocol
->store((ulonglong
) lex_mi
->pos
);
481 if (protocol
->write())
489 Asks the master for the list of its other connected slaves.
491 This is for failsafe replication:
492 in order for failsafe replication to work, the servers involved in
493 replication must know of each other. We accomplish this by having each
494 slave report to the master how to reach it, and on connection, each
495 slave receives information about where the other slaves are.
497 @param mysql pre-existing connection to the master
498 @param mi master info
501 mi is used only to give detailed error messages which include the
502 hostname/port of the master, the username used by the slave to connect to
504 If the user used by the slave to connect to the master does not have the
505 REPLICATION SLAVE privilege, it will pop in this function because
506 SHOW SLAVE HOSTS will fail on the master.
514 int update_slave_list(MYSQL
* mysql
, Master_info
* mi
)
521 DBUG_ENTER("update_slave_list");
523 if (mysql_real_query(mysql
, STRING_WITH_LEN("SHOW SLAVE HOSTS")) ||
524 !(res
= mysql_store_result(mysql
)))
526 error
= mysql_error(mysql
);
530 switch (mysql_num_fields(res
)) {
540 error
= "the master returned an invalid number of fields for SHOW SLAVE \
545 pthread_mutex_lock(&LOCK_slave_list
);
547 while ((row
= mysql_fetch_row(res
)))
549 uint32 log_server_id
;
550 SLAVE_INFO
* si
, *old_si
;
551 log_server_id
= atoi(row
[0]);
552 if ((old_si
= (SLAVE_INFO
*)hash_search(&slave_list
,
553 (uchar
*)&log_server_id
,4)))
557 if (!(si
= (SLAVE_INFO
*)my_malloc(sizeof(SLAVE_INFO
), MYF(MY_WME
))))
559 error
= "the slave is out of memory";
560 pthread_mutex_unlock(&LOCK_slave_list
);
563 si
->server_id
= log_server_id
;
564 if (my_hash_insert(&slave_list
, (uchar
*)si
))
566 error
= "the slave is out of memory";
567 pthread_mutex_unlock(&LOCK_slave_list
);
571 strmake(si
->host
, row
[1], sizeof(si
->host
)-1);
572 si
->port
= atoi(row
[port_ind
]);
573 si
->rpl_recovery_rank
= atoi(row
[port_ind
+1]);
574 si
->master_id
= atoi(row
[port_ind
+2]);
577 strmake(si
->user
, row
[2], sizeof(si
->user
)-1);
578 strmake(si
->password
, row
[3], sizeof(si
->password
)-1);
581 pthread_mutex_unlock(&LOCK_slave_list
);
585 mysql_free_result(res
);
588 sql_print_error("While trying to obtain the list of slaves from the master "
589 "'%s:%d', user '%s' got the following error: '%s'",
590 mi
->host
, mi
->port
, mi
->user
, error
);
598 int find_recovery_captain(THD
* thd
, MYSQL
* mysql
)
605 pthread_handler_t
handle_failsafe_rpl(void *arg
)
607 DBUG_ENTER("handle_failsafe_rpl");
609 thd
->thread_stack
= (char*)&thd
;
610 MYSQL
* recovery_captain
= 0;
613 pthread_detach_this_thread();
614 if (init_failsafe_rpl_thread(thd
) || !(recovery_captain
=mysql_init(0)))
616 sql_print_error("Could not initialize failsafe replication thread");
619 pthread_mutex_lock(&LOCK_rpl_status
);
620 msg
= thd
->enter_cond(&COND_rpl_status
,
621 &LOCK_rpl_status
, "Waiting for request");
622 while (!thd
->killed
&& !abort_loop
)
624 bool break_req_chain
= 0;
625 pthread_cond_wait(&COND_rpl_status
, &LOCK_rpl_status
);
626 thd_proc_info(thd
, "Processing request");
627 while (!break_req_chain
)
629 switch (rpl_status
) {
630 case RPL_LOST_SOLDIER
:
631 if (find_recovery_captain(thd
, recovery_captain
))
632 rpl_status
=RPL_TROOP_SOLDIER
;
634 rpl_status
=RPL_RECOVERY_CAPTAIN
;
635 break_req_chain
=1; /* for now until other states are implemented */
645 if (recovery_captain
)
646 mysql_close(recovery_captain
);
649 DBUG_LEAVE
; // Must match DBUG_ENTER()
652 return 0; // Avoid compiler warnings
658 Execute a SHOW SLAVE HOSTS statement.
660 @param thd Pointer to THD object for the client thread executing the
663 @retval FALSE success
666 bool show_slave_hosts(THD
* thd
)
668 List
<Item
> field_list
;
669 Protocol
*protocol
= thd
->protocol
;
670 DBUG_ENTER("show_slave_hosts");
672 field_list
.push_back(new Item_return_int("Server_id", 10,
674 field_list
.push_back(new Item_empty_string("Host", 20));
675 if (opt_show_slave_auth_info
)
677 field_list
.push_back(new Item_empty_string("User",20));
678 field_list
.push_back(new Item_empty_string("Password",20));
680 field_list
.push_back(new Item_return_int("Port", 7, MYSQL_TYPE_LONG
));
681 field_list
.push_back(new Item_return_int("Rpl_recovery_rank", 7,
683 field_list
.push_back(new Item_return_int("Master_id", 10,
686 if (protocol
->send_fields(&field_list
,
687 Protocol::SEND_NUM_ROWS
| Protocol::SEND_EOF
))
690 pthread_mutex_lock(&LOCK_slave_list
);
692 for (uint i
= 0; i
< slave_list
.records
; ++i
)
694 SLAVE_INFO
* si
= (SLAVE_INFO
*) hash_element(&slave_list
, i
);
695 protocol
->prepare_for_resend();
696 protocol
->store((uint32
) si
->server_id
);
697 protocol
->store(si
->host
, &my_charset_bin
);
698 if (opt_show_slave_auth_info
)
700 protocol
->store(si
->user
, &my_charset_bin
);
701 protocol
->store(si
->password
, &my_charset_bin
);
703 protocol
->store((uint32
) si
->port
);
704 protocol
->store((uint32
) si
->rpl_recovery_rank
);
705 protocol
->store((uint32
) si
->master_id
);
706 if (protocol
->write())
708 pthread_mutex_unlock(&LOCK_slave_list
);
712 pthread_mutex_unlock(&LOCK_slave_list
);
718 int connect_to_master(THD
*thd
, MYSQL
* mysql
, Master_info
* mi
)
720 DBUG_ENTER("connect_to_master");
722 if (!mi
->host
|| !*mi
->host
) /* empty host */
724 strmov(mysql
->net
.last_error
, "Master is not configured");
727 mysql_options(mysql
, MYSQL_OPT_CONNECT_TIMEOUT
, (char *) &slave_net_timeout
);
728 mysql_options(mysql
, MYSQL_OPT_READ_TIMEOUT
, (char *) &slave_net_timeout
);
734 mi
->ssl_key
[0]?mi
->ssl_key
:0,
735 mi
->ssl_cert
[0]?mi
->ssl_cert
:0,
736 mi
->ssl_ca
[0]?mi
->ssl_ca
:0,
737 mi
->ssl_capath
[0]?mi
->ssl_capath
:0,
738 mi
->ssl_cipher
[0]?mi
->ssl_cipher
:0);
739 mysql_options(mysql
, MYSQL_OPT_SSL_VERIFY_SERVER_CERT
,
740 &mi
->ssl_verify_server_cert
);
744 mysql_options(mysql
, MYSQL_SET_CHARSET_NAME
, default_charset_info
->csname
);
745 mysql_options(mysql
, MYSQL_SET_CHARSET_DIR
, (char *) charsets_dir
);
746 if (!mysql_real_connect(mysql
, mi
->host
, mi
->user
, mi
->password
, 0,
754 static inline void cleanup_mysql_results(MYSQL_RES
* db_res
,
755 MYSQL_RES
** cur
, MYSQL_RES
** start
)
757 for (; cur
>= start
; --cur
)
760 mysql_free_result(*cur
);
762 mysql_free_result(db_res
);
766 static int fetch_db_tables(THD
*thd
, MYSQL
*mysql
, const char *db
,
767 MYSQL_RES
*table_res
, Master_info
*mi
)
770 for (row
= mysql_fetch_row(table_res
); row
;
771 row
= mysql_fetch_row(table_res
))
774 const char* table_name
= row
[0];
776 if (rpl_filter
->is_on())
778 bzero((char*) &table
, sizeof(table
)); //just for safe
779 table
.db
= (char*) db
;
780 table
.table_name
= (char*) table_name
;
783 if (!rpl_filter
->tables_ok(thd
->db
, &table
))
786 /* download master's table and overwrite slave's table */
787 if ((error
= fetch_master_table(thd
, db
, table_name
, mi
, mysql
, 1)))
794 Load all MyISAM tables from master to this slave.
797 - No active transaction (flush_relay_log_info would not work in this case).
800 - add special option, not enabled
801 by default, to allow inclusion of mysql database into load
805 bool load_master_data(THD
* thd
)
808 MYSQL_RES
* master_status_res
= 0;
810 const char* errmsg
=0;
811 int restart_thread_mask
;
812 HA_CREATE_INFO create_info
;
817 We do not want anyone messing with the slave at all for the entire
818 duration of the data load.
820 pthread_mutex_lock(&LOCK_active_mi
);
821 lock_slave_threads(active_mi
);
822 init_thread_mask(&restart_thread_mask
,active_mi
,0 /*not inverse*/);
823 if (restart_thread_mask
&&
824 (error
=terminate_slave_threads(active_mi
,restart_thread_mask
,
827 my_message(error
, ER(error
), MYF(0));
828 unlock_slave_threads(active_mi
);
829 pthread_mutex_unlock(&LOCK_active_mi
);
833 if (connect_to_master(thd
, &mysql
, active_mi
))
835 my_error(error
= ER_CONNECT_TO_MASTER
, MYF(0), mysql_error(&mysql
));
839 // now that we are connected, get all database and tables in each
841 MYSQL_RES
*db_res
, **table_res
, **table_res_end
, **cur_table_res
;
844 if (mysql_real_query(&mysql
, STRING_WITH_LEN("SHOW DATABASES")) ||
845 !(db_res
= mysql_store_result(&mysql
)))
847 my_error(error
= ER_QUERY_ON_MASTER
, MYF(0), mysql_error(&mysql
));
851 if (!(num_dbs
= (uint
) mysql_num_rows(db_res
)))
854 In theory, the master could have no databases at all
855 and run with skip-grant
858 if (!(table_res
= (MYSQL_RES
**)thd
->alloc(num_dbs
* sizeof(MYSQL_RES
*))))
860 my_message(error
= ER_OUTOFMEMORY
, ER(ER_OUTOFMEMORY
), MYF(0));
865 This is a temporary solution until we have online backup
866 capabilities - to be replaced once online backup is working
867 we wait to issue FLUSH TABLES WITH READ LOCK for as long as we
868 can to minimize the lock time.
870 if (mysql_real_query(&mysql
,
871 STRING_WITH_LEN("FLUSH TABLES WITH READ LOCK")) ||
872 mysql_real_query(&mysql
, STRING_WITH_LEN("SHOW MASTER STATUS")) ||
873 !(master_status_res
= mysql_store_result(&mysql
)))
875 my_error(error
= ER_QUERY_ON_MASTER
, MYF(0), mysql_error(&mysql
));
880 Go through every table in every database, and if the replication
881 rules allow replicating it, get it
884 table_res_end
= table_res
+ num_dbs
;
886 for (cur_table_res
= table_res
; cur_table_res
< table_res_end
;
889 // since we know how many rows we have, this can never be NULL
890 MYSQL_ROW row
= mysql_fetch_row(db_res
);
894 Do not replicate databases excluded by rules. We also test
895 replicate_wild_*_table rules (replicate_wild_ignore_table='db1.%' will
896 be considered as "ignore the 'db1' database as a whole, as it already
897 works for CREATE DATABASE and DROP DATABASE).
898 Also skip 'mysql' database - in most cases the user will
899 mess up and not exclude mysql database with the rules when
900 he actually means to - in this case, he is up for a surprise if
901 his priv tables get dropped and downloaded from master
902 TODO - add special option, not enabled
903 by default, to allow inclusion of mysql database into load
907 if (!rpl_filter
->db_ok(db
) ||
908 !rpl_filter
->db_ok_with_wild_table(db
) ||
909 !strcmp(db
,"mysql") ||
916 bzero((char*) &create_info
, sizeof(create_info
));
917 create_info
.options
= HA_LEX_CREATE_IF_NOT_EXISTS
;
919 if (mysql_create_db(thd
, db
, &create_info
, 1))
921 cleanup_mysql_results(db_res
, cur_table_res
- 1, table_res
);
924 /* Clear the result of mysql_create_db(). */
925 thd
->main_da
.reset_diagnostics_area();
927 if (mysql_select_db(&mysql
, db
) ||
928 mysql_real_query(&mysql
, STRING_WITH_LEN("SHOW TABLES")) ||
929 !(*cur_table_res
= mysql_store_result(&mysql
)))
931 my_error(error
= ER_QUERY_ON_MASTER
, MYF(0), mysql_error(&mysql
));
932 cleanup_mysql_results(db_res
, cur_table_res
- 1, table_res
);
936 if ((error
= fetch_db_tables(thd
,&mysql
,db
,*cur_table_res
,active_mi
)))
938 // we do not report the error - fetch_db_tables handles it
939 cleanup_mysql_results(db_res
, cur_table_res
, table_res
);
944 cleanup_mysql_results(db_res
, cur_table_res
- 1, table_res
);
946 // adjust replication coordinates from the master
947 if (master_status_res
)
949 MYSQL_ROW row
= mysql_fetch_row(master_status_res
);
952 We need this check because the master may not be running with
953 log-bin, but it will still allow us to do all the steps
954 of LOAD DATA FROM MASTER - no reason to forbid it, really,
955 although it does not make much sense for the user to do it
957 if (row
&& row
[0] && row
[1])
960 If the slave's master info is not inited, we init it, then we write
961 the new coordinates to it. Must call init_master_info() *before*
962 setting active_mi, because init_master_info() sets active_mi with
967 if (init_master_info(active_mi
, master_info_file
, relay_log_info_file
,
968 0, (SLAVE_IO
| SLAVE_SQL
)))
969 my_message(ER_MASTER_INFO
, ER(ER_MASTER_INFO
), MYF(0));
970 strmake(active_mi
->master_log_name
, row
[0],
971 sizeof(active_mi
->master_log_name
) -1);
972 active_mi
->master_log_pos
= my_strtoll10(row
[1], (char**) 0, &error_2
);
973 /* at least in recent versions, the condition below should be false */
974 if (active_mi
->master_log_pos
< BIN_LOG_HEADER_SIZE
)
975 active_mi
->master_log_pos
= BIN_LOG_HEADER_SIZE
;
977 Relay log's IO_CACHE may not be inited (even if we are sure that some
978 host was specified; there could have been a problem when replication
979 started, which led to relay log's IO_CACHE to not be inited.
981 if (flush_master_info(active_mi
, FALSE
, FALSE
))
982 sql_print_error("Failed to flush master info file");
984 mysql_free_result(master_status_res
);
987 if (mysql_real_query(&mysql
, STRING_WITH_LEN("UNLOCK TABLES")))
989 my_error(error
= ER_QUERY_ON_MASTER
, MYF(0), mysql_error(&mysql
));
993 thd_proc_info(thd
, "purging old relay logs");
994 if (purge_relay_logs(&active_mi
->rli
,thd
,
995 0 /* not only reset, but also reinit */,
998 my_error(ER_RELAY_LOG_FAIL
, MYF(0), errmsg
);
999 unlock_slave_threads(active_mi
);
1000 pthread_mutex_unlock(&LOCK_active_mi
);
1003 pthread_mutex_lock(&active_mi
->rli
.data_lock
);
1004 active_mi
->rli
.group_master_log_pos
= active_mi
->master_log_pos
;
1005 strmake(active_mi
->rli
.group_master_log_name
,active_mi
->master_log_name
,
1006 sizeof(active_mi
->rli
.group_master_log_name
)-1);
1008 Cancel the previous START SLAVE UNTIL, as the fact to download
1009 a new copy logically makes UNTIL irrelevant.
1011 active_mi
->rli
.clear_until_condition();
1014 No need to update rli.event* coordinates, they will be when the slave
1015 threads start ; only rli.group* coordinates are necessary here.
1017 flush_relay_log_info(&active_mi
->rli
);
1018 pthread_cond_broadcast(&active_mi
->rli
.data_cond
);
1019 pthread_mutex_unlock(&active_mi
->rli
.data_lock
);
1020 thd_proc_info(thd
, "starting slave");
1021 if (restart_thread_mask
)
1023 error
=start_slave_threads(0 /* mutex not needed */,
1024 1 /* wait for start */,
1025 active_mi
,master_info_file
,relay_log_info_file
,
1026 restart_thread_mask
);
1030 unlock_slave_threads(active_mi
);
1031 pthread_mutex_unlock(&LOCK_active_mi
);
1032 thd_proc_info(thd
, 0);
1034 mysql_close(&mysql
); // safe to call since we always do mysql_init()
1041 #endif /* HAVE_REPLICATION */