1 /* Copyright (c) 2000, 2019, 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, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software Foundation,
21    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
22 
23 
24 /**
25   @addtogroup Replication
26   @{
27 
28   @file
29 
30   @brief Code to run the io thread and the sql thread on the
31   replication slave.
32 */
33 
34 #include "sql_priv.h"
35 #include "my_global.h"
36 #include "rpl_slave.h"
37 #include "sql_parse.h"                         // execute_init_command
38 #include "sql_table.h"                         // mysql_rm_table
39 #include "rpl_mi.h"
40 #include "rpl_rli.h"
41 #include "rpl_filter.h"
42 #include "rpl_info_factory.h"
43 #include "transaction.h"
44 #include <thr_alarm.h>
45 #include <my_dir.h>
46 #include <sql_common.h>
47 #include <errmsg.h>
48 #include <mysqld_error.h>
49 #include <mysys_err.h>
50 #include "rpl_handler.h"
51 #include "rpl_info_dummy.h"
52 #include <signal.h>
53 #include <mysql.h>
54 #include <myisam.h>
55 
56 #include "sql_base.h"                           // close_thread_tables
57 #include "tztime.h"                             // struct Time_zone
58 #include "log_event.h"                          // Rotate_log_event,
59                                                 // Create_file_log_event,
60                                                 // Format_description_log_event
61 #include "dynamic_ids.h"
62 #include "rpl_rli_pdb.h"
63 #include "global_threads.h"
64 
65 #ifdef HAVE_REPLICATION
66 
67 #include "rpl_tblmap.h"
68 #include "debug_sync.h"
69 
70 using std::min;
71 using std::max;
72 
73 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
74 
75 #define MAX_SLAVE_RETRY_PAUSE 5
76 /*
77   a parameter of sql_slave_killed() to defer the killed status
78 */
79 #define SLAVE_WAIT_GROUP_DONE 60
80 bool use_slave_mask = 0;
81 MY_BITMAP slave_error_mask;
82 char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE];
83 
84 static unsigned long stop_wait_timeout;
85 char* slave_load_tmpdir = 0;
86 Master_info *active_mi= 0;
87 my_bool replicate_same_server_id;
88 ulonglong relay_log_space_limit = 0;
89 
90 const char *relay_log_index= 0;
91 const char *relay_log_basename= 0;
92 
93 /*
94   MTS load-ballancing parameter.
95   Max length of one MTS Worker queue. The value also determines the size
96   of Relay_log_info::gaq (see @c slave_start_workers()).
97   It can be set to any value in [1, ULONG_MAX - 1] range.
98 */
99 const ulong mts_slave_worker_queue_len_max= 16384;
100 
101 /*
102   Statistics go to the error log every # of seconds when --log-warnings > 1
103 */
104 const long mts_online_stat_period= 60 * 2;
105 
106 
107 /*
108   MTS load-ballancing parameter.
109   Time unit in microsecs to sleep by MTS Coordinator to avoid extra thread
110   signalling in the case of Worker queues are close to be filled up.
111 */
112 const ulong mts_coordinator_basic_nap= 5;
113 
114 /*
115   MTS load-ballancing parameter.
116   Percent of Worker queue size at which Worker is considered to become
117   hungry.
118 
119   C enqueues --+                   . underrun level
120                V                   "
121    +----------+-+------------------+--------------+
122    | empty    |.|::::::::::::::::::|xxxxxxxxxxxxxx| ---> Worker dequeues
123    +----------+-+------------------+--------------+
124 
125    Like in the above diagram enqueuing to the x-d area would indicate
126    actual underrruning by Worker.
127 */
128 const ulong mts_worker_underrun_level= 10;
129 
130 Slave_job_item * de_queue(Slave_jobs_queue *jobs, Slave_job_item *ret);
131 bool append_item_to_jobs(slave_job_item *job_item,
132                          Slave_worker *w, Relay_log_info *rli);
133 
134 /*
135   When slave thread exits, we need to remember the temporary tables so we
136   can re-use them on slave start.
137 
138   TODO: move the vars below under Master_info
139 */
140 
141 int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
142 
143 static pthread_key(Master_info*, RPL_MASTER_INFO);
144 
145 enum enum_slave_reconnect_actions
146 {
147   SLAVE_RECON_ACT_REG= 0,
148   SLAVE_RECON_ACT_DUMP= 1,
149   SLAVE_RECON_ACT_EVENT= 2,
150   SLAVE_RECON_ACT_MAX
151 };
152 
153 enum enum_slave_reconnect_messages
154 {
155   SLAVE_RECON_MSG_WAIT= 0,
156   SLAVE_RECON_MSG_KILLED_WAITING= 1,
157   SLAVE_RECON_MSG_AFTER= 2,
158   SLAVE_RECON_MSG_FAILED= 3,
159   SLAVE_RECON_MSG_COMMAND= 4,
160   SLAVE_RECON_MSG_KILLED_AFTER= 5,
161   SLAVE_RECON_MSG_MAX
162 };
163 
164 static const char *reconnect_messages[SLAVE_RECON_ACT_MAX][SLAVE_RECON_MSG_MAX]=
165 {
166   {
167     "Waiting to reconnect after a failed registration on master",
168     "Slave I/O thread killed while waitnig to reconnect after a failed \
169 registration on master",
170     "Reconnecting after a failed registration on master",
171     "failed registering on master, reconnecting to try again, \
172 log '%s' at position %s",
173     "COM_REGISTER_SLAVE",
174     "Slave I/O thread killed during or after reconnect"
175   },
176   {
177     "Waiting to reconnect after a failed binlog dump request",
178     "Slave I/O thread killed while retrying master dump",
179     "Reconnecting after a failed binlog dump request",
180     "failed dump request, reconnecting to try again, log '%s' at position %s",
181     "COM_BINLOG_DUMP",
182     "Slave I/O thread killed during or after reconnect"
183   },
184   {
185     "Waiting to reconnect after a failed master event read",
186     "Slave I/O thread killed while waiting to reconnect after a failed read",
187     "Reconnecting after a failed master event read",
188     "Slave I/O thread: Failed reading log event, reconnecting to retry, \
189 log '%s' at position %s",
190     "",
191     "Slave I/O thread killed during or after a reconnect done to recover from \
192 failed read"
193   }
194 };
195 
196 enum enum_slave_apply_event_and_update_pos_retval
197 {
198   SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK= 0,
199   SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR= 1,
200   SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR= 2,
201   SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR= 3,
202   SLAVE_APPLY_EVENT_AND_UPDATE_POS_MAX
203 };
204 
205 
206 static int process_io_rotate(Master_info* mi, Rotate_log_event* rev);
207 static int process_io_create_file(Master_info* mi, Create_file_log_event* cev);
208 static bool wait_for_relay_log_space(Relay_log_info* rli);
209 static inline bool io_slave_killed(THD* thd,Master_info* mi);
210 static inline bool sql_slave_killed(THD* thd,Relay_log_info* rli);
211 static inline bool is_autocommit_off_and_infotables(THD* thd);
212 static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
213 static void print_slave_skip_errors(void);
214 static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi);
215 static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
216                           bool suppress_warnings);
217 static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
218                              bool reconnect, bool suppress_warnings);
219 static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi);
220 static int get_master_uuid(MYSQL *mysql, Master_info *mi);
221 int io_thread_init_commands(MYSQL *mysql, Master_info *mi);
222 static Log_event* next_event(Relay_log_info* rli);
223 static int queue_event(Master_info* mi,const char* buf,ulong event_len);
224 static void set_stop_slave_wait_timeout(unsigned long wait_timeout);
225 static int terminate_slave_thread(THD *thd,
226                                   mysql_mutex_t *term_lock,
227                                   mysql_cond_t *term_cond,
228                                   volatile uint *slave_running,
229                                   bool need_lock_term);
230 static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info);
231 int slave_worker_exec_job(Slave_worker * w, Relay_log_info *rli);
232 static int mts_event_coord_cmp(LOG_POS_COORD *id1, LOG_POS_COORD *id2);
233 /*
234   Function to set the slave's max_allowed_packet based on the value
235   of slave_max_allowed_packet.
236 
237     @in_param    thd    Thread handler for slave
238     @in_param    mysql  MySQL connection handle
239 */
240 
set_slave_max_allowed_packet(THD * thd,MYSQL * mysql)241 static void set_slave_max_allowed_packet(THD *thd, MYSQL *mysql)
242 {
243   DBUG_ENTER("set_slave_max_allowed_packet");
244   // thd and mysql must be valid
245   DBUG_ASSERT(thd && mysql);
246 
247   thd->variables.max_allowed_packet= slave_max_allowed_packet;
248   thd->net.max_packet_size= slave_max_allowed_packet;
249   /*
250     Adding MAX_LOG_EVENT_HEADER_LEN to the max_packet_size on the I/O
251     thread and the mysql->option max_allowed_packet, since a
252     replication event can become this much  larger than
253     the corresponding packet (query) sent from client to master.
254   */
255   thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER;
256   /*
257     Skipping the setting of mysql->net.max_packet size to slave
258     max_allowed_packet since this is done during mysql_real_connect.
259   */
260   mysql->options.max_allowed_packet=
261     slave_max_allowed_packet+MAX_LOG_EVENT_HEADER;
262   DBUG_VOID_RETURN;
263 }
264 
265 /*
266   Find out which replications threads are running
267 
268   SYNOPSIS
269     init_thread_mask()
270     mask                Return value here
271     mi                  master_info for slave
272     inverse             If set, returns which threads are not running
273 
274   IMPLEMENTATION
275     Get a bit mask for which threads are running so that we can later restart
276     these threads.
277 
278   RETURN
279     mask        If inverse == 0, running threads
280                 If inverse == 1, stopped threads
281 */
282 
init_thread_mask(int * mask,Master_info * mi,bool inverse)283 void init_thread_mask(int* mask, Master_info* mi, bool inverse)
284 {
285   bool set_io = mi->slave_running, set_sql = mi->rli->slave_running;
286   register int tmp_mask=0;
287   DBUG_ENTER("init_thread_mask");
288 
289   if (set_io)
290     tmp_mask |= SLAVE_IO;
291   if (set_sql)
292     tmp_mask |= SLAVE_SQL;
293   if (inverse)
294     tmp_mask^= (SLAVE_IO | SLAVE_SQL);
295   *mask = tmp_mask;
296   DBUG_VOID_RETURN;
297 }
298 
299 
300 /*
301   lock_slave_threads()
302 */
303 
lock_slave_threads(Master_info * mi)304 void lock_slave_threads(Master_info* mi)
305 {
306   DBUG_ENTER("lock_slave_threads");
307 
308   //TODO: see if we can do this without dual mutex
309   mysql_mutex_lock(&mi->run_lock);
310   mysql_mutex_lock(&mi->rli->run_lock);
311   DBUG_VOID_RETURN;
312 }
313 
314 
315 /*
316   unlock_slave_threads()
317 */
318 
unlock_slave_threads(Master_info * mi)319 void unlock_slave_threads(Master_info* mi)
320 {
321   DBUG_ENTER("unlock_slave_threads");
322 
323   //TODO: see if we can do this without dual mutex
324   mysql_mutex_unlock(&mi->rli->run_lock);
325   mysql_mutex_unlock(&mi->run_lock);
326   DBUG_VOID_RETURN;
327 }
328 
329 #ifdef HAVE_PSI_INTERFACE
330 static PSI_thread_key key_thread_slave_io, key_thread_slave_sql, key_thread_slave_worker;
331 
332 static PSI_thread_info all_slave_threads[]=
333 {
334   { &key_thread_slave_io, "slave_io", PSI_FLAG_GLOBAL},
335   { &key_thread_slave_sql, "slave_sql", PSI_FLAG_GLOBAL},
336   { &key_thread_slave_worker, "slave_worker", PSI_FLAG_GLOBAL}
337 };
338 
init_slave_psi_keys(void)339 static void init_slave_psi_keys(void)
340 {
341   const char* category= "sql";
342   int count;
343 
344   count= array_elements(all_slave_threads);
345   mysql_thread_register(category, all_slave_threads, count);
346 }
347 #endif /* HAVE_PSI_INTERFACE */
348 
349 /* Initialize slave structures */
350 
init_slave()351 int init_slave()
352 {
353   DBUG_ENTER("init_slave");
354   int error= 0;
355   int thread_mask= SLAVE_SQL | SLAVE_IO;
356   Relay_log_info* rli= NULL;
357 
358 #ifdef HAVE_PSI_INTERFACE
359   init_slave_psi_keys();
360 #endif
361 
362   /*
363     This is called when mysqld starts. Before client connections are
364     accepted. However bootstrap may conflict with us if it does START SLAVE.
365     So it's safer to take the lock.
366   */
367   mysql_mutex_lock(&LOCK_active_mi);
368 
369   if (pthread_key_create(&RPL_MASTER_INFO, NULL))
370     DBUG_RETURN(1);
371 
372   if ((error= Rpl_info_factory::create_coordinators(opt_mi_repository_id, &active_mi,
373                                                     opt_rli_repository_id, &rli)))
374   {
375     sql_print_error("Failed to create or recover replication info repository.");
376     error= 1;
377     goto err;
378   }
379 
380   /*
381     This is the startup routine and as such we try to
382     configure both the SLAVE_SQL and SLAVE_IO.
383   */
384   if (global_init_info(active_mi, true, thread_mask))
385   {
386     sql_print_error("Failed to initialize the master info structure");
387     error= 1;
388     goto err;
389   }
390 
391   DBUG_PRINT("info", ("init group master %s %lu  group relay %s %lu event %s %lu\n",
392     rli->get_group_master_log_name(),
393     (ulong) rli->get_group_master_log_pos(),
394     rli->get_group_relay_log_name(),
395     (ulong) rli->get_group_relay_log_pos(),
396     rli->get_event_relay_log_name(),
397     (ulong) rli->get_event_relay_log_pos()));
398 
399   /* If server id is not set, start_slave_thread() will say it */
400   if (active_mi->host[0] && !opt_skip_slave_start)
401   {
402     /* same as in start_slave() cache the global var values into rli's members */
403     active_mi->rli->opt_slave_parallel_workers= opt_mts_slave_parallel_workers;
404     active_mi->rli->checkpoint_group= opt_mts_checkpoint_group;
405     if (start_slave_threads(true/*need_lock_slave=true*/,
406                             false/*wait_for_start=false*/,
407                             active_mi,
408                             thread_mask))
409     {
410       sql_print_error("Failed to create slave threads");
411       error= 1;
412       goto err;
413     }
414   }
415 
416 err:
417   mysql_mutex_unlock(&LOCK_active_mi);
418   if (error)
419     sql_print_information("Check error log for additional messages. "
420                           "You will not be able to start replication until "
421                           "the issue is resolved and the server restarted.");
422   DBUG_RETURN(error);
423 }
424 
425 /**
426    Parse the given relay log and identify the rotate event from the master.
427    Ignore the Format description event, Previous_gtid log event and ignorable
428    events within the relay log. When a rotate event is found check if it is a
429    rotate that is originated from the master or not based on the server_id. If
430    the rotate is from slave or if it is a fake rotate event ignore the event.
431    If any other events are encountered apart from the above events generate an
432    error. From the rotate event extract the master's binary log name and
433    position.
434 
435    @param filename
436           Relay log name which needs to be parsed.
437 
438    @param[OUT] master_log_file
439           Set the master_log_file to the log file name that is extracted from
440           rotate event. The master_log_file should contain string of len
441           FN_REFLEN.
442 
443    @param[OUT] master_log_pos
444           Set the master_log_pos to the log position extracted from rotate
445           event.
446 
447    @retval FOUND_ROTATE: When rotate event is found in the relay log
448    @retval NOT_FOUND_ROTATE: When rotate event is not found in the relay log
449    @retval ERROR: On error
450  */
451 enum enum_read_rotate_from_relay_log_status
452 { FOUND_ROTATE, NOT_FOUND_ROTATE, ERROR };
453 
454 static enum_read_rotate_from_relay_log_status
read_rotate_from_relay_log(char * filename,char * master_log_file,my_off_t * master_log_pos)455 read_rotate_from_relay_log(char *filename, char *master_log_file,
456                            my_off_t *master_log_pos)
457 {
458   DBUG_ENTER("read_rotate_from_relay_log");
459   /*
460     Create a Format_description_log_event that is used to read the
461     first event of the log.
462    */
463   Format_description_log_event fd_ev(BINLOG_VERSION), *fd_ev_p= &fd_ev;
464   DBUG_ASSERT(fd_ev.is_valid());
465   IO_CACHE log;
466   const char *errmsg= NULL;
467   File file= open_binlog_file(&log, filename, &errmsg);
468   if (file < 0)
469   {
470     sql_print_error("Error during --relay-log-recovery: %s", errmsg);
471     DBUG_RETURN(ERROR);
472   }
473   my_b_seek(&log, BIN_LOG_HEADER_SIZE);
474   Log_event *ev= NULL;
475   bool done= false;
476   enum_read_rotate_from_relay_log_status ret= NOT_FOUND_ROTATE;
477   while (!done &&
478          (ev= Log_event::read_log_event(&log, 0, fd_ev_p, opt_slave_sql_verify_checksum)) !=
479          NULL)
480   {
481     DBUG_PRINT("info", ("Read event of type %s", ev->get_type_str()));
482     switch (ev->get_type_code())
483     {
484     case FORMAT_DESCRIPTION_EVENT:
485       if (fd_ev_p != &fd_ev)
486         delete fd_ev_p;
487       fd_ev_p= (Format_description_log_event *)ev;
488       break;
489     case ROTATE_EVENT:
490       /*
491         Check for rotate event from the master. Ignore the ROTATE event if it
492         is a fake rotate event with server_id=0.
493        */
494       if (ev->server_id && ev->server_id != ::server_id)
495       {
496         Rotate_log_event *rotate_ev= (Rotate_log_event *)ev;
497         DBUG_ASSERT(FN_REFLEN >= rotate_ev->ident_len + 1);
498         memcpy(master_log_file, rotate_ev->new_log_ident, rotate_ev->ident_len + 1);
499         *master_log_pos= rotate_ev->pos;
500         ret= FOUND_ROTATE;
501         done= true;
502       }
503       break;
504     case PREVIOUS_GTIDS_LOG_EVENT:
505       break;
506     case IGNORABLE_LOG_EVENT:
507       break;
508     default:
509       sql_print_error("Error during --relay-log-recovery: Could not locate "
510                       "rotate event from the master.");
511       ret= ERROR;
512       done= true;
513       break;
514     }
515     if (ev != fd_ev_p)
516       delete ev;
517   }
518   if (log.error < 0)
519   {
520     sql_print_error("Error during --relay-log-recovery: Error reading events from relay log: %d",
521                     log.error);
522     DBUG_RETURN(ERROR);
523   }
524 
525   if (fd_ev_p != &fd_ev)
526   {
527     delete fd_ev_p;
528     fd_ev_p= &fd_ev;
529   }
530 
531   if (mysql_file_close(file, MYF(MY_WME)))
532     DBUG_RETURN(ERROR);
533   if (end_io_cache(&log))
534   {
535     sql_print_error("Error during --relay-log-recovery: Error while freeing "
536                     "IO_CACHE object");
537     DBUG_RETURN(ERROR);
538   }
539   DBUG_RETURN(ret);
540 }
541 
542 /**
543    Reads relay logs one by one starting from the first relay log. Looks for
544    the first rotate event from the master. If rotate is not found in the relay
545    log search continues to next relay log. If rotate event from master is
546    found then the extracted master_log_file and master_log_pos are used to set
547    rli->group_master_log_name and rli->group_master_log_pos. If an error has
548    occurred the error code is retuned back.
549 
550    @param rli
551           Relay_log_info object to read relay log files and to set
552           group_master_log_name and group_master_log_pos.
553 
554    @retval 0 On success
555    @retval 1 On failure
556  */
557 static int
find_first_relay_log_with_rotate_from_master(Relay_log_info * rli)558 find_first_relay_log_with_rotate_from_master(Relay_log_info* rli)
559 {
560   DBUG_ENTER("find_first_relay_log_with_rotate_from_master");
561   int error= 0;
562   LOG_INFO linfo;
563   bool got_rotate_from_master= false;
564   int pos;
565   char master_log_file[FN_REFLEN];
566   my_off_t master_log_pos= 0;
567 
568   for (pos= rli->relay_log.find_log_pos(&linfo, NULL, true);
569        !pos;
570        pos= rli->relay_log.find_next_log(&linfo, true))
571   {
572     switch (read_rotate_from_relay_log(linfo.log_file_name, master_log_file,
573                                        &master_log_pos))
574     {
575     case ERROR:
576       error= 1;
577       break;
578     case FOUND_ROTATE:
579       got_rotate_from_master= true;
580       break;
581     case NOT_FOUND_ROTATE:
582       break;
583     }
584     if (error || got_rotate_from_master)
585       break;
586   }
587   if (pos== LOG_INFO_IO)
588   {
589     error= 1;
590     sql_print_error("Error during --relay-log-recovery: Could not read "
591                     "relay log index file due to an IO error.");
592     goto err;
593   }
594   if (pos== LOG_INFO_EOF)
595   {
596     error= 1;
597     sql_print_error("Error during --relay-log-recovery: Could not locate "
598                     "rotate event from master in relay log file.");
599     goto err;
600   }
601   if (!error && got_rotate_from_master)
602   {
603     rli->set_group_master_log_name(master_log_file);
604     rli->set_group_master_log_pos(master_log_pos);
605   }
606 err:
607   DBUG_RETURN(error);
608 }
609 
610 /*
611   Updates the master info based on the information stored in the
612   relay info and ignores relay logs previously retrieved by the IO
613   thread, which thus starts fetching again based on to the
614   master_log_pos and master_log_name. Eventually, the old
615   relay logs will be purged by the normal purge mechanism.
616 
617   When GTID's are enabled the "Retrieved GTID" set should be cleared
618   so that partial read events are discarded and they are
619   fetched once again
620 
621   @param mi    pointer to Master_info instance
622 */
recover_relay_log(Master_info * mi)623 static void recover_relay_log(Master_info *mi)
624 {
625   Relay_log_info *rli=mi->rli;
626   // Set Receiver Thread's positions as per the recovered Applier Thread.
627   mi->set_master_log_pos(max<ulonglong>(BIN_LOG_HEADER_SIZE,
628                                         rli->get_group_master_log_pos()));
629   mi->set_master_log_name(rli->get_group_master_log_name());
630 
631   sql_print_warning("Recovery from master pos %ld and file %s. "
632                     "Previous relay log pos and relay log file had "
633                     "been set to %lld, %s respectively.",
634                     (ulong) mi->get_master_log_pos(), mi->get_master_log_name(),
635                     rli->get_group_relay_log_pos(), rli->get_group_relay_log_name());
636 
637   // Start with a fresh relay log.
638   rli->set_group_relay_log_name(rli->relay_log.get_log_fname());
639   rli->set_event_relay_log_name(rli->relay_log.get_log_fname());
640   rli->set_group_relay_log_pos(BIN_LOG_HEADER_SIZE);
641   rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
642   /*
643     Clear the retrieved GTID set so that events that are written partially
644     will be fetched again.
645   */
646   if (gtid_mode == GTID_MODE_ON)
647   {
648     global_sid_lock->wrlock();
649     (const_cast<Gtid_set *>(rli->get_gtid_set()))->clear();
650     global_sid_lock->unlock();
651   }
652 }
653 
654 
655 /*
656   Updates the master info based on the information stored in the
657   relay info and ignores relay logs previously retrieved by the IO
658   thread, which thus starts fetching again based on to the
659   master_log_pos and master_log_name. Eventually, the old
660   relay logs will be purged by the normal purge mechanism.
661 
662   There can be a special case where rli->group_master_log_name and
663   rli->group_master_log_pos are not intialized, as the sql thread was never
664   started at all. In those cases all the existing relay logs are parsed
665   starting from the first one and the initial rotate event that was received
666   from the master is identified. From the rotate event master_log_name and
667   master_log_pos are extracted and they are set to rli->group_master_log_name
668   and rli->group_master_log_pos.
669 
670   In the feature, we should improve this routine in order to avoid throwing
671   away logs that are safely stored in the disk. Note also that this recovery
672   routine relies on the correctness of the relay-log.info and only tolerates
673   coordinate problems in master.info.
674 
675   In this function, there is no need for a mutex as the caller
676   (i.e. init_slave) already has one acquired.
677 
678   Specifically, the following structures are updated:
679 
680   1 - mi->master_log_pos  <-- rli->group_master_log_pos
681   2 - mi->master_log_name <-- rli->group_master_log_name
682   3 - It moves the relay log to the new relay log file, by
683       rli->group_relay_log_pos  <-- BIN_LOG_HEADER_SIZE;
684       rli->event_relay_log_pos  <-- BIN_LOG_HEADER_SIZE;
685       rli->group_relay_log_name <-- rli->relay_log.get_log_fname();
686       rli->event_relay_log_name <-- rli->relay_log.get_log_fname();
687 
688    If there is an error, it returns (1), otherwise returns (0).
689  */
init_recovery(Master_info * mi,const char ** errmsg)690 int init_recovery(Master_info* mi, const char** errmsg)
691 {
692   DBUG_ENTER("init_recovery");
693 
694   int error= 0;
695   Relay_log_info *rli= mi->rli;
696   char *group_master_log_name= NULL;
697 
698   if (rli->recovery_parallel_workers)
699   {
700     /*
701       This is not idempotent and a crash after this function and before
702       the recovery is actually done may lead the system to an inconsistent
703       state.
704 
705       This may happen because the gap is not persitent stored anywhere
706       and eventually old relay log files will be removed and further
707       calculations on the gaps will be impossible.
708 
709       We need to improve this. /Alfranio.
710     */
711     error= mts_recovery_groups(rli);
712     if (rli->mts_recovery_group_cnt)
713     {
714       if (gtid_mode == GTID_MODE_ON)
715       {
716         rli->recovery_parallel_workers= 0;
717         rli->clear_mts_recovery_groups();
718       }
719       else
720         DBUG_RETURN(error);
721     }
722   }
723 
724   group_master_log_name= const_cast<char *>(rli->get_group_master_log_name());
725   if (!error)
726   {
727     if (!group_master_log_name[0])
728     {
729       if (rli->replicate_same_server_id)
730       {
731         error= 1;
732         sql_print_error("Error during --relay-log-recovery: "
733                         "replicate_same_server_id is in use and sql thread's "
734                         "positions are not initialized, hence relay log "
735                         "recovery cannot happen.");
736         DBUG_RETURN(error);
737       }
738       error= find_first_relay_log_with_rotate_from_master(rli);
739       if (error)
740         DBUG_RETURN(error);
741     }
742     recover_relay_log(mi);
743   }
744   DBUG_RETURN(error);
745 }
746 
747 /*
748   Relay log recovery in the case of MTS, is handled by the following function.
749   Gaps in MTS execution are filled using implicit execution of
750   START SLAVE UNTIL SQL_AFTER_MTS_GAPS call. Once slave reaches a consistent
751   gapless state receiver thread's positions are initialized to applier thread's
752   positions and the old relay logs are discarded. This completes the recovery
753   process.
754 
755   @param mi    pointer to Master_info instance.
756 
757   @retval 0 success
758   @retval 1 error
759 */
fill_mts_gaps_and_recover(Master_info * mi)760 static inline int fill_mts_gaps_and_recover(Master_info* mi)
761 {
762   DBUG_ENTER("fill_mts_gaps_and_recover");
763   Relay_log_info *rli= mi->rli;
764   int recovery_error= 0;
765   rli->is_relay_log_recovery= FALSE;
766   rli->until_condition= Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS;
767   rli->opt_slave_parallel_workers= rli->recovery_parallel_workers;
768   sql_print_information("MTS recovery: starting coordinator thread to fill MTS "
769                         "gaps.");
770   recovery_error= start_slave_thread(
771 #ifdef HAVE_PSI_INTERFACE
772                                      key_thread_slave_sql,
773 #endif
774                                      handle_slave_sql, &rli->run_lock,
775                                      &rli->run_lock,
776                                      &rli->start_cond,
777                                      &rli->slave_running,
778                                      &rli->slave_run_id,
779                                      mi);
780 
781   if (recovery_error)
782   {
783     sql_print_warning("MTS recovery: failed to start the coordinator "
784                       "thread. Check the error log for additional"
785                       " details.");
786     goto err;
787   }
788   mysql_mutex_lock(&rli->run_lock);
789   mysql_cond_wait(&rli->stop_cond, &rli->run_lock);
790   mysql_mutex_unlock(&rli->run_lock);
791   if (rli->until_condition != Relay_log_info::UNTIL_DONE)
792   {
793     sql_print_warning("MTS recovery: automatic recovery failed. Either the "
794                       "slave server had stopped due to an error during an "
795                       "earlier session or relay logs are corrupted."
796                       "Fix the cause of the slave side error and restart the "
797                       "slave server or consider using RESET SLAVE.");
798     goto err;
799   }
800 
801   /*
802     We need a mutex while we are changing master info parameters to
803     keep other threads from reading bogus info
804   */
805   mysql_mutex_lock(&mi->data_lock);
806   mysql_mutex_lock(&rli->data_lock);
807   recover_relay_log(mi);
808 
809   const char* msg;
810   if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
811                               rli->get_group_relay_log_pos(),
812                               false/*need_data_lock=false*/,
813                               &msg, 0))
814   {
815     char llbuf[22];
816     sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s).",
817                     rli->get_group_relay_log_name(),
818                     llstr(rli->get_group_relay_log_pos(), llbuf));
819 
820     recovery_error=1;
821     mysql_mutex_unlock(&mi->data_lock);
822     mysql_mutex_unlock(&rli->data_lock);
823     goto err;
824   }
825   if (mi->flush_info(true) || rli->flush_info(true))
826   {
827     recovery_error= 1;
828     mysql_mutex_unlock(&mi->data_lock);
829     mysql_mutex_unlock(&rli->data_lock);
830     goto err;
831   }
832   rli->inited=1;
833   rli->error_on_rli_init_info= false;
834   mysql_mutex_unlock(&mi->data_lock);
835   mysql_mutex_unlock(&rli->data_lock);
836   sql_print_information("MTS recovery: completed successfully.\n");
837   DBUG_RETURN(recovery_error);
838 err:
839   /*
840     If recovery failed means we failed to initialize rli object in the case
841     of MTS. We should not allow the START SLAVE command to work as we do in
842     the case of STS. i.e if init_recovery call fails then we set inited=0.
843   */
844   rli->end_info();
845   rli->inited=0;
846   rli->error_on_rli_init_info= true;
847   DBUG_RETURN(recovery_error);
848 }
849 
global_init_info(Master_info * mi,bool ignore_if_no_info,int thread_mask)850 int global_init_info(Master_info* mi, bool ignore_if_no_info, int thread_mask)
851 {
852   DBUG_ENTER("init_info");
853   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
854   int init_error= 0;
855   enum_return_check check_return= ERROR_CHECKING_REPOSITORY;
856   THD *thd= current_thd;
857 
858   /*
859     We need a mutex while we are changing master info parameters to
860     keep other threads from reading bogus info
861   */
862   mysql_mutex_lock(&mi->data_lock);
863   mysql_mutex_lock(&mi->rli->data_lock);
864 
865   /*
866     When info tables are used and autocommit= 0 we force a new
867     transaction start to avoid table access deadlocks when START SLAVE
868     is executed after RESET SLAVE.
869   */
870   if (is_autocommit_off_and_infotables(thd))
871   {
872     if (trans_begin(thd))
873     {
874       init_error= 1;
875       goto end;
876     }
877   }
878 
879   /*
880     This takes care of the startup dependency between the master_info
881     and relay_info. It initializes the master info if the SLAVE_IO
882     thread is being started and the relay log info if either the
883     SLAVE_SQL thread is being started or was not initialized as it is
884     required by the SLAVE_IO thread.
885   */
886   check_return= mi->check_info();
887   if (check_return == ERROR_CHECKING_REPOSITORY)
888   {
889     init_error= 1;
890     goto end;
891   }
892 
893   if (!(ignore_if_no_info && check_return == REPOSITORY_DOES_NOT_EXIST))
894   {
895     if ((thread_mask & SLAVE_IO) != 0 && mi->mi_init_info())
896       init_error= 1;
897   }
898 
899   check_return= mi->rli->check_info();
900   if (check_return == ERROR_CHECKING_REPOSITORY)
901   {
902     init_error= 1;
903     goto end;
904   }
905   if (!(ignore_if_no_info && check_return == REPOSITORY_DOES_NOT_EXIST))
906   {
907     if (((thread_mask & SLAVE_SQL) != 0 || !(mi->rli->inited))
908         && mi->rli->rli_init_info())
909       init_error= 1;
910   }
911 
912   DBUG_EXECUTE_IF("enable_mts_worker_failure_init",
913                   {DBUG_SET("+d,mts_worker_thread_init_fails");});
914 end:
915   /*
916     When info tables are used and autocommit= 0 we force transaction
917     commit to avoid table access deadlocks when START SLAVE is executed
918     after RESET SLAVE.
919   */
920   if (is_autocommit_off_and_infotables(thd))
921     if (trans_commit(thd))
922       init_error= 1;
923 
924   mysql_mutex_unlock(&mi->rli->data_lock);
925   mysql_mutex_unlock(&mi->data_lock);
926 
927   /*
928     Handling MTS Relay-log recovery after successful initialization of mi and
929     rli objects.
930 
931     MTS Relay-log recovery is handled by SSUG command. In order to start the
932     slave applier thread rli needs to be inited and mi->rli->data_lock should
933     be in released state. Hence we do the MTS recovery at this point of time
934     where both conditions are satisfied.
935   */
936   if (!init_error && mi->rli->is_relay_log_recovery
937       && mi->rli->mts_recovery_group_cnt)
938     init_error= fill_mts_gaps_and_recover(mi);
939   DBUG_RETURN(init_error);
940 }
941 
end_info(Master_info * mi)942 void end_info(Master_info* mi)
943 {
944   DBUG_ENTER("end_info");
945   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
946 
947   /*
948     The previous implementation was not acquiring locks.  We do the same here.
949     However, this is quite strange.
950   */
951   mi->end_info();
952   mi->rli->end_info();
953 
954   DBUG_VOID_RETURN;
955 }
956 
remove_info(Master_info * mi)957 int remove_info(Master_info* mi)
958 {
959   int error= 1;
960   DBUG_ENTER("remove_info");
961   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
962 
963   /*
964     The previous implementation was not acquiring locks.
965     We do the same here. However, this is quite strange.
966   */
967   /*
968     Reset errors (the idea is that we forget about the
969     old master).
970   */
971   mi->clear_error();
972   mi->rli->clear_error();
973   mi->rli->clear_until_condition();
974   mi->rli->clear_sql_delay();
975 
976   mi->end_info();
977   mi->rli->end_info();
978 
979   if (mi->remove_info() || Rpl_info_factory::reset_workers(mi->rli) ||
980       mi->rli->remove_info())
981     goto err;
982 
983   error= 0;
984 
985 err:
986   DBUG_RETURN(error);
987 }
988 
flush_master_info(Master_info * mi,bool force)989 int flush_master_info(Master_info* mi, bool force)
990 {
991   DBUG_ENTER("flush_master_info");
992   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
993   /*
994     The previous implementation was not acquiring locks.
995     We do the same here. However, this is quite strange.
996   */
997   /*
998     With the appropriate recovery process, we will not need to flush
999     the content of the current log.
1000 
1001     For now, we flush the relay log BEFORE the master.info file, because
1002     if we crash, we will get a duplicate event in the relay log at restart.
1003     If we change the order, there might be missing events.
1004 
1005     If we don't do this and the slave server dies when the relay log has
1006     some parts (its last kilobytes) in memory only, with, say, from master's
1007     position 100 to 150 in memory only (not on disk), and with position 150
1008     in master.info, there will be missing information. When the slave restarts,
1009     the I/O thread will fetch binlogs from 150, so in the relay log we will
1010     have "[0, 100] U [150, infinity[" and nobody will notice it, so the SQL
1011     thread will jump from 100 to 150, and replication will silently break.
1012   */
1013   mysql_mutex_t *log_lock= mi->rli->relay_log.get_log_lock();
1014 
1015   mysql_mutex_lock(log_lock);
1016 
1017   int err=  (mi->rli->flush_current_log() ||
1018              mi->flush_info(force));
1019 
1020   mysql_mutex_unlock(log_lock);
1021 
1022   DBUG_RETURN (err);
1023 }
1024 
1025 /**
1026   Convert slave skip errors bitmap into a printable string.
1027 */
1028 
print_slave_skip_errors(void)1029 static void print_slave_skip_errors(void)
1030 {
1031   /*
1032     To be safe, we want 10 characters of room in the buffer for a number
1033     plus terminators. Also, we need some space for constant strings.
1034     10 characters must be sufficient for a number plus {',' | '...'}
1035     plus a NUL terminator. That is a max 6 digit number.
1036   */
1037   const size_t MIN_ROOM= 10;
1038   DBUG_ENTER("print_slave_skip_errors");
1039   DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
1040   DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
1041 
1042   if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
1043   {
1044     /* purecov: begin tested */
1045     memcpy(slave_skip_error_names, STRING_WITH_LEN("OFF"));
1046     /* purecov: end */
1047   }
1048   else if (bitmap_is_set_all(&slave_error_mask))
1049   {
1050     /* purecov: begin tested */
1051     memcpy(slave_skip_error_names, STRING_WITH_LEN("ALL"));
1052     /* purecov: end */
1053   }
1054   else
1055   {
1056     char *buff= slave_skip_error_names;
1057     char *bend= buff + sizeof(slave_skip_error_names);
1058     int  errnum;
1059 
1060     for (errnum= 0; errnum < MAX_SLAVE_ERROR; errnum++)
1061     {
1062       if (bitmap_is_set(&slave_error_mask, errnum))
1063       {
1064         if (buff + MIN_ROOM >= bend)
1065           break; /* purecov: tested */
1066         buff= int10_to_str(errnum, buff, 10);
1067         *buff++= ',';
1068       }
1069     }
1070     if (buff != slave_skip_error_names)
1071       buff--; // Remove last ','
1072     if (errnum < MAX_SLAVE_ERROR)
1073     {
1074       /* Couldn't show all errors */
1075       buff= strmov(buff, "..."); /* purecov: tested */
1076     }
1077     *buff=0;
1078   }
1079   DBUG_PRINT("init", ("error_names: '%s'", slave_skip_error_names));
1080   DBUG_VOID_RETURN;
1081 }
1082 
set_stop_slave_wait_timeout(unsigned long wait_timeout)1083 static void set_stop_slave_wait_timeout(unsigned long wait_timeout) {
1084   stop_wait_timeout = wait_timeout;
1085 }
1086 
1087 /**
1088  Change arg to the string with the nice, human-readable skip error values.
1089    @param slave_skip_errors_ptr
1090           The pointer to be changed
1091 */
set_slave_skip_errors(char ** slave_skip_errors_ptr)1092 void set_slave_skip_errors(char** slave_skip_errors_ptr)
1093 {
1094   DBUG_ENTER("set_slave_skip_errors");
1095   print_slave_skip_errors();
1096   *slave_skip_errors_ptr= slave_skip_error_names;
1097   DBUG_VOID_RETURN;
1098 }
1099 
1100 /**
1101   Init function to set up array for errors that should be skipped for slave
1102 */
init_slave_skip_errors()1103 static void init_slave_skip_errors()
1104 {
1105   DBUG_ENTER("init_slave_skip_errors");
1106   DBUG_ASSERT(!use_slave_mask); // not already initialized
1107 
1108   if (bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0))
1109   {
1110     fprintf(stderr, "Badly out of memory, please check your system status\n");
1111     exit(1);
1112   }
1113   use_slave_mask = 1;
1114   DBUG_VOID_RETURN;
1115 }
1116 
add_slave_skip_errors(const uint * errors,uint n_errors)1117 static void add_slave_skip_errors(const uint* errors, uint n_errors)
1118 {
1119   DBUG_ENTER("add_slave_skip_errors");
1120   DBUG_ASSERT(errors);
1121   DBUG_ASSERT(use_slave_mask);
1122 
1123   for (uint i = 0; i < n_errors; i++)
1124   {
1125     const uint err_code = errors[i];
1126     if (err_code < MAX_SLAVE_ERROR)
1127        bitmap_set_bit(&slave_error_mask, err_code);
1128   }
1129   DBUG_VOID_RETURN;
1130 }
1131 
1132 /*
1133   Add errors that should be skipped for slave
1134 
1135   SYNOPSIS
1136     add_slave_skip_errors()
1137     arg         List of errors numbers to be added to skip, separated with ','
1138 
1139   NOTES
1140     Called from get_options() in mysqld.cc on start-up
1141 */
1142 
add_slave_skip_errors(const char * arg)1143 void add_slave_skip_errors(const char* arg)
1144 {
1145   const char *p= NULL;
1146   /*
1147     ALL is only valid when nothing else is provided.
1148   */
1149   const uchar SKIP_ALL[]= "all";
1150   size_t SIZE_SKIP_ALL= strlen((const char *) SKIP_ALL) + 1;
1151   /*
1152     IGNORE_DDL_ERRORS can be combined with other parameters
1153     but must be the first one provided.
1154   */
1155   const uchar SKIP_DDL_ERRORS[]= "ddl_exist_errors";
1156   size_t SIZE_SKIP_DDL_ERRORS= strlen((const char *) SKIP_DDL_ERRORS);
1157   DBUG_ENTER("add_slave_skip_errors");
1158 
1159   // initialize mask if not done yet
1160   if (!use_slave_mask)
1161     init_slave_skip_errors();
1162 
1163   for (; my_isspace(system_charset_info,*arg); ++arg)
1164     /* empty */;
1165   if (!my_strnncoll(system_charset_info, (uchar*)arg, SIZE_SKIP_ALL,
1166                     SKIP_ALL, SIZE_SKIP_ALL))
1167   {
1168     bitmap_set_all(&slave_error_mask);
1169     DBUG_VOID_RETURN;
1170   }
1171   if (!my_strnncoll(system_charset_info, (uchar*)arg, SIZE_SKIP_DDL_ERRORS,
1172                     SKIP_DDL_ERRORS, SIZE_SKIP_DDL_ERRORS))
1173   {
1174     // DDL errors to be skipped for relaxed 'exist' handling
1175     const uint ddl_errors[] = {
1176       // error codes with create/add <schema object>
1177       ER_DB_CREATE_EXISTS, ER_TABLE_EXISTS_ERROR, ER_DUP_KEYNAME,
1178       ER_MULTIPLE_PRI_KEY,
1179       // error codes with change/rename <schema object>
1180       ER_BAD_FIELD_ERROR, ER_NO_SUCH_TABLE, ER_DUP_FIELDNAME,
1181       // error codes with drop <schema object>
1182       ER_DB_DROP_EXISTS, ER_BAD_TABLE_ERROR, ER_CANT_DROP_FIELD_OR_KEY
1183     };
1184 
1185     add_slave_skip_errors(ddl_errors,
1186                           sizeof(ddl_errors)/sizeof(ddl_errors[0]));
1187     /*
1188       After processing the SKIP_DDL_ERRORS, the pointer is
1189       increased to the position after the comma.
1190     */
1191     if (strlen(arg) > SIZE_SKIP_DDL_ERRORS + 1)
1192       arg+= SIZE_SKIP_DDL_ERRORS + 1;
1193   }
1194   for (p= arg ; *p; )
1195   {
1196     long err_code;
1197     if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
1198       break;
1199     if (err_code < MAX_SLAVE_ERROR)
1200        bitmap_set_bit(&slave_error_mask,(uint)err_code);
1201     while (!my_isdigit(system_charset_info,*p) && *p)
1202       p++;
1203   }
1204   DBUG_VOID_RETURN;
1205 }
1206 
set_thd_in_use_temporary_tables(Relay_log_info * rli)1207 static void set_thd_in_use_temporary_tables(Relay_log_info *rli)
1208 {
1209   TABLE *table;
1210 
1211   for (table= rli->save_temporary_tables ; table ; table= table->next)
1212   {
1213     table->in_use= rli->info_thd;
1214     if (table->file != NULL)
1215     {
1216       /*
1217         Since we are stealing opened temporary tables from one thread to another,
1218         we need to let the performance schema know that,
1219         for aggregates per thread to work properly.
1220       */
1221       table->file->unbind_psi();
1222       table->file->rebind_psi();
1223     }
1224   }
1225 }
1226 
terminate_slave_threads(Master_info * mi,int thread_mask,bool need_lock_term)1227 int terminate_slave_threads(Master_info* mi,int thread_mask,bool need_lock_term)
1228 {
1229   DBUG_ENTER("terminate_slave_threads");
1230 
1231   if (!mi->inited)
1232     DBUG_RETURN(0); /* successfully do nothing */
1233   int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
1234   mysql_mutex_t *sql_lock = &mi->rli->run_lock, *io_lock = &mi->run_lock;
1235   mysql_mutex_t *log_lock= mi->rli->relay_log.get_log_lock();
1236   set_stop_slave_wait_timeout(rpl_stop_slave_timeout);
1237 
1238   if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
1239   {
1240     DBUG_PRINT("info",("Terminating SQL thread"));
1241     mi->rli->abort_slave= 1;
1242     if ((error=terminate_slave_thread(mi->rli->info_thd, sql_lock,
1243                                       &mi->rli->stop_cond,
1244                                       &mi->rli->slave_running,
1245                                       need_lock_term)) &&
1246         !force_all)
1247     {
1248       if (error == 1)
1249       {
1250         DBUG_RETURN(ER_STOP_SLAVE_SQL_THREAD_TIMEOUT);
1251       }
1252       DBUG_RETURN(error);
1253     }
1254     mysql_mutex_lock(log_lock);
1255 
1256     DBUG_PRINT("info",("Flushing relay-log info file."));
1257     if (current_thd)
1258       THD_STAGE_INFO(current_thd, stage_flushing_relay_log_info_file);
1259 
1260     /*
1261       Flushes the relay log info regardles of the sync_relay_log_info option.
1262     */
1263     if (mi->rli->flush_info(TRUE))
1264     {
1265       mysql_mutex_unlock(log_lock);
1266       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1267     }
1268 
1269     mysql_mutex_unlock(log_lock);
1270   }
1271   if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
1272   {
1273     DBUG_PRINT("info",("Terminating IO thread"));
1274     mi->abort_slave=1;
1275     if ((error=terminate_slave_thread(mi->info_thd,io_lock,
1276                                       &mi->stop_cond,
1277                                       &mi->slave_running,
1278                                       need_lock_term)) &&
1279         !force_all)
1280     {
1281       if (error == 1)
1282       {
1283         DBUG_RETURN(ER_STOP_SLAVE_IO_THREAD_TIMEOUT);
1284       }
1285       DBUG_RETURN(error);
1286     }
1287     mysql_mutex_lock(log_lock);
1288 
1289     DBUG_PRINT("info",("Flushing relay log and master info repository."));
1290     if (current_thd)
1291       THD_STAGE_INFO(current_thd, stage_flushing_relay_log_and_master_info_repository);
1292 
1293     /*
1294       Flushes the master info regardles of the sync_master_info option.
1295     */
1296     if (mi->flush_info(TRUE))
1297     {
1298       mysql_mutex_unlock(log_lock);
1299       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1300     }
1301 
1302     /*
1303       Flushes the relay log regardles of the sync_relay_log option.
1304     */
1305     if (mi->rli->relay_log.is_open() &&
1306         mi->rli->relay_log.flush_and_sync(true))
1307     {
1308       mysql_mutex_unlock(log_lock);
1309       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1310     }
1311 
1312     mysql_mutex_unlock(log_lock);
1313   }
1314   DBUG_RETURN(0);
1315 }
1316 
1317 
1318 /**
1319    Wait for a slave thread to terminate.
1320 
1321    This function is called after requesting the thread to terminate
1322    (by setting @c abort_slave member of @c Relay_log_info or @c
1323    Master_info structure to 1). Termination of the thread is
1324    controlled with the the predicate <code>*slave_running</code>.
1325 
1326    Function will acquire @c term_lock before waiting on the condition
1327    unless @c need_lock_term is false in which case the mutex should be
1328    owned by the caller of this function and will remain acquired after
1329    return from the function.
1330 
1331    @param term_lock
1332           Associated lock to use when waiting for @c term_cond
1333 
1334    @param term_cond
1335           Condition that is signalled when the thread has terminated
1336 
1337    @param slave_running
1338           Pointer to predicate to check for slave thread termination
1339 
1340    @param need_lock_term
1341           If @c false the lock will not be acquired before waiting on
1342           the condition. In this case, it is assumed that the calling
1343           function acquires the lock before calling this function.
1344 
1345    @retval 0 All OK, 1 on "STOP SLAVE" command timeout, ER_SLAVE_NOT_RUNNING otherwise.
1346 
1347    @note  If the executing thread has to acquire term_lock
1348           (need_lock_term is true, the negative running status does not
1349           represent any issue therefore no error is reported.
1350 
1351  */
1352 static int
terminate_slave_thread(THD * thd,mysql_mutex_t * term_lock,mysql_cond_t * term_cond,volatile uint * slave_running,bool need_lock_term)1353 terminate_slave_thread(THD *thd,
1354                        mysql_mutex_t *term_lock,
1355                        mysql_cond_t *term_cond,
1356                        volatile uint *slave_running,
1357                        bool need_lock_term)
1358 {
1359   DBUG_ENTER("terminate_slave_thread");
1360   if (need_lock_term)
1361   {
1362     mysql_mutex_lock(term_lock);
1363   }
1364   else
1365   {
1366     mysql_mutex_assert_owner(term_lock);
1367   }
1368   if (!*slave_running)
1369   {
1370     if (need_lock_term)
1371     {
1372       /*
1373         if run_lock (term_lock) is acquired locally then either
1374         slave_running status is fine
1375       */
1376       mysql_mutex_unlock(term_lock);
1377       DBUG_RETURN(0);
1378     }
1379     else
1380     {
1381       DBUG_RETURN(ER_SLAVE_NOT_RUNNING);
1382     }
1383   }
1384   DBUG_ASSERT(thd != 0);
1385   THD_CHECK_SENTRY(thd);
1386 
1387   /*
1388     Is is critical to test if the slave is running. Otherwise, we might
1389     be referening freed memory trying to kick it
1390   */
1391 
1392   while (*slave_running)                        // Should always be true
1393   {
1394     int error MY_ATTRIBUTE((unused));
1395     DBUG_PRINT("loop", ("killing slave thread"));
1396 
1397     mysql_mutex_lock(&thd->LOCK_thd_data);
1398 #ifndef DONT_USE_THR_ALARM
1399     /*
1400       Error codes from pthread_kill are:
1401       EINVAL: invalid signal number (can't happen)
1402       ESRCH: thread already killed (can happen, should be ignored)
1403     */
1404     int err MY_ATTRIBUTE((unused))= pthread_kill(thd->real_id, thr_client_alarm);
1405     DBUG_ASSERT(err != EINVAL);
1406 #endif
1407     thd->awake(THD::NOT_KILLED);
1408     mysql_mutex_unlock(&thd->LOCK_thd_data);
1409 
1410     /*
1411       There is a small chance that slave thread might miss the first
1412       alarm. To protect againts it, resend the signal until it reacts
1413     */
1414     struct timespec abstime;
1415     set_timespec(abstime,2);
1416     error= mysql_cond_timedwait(term_cond, term_lock, &abstime);
1417     if (stop_wait_timeout >= 2)
1418       stop_wait_timeout= stop_wait_timeout - 2;
1419     else if (*slave_running)
1420     {
1421       if (need_lock_term)
1422         mysql_mutex_unlock(term_lock);
1423       DBUG_RETURN (1);
1424     }
1425     DBUG_ASSERT(error == ETIMEDOUT || error == 0);
1426   }
1427 
1428   DBUG_ASSERT(*slave_running == 0);
1429 
1430   if (need_lock_term)
1431     mysql_mutex_unlock(term_lock);
1432   DBUG_RETURN(0);
1433 }
1434 
1435 
start_slave_thread(PSI_thread_key thread_key,pthread_handler h_func,mysql_mutex_t * start_lock,mysql_mutex_t * cond_lock,mysql_cond_t * start_cond,volatile uint * slave_running,volatile ulong * slave_run_id,Master_info * mi)1436 int start_slave_thread(
1437 #ifdef HAVE_PSI_INTERFACE
1438                        PSI_thread_key thread_key,
1439 #endif
1440                        pthread_handler h_func, mysql_mutex_t *start_lock,
1441                        mysql_mutex_t *cond_lock,
1442                        mysql_cond_t *start_cond,
1443                        volatile uint *slave_running,
1444                        volatile ulong *slave_run_id,
1445                        Master_info* mi)
1446 {
1447   pthread_t th;
1448   ulong start_id;
1449   int error;
1450   DBUG_ENTER("start_slave_thread");
1451 
1452   if (start_lock)
1453     mysql_mutex_lock(start_lock);
1454   if (!server_id)
1455   {
1456     if (start_cond)
1457       mysql_cond_broadcast(start_cond);
1458     if (start_lock)
1459       mysql_mutex_unlock(start_lock);
1460     sql_print_error("Server id not set, will not start slave");
1461     DBUG_RETURN(ER_BAD_SLAVE);
1462   }
1463 
1464   if (*slave_running)
1465   {
1466     if (start_cond)
1467       mysql_cond_broadcast(start_cond);
1468     if (start_lock)
1469       mysql_mutex_unlock(start_lock);
1470     DBUG_RETURN(ER_SLAVE_MUST_STOP);
1471   }
1472   start_id= *slave_run_id;
1473   DBUG_PRINT("info",("Creating new slave thread"));
1474   if ((error= mysql_thread_create(thread_key,
1475                           &th, &connection_attrib, h_func, (void*)mi)))
1476   {
1477     sql_print_error("Can't create slave thread (errno= %d).", error);
1478     if (start_lock)
1479       mysql_mutex_unlock(start_lock);
1480     DBUG_RETURN(ER_SLAVE_THREAD);
1481   }
1482   if (start_cond && cond_lock) // caller has cond_lock
1483   {
1484     THD* thd = current_thd;
1485     while (start_id == *slave_run_id && thd != NULL)
1486     {
1487       DBUG_PRINT("sleep",("Waiting for slave thread to start"));
1488       PSI_stage_info saved_stage= {0, "", 0};
1489       thd->ENTER_COND(start_cond, cond_lock,
1490                       & stage_waiting_for_slave_thread_to_start,
1491                       & saved_stage);
1492       /*
1493         It is not sufficient to test this at loop bottom. We must test
1494         it after registering the mutex in enter_cond(). If the kill
1495         happens after testing of thd->killed and before the mutex is
1496         registered, we could otherwise go waiting though thd->killed is
1497         set.
1498       */
1499       if (!thd->killed)
1500         mysql_cond_wait(start_cond, cond_lock);
1501       thd->EXIT_COND(& saved_stage);
1502       mysql_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
1503       if (thd->killed)
1504       {
1505         if (start_lock)
1506           mysql_mutex_unlock(start_lock);
1507         DBUG_RETURN(thd->killed_errno());
1508       }
1509     }
1510   }
1511   if (start_lock)
1512     mysql_mutex_unlock(start_lock);
1513   DBUG_RETURN(0);
1514 }
1515 
1516 
1517 /*
1518   start_slave_threads()
1519 
1520   NOTES
1521     SLAVE_FORCE_ALL is not implemented here on purpose since it does not make
1522     sense to do that for starting a slave--we always care if it actually
1523     started the threads that were not previously running
1524 */
1525 
start_slave_threads(bool need_lock_slave,bool wait_for_start,Master_info * mi,int thread_mask)1526 int start_slave_threads(bool need_lock_slave, bool wait_for_start,
1527                         Master_info* mi, int thread_mask)
1528 {
1529   mysql_mutex_t *lock_io=0, *lock_sql=0, *lock_cond_io=0, *lock_cond_sql=0;
1530   mysql_cond_t* cond_io=0, *cond_sql=0;
1531   int error=0;
1532   DBUG_ENTER("start_slave_threads");
1533   DBUG_EXECUTE_IF("uninitialized_master-info_structure",
1534                    mi->inited= FALSE;);
1535 
1536   if (!mi->inited || !mi->rli->inited)
1537   {
1538     error= !mi->inited ? ER_SLAVE_MI_INIT_REPOSITORY :
1539                          ER_SLAVE_RLI_INIT_REPOSITORY;
1540     Rpl_info *info= (!mi->inited ?  mi : static_cast<Rpl_info *>(mi->rli));
1541     const char* prefix= current_thd ? ER(error) : ER_DEFAULT(error);
1542     info->report(ERROR_LEVEL, error, prefix, NULL);
1543 
1544     DBUG_RETURN(error);
1545   }
1546 
1547   if (need_lock_slave)
1548   {
1549     lock_io = &mi->run_lock;
1550     lock_sql = &mi->rli->run_lock;
1551   }
1552   if (wait_for_start)
1553   {
1554     cond_io = &mi->start_cond;
1555     cond_sql = &mi->rli->start_cond;
1556     lock_cond_io = &mi->run_lock;
1557     lock_cond_sql = &mi->rli->run_lock;
1558   }
1559 
1560   if (thread_mask & SLAVE_IO)
1561     error= start_slave_thread(
1562 #ifdef HAVE_PSI_INTERFACE
1563                               key_thread_slave_io,
1564 #endif
1565                               handle_slave_io, lock_io, lock_cond_io,
1566                               cond_io,
1567                               &mi->slave_running, &mi->slave_run_id,
1568                               mi);
1569   if (!error && (thread_mask & SLAVE_SQL))
1570   {
1571     /*
1572       MTS-recovery gaps gathering is placed onto common execution path
1573       for either START-SLAVE and --skip-start-slave= 0
1574     */
1575     if (mi->rli->recovery_parallel_workers != 0)
1576       error= mts_recovery_groups(mi->rli);
1577     if (!error)
1578       error= start_slave_thread(
1579 #ifdef HAVE_PSI_INTERFACE
1580                                 key_thread_slave_sql,
1581 #endif
1582                                 handle_slave_sql, lock_sql, lock_cond_sql,
1583                                 cond_sql,
1584                                 &mi->rli->slave_running, &mi->rli->slave_run_id,
1585                                 mi);
1586     if (error)
1587       terminate_slave_threads(mi, thread_mask & SLAVE_IO, need_lock_slave);
1588   }
1589   DBUG_RETURN(error);
1590 }
1591 
1592 /*
1593   Release slave threads at time of executing shutdown.
1594 
1595   SYNOPSIS
1596     end_slave()
1597 */
1598 
end_slave()1599 void end_slave()
1600 {
1601   DBUG_ENTER("end_slave");
1602 
1603   /*
1604     This is called when the server terminates, in close_connections().
1605     It terminates slave threads. However, some CHANGE MASTER etc may still be
1606     running presently. If a START SLAVE was in progress, the mutex lock below
1607     will make us wait until slave threads have started, and START SLAVE
1608     returns, then we terminate them here.
1609   */
1610   mysql_mutex_lock(&LOCK_active_mi);
1611   if (active_mi)
1612   {
1613     /*
1614       TODO: replace the line below with
1615       list_walk(&master_list, (list_walk_action)end_slave_on_walk,0);
1616       once multi-master code is ready.
1617     */
1618     terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
1619   }
1620   mysql_mutex_unlock(&LOCK_active_mi);
1621   DBUG_VOID_RETURN;
1622 }
1623 
1624 /**
1625    Free all resources used by slave threads at time of executing shutdown.
1626    The routine must be called after all possible users of @c active_mi
1627    have left.
1628 
1629    SYNOPSIS
1630      close_active_mi()
1631 
1632 */
close_active_mi()1633 void close_active_mi()
1634 {
1635   mysql_mutex_lock(&LOCK_active_mi);
1636   if (active_mi)
1637   {
1638     end_info(active_mi);
1639     if (active_mi->rli)
1640       delete active_mi->rli;
1641     delete active_mi;
1642     active_mi= 0;
1643   }
1644   mysql_mutex_unlock(&LOCK_active_mi);
1645 }
1646 
1647 /**
1648    Check if multi-statement transaction mode and master and slave info
1649    repositories are set to table.
1650 
1651    @param THD    THD object
1652 
1653    @retval true  Success
1654    @retval false Failure
1655 */
is_autocommit_off_and_infotables(THD * thd)1656 static bool is_autocommit_off_and_infotables(THD* thd)
1657 {
1658   DBUG_ENTER("is_autocommit_off_and_infotables");
1659   DBUG_RETURN((thd && thd->in_multi_stmt_transaction_mode() &&
1660                (opt_mi_repository_id == INFO_REPOSITORY_TABLE ||
1661                 opt_rli_repository_id == INFO_REPOSITORY_TABLE))?
1662               true : false);
1663 }
1664 
io_slave_killed(THD * thd,Master_info * mi)1665 static bool io_slave_killed(THD* thd, Master_info* mi)
1666 {
1667   DBUG_ENTER("io_slave_killed");
1668 
1669   DBUG_ASSERT(mi->info_thd == thd);
1670   DBUG_ASSERT(mi->slave_running); // tracking buffer overrun
1671   DBUG_RETURN(mi->abort_slave || abort_loop || thd->killed);
1672 }
1673 
1674 /**
1675    The function analyzes a possible killed status and makes
1676    a decision whether to accept it or not.
1677    Normally upon accepting the sql thread goes to shutdown.
1678    In the event of deferring decision @rli->last_event_start_time waiting
1679    timer is set to force the killed status be accepted upon its expiration.
1680 
1681    Notice Multi-Threaded-Slave behaves similarly in that when it's being
1682    stopped and the current group of assigned events has not yet scheduled
1683    completely, Coordinator defers to accept to leave its read-distribute
1684    state. The above timeout ensures waiting won't last endlessly, and in
1685    such case an error is reported.
1686 
1687    @param thd   pointer to a THD instance
1688    @param rli   pointer to Relay_log_info instance
1689 
1690    @return TRUE the killed status is recognized, FALSE a possible killed
1691            status is deferred.
1692 */
sql_slave_killed(THD * thd,Relay_log_info * rli)1693 static bool sql_slave_killed(THD* thd, Relay_log_info* rli)
1694 {
1695   bool is_parallel_warn= FALSE;
1696 
1697   DBUG_ENTER("sql_slave_killed");
1698 
1699   DBUG_ASSERT(rli->info_thd == thd);
1700   DBUG_ASSERT(rli->slave_running == 1);
1701   if (rli->sql_thread_kill_accepted)
1702     DBUG_RETURN(true);
1703   DBUG_EXECUTE_IF("stop_when_mts_in_group", rli->abort_slave = 1;
1704                   DBUG_SET("-d,stop_when_mts_in_group");
1705                   DBUG_SET("-d,simulate_stop_when_mts_in_group");
1706                   DBUG_RETURN(false););
1707   if (abort_loop || thd->killed || rli->abort_slave)
1708   {
1709     rli->sql_thread_kill_accepted= true;
1710     is_parallel_warn= (rli->is_parallel_exec() &&
1711                        (rli->is_mts_in_group() || thd->killed));
1712     /*
1713       Slave can execute stop being in one of two MTS or Single-Threaded mode.
1714       The modes define different criteria to accept the stop.
1715       In particular that relates to the concept of groupping.
1716       Killed Coordinator thread expects the worst so it warns on
1717       possible consistency issue.
1718     */
1719     if (is_parallel_warn ||
1720         (!rli->is_parallel_exec() &&
1721          thd->transaction.all.cannot_safely_rollback() && rli->is_in_group()))
1722     {
1723       char msg_stopped[]=
1724         "... Slave SQL Thread stopped with incomplete event group "
1725         "having non-transactional changes. "
1726         "If the group consists solely of row-based events, you can try "
1727         "to restart the slave with --slave-exec-mode=IDEMPOTENT, which "
1728         "ignores duplicate key, key not found, and similar errors (see "
1729         "documentation for details).";
1730       char msg_stopped_mts[]=
1731         "... The slave coordinator and worker threads are stopped, possibly "
1732         "leaving data in inconsistent state. A restart should "
1733         "restore consistency automatically, although using non-transactional "
1734         "storage for data or info tables or DDL queries could lead to problems. "
1735         "In such cases you have to examine your data (see documentation for "
1736         "details).";
1737 
1738       if (rli->abort_slave)
1739       {
1740         DBUG_PRINT("info", ("Request to stop slave SQL Thread received while "
1741                             "applying an MTS group or a group that "
1742                             "has non-transactional "
1743                             "changes; waiting for completion of the group ... "));
1744 
1745         /*
1746           Slave sql thread shutdown in face of unfinished group modified
1747           Non-trans table is handled via a timer. The slave may eventually
1748           give out to complete the current group and in that case there
1749           might be issues at consequent slave restart, see the error message.
1750           WL#2975 offers a robust solution requiring to store the last exectuted
1751           event's coordinates along with the group's coordianates
1752           instead of waiting with @c last_event_start_time the timer.
1753         */
1754 
1755         if (rli->last_event_start_time == 0)
1756           rli->last_event_start_time= my_time(0);
1757         rli->sql_thread_kill_accepted= difftime(my_time(0),
1758                                                rli->last_event_start_time) <=
1759                                                SLAVE_WAIT_GROUP_DONE ?
1760                                                FALSE : TRUE;
1761 
1762         DBUG_EXECUTE_IF("stop_slave_middle_group",
1763                         DBUG_EXECUTE_IF("incomplete_group_in_relay_log",
1764                                         rli->sql_thread_kill_accepted= TRUE;);); // time is over
1765 
1766         if (!rli->sql_thread_kill_accepted && !rli->reported_unsafe_warning)
1767         {
1768           rli->report(WARNING_LEVEL, 0,
1769                       !is_parallel_warn ?
1770                       "Request to stop slave SQL Thread received while "
1771                       "applying a group that has non-transactional "
1772                       "changes; waiting for completion of the group ... "
1773                       :
1774                       "Coordinator thread of multi-threaded slave is being "
1775                       "stopped in the middle of assigning a group of events; "
1776                       "deferring to exit until the group completion ... ");
1777           rli->reported_unsafe_warning= true;
1778         }
1779       }
1780       if (rli->sql_thread_kill_accepted)
1781       {
1782         rli->last_event_start_time= 0;
1783         if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
1784         {
1785           rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
1786         }
1787         if (is_parallel_warn)
1788           rli->report(!rli->is_error() ? ERROR_LEVEL :
1789                       WARNING_LEVEL,    // an error was reported by Worker
1790                       ER_MTS_INCONSISTENT_DATA,
1791                       ER(ER_MTS_INCONSISTENT_DATA),
1792                       msg_stopped_mts);
1793         else
1794           rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
1795                       ER(ER_SLAVE_FATAL_ERROR), msg_stopped);
1796       }
1797     }
1798   }
1799   DBUG_RETURN(rli->sql_thread_kill_accepted);
1800 }
1801 
1802 
1803 /*
1804   skip_load_data_infile()
1805 
1806   NOTES
1807     This is used to tell a 3.23 master to break send_file()
1808 */
1809 
skip_load_data_infile(NET * net)1810 void skip_load_data_infile(NET *net)
1811 {
1812   DBUG_ENTER("skip_load_data_infile");
1813 
1814   (void)net_request_file(net, "/dev/null");
1815   (void)my_net_read(net);                               // discard response
1816   (void)net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0); // ok
1817   DBUG_VOID_RETURN;
1818 }
1819 
1820 
net_request_file(NET * net,const char * fname)1821 bool net_request_file(NET* net, const char* fname)
1822 {
1823   DBUG_ENTER("net_request_file");
1824   DBUG_RETURN(net_write_command(net, 251, (uchar*) fname, strlen(fname),
1825                                 (uchar*) "", 0));
1826 }
1827 
1828 /*
1829   From other comments and tests in code, it looks like
1830   sometimes Query_log_event and Load_log_event can have db == 0
1831   (see rewrite_db() above for example)
1832   (cases where this happens are unclear; it may be when the master is 3.23).
1833 */
1834 
print_slave_db_safe(const char * db)1835 const char *print_slave_db_safe(const char* db)
1836 {
1837   DBUG_ENTER("*print_slave_db_safe");
1838 
1839   DBUG_RETURN((db ? db : ""));
1840 }
1841 
1842 /*
1843   Check if the error is caused by network.
1844   @param[in]   errorno   Number of the error.
1845   RETURNS:
1846   TRUE         network error
1847   FALSE        not network error
1848 */
1849 
is_network_error(uint errorno)1850 bool is_network_error(uint errorno)
1851 {
1852   if (errorno == CR_CONNECTION_ERROR ||
1853       errorno == CR_CONN_HOST_ERROR ||
1854       errorno == CR_SERVER_GONE_ERROR ||
1855       errorno == CR_SERVER_LOST ||
1856       errorno == ER_CON_COUNT_ERROR ||
1857       errorno == ER_SERVER_SHUTDOWN)
1858     return TRUE;
1859 
1860   return FALSE;
1861 }
1862 
1863 
1864 /**
1865   Execute an initialization query for the IO thread.
1866 
1867   If there is an error, then this function calls mysql_free_result;
1868   otherwise the MYSQL object holds the result after this call.  If
1869   there is an error other than allowed_error, then this function
1870   prints a message and returns -1.
1871 
1872   @param mysql MYSQL object.
1873   @param query Query string.
1874   @param allowed_error Allowed error code, or 0 if no errors are allowed.
1875   @param[out] master_res If this is not NULL and there is no error, then
1876   mysql_store_result() will be called and the result stored in this pointer.
1877   @param[out] master_row If this is not NULL and there is no error, then
1878   mysql_fetch_row() will be called and the result stored in this pointer.
1879 
1880   @retval COMMAND_STATUS_OK No error.
1881   @retval COMMAND_STATUS_ALLOWED_ERROR There was an error and the
1882   error code was 'allowed_error'.
1883   @retval COMMAND_STATUS_ERROR There was an error and the error code
1884   was not 'allowed_error'.
1885 */
1886 enum enum_command_status
1887 { COMMAND_STATUS_OK, COMMAND_STATUS_ERROR, COMMAND_STATUS_ALLOWED_ERROR };
1888 static enum_command_status
io_thread_init_command(Master_info * mi,const char * query,int allowed_error,MYSQL_RES ** master_res=NULL,MYSQL_ROW * master_row=NULL)1889 io_thread_init_command(Master_info *mi, const char *query, int allowed_error,
1890                        MYSQL_RES **master_res= NULL,
1891                        MYSQL_ROW *master_row= NULL)
1892 {
1893   DBUG_ENTER("io_thread_init_command");
1894   DBUG_PRINT("info", ("IO thread initialization command: '%s'", query));
1895   MYSQL *mysql= mi->mysql;
1896   int ret= mysql_real_query(mysql, query, strlen(query));
1897   if (io_slave_killed(mi->info_thd, mi))
1898   {
1899     sql_print_information("The slave IO thread was killed while executing "
1900                           "initialization query '%s'", query);
1901     mysql_free_result(mysql_store_result(mysql));
1902     DBUG_RETURN(COMMAND_STATUS_ERROR);
1903   }
1904   if (ret != 0)
1905   {
1906     int err= mysql_errno(mysql);
1907     mysql_free_result(mysql_store_result(mysql));
1908     if (!err || err != allowed_error)
1909     {
1910       mi->report(is_network_error(err) ? WARNING_LEVEL : ERROR_LEVEL, err,
1911                  "The slave IO thread stops because the initialization query "
1912                  "'%s' failed with error '%s'.",
1913                  query, mysql_error(mysql));
1914       DBUG_RETURN(COMMAND_STATUS_ERROR);
1915     }
1916     DBUG_RETURN(COMMAND_STATUS_ALLOWED_ERROR);
1917   }
1918   if (master_res != NULL)
1919   {
1920     if ((*master_res= mysql_store_result(mysql)) == NULL)
1921     {
1922       mi->report(WARNING_LEVEL, mysql_errno(mysql),
1923                  "The slave IO thread stops because the initialization query "
1924                  "'%s' did not return any result.",
1925                  query);
1926       DBUG_RETURN(COMMAND_STATUS_ERROR);
1927     }
1928     if (master_row != NULL)
1929     {
1930       if ((*master_row= mysql_fetch_row(*master_res)) == NULL)
1931       {
1932         mysql_free_result(*master_res);
1933         mi->report(WARNING_LEVEL, mysql_errno(mysql),
1934                    "The slave IO thread stops because the initialization query "
1935                    "'%s' did not return any row.",
1936                    query);
1937         DBUG_RETURN(COMMAND_STATUS_ERROR);
1938       }
1939     }
1940   }
1941   else
1942     DBUG_ASSERT(master_row == NULL);
1943   DBUG_RETURN(COMMAND_STATUS_OK);
1944 }
1945 
1946 
1947 /**
1948   Set user variables after connecting to the master.
1949 
1950   @param  mysql MYSQL to request uuid from master.
1951   @param  mi    Master_info to set master_uuid
1952 
1953   @return 0: Success, 1: Fatal error, 2: Network error.
1954  */
io_thread_init_commands(MYSQL * mysql,Master_info * mi)1955 int io_thread_init_commands(MYSQL *mysql, Master_info *mi)
1956 {
1957   char query[256];
1958   int ret= 0;
1959   DBUG_EXECUTE_IF("fake_5_5_version_slave", return ret;);
1960 
1961   sprintf(query, "SET @slave_uuid= '%s'", server_uuid);
1962   if (mysql_real_query(mysql, query, strlen(query))
1963       && !check_io_slave_killed(mi->info_thd, mi, NULL))
1964     goto err;
1965 
1966   mysql_free_result(mysql_store_result(mysql));
1967   return ret;
1968 
1969 err:
1970   if (mysql_errno(mysql) && is_network_error(mysql_errno(mysql)))
1971   {
1972     mi->report(WARNING_LEVEL, mysql_errno(mysql),
1973                "The initialization command '%s' failed with the following"
1974                " error: '%s'.", query, mysql_error(mysql));
1975     ret= 2;
1976   }
1977   else
1978   {
1979     char errmsg[512];
1980     const char *errmsg_fmt=
1981       "The slave I/O thread stops because a fatal error is encountered "
1982       "when it tries to send query to master(query: %s).";
1983 
1984     sprintf(errmsg, errmsg_fmt, query);
1985     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
1986                errmsg);
1987     ret= 1;
1988   }
1989   mysql_free_result(mysql_store_result(mysql));
1990   return ret;
1991 }
1992 
1993 /**
1994   Get master's uuid on connecting.
1995 
1996   @param  mysql MYSQL to request uuid from master.
1997   @param  mi    Master_info to set master_uuid
1998 
1999   @return 0: Success, 1: Fatal error, 2: Network error.
2000 */
get_master_uuid(MYSQL * mysql,Master_info * mi)2001 static int get_master_uuid(MYSQL *mysql, Master_info *mi)
2002 {
2003   const char *errmsg;
2004   MYSQL_RES *master_res= NULL;
2005   MYSQL_ROW master_row= NULL;
2006   int ret= 0;
2007 
2008   DBUG_EXECUTE_IF("dbug.before_get_MASTER_UUID",
2009                   {
2010                     const char act[]= "now wait_for signal.get_master_uuid";
2011                     DBUG_ASSERT(opt_debug_sync_timeout > 0);
2012                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
2013                                                        STRING_WITH_LEN(act)));
2014                   };);
2015 
2016   DBUG_EXECUTE_IF("dbug.simulate_busy_io",
2017                   {
2018                     const char act[]= "now signal Reached wait_for signal.got_stop_slave";
2019                     DBUG_ASSERT(opt_debug_sync_timeout > 0);
2020                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
2021                                                        STRING_WITH_LEN(act)));
2022                   };);
2023   if (!mysql_real_query(mysql,
2024                         STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_UUID'")) &&
2025       (master_res= mysql_store_result(mysql)) &&
2026       (master_row= mysql_fetch_row(master_res)))
2027   {
2028     if (!strcmp(::server_uuid, master_row[1]) &&
2029         !mi->rli->replicate_same_server_id)
2030     {
2031       errmsg= "The slave I/O thread stops because master and slave have equal "
2032               "MySQL server UUIDs; these UUIDs must be different for "
2033               "replication to work.";
2034       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
2035                  errmsg);
2036       // Fatal error
2037       ret= 1;
2038     }
2039     else
2040     {
2041       if (mi->master_uuid[0] != 0 && strcmp(mi->master_uuid, master_row[1]))
2042         sql_print_warning("The master's UUID has changed, although this should"
2043                           " not happen unless you have changed it manually."
2044                           " The old UUID was %s.",
2045                           mi->master_uuid);
2046       strncpy(mi->master_uuid, master_row[1], UUID_LENGTH);
2047       mi->master_uuid[UUID_LENGTH]= 0;
2048     }
2049   }
2050   else if (mysql_errno(mysql))
2051   {
2052     if (is_network_error(mysql_errno(mysql)))
2053     {
2054       mi->report(WARNING_LEVEL, mysql_errno(mysql),
2055                  "Get master SERVER_UUID failed with error: %s",
2056                  mysql_error(mysql));
2057       ret= 2;
2058     }
2059     else
2060     {
2061       /* Fatal error */
2062       errmsg= "The slave I/O thread stops because a fatal error is encountered "
2063         "when it tries to get the value of SERVER_UUID variable from master.";
2064       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
2065                  errmsg);
2066       ret= 1;
2067     }
2068   }
2069   else if (!master_row && master_res)
2070   {
2071     mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2072                "Unknown system variable 'SERVER_UUID' on master. "
2073                "A probable cause is that the variable is not supported on the "
2074                "master (version: %s), even though it is on the slave (version: %s)",
2075                mysql->server_version, server_version);
2076   }
2077 
2078   if (master_res)
2079     mysql_free_result(master_res);
2080   return ret;
2081 }
2082 
2083 
2084 /**
2085   Determine, case-sensitively, if short_string is equal to
2086   long_string, or a true prefix of long_string, or not a prefix.
2087 
2088   @retval 0 short_string is not a prefix of long_string.
2089   @retval 1 short_string is a true prefix of long_string (not equal).
2090   @retval 2 short_string is equal to long_string.
2091 */
is_str_prefix_case(const char * short_string,const char * long_string)2092 static int is_str_prefix_case(const char *short_string, const char *long_string)
2093 {
2094   int i;
2095   for (i= 0; short_string[i]; i++)
2096     if (my_toupper(system_charset_info, short_string[i]) !=
2097         my_toupper(system_charset_info, long_string[i]))
2098       return 0;
2099   return long_string[i] ? 1 : 2;
2100 }
2101 
2102 /*
2103   Note that we rely on the master's version (3.23, 4.0.14 etc) instead of
2104   relying on the binlog's version. This is not perfect: imagine an upgrade
2105   of the master without waiting that all slaves are in sync with the master;
2106   then a slave could be fooled about the binlog's format. This is what happens
2107   when people upgrade a 3.23 master to 4.0 without doing RESET MASTER: 4.0
2108   slaves are fooled. So we do this only to distinguish between 3.23 and more
2109   recent masters (it's too late to change things for 3.23).
2110 
2111   RETURNS
2112   0       ok
2113   1       error
2114   2       transient network problem, the caller should try to reconnect
2115 */
2116 
get_master_version_and_clock(MYSQL * mysql,Master_info * mi)2117 static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
2118 {
2119   char err_buff[MAX_SLAVE_ERRMSG];
2120   const char* errmsg= 0;
2121   int err_code= 0;
2122   int version_number=0;
2123   version_number= atoi(mysql->server_version);
2124 
2125   MYSQL_RES *master_res= 0;
2126   MYSQL_ROW master_row;
2127   DBUG_ENTER("get_master_version_and_clock");
2128 
2129   /*
2130     Free old mi_description_event (that is needed if we are in
2131     a reconnection).
2132   */
2133   DBUG_EXECUTE_IF("unrecognized_master_version",
2134                  {
2135                    version_number= 1;
2136                  };);
2137   mysql_mutex_lock(&mi->data_lock);
2138   mi->set_mi_description_event(NULL);
2139 
2140   if (!my_isdigit(&my_charset_bin,*mysql->server_version))
2141   {
2142     errmsg = "Master reported unrecognized MySQL version";
2143     err_code= ER_SLAVE_FATAL_ERROR;
2144     sprintf(err_buff, ER(err_code), errmsg);
2145   }
2146   else
2147   {
2148     /*
2149       Note the following switch will bug when we have MySQL branch 30 ;)
2150     */
2151     switch (version_number)
2152     {
2153     case 0:
2154     case 1:
2155     case 2:
2156       errmsg = "Master reported unrecognized MySQL version";
2157       err_code= ER_SLAVE_FATAL_ERROR;
2158       sprintf(err_buff, ER(err_code), errmsg);
2159       break;
2160     case 3:
2161       mi->set_mi_description_event(new
2162         Format_description_log_event(1, mysql->server_version));
2163       break;
2164     case 4:
2165       mi->set_mi_description_event(new
2166         Format_description_log_event(3, mysql->server_version));
2167       break;
2168     default:
2169       /*
2170         Master is MySQL >=5.0. Give a default Format_desc event, so that we can
2171         take the early steps (like tests for "is this a 3.23 master") which we
2172         have to take before we receive the real master's Format_desc which will
2173         override this one. Note that the Format_desc we create below is garbage
2174         (it has the format of the *slave*); it's only good to help know if the
2175         master is 3.23, 4.0, etc.
2176       */
2177       mi->set_mi_description_event(new
2178         Format_description_log_event(4, mysql->server_version));
2179       break;
2180     }
2181   }
2182 
2183   /*
2184      This does not mean that a 5.0 slave will be able to read a 5.5 master; but
2185      as we don't know yet, we don't want to forbid this for now. If a 5.0 slave
2186      can't read a 5.5 master, this will show up when the slave can't read some
2187      events sent by the master, and there will be error messages.
2188   */
2189 
2190   if (errmsg)
2191   {
2192     /* unlock the mutex on master info structure */
2193     mysql_mutex_unlock(&mi->data_lock);
2194     goto err;
2195   }
2196 
2197   /* as we are here, we tried to allocate the event */
2198   if (mi->get_mi_description_event() == NULL)
2199   {
2200     mysql_mutex_unlock(&mi->data_lock);
2201     errmsg= "default Format_description_log_event";
2202     err_code= ER_SLAVE_CREATE_EVENT_FAILURE;
2203     sprintf(err_buff, ER(err_code), errmsg);
2204     goto err;
2205   }
2206 
2207   if (mi->get_mi_description_event()->binlog_version < 4 &&
2208       opt_slave_sql_verify_checksum)
2209   {
2210     sql_print_warning("Found a master with MySQL server version older than "
2211                       "5.0. With checksums enabled on the slave, replication "
2212                       "might not work correctly. To ensure correct "
2213                       "replication, restart the slave server with "
2214                       "--slave_sql_verify_checksum=0.");
2215   }
2216   /*
2217     FD_q's (A) is set initially from RL's (A): FD_q.(A) := RL.(A).
2218     It's necessary to adjust FD_q.(A) at this point because in the following
2219     course FD_q is going to be dumped to RL.
2220     Generally FD_q is derived from a received FD_m (roughly FD_q := FD_m)
2221     in queue_event and the master's (A) is installed.
2222     At one step with the assignment the Relay-Log's checksum alg is set to
2223     a new value: RL.(A) := FD_q.(A). If the slave service is stopped
2224     the last time assigned RL.(A) will be passed over to the restarting
2225     service (to the current execution point).
2226     RL.A is a "codec" to verify checksum in queue_event() almost all the time
2227     the first fake Rotate event.
2228     Starting from this point IO thread will executes the following checksum
2229     warmup sequence  of actions:
2230 
2231     FD_q.A := RL.A,
2232     A_m^0 := master.@@global.binlog_checksum,
2233     {queue_event(R_f): verifies(R_f, A_m^0)},
2234     {queue_event(FD_m): verifies(FD_m, FD_m.A), dump(FD_q), rotate(RL),
2235                         FD_q := FD_m, RL.A := FD_q.A)}
2236 
2237     See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg
2238     docs lines (binlog.h).
2239     In above A_m^0 - the value of master's
2240     @@binlog_checksum determined in the upcoming handshake (stored in
2241     mi->checksum_alg_before_fd).
2242 
2243 
2244     After the warm-up sequence IO gets to "normal" checksum verification mode
2245     to use RL.A in
2246 
2247     {queue_event(E_m): verifies(E_m, RL.A)}
2248 
2249     until it has received a new FD_m.
2250   */
2251   mi->get_mi_description_event()->checksum_alg=
2252     mi->rli->relay_log.relay_log_checksum_alg;
2253 
2254   DBUG_ASSERT(mi->get_mi_description_event()->checksum_alg !=
2255               BINLOG_CHECKSUM_ALG_UNDEF);
2256   DBUG_ASSERT(mi->rli->relay_log.relay_log_checksum_alg !=
2257               BINLOG_CHECKSUM_ALG_UNDEF);
2258 
2259   mysql_mutex_unlock(&mi->data_lock);
2260 
2261   /*
2262     Compare the master and slave's clock. Do not die if master's clock is
2263     unavailable (very old master not supporting UNIX_TIMESTAMP()?).
2264   */
2265 
2266   DBUG_EXECUTE_IF("dbug.before_get_UNIX_TIMESTAMP",
2267                   {
2268                     const char act[]=
2269                       "now "
2270                       "wait_for signal.get_unix_timestamp";
2271                     DBUG_ASSERT(opt_debug_sync_timeout > 0);
2272                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
2273                                                        STRING_WITH_LEN(act)));
2274                   };);
2275 
2276   master_res= NULL;
2277   if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
2278       (master_res= mysql_store_result(mysql)) &&
2279       (master_row= mysql_fetch_row(master_res)))
2280   {
2281     mysql_mutex_lock(&mi->data_lock);
2282     mi->clock_diff_with_master=
2283       (long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
2284     mysql_mutex_unlock(&mi->data_lock);
2285   }
2286   else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2287     goto slave_killed_err;
2288   else if (is_network_error(mysql_errno(mysql)))
2289   {
2290     mi->report(WARNING_LEVEL, mysql_errno(mysql),
2291                "Get master clock failed with error: %s", mysql_error(mysql));
2292     goto network_err;
2293   }
2294   else
2295   {
2296     mysql_mutex_lock(&mi->data_lock);
2297     mi->clock_diff_with_master= 0; /* The "most sensible" value */
2298     mysql_mutex_unlock(&mi->data_lock);
2299     sql_print_warning("\"SELECT UNIX_TIMESTAMP()\" failed on master, "
2300                       "do not trust column Seconds_Behind_Master of SHOW "
2301                       "SLAVE STATUS. Error: %s (%d)",
2302                       mysql_error(mysql), mysql_errno(mysql));
2303   }
2304   if (master_res)
2305   {
2306     mysql_free_result(master_res);
2307     master_res= NULL;
2308   }
2309 
2310   /*
2311     Check that the master's server id and ours are different. Because if they
2312     are equal (which can result from a simple copy of master's datadir to slave,
2313     thus copying some my.cnf), replication will work but all events will be
2314     skipped.
2315     Do not die if SHOW VARIABLES LIKE 'SERVER_ID' fails on master (very old
2316     master?).
2317     Note: we could have put a @@SERVER_ID in the previous SELECT
2318     UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters.
2319   */
2320   DBUG_EXECUTE_IF("dbug.before_get_SERVER_ID",
2321                   {
2322                     const char act[]=
2323                       "now "
2324                       "wait_for signal.get_server_id";
2325                     DBUG_ASSERT(opt_debug_sync_timeout > 0);
2326                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
2327                                                        STRING_WITH_LEN(act)));
2328                   };);
2329   master_res= NULL;
2330   master_row= NULL;
2331   if (!mysql_real_query(mysql,
2332                         STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_ID'")) &&
2333       (master_res= mysql_store_result(mysql)) &&
2334       (master_row= mysql_fetch_row(master_res)))
2335   {
2336     if ((::server_id == (mi->master_id= strtoul(master_row[1], 0, 10))) &&
2337         !mi->rli->replicate_same_server_id)
2338     {
2339       errmsg= "The slave I/O thread stops because master and slave have equal \
2340 MySQL server ids; these ids must be different for replication to work (or \
2341 the --replicate-same-server-id option must be used on slave but this does \
2342 not always make sense; please check the manual before using it).";
2343       err_code= ER_SLAVE_FATAL_ERROR;
2344       sprintf(err_buff, ER(err_code), errmsg);
2345       goto err;
2346     }
2347   }
2348   else if (mysql_errno(mysql))
2349   {
2350     if (check_io_slave_killed(mi->info_thd, mi, NULL))
2351       goto slave_killed_err;
2352     else if (is_network_error(mysql_errno(mysql)))
2353     {
2354       mi->report(WARNING_LEVEL, mysql_errno(mysql),
2355                  "Get master SERVER_ID failed with error: %s", mysql_error(mysql));
2356       goto network_err;
2357     }
2358     /* Fatal error */
2359     errmsg= "The slave I/O thread stops because a fatal error is encountered \
2360 when it try to get the value of SERVER_ID variable from master.";
2361     err_code= mysql_errno(mysql);
2362     sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2363     goto err;
2364   }
2365   else if (!master_row && master_res)
2366   {
2367     mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2368                "Unknown system variable 'SERVER_ID' on master, \
2369 maybe it is a *VERY OLD MASTER*.");
2370   }
2371   if (master_res)
2372   {
2373     mysql_free_result(master_res);
2374     master_res= NULL;
2375   }
2376   if (mi->master_id == 0 && mi->ignore_server_ids->dynamic_ids.elements > 0)
2377   {
2378     errmsg= "Slave configured with server id filtering could not detect the master server id.";
2379     err_code= ER_SLAVE_FATAL_ERROR;
2380     sprintf(err_buff, ER(err_code), errmsg);
2381     goto err;
2382   }
2383 
2384   /*
2385     Check that the master's global character_set_server and ours are the same.
2386     Not fatal if query fails (old master?).
2387     Note that we don't check for equality of global character_set_client and
2388     collation_connection (neither do we prevent their setting in
2389     set_var.cc). That's because from what I (Guilhem) have tested, the global
2390     values of these 2 are never used (new connections don't use them).
2391     We don't test equality of global collation_database either as it's is
2392     going to be deprecated (made read-only) in 4.1 very soon.
2393     The test is only relevant if master < 5.0.3 (we'll test only if it's older
2394     than the 5 branch; < 5.0.3 was alpha...), as >= 5.0.3 master stores
2395     charset info in each binlog event.
2396     We don't do it for 3.23 because masters <3.23.50 hang on
2397     SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). So finally we
2398     test only if master is 4.x.
2399   */
2400 
2401   /* redundant with rest of code but safer against later additions */
2402   if (*mysql->server_version == '3')
2403     goto err;
2404 
2405   if (*mysql->server_version == '4')
2406   {
2407     master_res= NULL;
2408     if (!mysql_real_query(mysql,
2409                           STRING_WITH_LEN("SELECT @@GLOBAL.COLLATION_SERVER")) &&
2410         (master_res= mysql_store_result(mysql)) &&
2411         (master_row= mysql_fetch_row(master_res)))
2412     {
2413       if (strcmp(master_row[0], global_system_variables.collation_server->name))
2414       {
2415         errmsg= "The slave I/O thread stops because master and slave have \
2416 different values for the COLLATION_SERVER global variable. The values must \
2417 be equal for the Statement-format replication to work";
2418         err_code= ER_SLAVE_FATAL_ERROR;
2419         sprintf(err_buff, ER(err_code), errmsg);
2420         goto err;
2421       }
2422     }
2423     else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2424       goto slave_killed_err;
2425     else if (is_network_error(mysql_errno(mysql)))
2426     {
2427       mi->report(WARNING_LEVEL, mysql_errno(mysql),
2428                  "Get master COLLATION_SERVER failed with error: %s", mysql_error(mysql));
2429       goto network_err;
2430     }
2431     else if (mysql_errno(mysql) != ER_UNKNOWN_SYSTEM_VARIABLE)
2432     {
2433       /* Fatal error */
2434       errmsg= "The slave I/O thread stops because a fatal error is encountered \
2435 when it try to get the value of COLLATION_SERVER global variable from master.";
2436       err_code= mysql_errno(mysql);
2437       sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2438       goto err;
2439     }
2440     else
2441       mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2442                  "Unknown system variable 'COLLATION_SERVER' on master, \
2443 maybe it is a *VERY OLD MASTER*. *NOTE*: slave may experience \
2444 inconsistency if replicated data deals with collation.");
2445 
2446     if (master_res)
2447     {
2448       mysql_free_result(master_res);
2449       master_res= NULL;
2450     }
2451   }
2452 
2453   /*
2454     Perform analogous check for time zone. Theoretically we also should
2455     perform check here to verify that SYSTEM time zones are the same on
2456     slave and master, but we can't rely on value of @@system_time_zone
2457     variable (it is time zone abbreviation) since it determined at start
2458     time and so could differ for slave and master even if they are really
2459     in the same system time zone. So we are omiting this check and just
2460     relying on documentation. Also according to Monty there are many users
2461     who are using replication between servers in various time zones. Hence
2462     such check will broke everything for them. (And now everything will
2463     work for them because by default both their master and slave will have
2464     'SYSTEM' time zone).
2465     This check is only necessary for 4.x masters (and < 5.0.4 masters but
2466     those were alpha).
2467   */
2468   if (*mysql->server_version == '4')
2469   {
2470     master_res= NULL;
2471     if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) &&
2472         (master_res= mysql_store_result(mysql)) &&
2473         (master_row= mysql_fetch_row(master_res)))
2474     {
2475       if (strcmp(master_row[0],
2476                  global_system_variables.time_zone->get_name()->ptr()))
2477       {
2478         errmsg= "The slave I/O thread stops because master and slave have \
2479 different values for the TIME_ZONE global variable. The values must \
2480 be equal for the Statement-format replication to work";
2481         err_code= ER_SLAVE_FATAL_ERROR;
2482         sprintf(err_buff, ER(err_code), errmsg);
2483         goto err;
2484       }
2485     }
2486     else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2487       goto slave_killed_err;
2488     else if (is_network_error(mysql_errno(mysql)))
2489     {
2490       mi->report(WARNING_LEVEL, mysql_errno(mysql),
2491                  "Get master TIME_ZONE failed with error: %s", mysql_error(mysql));
2492       goto network_err;
2493     }
2494     else
2495     {
2496       /* Fatal error */
2497       errmsg= "The slave I/O thread stops because a fatal error is encountered \
2498 when it try to get the value of TIME_ZONE global variable from master.";
2499       err_code= mysql_errno(mysql);
2500       sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2501       goto err;
2502     }
2503     if (master_res)
2504     {
2505       mysql_free_result(master_res);
2506       master_res= NULL;
2507     }
2508   }
2509 
2510   if (mi->heartbeat_period != 0.0)
2511   {
2512     char llbuf[22];
2513     const char query_format[]= "SET @master_heartbeat_period= %s";
2514     char query[sizeof(query_format) - 2 + sizeof(llbuf)];
2515     /*
2516        the period is an ulonglong of nano-secs.
2517     */
2518     llstr((ulonglong) (mi->heartbeat_period*1000000000UL), llbuf);
2519     sprintf(query, query_format, llbuf);
2520 
2521     if (mysql_real_query(mysql, query, strlen(query)))
2522     {
2523       if (check_io_slave_killed(mi->info_thd, mi, NULL))
2524         goto slave_killed_err;
2525 
2526       if (is_network_error(mysql_errno(mysql)))
2527       {
2528         mi->report(WARNING_LEVEL, mysql_errno(mysql),
2529                    "SET @master_heartbeat_period to master failed with error: %s",
2530                    mysql_error(mysql));
2531         mysql_free_result(mysql_store_result(mysql));
2532         goto network_err;
2533       }
2534       else
2535       {
2536         /* Fatal error */
2537         errmsg= "The slave I/O thread stops because a fatal error is encountered "
2538           " when it tries to SET @master_heartbeat_period on master.";
2539         err_code= ER_SLAVE_FATAL_ERROR;
2540         sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2541         mysql_free_result(mysql_store_result(mysql));
2542         goto err;
2543       }
2544     }
2545     mysql_free_result(mysql_store_result(mysql));
2546   }
2547 
2548   /*
2549     Querying if master is capable to checksum and notifying it about own
2550     CRC-awareness. The master's side instant value of @@global.binlog_checksum
2551     is stored in the dump thread's uservar area as well as cached locally
2552     to become known in consensus by master and slave.
2553   */
2554   if (DBUG_EVALUATE_IF("simulate_slave_unaware_checksum", 0, 1))
2555   {
2556     int rc;
2557     const char query[]= "SET @master_binlog_checksum= @@global.binlog_checksum";
2558     master_res= NULL;
2559     mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF; //initially undefined
2560     /*
2561       @c checksum_alg_before_fd is queried from master in this block.
2562       If master is old checksum-unaware the value stays undefined.
2563       Once the first FD will be received its alg descriptor will replace
2564       the being queried one.
2565     */
2566     rc= mysql_real_query(mysql, query, strlen(query));
2567     if (rc != 0)
2568     {
2569       mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_OFF;
2570       if (check_io_slave_killed(mi->info_thd, mi, NULL))
2571         goto slave_killed_err;
2572 
2573       if (mysql_errno(mysql) == ER_UNKNOWN_SYSTEM_VARIABLE)
2574       {
2575         // this is tolerable as OM -> NS is supported
2576         mi->report(WARNING_LEVEL, mysql_errno(mysql),
2577                    "Notifying master by %s failed with "
2578                    "error: %s", query, mysql_error(mysql));
2579       }
2580       else
2581       {
2582         if (is_network_error(mysql_errno(mysql)))
2583         {
2584           mi->report(WARNING_LEVEL, mysql_errno(mysql),
2585                      "Notifying master by %s failed with "
2586                      "error: %s", query, mysql_error(mysql));
2587           mysql_free_result(mysql_store_result(mysql));
2588           goto network_err;
2589         }
2590         else
2591         {
2592           errmsg= "The slave I/O thread stops because a fatal error is encountered "
2593             "when it tried to SET @master_binlog_checksum on master.";
2594           err_code= ER_SLAVE_FATAL_ERROR;
2595           sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2596           mysql_free_result(mysql_store_result(mysql));
2597           goto err;
2598         }
2599       }
2600     }
2601     else
2602     {
2603       mysql_free_result(mysql_store_result(mysql));
2604       if (!mysql_real_query(mysql,
2605                             STRING_WITH_LEN("SELECT @master_binlog_checksum")) &&
2606           (master_res= mysql_store_result(mysql)) &&
2607           (master_row= mysql_fetch_row(master_res)) &&
2608           (master_row[0] != NULL))
2609       {
2610         mi->checksum_alg_before_fd= (uint8)
2611           find_type(master_row[0], &binlog_checksum_typelib, 1) - 1;
2612 
2613        DBUG_EXECUTE_IF("undefined_algorithm_on_slave",
2614         mi->checksum_alg_before_fd = BINLOG_CHECKSUM_ALG_UNDEF;);
2615        if(mi->checksum_alg_before_fd == BINLOG_CHECKSUM_ALG_UNDEF)
2616        {
2617          errmsg= "The slave I/O thread was stopped because a fatal error is encountered "
2618                  "The checksum algorithm used by master is unknown to slave.";
2619          err_code= ER_SLAVE_FATAL_ERROR;
2620          sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2621          mysql_free_result(mysql_store_result(mysql));
2622          goto err;
2623        }
2624 
2625         // valid outcome is either of
2626         DBUG_ASSERT(mi->checksum_alg_before_fd == BINLOG_CHECKSUM_ALG_OFF ||
2627                     mi->checksum_alg_before_fd == BINLOG_CHECKSUM_ALG_CRC32);
2628       }
2629       else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2630         goto slave_killed_err;
2631       else if (is_network_error(mysql_errno(mysql)))
2632       {
2633         mi->report(WARNING_LEVEL, mysql_errno(mysql),
2634                    "Get master BINLOG_CHECKSUM failed with error: %s", mysql_error(mysql));
2635         goto network_err;
2636       }
2637       else
2638       {
2639         errmsg= "The slave I/O thread stops because a fatal error is encountered "
2640           "when it tried to SELECT @master_binlog_checksum.";
2641         err_code= ER_SLAVE_FATAL_ERROR;
2642         sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2643         mysql_free_result(mysql_store_result(mysql));
2644         goto err;
2645       }
2646     }
2647     if (master_res)
2648     {
2649       mysql_free_result(master_res);
2650       master_res= NULL;
2651     }
2652   }
2653   else
2654     mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_OFF;
2655 
2656   if (DBUG_EVALUATE_IF("simulate_slave_unaware_gtid", 0, 1))
2657   {
2658     switch (io_thread_init_command(mi, "SELECT @@GLOBAL.GTID_MODE",
2659                                    ER_UNKNOWN_SYSTEM_VARIABLE,
2660                                    &master_res, &master_row))
2661     {
2662     case COMMAND_STATUS_ERROR:
2663       DBUG_RETURN(2);
2664     case COMMAND_STATUS_ALLOWED_ERROR:
2665       // master is old and does not have @@GLOBAL.GTID_MODE
2666       mi->master_gtid_mode= 0;
2667       break;
2668     case COMMAND_STATUS_OK:
2669       const char *master_gtid_mode_string= master_row[0];
2670       bool found_valid_mode= false;
2671       DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_on_permissive",
2672                       { master_gtid_mode_string= "on_permissive"; });
2673       DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_off_permissive",
2674                       { master_gtid_mode_string= "off_permissive"; });
2675       DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_on_something",
2676                       { master_gtid_mode_string= "on_something"; });
2677       DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_off_something",
2678                       { master_gtid_mode_string= "off_something"; });
2679       DBUG_EXECUTE_IF("simulate_master_has_unknown_gtid_mode",
2680                       { master_gtid_mode_string= "Krakel Spektakel"; });
2681       for (int mode= 0; mode <= 3 && !found_valid_mode; mode+= 3)
2682       {
2683         switch (is_str_prefix_case(gtid_mode_typelib.type_names[mode],
2684                                    master_gtid_mode_string))
2685         {
2686         case 0: // is not a prefix
2687           break;
2688         case 1: // is a true prefix, i.e. not equal
2689           mi->report(WARNING_LEVEL, ER_UNKNOWN_ERROR,
2690                      "The master uses an unknown GTID_MODE '%s'. "
2691                      "Treating it as '%s'.",
2692                      master_gtid_mode_string,
2693                      gtid_mode_typelib.type_names[mode]);
2694           // fall through
2695         case 2: // is equal
2696           found_valid_mode= true;
2697           mi->master_gtid_mode= mode;
2698           break;
2699         }
2700       }
2701       if (!found_valid_mode)
2702       {
2703         mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
2704                    "The slave IO thread stops because the master has "
2705                    "an unknown @@GLOBAL.GTID_MODE '%s'.",
2706                    master_gtid_mode_string);
2707         mysql_free_result(master_res);
2708         DBUG_RETURN(1);
2709       }
2710       mysql_free_result(master_res);
2711       break;
2712     }
2713     if (mi->master_gtid_mode > gtid_mode + 1 ||
2714         gtid_mode > mi->master_gtid_mode + 1)
2715     {
2716       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
2717                  "The slave IO thread stops because the master has "
2718                  "@@GLOBAL.GTID_MODE %s and this server has "
2719                  "@@GLOBAL.GTID_MODE %s",
2720                  gtid_mode_names[mi->master_gtid_mode],
2721                  gtid_mode_names[gtid_mode]);
2722       DBUG_RETURN(1);
2723     }
2724     if (mi->is_auto_position() && mi->master_gtid_mode != 3)
2725     {
2726       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
2727                  "The slave IO thread stops because the master has "
2728                  "@@GLOBAL.GTID_MODE %s and we are trying to connect "
2729                  "using MASTER_AUTO_POSITION.",
2730                  gtid_mode_names[mi->master_gtid_mode]);
2731       DBUG_RETURN(1);
2732     }
2733   }
2734 
2735 err:
2736   if (errmsg)
2737   {
2738     if (master_res)
2739       mysql_free_result(master_res);
2740     DBUG_ASSERT(err_code != 0);
2741     mi->report(ERROR_LEVEL, err_code, "%s", err_buff);
2742     DBUG_RETURN(1);
2743   }
2744 
2745   DBUG_RETURN(0);
2746 
2747 network_err:
2748   if (master_res)
2749     mysql_free_result(master_res);
2750   DBUG_RETURN(2);
2751 
2752 slave_killed_err:
2753   if (master_res)
2754     mysql_free_result(master_res);
2755   DBUG_RETURN(2);
2756 }
2757 
wait_for_relay_log_space(Relay_log_info * rli)2758 static bool wait_for_relay_log_space(Relay_log_info* rli)
2759 {
2760   bool slave_killed=0;
2761   Master_info* mi = rli->mi;
2762   PSI_stage_info old_stage;
2763   THD* thd = mi->info_thd;
2764   DBUG_ENTER("wait_for_relay_log_space");
2765 
2766   mysql_mutex_lock(&rli->log_space_lock);
2767   thd->ENTER_COND(&rli->log_space_cond,
2768                   &rli->log_space_lock,
2769                   &stage_waiting_for_relay_log_space,
2770                   &old_stage);
2771   while (rli->log_space_limit < rli->log_space_total &&
2772          !(slave_killed=io_slave_killed(thd,mi)) &&
2773          !rli->ignore_log_space_limit)
2774     mysql_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
2775 
2776   /*
2777     Makes the IO thread read only one event at a time
2778     until the SQL thread is able to purge the relay
2779     logs, freeing some space.
2780 
2781     Therefore, once the SQL thread processes this next
2782     event, it goes to sleep (no more events in the queue),
2783     sets ignore_log_space_limit=true and wakes the IO thread.
2784     However, this event may have been enough already for
2785     the SQL thread to purge some log files, freeing
2786     rli->log_space_total .
2787 
2788     This guarantees that the SQL and IO thread move
2789     forward only one event at a time (to avoid deadlocks),
2790     when the relay space limit is reached. It also
2791     guarantees that when the SQL thread is prepared to
2792     rotate (to be able to purge some logs), the IO thread
2793     will know about it and will rotate.
2794 
2795     NOTE: The ignore_log_space_limit is only set when the SQL
2796           thread sleeps waiting for events.
2797 
2798    */
2799   if (rli->ignore_log_space_limit)
2800   {
2801 #ifndef DBUG_OFF
2802     {
2803       char llbuf1[22], llbuf2[22];
2804       DBUG_PRINT("info", ("log_space_limit=%s "
2805                           "log_space_total=%s "
2806                           "ignore_log_space_limit=%d "
2807                           "sql_force_rotate_relay=%d",
2808                         llstr(rli->log_space_limit,llbuf1),
2809                         llstr(rli->log_space_total,llbuf2),
2810                         (int) rli->ignore_log_space_limit,
2811                         (int) rli->sql_force_rotate_relay));
2812     }
2813 #endif
2814     if (rli->sql_force_rotate_relay)
2815     {
2816       mysql_mutex_lock(&mi->data_lock);
2817       rotate_relay_log(mi, false/*need_log_space_lock=false*/);
2818       mysql_mutex_unlock(&mi->data_lock);
2819       rli->sql_force_rotate_relay= false;
2820     }
2821 
2822     rli->ignore_log_space_limit= false;
2823   }
2824 
2825   thd->EXIT_COND(&old_stage);
2826   DBUG_RETURN(slave_killed);
2827 }
2828 
2829 
2830 /*
2831   Builds a Rotate from the ignored events' info and writes it to relay log.
2832 
2833   The caller must hold mi->data_lock before invoking this function.
2834 
2835   @param thd pointer to I/O Thread's Thd.
2836   @param mi  point to I/O Thread metadata class.
2837 
2838   @return 0 if everything went fine, 1 otherwise.
2839 */
write_ignored_events_info_to_relay_log(THD * thd,Master_info * mi)2840 static int write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
2841 {
2842   Relay_log_info *rli= mi->rli;
2843   mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
2844   int error= 0;
2845   DBUG_ENTER("write_ignored_events_info_to_relay_log");
2846 
2847   DBUG_ASSERT(thd == mi->info_thd);
2848   mysql_mutex_assert_owner(&mi->data_lock);
2849   mysql_mutex_lock(log_lock);
2850   if (rli->ign_master_log_name_end[0])
2851   {
2852     DBUG_PRINT("info",("writing a Rotate event to track down ignored events"));
2853     Rotate_log_event *ev= new Rotate_log_event(rli->ign_master_log_name_end,
2854                                                0, rli->ign_master_log_pos_end,
2855                                                Rotate_log_event::DUP_NAME);
2856     if (mi->get_mi_description_event() != NULL)
2857       ev->checksum_alg= mi->get_mi_description_event()->checksum_alg;
2858 
2859     rli->ign_master_log_name_end[0]= 0;
2860     /* can unlock before writing as slave SQL thd will soon see our Rotate */
2861     mysql_mutex_unlock(log_lock);
2862     if (likely((bool)ev))
2863     {
2864       ev->server_id= 0; // don't be ignored by slave SQL thread
2865       if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
2866         mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
2867                    ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
2868                    "failed to write a Rotate event"
2869                    " to the relay log, SHOW SLAVE STATUS may be"
2870                    " inaccurate");
2871       rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
2872       if (flush_master_info(mi, TRUE))
2873       {
2874         error= 1;
2875         sql_print_error("Failed to flush master info file.");
2876       }
2877       delete ev;
2878     }
2879     else
2880     {
2881       error= 1;
2882       mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE,
2883                  ER(ER_SLAVE_CREATE_EVENT_FAILURE),
2884                  "Rotate_event (out of memory?),"
2885                  " SHOW SLAVE STATUS may be inaccurate");
2886     }
2887   }
2888   else
2889     mysql_mutex_unlock(log_lock);
2890 
2891   DBUG_RETURN(error);
2892 }
2893 
2894 
register_slave_on_master(MYSQL * mysql,Master_info * mi,bool * suppress_warnings)2895 int register_slave_on_master(MYSQL* mysql, Master_info *mi,
2896                              bool *suppress_warnings)
2897 {
2898   uchar buf[1024], *pos= buf;
2899   uint report_host_len=0, report_user_len=0, report_password_len=0;
2900   DBUG_ENTER("register_slave_on_master");
2901 
2902   *suppress_warnings= FALSE;
2903   if (report_host)
2904     report_host_len= strlen(report_host);
2905   if (report_host_len > HOSTNAME_LENGTH)
2906   {
2907     sql_print_warning("The length of report_host is %d. "
2908                       "It is larger than the max length(%d), so this "
2909                       "slave cannot be registered to the master.",
2910                       report_host_len, HOSTNAME_LENGTH);
2911     DBUG_RETURN(0);
2912   }
2913 
2914   if (report_user)
2915     report_user_len= strlen(report_user);
2916   if (report_user_len > USERNAME_LENGTH)
2917   {
2918     sql_print_warning("The length of report_user is %d. "
2919                       "It is larger than the max length(%d), so this "
2920                       "slave cannot be registered to the master.",
2921                       report_user_len, USERNAME_LENGTH);
2922     DBUG_RETURN(0);
2923   }
2924 
2925   if (report_password)
2926     report_password_len= strlen(report_password);
2927   if (report_password_len > MAX_PASSWORD_LENGTH)
2928   {
2929     sql_print_warning("The length of report_password is %d. "
2930                       "It is larger than the max length(%d), so this "
2931                       "slave cannot be registered to the master.",
2932                       report_password_len, MAX_PASSWORD_LENGTH);
2933     DBUG_RETURN(0);
2934   }
2935 
2936   int4store(pos, server_id); pos+= 4;
2937   pos= net_store_data(pos, (uchar*) report_host, report_host_len);
2938   pos= net_store_data(pos, (uchar*) report_user, report_user_len);
2939   pos= net_store_data(pos, (uchar*) report_password, report_password_len);
2940   int2store(pos, (uint16) report_port); pos+= 2;
2941   /*
2942     Fake rpl_recovery_rank, which was removed in BUG#13963,
2943     so that this server can register itself on old servers,
2944     see BUG#49259.
2945    */
2946   int4store(pos, /* rpl_recovery_rank */ 0);    pos+= 4;
2947   /* The master will fill in master_id */
2948   int4store(pos, 0);                    pos+= 4;
2949 
2950   if (simple_command(mysql, COM_REGISTER_SLAVE, buf, (size_t) (pos- buf), 0))
2951   {
2952     if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
2953     {
2954       *suppress_warnings= TRUE;                 // Suppress reconnect warning
2955     }
2956     else if (!check_io_slave_killed(mi->info_thd, mi, NULL))
2957     {
2958       char buf[256];
2959       my_snprintf(buf, sizeof(buf), "%s (Errno: %d)", mysql_error(mysql),
2960                   mysql_errno(mysql));
2961       mi->report(ERROR_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
2962                  ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_REGISTER_SLAVE", buf);
2963     }
2964     DBUG_RETURN(1);
2965   }
2966 
2967   DBUG_EXECUTE_IF("simulate_register_slave_killed", {
2968     mi->abort_slave = 1;
2969     DBUG_RETURN(1);
2970   };);
2971 
2972   DBUG_RETURN(0);
2973 }
2974 
2975 
2976 /**
2977   Execute a SHOW SLAVE STATUS statement.
2978 
2979   @param thd Pointer to THD object for the client thread executing the
2980   statement.
2981 
2982   @param mi Pointer to Master_info object for the IO thread.
2983 
2984   @retval FALSE success
2985   @retval TRUE failure
2986 */
show_slave_status(THD * thd,Master_info * mi)2987 bool show_slave_status(THD* thd, Master_info* mi)
2988 {
2989   // TODO: fix this for multi-master
2990   List<Item> field_list;
2991   Protocol *protocol= thd->protocol;
2992   char *slave_sql_running_state= NULL;
2993   char *sql_gtid_set_buffer= NULL, *io_gtid_set_buffer= NULL;
2994   int sql_gtid_set_size= 0, io_gtid_set_size= 0;
2995   DBUG_ENTER("show_slave_status");
2996 
2997   if (mi != NULL)
2998   {
2999     global_sid_lock->wrlock();
3000     const Gtid_set* sql_gtid_set= gtid_state->get_logged_gtids();
3001     const Gtid_set* io_gtid_set= mi->rli->get_gtid_set();
3002     if ((sql_gtid_set_size= sql_gtid_set->to_string(&sql_gtid_set_buffer)) < 0 ||
3003         (io_gtid_set_size= io_gtid_set->to_string(&io_gtid_set_buffer)) < 0)
3004     {
3005       my_eof(thd);
3006       my_free(sql_gtid_set_buffer);
3007       my_free(io_gtid_set_buffer);
3008       global_sid_lock->unlock();
3009       DBUG_RETURN(true);
3010     }
3011     global_sid_lock->unlock();
3012   }
3013 
3014   field_list.push_back(new Item_empty_string("Slave_IO_State",
3015                                                      14));
3016   field_list.push_back(new Item_empty_string("Master_Host", mi != NULL ?
3017                                                      sizeof(mi->host) : 0));
3018   field_list.push_back(new Item_empty_string("Master_User", mi != NULL ?
3019                                                      mi->get_user_size() : 0));
3020   field_list.push_back(new Item_return_int("Master_Port", 7,
3021                                            MYSQL_TYPE_LONG));
3022   field_list.push_back(new Item_return_int("Connect_Retry", 10,
3023                                            MYSQL_TYPE_LONG));
3024   field_list.push_back(new Item_empty_string("Master_Log_File",
3025                                              FN_REFLEN));
3026   field_list.push_back(new Item_return_int("Read_Master_Log_Pos", 10,
3027                                            MYSQL_TYPE_LONGLONG));
3028   field_list.push_back(new Item_empty_string("Relay_Log_File",
3029                                              FN_REFLEN));
3030   field_list.push_back(new Item_return_int("Relay_Log_Pos", 10,
3031                                            MYSQL_TYPE_LONGLONG));
3032   field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
3033                                              FN_REFLEN));
3034   field_list.push_back(new Item_empty_string("Slave_IO_Running", 3));
3035   field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3));
3036   field_list.push_back(new Item_empty_string("Replicate_Do_DB", 20));
3037   field_list.push_back(new Item_empty_string("Replicate_Ignore_DB", 20));
3038   field_list.push_back(new Item_empty_string("Replicate_Do_Table", 20));
3039   field_list.push_back(new Item_empty_string("Replicate_Ignore_Table", 23));
3040   field_list.push_back(new Item_empty_string("Replicate_Wild_Do_Table", 24));
3041   field_list.push_back(new Item_empty_string("Replicate_Wild_Ignore_Table",
3042                                              28));
3043   field_list.push_back(new Item_return_int("Last_Errno", 4, MYSQL_TYPE_LONG));
3044   field_list.push_back(new Item_empty_string("Last_Error", 20));
3045   field_list.push_back(new Item_return_int("Skip_Counter", 10,
3046                                            MYSQL_TYPE_LONG));
3047   field_list.push_back(new Item_return_int("Exec_Master_Log_Pos", 10,
3048                                            MYSQL_TYPE_LONGLONG));
3049   field_list.push_back(new Item_return_int("Relay_Log_Space", 10,
3050                                            MYSQL_TYPE_LONGLONG));
3051   field_list.push_back(new Item_empty_string("Until_Condition", 6));
3052   field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN));
3053   field_list.push_back(new Item_return_int("Until_Log_Pos", 10,
3054                                            MYSQL_TYPE_LONGLONG));
3055   field_list.push_back(new Item_empty_string("Master_SSL_Allowed", 7));
3056   field_list.push_back(new Item_empty_string("Master_SSL_CA_File", mi != NULL ?
3057                                              sizeof(mi->ssl_ca) : 0));
3058   field_list.push_back(new Item_empty_string("Master_SSL_CA_Path", mi != NULL ?
3059                                              sizeof(mi->ssl_capath) : 0));
3060   field_list.push_back(new Item_empty_string("Master_SSL_Cert", mi != NULL ?
3061                                              sizeof(mi->ssl_cert) : 0));
3062   field_list.push_back(new Item_empty_string("Master_SSL_Cipher", mi != NULL ?
3063                                              sizeof(mi->ssl_cipher) : 0));
3064   field_list.push_back(new Item_empty_string("Master_SSL_Key", mi != NULL ?
3065                                              sizeof(mi->ssl_key) : 0));
3066   field_list.push_back(new Item_return_int("Seconds_Behind_Master", 10,
3067                                            MYSQL_TYPE_LONGLONG));
3068   field_list.push_back(new Item_empty_string("Master_SSL_Verify_Server_Cert",
3069                                              3));
3070   field_list.push_back(new Item_return_int("Last_IO_Errno", 4, MYSQL_TYPE_LONG));
3071   field_list.push_back(new Item_empty_string("Last_IO_Error", 20));
3072   field_list.push_back(new Item_return_int("Last_SQL_Errno", 4, MYSQL_TYPE_LONG));
3073   field_list.push_back(new Item_empty_string("Last_SQL_Error", 20));
3074   field_list.push_back(new Item_empty_string("Replicate_Ignore_Server_Ids",
3075                                              FN_REFLEN));
3076   field_list.push_back(new Item_return_int("Master_Server_Id", sizeof(ulong),
3077                                            MYSQL_TYPE_LONG));
3078   field_list.push_back(new Item_empty_string("Master_UUID", UUID_LENGTH));
3079   field_list.push_back(new Item_empty_string("Master_Info_File",
3080                                              2 * FN_REFLEN));
3081   field_list.push_back(new Item_return_int("SQL_Delay", 10, MYSQL_TYPE_LONG));
3082   field_list.push_back(new Item_return_int("SQL_Remaining_Delay", 8, MYSQL_TYPE_LONG));
3083   field_list.push_back(new Item_empty_string("Slave_SQL_Running_State", 20));
3084   field_list.push_back(new Item_return_int("Master_Retry_Count", 10,
3085                                            MYSQL_TYPE_LONGLONG));
3086   field_list.push_back(new Item_empty_string("Master_Bind", mi != NULL ?
3087                                              sizeof(mi->bind_addr) : 0));
3088   field_list.push_back(new Item_empty_string("Last_IO_Error_Timestamp", 20));
3089   field_list.push_back(new Item_empty_string("Last_SQL_Error_Timestamp", 20));
3090   field_list.push_back(new Item_empty_string("Master_SSL_Crl", mi != NULL ?
3091                                              sizeof(mi->ssl_crl) : 0));
3092   field_list.push_back(new Item_empty_string("Master_SSL_Crlpath", mi != NULL ?
3093                                              sizeof(mi->ssl_crlpath) : 0));
3094   field_list.push_back(new Item_empty_string("Retrieved_Gtid_Set",
3095                                              io_gtid_set_size));
3096   field_list.push_back(new Item_empty_string("Executed_Gtid_Set",
3097                                              sql_gtid_set_size));
3098   field_list.push_back(new Item_return_int("Auto_Position", sizeof(ulong),
3099                                            MYSQL_TYPE_LONG));
3100 
3101   if (protocol->send_result_set_metadata(&field_list,
3102                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
3103   {
3104     my_free(sql_gtid_set_buffer);
3105     my_free(io_gtid_set_buffer);
3106     DBUG_RETURN(true);
3107   }
3108 
3109   if (mi != NULL && mi->host[0])
3110   {
3111     DBUG_PRINT("info",("host is set: '%s'", mi->host));
3112     String *packet= &thd->packet;
3113     protocol->prepare_for_resend();
3114 
3115     /*
3116       slave_running can be accessed without run_lock but not other
3117       non-volotile members like mi->info_thd, which is guarded by the mutex.
3118     */
3119     mysql_mutex_lock(&mi->run_lock);
3120     protocol->store(mi->info_thd ? mi->info_thd->get_proc_info() : "", &my_charset_bin);
3121     mysql_mutex_unlock(&mi->run_lock);
3122 
3123     mysql_mutex_lock(&mi->rli->run_lock);
3124     slave_sql_running_state= const_cast<char *>(mi->rli->info_thd ? mi->rli->info_thd->get_proc_info() : "");
3125     mysql_mutex_unlock(&mi->rli->run_lock);
3126 
3127     mysql_mutex_lock(&mi->data_lock);
3128     mysql_mutex_lock(&mi->rli->data_lock);
3129     mysql_mutex_lock(&mi->err_lock);
3130     mysql_mutex_lock(&mi->rli->err_lock);
3131 
3132     DEBUG_SYNC(thd, "wait_after_lock_active_mi_and_rli_data_lock_is_acquired");
3133     protocol->store(mi->host, &my_charset_bin);
3134     protocol->store(mi->get_user(), &my_charset_bin);
3135     protocol->store((uint32) mi->port);
3136     protocol->store((uint32) mi->connect_retry);
3137     protocol->store(mi->get_master_log_name(), &my_charset_bin);
3138     protocol->store((ulonglong) mi->get_master_log_pos());
3139     protocol->store(mi->rli->get_group_relay_log_name() +
3140                     dirname_length(mi->rli->get_group_relay_log_name()),
3141                     &my_charset_bin);
3142     protocol->store((ulonglong) mi->rli->get_group_relay_log_pos());
3143     protocol->store(mi->rli->get_group_master_log_name(), &my_charset_bin);
3144     protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
3145                     "Yes" : (mi->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT ?
3146                              "Connecting" : "No"), &my_charset_bin);
3147     protocol->store(mi->rli->slave_running ? "Yes":"No", &my_charset_bin);
3148     protocol->store(rpl_filter->get_do_db());
3149     protocol->store(rpl_filter->get_ignore_db());
3150 
3151     char buf[256];
3152     String tmp(buf, sizeof(buf), &my_charset_bin);
3153     rpl_filter->get_do_table(&tmp);
3154     protocol->store(&tmp);
3155     rpl_filter->get_ignore_table(&tmp);
3156     protocol->store(&tmp);
3157     rpl_filter->get_wild_do_table(&tmp);
3158     protocol->store(&tmp);
3159     rpl_filter->get_wild_ignore_table(&tmp);
3160     protocol->store(&tmp);
3161 
3162     protocol->store(mi->rli->last_error().number);
3163     protocol->store(mi->rli->last_error().message, &my_charset_bin);
3164     protocol->store((uint32) mi->rli->slave_skip_counter);
3165     protocol->store((ulonglong) mi->rli->get_group_master_log_pos());
3166     protocol->store((ulonglong) mi->rli->log_space_total);
3167 
3168     const char *until_type= "";
3169 
3170     switch (mi->rli->until_condition)
3171     {
3172     case Relay_log_info::UNTIL_NONE:
3173       until_type= "None";
3174       break;
3175     case Relay_log_info::UNTIL_MASTER_POS:
3176       until_type= "Master";
3177       break;
3178     case Relay_log_info::UNTIL_RELAY_POS:
3179       until_type= "Relay";
3180       break;
3181     case Relay_log_info::UNTIL_SQL_BEFORE_GTIDS:
3182       until_type= "SQL_BEFORE_GTIDS";
3183       break;
3184     case Relay_log_info::UNTIL_SQL_AFTER_GTIDS:
3185       until_type= "SQL_AFTER_GTIDS";
3186       break;
3187     case Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS:
3188       until_type= "SQL_AFTER_MTS_GAPS";
3189     case Relay_log_info::UNTIL_DONE:
3190       until_type= "DONE";
3191       break;
3192     default:
3193       DBUG_ASSERT(0);
3194     }
3195     protocol->store(until_type, &my_charset_bin);
3196     protocol->store(mi->rli->until_log_name, &my_charset_bin);
3197     protocol->store((ulonglong) mi->rli->until_log_pos);
3198 
3199 #ifdef HAVE_OPENSSL
3200     protocol->store(mi->ssl? "Yes":"No", &my_charset_bin);
3201 #else
3202     protocol->store(mi->ssl? "Ignored":"No", &my_charset_bin);
3203 #endif
3204     protocol->store(mi->ssl_ca, &my_charset_bin);
3205     protocol->store(mi->ssl_capath, &my_charset_bin);
3206     protocol->store(mi->ssl_cert, &my_charset_bin);
3207     protocol->store(mi->ssl_cipher, &my_charset_bin);
3208     protocol->store(mi->ssl_key, &my_charset_bin);
3209 
3210     /*
3211       The pseudo code to compute Seconds_Behind_Master:
3212         if (SQL thread is running)
3213         {
3214           if (SQL thread processed all the available relay log)
3215           {
3216             if (IO thread is running)
3217               print 0;
3218             else
3219               print NULL;
3220           }
3221           else
3222             compute Seconds_Behind_Master;
3223         }
3224         else
3225           print NULL;
3226     */
3227     if (mi->rli->slave_running)
3228     {
3229       /* Check if SQL thread is at the end of relay log
3230            Checking should be done using two conditions
3231            condition1: compare the log positions and
3232            condition2: compare the file names (to handle rotation case)
3233       */
3234       if ((mi->get_master_log_pos() == mi->rli->get_group_master_log_pos()) &&
3235            (!strcmp(mi->get_master_log_name(), mi->rli->get_group_master_log_name())))
3236       {
3237         if (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT)
3238           protocol->store(0LL);
3239         else
3240           protocol->store_null();
3241       }
3242       else
3243       {
3244         long time_diff= ((long)(time(0) - mi->rli->last_master_timestamp)
3245                                 - mi->clock_diff_with_master);
3246       /*
3247         Apparently on some systems time_diff can be <0. Here are possible
3248         reasons related to MySQL:
3249         - the master is itself a slave of another master whose time is ahead.
3250         - somebody used an explicit SET TIMESTAMP on the master.
3251         Possible reason related to granularity-to-second of time functions
3252         (nothing to do with MySQL), which can explain a value of -1:
3253         assume the master's and slave's time are perfectly synchronized, and
3254         that at slave's connection time, when the master's timestamp is read,
3255         it is at the very end of second 1, and (a very short time later) when
3256         the slave's timestamp is read it is at the very beginning of second
3257         2. Then the recorded value for master is 1 and the recorded value for
3258         slave is 2. At SHOW SLAVE STATUS time, assume that the difference
3259         between timestamp of slave and rli->last_master_timestamp is 0
3260         (i.e. they are in the same second), then we get 0-(2-1)=-1 as a result.
3261         This confuses users, so we don't go below 0: hence the max().
3262 
3263         last_master_timestamp == 0 (an "impossible" timestamp 1970) is a
3264         special marker to say "consider we have caught up".
3265       */
3266         protocol->store((longlong)(mi->rli->last_master_timestamp ?
3267                                    max(0L, time_diff) : 0));
3268       }
3269     }
3270     else
3271     {
3272       protocol->store_null();
3273     }
3274     protocol->store(mi->ssl_verify_server_cert? "Yes":"No", &my_charset_bin);
3275 
3276     // Last_IO_Errno
3277     protocol->store(mi->last_error().number);
3278     // Last_IO_Error
3279     protocol->store(mi->last_error().message, &my_charset_bin);
3280     // Last_SQL_Errno
3281     protocol->store(mi->rli->last_error().number);
3282     // Last_SQL_Error
3283     protocol->store(mi->rli->last_error().message, &my_charset_bin);
3284     // Replicate_Ignore_Server_Ids
3285     {
3286       char buff[FN_REFLEN];
3287       ulong i, cur_len;
3288       for (i= 0, buff[0]= 0, cur_len= 0;
3289            i < mi->ignore_server_ids->dynamic_ids.elements; i++)
3290       {
3291         ulong s_id, slen;
3292         char sbuff[FN_REFLEN];
3293         get_dynamic(&(mi->ignore_server_ids->dynamic_ids), (uchar*) &s_id, i);
3294         slen= sprintf(sbuff, (i == 0 ? "%lu" : ", %lu"), s_id);
3295         if (cur_len + slen + 4 > FN_REFLEN)
3296         {
3297           /*
3298             break the loop whenever remained space could not fit
3299             ellipses on the next cycle
3300           */
3301           sprintf(buff + cur_len, "...");
3302           break;
3303         }
3304         cur_len += sprintf(buff + cur_len, "%s", sbuff);
3305       }
3306       protocol->store(buff, &my_charset_bin);
3307     }
3308     // Master_Server_id
3309     protocol->store((uint32) mi->master_id);
3310     protocol->store(mi->master_uuid, &my_charset_bin);
3311     // Master_Info_File
3312     protocol->store(mi->get_description_info(), &my_charset_bin);
3313     // SQL_Delay
3314     protocol->store((uint32) mi->rli->get_sql_delay());
3315     // SQL_Remaining_Delay
3316     if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name)
3317     {
3318       time_t t= my_time(0), sql_delay_end= mi->rli->get_sql_delay_end();
3319       protocol->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0));
3320     }
3321     else
3322       protocol->store_null();
3323     // Slave_SQL_Running_State
3324     protocol->store(slave_sql_running_state, &my_charset_bin);
3325     // Master_Retry_Count
3326     protocol->store((ulonglong) mi->retry_count);
3327     // Master_Bind
3328     protocol->store(mi->bind_addr, &my_charset_bin);
3329     // Last_IO_Error_Timestamp
3330     protocol->store(mi->last_error().timestamp, &my_charset_bin);
3331     // Last_SQL_Error_Timestamp
3332     protocol->store(mi->rli->last_error().timestamp, &my_charset_bin);
3333     // Master_Ssl_Crl
3334     protocol->store(mi->ssl_crl, &my_charset_bin);
3335     // Master_Ssl_Crlpath
3336     protocol->store(mi->ssl_crlpath, &my_charset_bin);
3337     // Retrieved_Gtid_Set
3338     protocol->store(io_gtid_set_buffer, &my_charset_bin);
3339     // Executed_Gtid_Set
3340     protocol->store(sql_gtid_set_buffer, &my_charset_bin);
3341     // Auto_Position
3342     protocol->store(mi->is_auto_position() ? 1 : 0);
3343 
3344     mysql_mutex_unlock(&mi->rli->err_lock);
3345     mysql_mutex_unlock(&mi->err_lock);
3346     mysql_mutex_unlock(&mi->rli->data_lock);
3347     mysql_mutex_unlock(&mi->data_lock);
3348 
3349     if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(), packet->length()))
3350     {
3351       my_free(sql_gtid_set_buffer);
3352       my_free(io_gtid_set_buffer);
3353       DBUG_RETURN(true);
3354     }
3355   }
3356   my_eof(thd);
3357   my_free(sql_gtid_set_buffer);
3358   my_free(io_gtid_set_buffer);
3359   DBUG_RETURN(false);
3360 }
3361 
3362 
set_slave_thread_options(THD * thd)3363 void set_slave_thread_options(THD* thd)
3364 {
3365   DBUG_ENTER("set_slave_thread_options");
3366   /*
3367      It's nonsense to constrain the slave threads with max_join_size; if a
3368      query succeeded on master, we HAVE to execute it. So set
3369      OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
3370      (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
3371      SELECT examining more than 4 billion rows would still fail (yes, because
3372      when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
3373      only for client threads.
3374   */
3375   ulonglong options= thd->variables.option_bits | OPTION_BIG_SELECTS;
3376   if (opt_log_slave_updates)
3377     options|= OPTION_BIN_LOG;
3378   else
3379     options&= ~OPTION_BIN_LOG;
3380   thd->variables.option_bits= options;
3381   thd->variables.completion_type= 0;
3382 
3383   /*
3384     Set autocommit= 1 when info tables are used and autocommit == 0 to
3385     avoid trigger asserts on mysql_execute_command(THD *thd) caused by
3386     info tables updates which do not commit, like Rotate, Stop and
3387     skipped events handling.
3388   */
3389   if (is_autocommit_off_and_infotables(thd))
3390   {
3391     thd->variables.option_bits|= OPTION_AUTOCOMMIT;
3392     thd->variables.option_bits&= ~OPTION_NOT_AUTOCOMMIT;
3393     thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
3394   }
3395 
3396   DBUG_VOID_RETURN;
3397 }
3398 
set_slave_thread_default_charset(THD * thd,Relay_log_info const * rli)3399 void set_slave_thread_default_charset(THD* thd, Relay_log_info const *rli)
3400 {
3401   DBUG_ENTER("set_slave_thread_default_charset");
3402 
3403   thd->variables.character_set_client=
3404     global_system_variables.character_set_client;
3405   thd->variables.collation_connection=
3406     global_system_variables.collation_connection;
3407   thd->variables.collation_server=
3408     global_system_variables.collation_server;
3409   thd->update_charset();
3410 
3411   /*
3412     We use a const cast here since the conceptual (and externally
3413     visible) behavior of the function is to set the default charset of
3414     the thread.  That the cache has to be invalidated is a secondary
3415     effect.
3416    */
3417   const_cast<Relay_log_info*>(rli)->cached_charset_invalidate();
3418   DBUG_VOID_RETURN;
3419 }
3420 
3421 /*
3422   init_slave_thread()
3423 */
3424 
init_slave_thread(THD * thd,SLAVE_THD_TYPE thd_type)3425 static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
3426 {
3427   DBUG_ENTER("init_slave_thread");
3428 #if !defined(DBUG_OFF)
3429   int simulate_error= 0;
3430 #endif
3431   thd->system_thread= (thd_type == SLAVE_THD_WORKER) ?
3432     SYSTEM_THREAD_SLAVE_WORKER : (thd_type == SLAVE_THD_SQL) ?
3433     SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
3434   thd->security_ctx->skip_grants();
3435   my_net_init(&thd->net, 0);
3436   thd->slave_thread = 1;
3437   thd->enable_slow_log= opt_log_slow_slave_statements;
3438   set_slave_thread_options(thd);
3439   mysql_mutex_lock(&LOCK_thread_count);
3440   thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
3441   mysql_mutex_unlock(&LOCK_thread_count);
3442 
3443   DBUG_EXECUTE_IF("simulate_io_slave_error_on_init",
3444                   simulate_error|= (1 << SLAVE_THD_IO););
3445   DBUG_EXECUTE_IF("simulate_sql_slave_error_on_init",
3446                   simulate_error|= (1 << SLAVE_THD_SQL););
3447 #if !defined(DBUG_OFF)
3448   if (init_thr_lock() || thd->store_globals() || simulate_error & (1<< thd_type))
3449 #else
3450   if (init_thr_lock() || thd->store_globals())
3451 #endif
3452   {
3453     DBUG_RETURN(-1);
3454   }
3455 
3456   if (thd_type == SLAVE_THD_SQL)
3457   {
3458     THD_STAGE_INFO(thd, stage_waiting_for_the_next_event_in_relay_log);
3459   }
3460   else
3461   {
3462     THD_STAGE_INFO(thd, stage_waiting_for_master_update);
3463   }
3464   thd->set_time();
3465   /* Do not use user-supplied timeout value for system threads. */
3466   thd->variables.lock_wait_timeout= LONG_TIMEOUT;
3467   DBUG_RETURN(0);
3468 }
3469 
3470 
3471 /**
3472   Sleep for a given amount of time or until killed.
3473 
3474   @param thd        Thread context of the current thread.
3475   @param seconds    The number of seconds to sleep.
3476   @param func       Function object to check if the thread has been killed.
3477   @param info       The Rpl_info object associated with this sleep.
3478 
3479   @retval True if the thread has been killed, false otherwise.
3480 */
3481 template <typename killed_func, typename rpl_info>
slave_sleep(THD * thd,time_t seconds,killed_func func,rpl_info info)3482 static inline bool slave_sleep(THD *thd, time_t seconds,
3483                                killed_func func, rpl_info info)
3484 {
3485   bool ret;
3486   struct timespec abstime;
3487   mysql_mutex_t *lock= &info->sleep_lock;
3488   mysql_cond_t *cond= &info->sleep_cond;
3489 
3490   /* Absolute system time at which the sleep time expires. */
3491   set_timespec(abstime, seconds);
3492 
3493   mysql_mutex_lock(lock);
3494   thd->ENTER_COND(cond, lock, NULL, NULL);
3495 
3496   while (! (ret= func(thd, info)))
3497   {
3498     int error= mysql_cond_timedwait(cond, lock, &abstime);
3499     if (error == ETIMEDOUT || error == ETIME)
3500       break;
3501   }
3502 
3503   /* Implicitly unlocks the mutex. */
3504   thd->EXIT_COND(NULL);
3505 
3506   return ret;
3507 }
3508 
request_dump(THD * thd,MYSQL * mysql,Master_info * mi,bool * suppress_warnings)3509 static int request_dump(THD *thd, MYSQL* mysql, Master_info* mi,
3510                         bool *suppress_warnings)
3511 {
3512   DBUG_ENTER("request_dump");
3513 
3514   const int BINLOG_NAME_INFO_SIZE= strlen(mi->get_master_log_name());
3515   int error= 1;
3516   size_t command_size= 0;
3517   enum_server_command command= mi->is_auto_position() ?
3518     COM_BINLOG_DUMP_GTID : COM_BINLOG_DUMP;
3519   uchar* command_buffer= NULL;
3520   ushort binlog_flags= 0;
3521 
3522   if (RUN_HOOK(binlog_relay_io,
3523                before_request_transmit,
3524                (thd, mi, binlog_flags)))
3525     goto err;
3526 
3527   *suppress_warnings= false;
3528   if (command == COM_BINLOG_DUMP_GTID)
3529   {
3530     // get set of GTIDs
3531     Sid_map sid_map(NULL/*no lock needed*/);
3532     Gtid_set gtid_executed(&sid_map);
3533     global_sid_lock->wrlock();
3534     gtid_state->dbug_print();
3535 
3536     /*
3537       We are unsure whether I/O thread retrieved the last gtid transaction
3538       completely or not (before it is going down because of a crash/normal
3539       shutdown/normal stop slave io_thread). It is possible that I/O thread
3540       would have retrieved and written only partial transaction events. So We
3541       request Master to send the last gtid event once again. We do this by
3542       removing the last I/O thread retrieved gtid event from
3543       "Retrieved_gtid_set".  Possible cases: 1) I/O thread would have
3544       retrieved full transaction already in the first time itself, but
3545       retrieving them again will not cause problem because GTID number is
3546       same, Hence SQL thread will not commit it again. 2) I/O thread would
3547       have retrieved full transaction already and SQL thread would have
3548       already executed it. In that case, We are not going remove last
3549       retrieved gtid from "Retrieved_gtid_set" otherwise we will see gaps in
3550       "Retrieved set". The same case is handled in the below code.  Please
3551       note there will be paritial transactions written in relay log but they
3552       will not cause any problem incase of transactional tables.  But incase
3553       of non-transaction tables, partial trx will create inconsistency
3554       between master and slave.  In that case, users need to check manually.
3555     */
3556 
3557     Gtid_set * retrieved_set= (const_cast<Gtid_set *>(mi->rli->get_gtid_set()));
3558     Gtid *last_retrieved_gtid= mi->rli->get_last_retrieved_gtid();
3559 
3560     /*
3561       Remove last_retrieved_gtid only if it is not part of
3562       executed_gtid_set
3563     */
3564     if (!last_retrieved_gtid->empty() &&
3565         !gtid_state->get_logged_gtids()->contains_gtid(*last_retrieved_gtid))
3566     {
3567       if (retrieved_set->_remove_gtid(*last_retrieved_gtid) != RETURN_STATUS_OK)
3568       {
3569         global_sid_lock->unlock();
3570         goto err;
3571       }
3572     }
3573 
3574     if (gtid_executed.add_gtid_set(mi->rli->get_gtid_set()) != RETURN_STATUS_OK ||
3575         gtid_executed.add_gtid_set(gtid_state->get_logged_gtids()) !=
3576         RETURN_STATUS_OK)
3577     {
3578       global_sid_lock->unlock();
3579       goto err;
3580     }
3581     global_sid_lock->unlock();
3582 
3583     // allocate buffer
3584     size_t encoded_data_size= gtid_executed.get_encoded_length();
3585     size_t allocation_size=
3586       ::BINLOG_FLAGS_INFO_SIZE + ::BINLOG_SERVER_ID_INFO_SIZE +
3587       ::BINLOG_NAME_SIZE_INFO_SIZE + BINLOG_NAME_INFO_SIZE +
3588       ::BINLOG_POS_INFO_SIZE + ::BINLOG_DATA_SIZE_INFO_SIZE +
3589       encoded_data_size + 1;
3590     if (!(command_buffer= (uchar *) my_malloc(allocation_size, MYF(MY_WME))))
3591       goto err;
3592     uchar* ptr_buffer= command_buffer;
3593 
3594     DBUG_PRINT("info", ("Do I know something about the master? (binary log's name %s - auto position %d).",
3595                mi->get_master_log_name(), mi->is_auto_position()));
3596     /*
3597       Note: binlog_flags is always 0.  However, in versions up to 5.6
3598       RC, the master would check the lowest bit and do something
3599       unexpected if it was set; in early versions of 5.6 it would also
3600       use the two next bits.  Therefore, for backward compatibility,
3601       if we ever start to use the flags, we should leave the three
3602       lowest bits unused.
3603     */
3604     int2store(ptr_buffer, binlog_flags);
3605     ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE;
3606     int4store(ptr_buffer, server_id);
3607     ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE;
3608     int4store(ptr_buffer, BINLOG_NAME_INFO_SIZE);
3609     ptr_buffer+= ::BINLOG_NAME_SIZE_INFO_SIZE;
3610     memset(ptr_buffer, 0, BINLOG_NAME_INFO_SIZE);
3611     ptr_buffer+= BINLOG_NAME_INFO_SIZE;
3612     int8store(ptr_buffer, 4LL);
3613     ptr_buffer+= ::BINLOG_POS_INFO_SIZE;
3614 
3615     int4store(ptr_buffer, encoded_data_size);
3616     ptr_buffer+= ::BINLOG_DATA_SIZE_INFO_SIZE;
3617     gtid_executed.encode(ptr_buffer);
3618     ptr_buffer+= encoded_data_size;
3619 
3620     command_size= ptr_buffer - command_buffer;
3621     DBUG_ASSERT(command_size == (allocation_size - 1));
3622   }
3623   else
3624   {
3625     size_t allocation_size= ::BINLOG_POS_OLD_INFO_SIZE +
3626       BINLOG_NAME_INFO_SIZE + ::BINLOG_FLAGS_INFO_SIZE +
3627       ::BINLOG_SERVER_ID_INFO_SIZE + 1;
3628     if (!(command_buffer= (uchar *) my_malloc(allocation_size, MYF(MY_WME))))
3629       goto err;
3630     uchar* ptr_buffer= command_buffer;
3631 
3632     int4store(ptr_buffer, mi->get_master_log_pos());
3633     ptr_buffer+= ::BINLOG_POS_OLD_INFO_SIZE;
3634     // See comment regarding binlog_flags above.
3635     int2store(ptr_buffer, binlog_flags);
3636     ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE;
3637     int4store(ptr_buffer, server_id);
3638     ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE;
3639     memcpy(ptr_buffer, mi->get_master_log_name(), BINLOG_NAME_INFO_SIZE);
3640     ptr_buffer+= BINLOG_NAME_INFO_SIZE;
3641 
3642     command_size= ptr_buffer - command_buffer;
3643     DBUG_ASSERT(command_size == (allocation_size - 1));
3644   }
3645 
3646   if (simple_command(mysql, command, command_buffer, command_size, 1))
3647   {
3648     /*
3649       Something went wrong, so we will just reconnect and retry later
3650       in the future, we should do a better error analysis, but for
3651       now we just fill up the error log :-)
3652     */
3653     if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
3654       *suppress_warnings= true;                 // Suppress reconnect warning
3655     else
3656       sql_print_error("Error on %s: %d  %s, will retry in %d secs",
3657                       command_name[command].str,
3658                       mysql_errno(mysql), mysql_error(mysql),
3659                       mi->connect_retry);
3660     goto err;
3661   }
3662   error= 0;
3663 
3664 err:
3665   my_free(command_buffer);
3666   DBUG_RETURN(error);
3667 }
3668 
3669 
3670 /*
3671   Read one event from the master
3672 
3673   SYNOPSIS
3674     read_event()
3675     mysql               MySQL connection
3676     mi                  Master connection information
3677     suppress_warnings   TRUE when a normal net read timeout has caused us to
3678                         try a reconnect.  We do not want to print anything to
3679                         the error log in this case because this a anormal
3680                         event in an idle server.
3681 
3682     RETURN VALUES
3683     'packet_error'      Error
3684     number              Length of packet
3685 */
3686 
read_event(MYSQL * mysql,Master_info * mi,bool * suppress_warnings)3687 static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings)
3688 {
3689   ulong len;
3690   DBUG_ENTER("read_event");
3691 
3692   *suppress_warnings= FALSE;
3693   /*
3694     my_real_read() will time us out
3695     We check if we were told to die, and if not, try reading again
3696   */
3697 #ifndef DBUG_OFF
3698   if (disconnect_slave_event_count && !(mi->events_until_exit--))
3699     DBUG_RETURN(packet_error);
3700 #endif
3701 
3702   len = cli_safe_read(mysql);
3703   if (len == packet_error || (long) len < 1)
3704   {
3705     if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
3706     {
3707       /*
3708         We are trying a normal reconnect after a read timeout;
3709         we suppress prints to .err file as long as the reconnect
3710         happens without problems
3711       */
3712       *suppress_warnings= TRUE;
3713     }
3714     else
3715     {
3716       if (!mi->abort_slave)
3717       {
3718         sql_print_error("Error reading packet from server: %s (server_errno=%d)",
3719                         mysql_error(mysql), mysql_errno(mysql));
3720       }
3721     }
3722     DBUG_RETURN(packet_error);
3723   }
3724 
3725   /* Check if eof packet */
3726   if (len < 8 && mysql->net.read_pos[0] == 254)
3727   {
3728      sql_print_information("Slave: received end packet from server due to dump "
3729                            "thread being killed on master. Dump threads are "
3730                            "killed for example during master shutdown, "
3731                            "explicitly by a user, or when the master receives "
3732                            "a binlog send request from a duplicate server "
3733                            "UUID <%s> : Error %s", ::server_uuid,
3734                            mysql_error(mysql));
3735      DBUG_RETURN(packet_error);
3736   }
3737 
3738   DBUG_PRINT("exit", ("len: %lu  net->read_pos[4]: %d",
3739                       len, mysql->net.read_pos[4]));
3740   DBUG_RETURN(len - 1);
3741 }
3742 
3743 
3744 /**
3745   If this is a lagging slave (specified with CHANGE MASTER TO MASTER_DELAY = X), delays accordingly. Also unlocks rli->data_lock.
3746 
3747   Design note: this is the place to unlock rli->data_lock. The lock
3748   must be held when reading delay info from rli, but it should not be
3749   held while sleeping.
3750 
3751   @param ev Event that is about to be executed.
3752 
3753   @param thd The sql thread's THD object.
3754 
3755   @param rli The sql thread's Relay_log_info structure.
3756 
3757   @retval 0 If the delay timed out and the event shall be executed.
3758 
3759   @retval nonzero If the delay was interrupted and the event shall be skipped.
3760 */
sql_delay_event(Log_event * ev,THD * thd,Relay_log_info * rli)3761 static int sql_delay_event(Log_event *ev, THD *thd, Relay_log_info *rli)
3762 {
3763   long sql_delay= rli->get_sql_delay();
3764 
3765   DBUG_ENTER("sql_delay_event");
3766   mysql_mutex_assert_owner(&rli->data_lock);
3767   DBUG_ASSERT(!rli->belongs_to_client());
3768 
3769   int type= ev->get_type_code();
3770   if (sql_delay && type != ROTATE_EVENT &&
3771       type != FORMAT_DESCRIPTION_EVENT && type != START_EVENT_V3)
3772   {
3773     // The time when we should execute the event.
3774     time_t sql_delay_end=
3775       ev->when.tv_sec + rli->mi->clock_diff_with_master + sql_delay;
3776     // The current time.
3777     time_t now= my_time(0);
3778     // The time we will have to sleep before executing the event.
3779     unsigned long nap_time= 0;
3780     if (sql_delay_end > now)
3781       nap_time= sql_delay_end - now;
3782 
3783     DBUG_PRINT("info", ("sql_delay= %lu "
3784                         "ev->when= %lu "
3785                         "rli->mi->clock_diff_with_master= %lu "
3786                         "now= %ld "
3787                         "sql_delay_end= %ld "
3788                         "nap_time= %ld",
3789                         sql_delay, (long) ev->when.tv_sec,
3790                         rli->mi->clock_diff_with_master,
3791                         (long)now, (long)sql_delay_end, (long)nap_time));
3792 
3793     if (sql_delay_end > now)
3794     {
3795       DBUG_PRINT("info", ("delaying replication event %lu secs",
3796                           nap_time));
3797       rli->start_sql_delay(sql_delay_end);
3798       mysql_mutex_unlock(&rli->data_lock);
3799       DBUG_RETURN(slave_sleep(thd, nap_time, sql_slave_killed, rli));
3800     }
3801   }
3802 
3803   mysql_mutex_unlock(&rli->data_lock);
3804 
3805   DBUG_RETURN(0);
3806 }
3807 
3808 /**
3809    a sort_dynamic function on ulong type
3810    returns as specified by @c qsort_cmp
3811 */
ulong_cmp(ulong * id1,ulong * id2)3812 int ulong_cmp(ulong *id1, ulong *id2)
3813 {
3814   return *id1 < *id2? -1 : (*id1 > *id2? 1 : 0);
3815 }
3816 
3817 /**
3818   Applies the given event and advances the relay log position.
3819 
3820   This is needed by the sql thread to execute events from the binlog,
3821   and by clients executing BINLOG statements.  Conceptually, this
3822   function does:
3823 
3824   @code
3825     ev->apply_event(rli);
3826     ev->update_pos(rli);
3827   @endcode
3828 
3829   It also does the following maintainance:
3830 
3831    - Initializes the thread's server_id and time; and the event's
3832      thread.
3833 
3834    - If !rli->belongs_to_client() (i.e., if it belongs to the slave
3835      sql thread instead of being used for executing BINLOG
3836      statements), it does the following things: (1) skips events if it
3837      is needed according to the server id or slave_skip_counter; (2)
3838      unlocks rli->data_lock; (3) sleeps if required by 'CHANGE MASTER
3839      TO MASTER_DELAY=X'; (4) maintains the running state of the sql
3840      thread (rli->thread_state).
3841 
3842    - Reports errors as needed.
3843 
3844   @param ptr_ev a pointer to a reference to the event to apply.
3845 
3846   @param thd The client thread that executes the event (i.e., the
3847   slave sql thread if called from a replication slave, or the client
3848   thread if called to execute a BINLOG statement).
3849 
3850   @param rli The relay log info (i.e., the slave's rli if called from
3851   a replication slave, or the client's thd->rli_fake if called to
3852   execute a BINLOG statement).
3853 
3854   @note MTS can store NULL to @c ptr_ev location to indicate
3855         the event is taken over by a Worker.
3856 
3857   @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK
3858           OK.
3859 
3860   @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR
3861           Error calling ev->apply_event().
3862 
3863   @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR
3864           No error calling ev->apply_event(), but error calling
3865           ev->update_pos().
3866 
3867   @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR
3868           append_item_to_jobs() failed, thread was killed while waiting
3869           for successful enqueue on worker.
3870 */
3871 enum enum_slave_apply_event_and_update_pos_retval
apply_event_and_update_pos(Log_event ** ptr_ev,THD * thd,Relay_log_info * rli)3872 apply_event_and_update_pos(Log_event** ptr_ev, THD* thd, Relay_log_info* rli)
3873 {
3874   int exec_res= 0;
3875   bool skip_event= FALSE;
3876   Log_event *ev= *ptr_ev;
3877   Log_event::enum_skip_reason reason= Log_event::EVENT_SKIP_NOT;
3878 
3879   DBUG_ENTER("apply_event_and_update_pos");
3880 
3881   DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)",
3882                            ev->get_type_str(), ev->get_type_code(),
3883                            ev->server_id));
3884   DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
3885                       FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT),
3886                       FLAGSTR(thd->variables.option_bits, OPTION_BEGIN),
3887                       (ulong) rli->last_event_start_time));
3888 
3889   /*
3890     Execute the event to change the database and update the binary
3891     log coordinates, but first we set some data that is needed for
3892     the thread.
3893 
3894     The event will be executed unless it is supposed to be skipped.
3895 
3896     Queries originating from this server must be skipped.  Low-level
3897     events (Format_description_log_event, Rotate_log_event,
3898     Stop_log_event) from this server must also be skipped. But for
3899     those we don't want to modify 'group_master_log_pos', because
3900     these events did not exist on the master.
3901     Format_description_log_event is not completely skipped.
3902 
3903     Skip queries specified by the user in 'slave_skip_counter'.  We
3904     can't however skip events that has something to do with the log
3905     files themselves.
3906 
3907     Filtering on own server id is extremely important, to ignore
3908     execution of events created by the creation/rotation of the relay
3909     log (remember that now the relay log starts with its Format_desc,
3910     has a Rotate etc).
3911   */
3912   /*
3913      Set the unmasked and actual server ids from the event
3914    */
3915   thd->server_id = ev->server_id; // use the original server id for logging
3916   thd->unmasked_server_id = ev->unmasked_server_id;
3917   thd->set_time();                            // time the query
3918   thd->lex->current_select= 0;
3919   if (!ev->when.tv_sec)
3920     my_micro_time_to_timeval(my_micro_time(), &ev->when);
3921   ev->thd = thd; // because up to this point, ev->thd == 0
3922 
3923   if (!(rli->is_mts_recovery() && bitmap_is_set(&rli->recovery_groups,
3924                                                 rli->mts_recovery_index)))
3925   {
3926     reason= ev->shall_skip(rli);
3927   }
3928 #ifndef DBUG_OFF
3929   if (rli->is_mts_recovery())
3930   {
3931     DBUG_PRINT("mts", ("Mts is recovering %d, number of bits set %d, "
3932                        "bitmap is set %d, index %lu.\n",
3933                        rli->is_mts_recovery(),
3934                        bitmap_bits_set(&rli->recovery_groups),
3935                        bitmap_is_set(&rli->recovery_groups,
3936                                      rli->mts_recovery_index),
3937                        rli->mts_recovery_index));
3938   }
3939 #endif
3940   if (reason == Log_event::EVENT_SKIP_COUNT)
3941   {
3942     sql_slave_skip_counter= --rli->slave_skip_counter;
3943     skip_event= TRUE;
3944   }
3945   if (reason == Log_event::EVENT_SKIP_NOT)
3946   {
3947     // Sleeps if needed, and unlocks rli->data_lock.
3948     if (sql_delay_event(ev, thd, rli))
3949       DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK);
3950 
3951     exec_res= ev->apply_event(rli);
3952     DBUG_EXECUTE_IF("simulate_stop_when_mts_in_group",
3953                     if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP
3954                         && rli->curr_group_seen_begin)
3955 		    DBUG_SET("+d,stop_when_mts_in_group"););
3956 
3957     if (!exec_res && (ev->worker != rli))
3958     {
3959       if (ev->worker)
3960       {
3961         Slave_job_item item= {ev}, *job_item= &item;
3962         Slave_worker *w= (Slave_worker *) ev->worker;
3963         // specially marked group typically with OVER_MAX_DBS_IN_EVENT_MTS db:s
3964         bool need_sync= ev->is_mts_group_isolated();
3965 
3966         // all events except BEGIN-query must be marked with a non-NULL Worker
3967         DBUG_ASSERT(((Slave_worker*) ev->worker) == rli->last_assigned_worker);
3968 
3969         DBUG_PRINT("Log_event::apply_event:",
3970                    ("-> job item data %p to W_%lu", job_item->data, w->id));
3971 
3972         // Reset mts in-group state
3973         if (rli->mts_group_status == Relay_log_info::MTS_END_GROUP)
3974         {
3975           // CGAP cleanup
3976           for (uint i= rli->curr_group_assigned_parts.elements; i > 0; i--)
3977             delete_dynamic_element(&rli->
3978                                    curr_group_assigned_parts, i - 1);
3979           // reset the B-group and Gtid-group marker
3980           rli->curr_group_seen_begin= rli->curr_group_seen_gtid= false;
3981           rli->last_assigned_worker= NULL;
3982         }
3983         /*
3984            Stroring GAQ index of the group that the event belongs to
3985            in the event. Deferred events are handled similarly below.
3986         */
3987         ev->mts_group_idx= rli->gaq->assigned_group_index;
3988 
3989         bool append_item_to_jobs_error= false;
3990         if (rli->curr_group_da.elements > 0)
3991         {
3992           /*
3993             the current event sorted out which partion the current group
3994             belongs to. It's time now to processed deferred array events.
3995           */
3996           for (uint i= 0; i < rli->curr_group_da.elements; i++)
3997           {
3998             Slave_job_item da_item;
3999             get_dynamic(&rli->curr_group_da, (uchar*) &da_item.data, i);
4000             DBUG_PRINT("mts", ("Assigning job %llu to worker %lu",
4001                       ((Log_event* )da_item.data)->log_pos, w->id));
4002             static_cast<Log_event*>(da_item.data)->mts_group_idx=
4003               rli->gaq->assigned_group_index; // similarly to above
4004             if (!append_item_to_jobs_error)
4005               append_item_to_jobs_error= append_item_to_jobs(&da_item, w, rli);
4006             if (append_item_to_jobs_error)
4007               delete static_cast<Log_event*>(da_item.data);
4008           }
4009           if (rli->curr_group_da.elements > rli->curr_group_da.max_element)
4010           {
4011             // reallocate to less mem
4012             rli->curr_group_da.elements= rli->curr_group_da.max_element;
4013             rli->curr_group_da.max_element= 0;
4014             freeze_size(&rli->curr_group_da); // restores max_element
4015           }
4016           rli->curr_group_da.elements= 0;
4017         }
4018         if (append_item_to_jobs_error)
4019           DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR);
4020 
4021         DBUG_PRINT("mts", ("Assigning job %llu to worker %lu\n",
4022                    ((Log_event* )job_item->data)->log_pos, w->id));
4023 
4024         /* Notice `ev' instance can be destoyed after `append()' */
4025         if (append_item_to_jobs(job_item, w, rli))
4026           DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR);
4027         if (need_sync)
4028         {
4029           /*
4030             combination of over-max db:s and end of the current group
4031             forces to wait for the assigned groups completion by assigned
4032             to the event worker.
4033             Indeed MTS group status could be safely set to MTS_NOT_IN_GROUP
4034             after wait_() returns.
4035             No need to know a possible error out of synchronization call.
4036           */
4037           (void) wait_for_workers_to_finish(rli);
4038         }
4039 
4040       }
4041       *ptr_ev= NULL; // announcing the event is passed to w-worker
4042 
4043       if (log_warnings > 1 &&
4044           rli->is_parallel_exec() && rli->mts_events_assigned % 1024 == 1)
4045       {
4046         time_t my_now= my_time(0);
4047 
4048         if ((my_now - rli->mts_last_online_stat) >=
4049             mts_online_stat_period)
4050         {
4051           sql_print_information("Multi-threaded slave statistics: "
4052                                 "seconds elapsed = %lu; "
4053                                 "events assigned = %llu; "
4054                                 "worker queues filled over overrun level = %lu; "
4055                                 "waited due a Worker queue full = %lu; "
4056                                 "waited due the total size = %lu; "
4057                                 "slept when Workers occupied = %lu ",
4058                                 static_cast<unsigned long>
4059                                 (my_now - rli->mts_last_online_stat),
4060                                 rli->mts_events_assigned,
4061                                 rli->mts_wq_overrun_cnt,
4062                                 rli->mts_wq_overfill_cnt,
4063                                 rli->wq_size_waits_cnt,
4064                                 rli->mts_wq_no_underrun_cnt);
4065           rli->mts_last_online_stat= my_now;
4066         }
4067       }
4068     }
4069   }
4070   else
4071     mysql_mutex_unlock(&rli->data_lock);
4072 
4073   DBUG_PRINT("info", ("apply_event error = %d", exec_res));
4074   if (exec_res == 0)
4075   {
4076     /*
4077       Positions are not updated here when an XID is processed. To make
4078       a slave crash-safe, positions must be updated while processing a
4079       XID event and as such do not need to be updated here again.
4080 
4081       However, if the event needs to be skipped, this means that it
4082       will not be processed and then positions need to be updated here.
4083 
4084       See sql/rpl_rli.h for further details.
4085     */
4086     int error= 0;
4087     if (*ptr_ev &&
4088         (ev->get_type_code() != XID_EVENT ||
4089          skip_event || (rli->is_mts_recovery() && !is_gtid_event(ev) &&
4090          (ev->ends_group() || !rli->mts_recovery_group_seen_begin) &&
4091           bitmap_is_set(&rli->recovery_groups, rli->mts_recovery_index))))
4092     {
4093 #ifndef DBUG_OFF
4094       /*
4095         This only prints information to the debug trace.
4096 
4097         TODO: Print an informational message to the error log?
4098       */
4099       static const char *const explain[] = {
4100         // EVENT_SKIP_NOT,
4101         "not skipped",
4102         // EVENT_SKIP_IGNORE,
4103         "skipped because event should be ignored",
4104         // EVENT_SKIP_COUNT
4105         "skipped because event skip counter was non-zero"
4106       };
4107       DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
4108                           MY_TEST(thd->variables.option_bits & OPTION_BEGIN),
4109                           rli->get_flag(Relay_log_info::IN_STMT)));
4110       DBUG_PRINT("skip_event", ("%s event was %s",
4111                                 ev->get_type_str(), explain[reason]));
4112 #endif
4113 
4114       error= ev->update_pos(rli);
4115 
4116 #ifndef DBUG_OFF
4117       DBUG_PRINT("info", ("update_pos error = %d", error));
4118       if (!rli->belongs_to_client())
4119       {
4120         char buf[22];
4121         DBUG_PRINT("info", ("group %s %s",
4122                             llstr(rli->get_group_relay_log_pos(), buf),
4123                             rli->get_group_relay_log_name()));
4124         DBUG_PRINT("info", ("event %s %s",
4125                             llstr(rli->get_event_relay_log_pos(), buf),
4126                             rli->get_event_relay_log_name()));
4127       }
4128 #endif
4129     }
4130     else
4131     {
4132       DBUG_ASSERT(*ptr_ev == ev || rli->is_parallel_exec() ||
4133 		  (!ev->worker &&
4134 		   (ev->get_type_code() == INTVAR_EVENT ||
4135 		    ev->get_type_code() == RAND_EVENT ||
4136 		    ev->get_type_code() == USER_VAR_EVENT)));
4137 
4138       rli->inc_event_relay_log_pos();
4139     }
4140 
4141     if (!error && rli->is_mts_recovery() &&
4142         ev->get_type_code() != ROTATE_EVENT &&
4143         ev->get_type_code() != FORMAT_DESCRIPTION_EVENT &&
4144         ev->get_type_code() != PREVIOUS_GTIDS_LOG_EVENT)
4145     {
4146       if (ev->starts_group())
4147       {
4148         rli->mts_recovery_group_seen_begin= true;
4149       }
4150       else if ((ev->ends_group() || !rli->mts_recovery_group_seen_begin) &&
4151                !is_gtid_event(ev))
4152       {
4153         rli->mts_recovery_index++;
4154         if (--rli->mts_recovery_group_cnt == 0)
4155         {
4156           rli->mts_recovery_index= 0;
4157           sql_print_information("Slave: MTS Recovery has completed at "
4158                                 "relay log %s, position %llu "
4159                                 "master log %s, position %llu.",
4160                                 rli->get_group_relay_log_name(),
4161                                 rli->get_group_relay_log_pos(),
4162                                 rli->get_group_master_log_name(),
4163                                 rli->get_group_master_log_pos());
4164           /*
4165              Few tests wait for UNTIL_SQL_AFTER_MTS_GAPS completion.
4166              Due to exisiting convention the status won't change
4167              prior to slave restarts.
4168              So making of UNTIL_SQL_AFTER_MTS_GAPS completion isdone here,
4169              and only in the debug build to make the test to catch the change
4170              despite a faulty design of UNTIL checking before execution.
4171           */
4172           if (rli->until_condition == Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS)
4173           {
4174             rli->until_condition= Relay_log_info::UNTIL_DONE;
4175           }
4176           // reset the Worker tables to remove last slave session time info
4177           if ((error= rli->mts_finalize_recovery()))
4178           {
4179             (void) Rpl_info_factory::reset_workers(rli);
4180           }
4181         }
4182         rli->mts_recovery_group_seen_begin= false;
4183         if (!error)
4184           error= rli->flush_info(true);
4185       }
4186     }
4187 
4188     if (error)
4189     {
4190       /*
4191         The update should not fail, so print an error message and
4192         return an error code.
4193 
4194         TODO: Replace this with a decent error message when merged
4195         with BUG#24954 (which adds several new error message).
4196       */
4197       char buf[22];
4198       rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
4199                   "It was not possible to update the positions"
4200                   " of the relay log information: the slave may"
4201                   " be in an inconsistent state."
4202                   " Stopped in %s position %s",
4203                   rli->get_group_relay_log_name(),
4204                   llstr(rli->get_group_relay_log_pos(), buf));
4205       DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR);
4206     }
4207   }
4208 
4209   DBUG_RETURN(exec_res ? SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR
4210                        : SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK);
4211 }
4212 
4213 /**
4214   Let the worker applying the current group to rollback and gracefully
4215   finish its work before.
4216 
4217   @param rli The slave's relay log info.
4218 
4219   @param ev a pointer to the event on hold before applying this rollback
4220   procedure.
4221 
4222   @retval false The rollback succeeded.
4223 
4224   @retval true  There was an error while injecting events.
4225 */
coord_handle_partial_binlogged_transaction(Relay_log_info * rli,const Log_event * ev)4226 static bool coord_handle_partial_binlogged_transaction(Relay_log_info *rli,
4227                                                        const Log_event *ev)
4228 {
4229   DBUG_ENTER("coord_handle_partial_binlogged_transaction");
4230   /*
4231     This function is called holding the rli->data_lock.
4232     We must return it still holding this lock, except in the case of returning
4233     error.
4234   */
4235   mysql_mutex_assert_owner(&rli->data_lock);
4236   THD *thd= rli->info_thd;
4237 
4238   if (!rli->curr_group_seen_begin)
4239   {
4240     DBUG_PRINT("info",("Injecting QUERY(BEGIN) to rollback worker"));
4241     Log_event *begin_event= new Query_log_event(thd,
4242                                                 STRING_WITH_LEN("BEGIN"),
4243                                                 true, /* using_trans */
4244                                                 false, /* immediate */
4245                                                 true, /* suppress_use */
4246                                                 0, /* error */
4247                                                 true /* ignore_command */);
4248     ((Query_log_event*) begin_event)->db= "";
4249     begin_event->data_written= 0;
4250     begin_event->server_id= ev->server_id;
4251     /*
4252       We must be careful to avoid SQL thread increasing its position
4253       farther than the event that triggered this QUERY(BEGIN).
4254     */
4255     begin_event->log_pos= ev->log_pos;
4256     begin_event->future_event_relay_log_pos= ev->future_event_relay_log_pos;
4257 
4258     if (apply_event_and_update_pos(&begin_event, thd, rli) !=
4259         SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK)
4260     {
4261       delete begin_event;
4262       DBUG_RETURN(true);
4263     }
4264     mysql_mutex_lock(&rli->data_lock);
4265   }
4266 
4267   DBUG_PRINT("info",("Injecting QUERY(ROLLBACK) to rollback worker"));
4268   Log_event *rollback_event= new Query_log_event(thd,
4269                                                  STRING_WITH_LEN("ROLLBACK"),
4270                                                  true, /* using_trans */
4271                                                  false, /* immediate */
4272                                                  true, /* suppress_use */
4273                                                  0, /* error */
4274                                                  true /* ignore_command */);
4275   ((Query_log_event*) rollback_event)->db= "";
4276   rollback_event->data_written= 0;
4277   rollback_event->server_id= ev->server_id;
4278   /*
4279     We must be careful to avoid SQL thread increasing its position
4280     farther than the event that triggered this QUERY(ROLLBACK).
4281   */
4282   rollback_event->log_pos= ev->log_pos;
4283   rollback_event->future_event_relay_log_pos= ev->future_event_relay_log_pos;
4284 
4285   if (apply_event_and_update_pos(&rollback_event, thd, rli) !=
4286       SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK)
4287   {
4288     delete rollback_event;
4289     DBUG_RETURN(true);
4290   }
4291   mysql_mutex_lock(&rli->data_lock);
4292 
4293   DBUG_RETURN(false);
4294 }
4295 
4296 /**
4297   Top-level function for executing the next event in the relay log.
4298   This is called from the SQL thread.
4299 
4300   This function reads the event from the relay log, executes it, and
4301   advances the relay log position.  It also handles errors, etc.
4302 
4303   This function may fail to apply the event for the following reasons:
4304 
4305    - The position specfied by the UNTIL condition of the START SLAVE
4306      command is reached.
4307 
4308    - It was not possible to read the event from the log.
4309 
4310    - The slave is killed.
4311 
4312    - An error occurred when applying the event, and the event has been
4313      tried slave_trans_retries times.  If the event has been retried
4314      fewer times, 0 is returned.
4315 
4316    - init_info or init_relay_log_pos failed. (These are called
4317      if a failure occurs when applying the event.)
4318 
4319    - An error occurred when updating the binlog position.
4320 
4321   @retval 0 The event was applied.
4322 
4323   @retval 1 The event was not applied.
4324 */
exec_relay_log_event(THD * thd,Relay_log_info * rli)4325 static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
4326 {
4327   DBUG_ENTER("exec_relay_log_event");
4328 
4329   /*
4330      We acquire this mutex since we need it for all operations except
4331      event execution. But we will release it in places where we will
4332      wait for something for example inside of next_event().
4333    */
4334   mysql_mutex_lock(&rli->data_lock);
4335 
4336   /*
4337     UNTIL_SQL_AFTER_GTIDS requires special handling since we have to check
4338     whether the until_condition is satisfied *before* the SQL threads goes on
4339     a wait inside next_event() for the relay log to grow. This is reuired since
4340     if we have already applied the last event in the waiting set but since he
4341     check happens only at the start of the next event we may end up waiting
4342     forever the next event is not available or is delayed.
4343   */
4344   if (rli->until_condition == Relay_log_info::UNTIL_SQL_AFTER_GTIDS &&
4345        rli->is_until_satisfied(thd, NULL))
4346   {
4347     rli->abort_slave= 1;
4348     mysql_mutex_unlock(&rli->data_lock);
4349     DBUG_RETURN(1);
4350   }
4351 
4352   Log_event *ev = next_event(rli), **ptr_ev;
4353 
4354   DBUG_ASSERT(rli->info_thd==thd);
4355 
4356   if (sql_slave_killed(thd,rli))
4357   {
4358     mysql_mutex_unlock(&rli->data_lock);
4359     delete ev;
4360     DBUG_RETURN(1);
4361   }
4362   if (ev)
4363   {
4364     enum enum_slave_apply_event_and_update_pos_retval exec_res;
4365 
4366     ptr_ev= &ev;
4367     /*
4368       Even if we don't execute this event, we keep the master timestamp,
4369       so that seconds behind master shows correct delta (there are events
4370       that are not replayed, so we keep falling behind).
4371 
4372       If it is an artificial event, or a relay log event (IO thread generated
4373       event) or ev->when is set to 0, or a FD from master, or a heartbeat
4374       event with server_id '0' then  we don't update the last_master_timestamp.
4375     */
4376     if (!(rli->is_parallel_exec() ||
4377           ev->is_artificial_event() || ev->is_relay_log_event() ||
4378           ev->when.tv_sec == 0 || ev->get_type_code() == FORMAT_DESCRIPTION_EVENT ||
4379           ev->server_id == 0))
4380     {
4381       rli->last_master_timestamp= ev->when.tv_sec + (time_t) ev->exec_time;
4382       DBUG_ASSERT(rli->last_master_timestamp >= 0);
4383     }
4384 
4385     /*
4386       This tests if the position of the beginning of the current event
4387       hits the UNTIL barrier.
4388       MTS: since the master and the relay-group coordinates change
4389       asynchronously logics of rli->is_until_satisfied() can't apply.
4390       A special UNTIL_SQL_AFTER_MTS_GAPS is still deployed here
4391       temporarily (see is_until_satisfied todo).
4392     */
4393     if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
4394         rli->until_condition != Relay_log_info::UNTIL_SQL_AFTER_GTIDS &&
4395         rli->is_until_satisfied(thd, ev))
4396     {
4397       /*
4398         Setting abort_slave flag because we do not want additional message about
4399         error in query execution to be printed.
4400       */
4401       rli->abort_slave= 1;
4402       mysql_mutex_unlock(&rli->data_lock);
4403       delete ev;
4404       DBUG_RETURN(1);
4405     }
4406 
4407     { /**
4408          The following failure injecion works in cooperation with tests
4409          setting @@global.debug= 'd,incomplete_group_in_relay_log'.
4410          Xid or Commit events are not executed to force the slave sql
4411          read hanging if the realy log does not have any more events.
4412       */
4413       DBUG_EXECUTE_IF("incomplete_group_in_relay_log",
4414                       if ((ev->get_type_code() == XID_EVENT) ||
4415                           ((ev->get_type_code() == QUERY_EVENT) &&
4416                            strcmp("COMMIT", ((Query_log_event *) ev)->query) == 0))
4417                       {
4418                         DBUG_ASSERT(thd->transaction.all.cannot_safely_rollback());
4419                         rli->abort_slave= 1;
4420                         mysql_mutex_unlock(&rli->data_lock);
4421                         delete ev;
4422                         rli->inc_event_relay_log_pos();
4423                         DBUG_RETURN(0);
4424                       };);
4425     }
4426 
4427     /*
4428       GTID protocol will put a FORMAT_DESCRIPTION_EVENT from the master with
4429       log_pos != 0 after each (re)connection if auto positioning is enabled.
4430       This means that the SQL thread might have already started to apply the
4431       current group but, as the IO thread had to reconnect, it left this
4432       group incomplete and will start it again from the beginning.
4433       So, before applying this FORMAT_DESCRIPTION_EVENT, we must let the
4434       worker roll back the current group and gracefully finish its work,
4435       before starting to apply the new (complete) copy of the group.
4436     */
4437     if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT &&
4438         ev->server_id != ::server_id && ev->log_pos != 0 &&
4439         rli->is_parallel_exec() && rli->curr_group_seen_gtid)
4440     {
4441       if (coord_handle_partial_binlogged_transaction(rli, ev))
4442         /*
4443           In the case of an error, coord_handle_partial_binlogged_transaction
4444           will not try to get the rli->data_lock again.
4445         */
4446         DBUG_RETURN(1);
4447     }
4448 
4449     /* ptr_ev can change to NULL indicating MTS coorinator passed to a Worker */
4450     exec_res= apply_event_and_update_pos(ptr_ev, thd, rli);
4451     /*
4452       Note: the above call to apply_event_and_update_pos executes
4453       mysql_mutex_unlock(&rli->data_lock);
4454     */
4455 
4456     /* For deferred events, the ptr_ev is set to NULL
4457         in Deferred_log_events::add() function.
4458         Hence deferred events wont be deleted here.
4459         They will be deleted in Deferred_log_events::rewind() funciton.
4460     */
4461     if (*ptr_ev)
4462     {
4463       DBUG_ASSERT(*ptr_ev == ev); // event remains to belong to Coordinator
4464 
4465       DBUG_EXECUTE_IF("dbug.calculate_sbm_after_previous_gtid_log_event",
4466                     {
4467                       if (ev->get_type_code() == PREVIOUS_GTIDS_LOG_EVENT)
4468                       {
4469                         const char act[]= "now signal signal.reached wait_for signal.done_sbm_calculation";
4470                         DBUG_ASSERT(opt_debug_sync_timeout > 0);
4471                         DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act)));
4472                       }
4473                     };);
4474       DBUG_EXECUTE_IF("dbug.calculate_sbm_after_fake_rotate_log_event",
4475                     {
4476                       if (ev->get_type_code() == ROTATE_EVENT && ev->is_artificial_event())
4477                       {
4478                       const char act[]= "now signal signal.reached wait_for signal.done_sbm_calculation";
4479                       DBUG_ASSERT(opt_debug_sync_timeout > 0);
4480                       DBUG_ASSERT(!debug_sync_set_action(thd,
4481                                                          STRING_WITH_LEN(act)));
4482                       }
4483                     };);
4484       /*
4485         Format_description_log_event should not be deleted because it will be
4486         used to read info about the relay log's format; it will be deleted when
4487         the SQL thread does not need it, i.e. when this thread terminates.
4488         ROWS_QUERY_LOG_EVENT is destroyed at the end of the current statement
4489         clean-up routine.
4490       */
4491       if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT &&
4492           ev->get_type_code() != ROWS_QUERY_LOG_EVENT)
4493       {
4494         DBUG_PRINT("info", ("Deleting the event after it has been executed"));
4495         delete ev;
4496         ev= NULL;
4497       }
4498     }
4499 
4500     /*
4501       exec_res == SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR
4502                   update_log_pos failed: this should not happen, so we
4503                   don't retry.
4504       exec_res == SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR
4505                   append_item_to_jobs() failed, this happened because
4506                   thread was killed while waiting for enqueue on worker.
4507     */
4508     if (exec_res >= SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR)
4509     {
4510       delete ev;
4511       DBUG_RETURN(1);
4512     }
4513 
4514     if (slave_trans_retries)
4515     {
4516       int UNINIT_VAR(temp_err);
4517       bool silent= false;
4518       if (exec_res && !is_mts_worker(thd) /* no reexecution in MTS mode */ &&
4519           (temp_err= rli->has_temporary_error(thd, 0, &silent)) &&
4520           !thd->transaction.all.cannot_safely_rollback())
4521       {
4522         const char *errmsg;
4523         /*
4524           We were in a transaction which has been rolled back because of a
4525           temporary error;
4526           let's seek back to BEGIN log event and retry it all again.
4527 	  Note, if lock wait timeout (innodb_lock_wait_timeout exceeded)
4528 	  there is no rollback since 5.0.13 (ref: manual).
4529           We have to not only seek but also
4530           a) init_info(), to seek back to hot relay log's start for later
4531           (for when we will come back to this hot log after re-processing the
4532           possibly existing old logs where BEGIN is: check_binlog_magic() will
4533           then need the cache to be at position 0 (see comments at beginning of
4534           init_info()).
4535           b) init_relay_log_pos(), because the BEGIN may be an older relay log.
4536         */
4537         if (rli->trans_retries < slave_trans_retries)
4538         {
4539           /*
4540             The transactions has to be rolled back before global_init_info is
4541             called. Because global_init_info will starts a new transaction if
4542             master_info_repository is TABLE.
4543           */
4544           rli->cleanup_context(thd, 1);
4545           /*
4546              We need to figure out if there is a test case that covers
4547              this part. \Alfranio.
4548           */
4549           if (global_init_info(rli->mi, false, SLAVE_SQL))
4550             sql_print_error("Failed to initialize the master info structure");
4551           else if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
4552                                            rli->get_group_relay_log_pos(),
4553                                            true/*need_data_lock=true*/,
4554                                            &errmsg, 1))
4555             sql_print_error("Error initializing relay log position: %s",
4556                             errmsg);
4557           else
4558           {
4559             exec_res= SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK;
4560             /* chance for concurrent connection to get more locks */
4561             slave_sleep(thd, min<ulong>(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
4562                         sql_slave_killed, rli);
4563             mysql_mutex_lock(&rli->data_lock); // because of SHOW STATUS
4564             if (!silent)
4565               rli->trans_retries++;
4566 
4567             rli->retried_trans++;
4568             mysql_mutex_unlock(&rli->data_lock);
4569             DBUG_PRINT("info", ("Slave retries transaction "
4570                                 "rli->trans_retries: %lu", rli->trans_retries));
4571           }
4572         }
4573         else
4574         {
4575           thd->is_fatal_error= 1;
4576           rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
4577                       "Slave SQL thread retried transaction %lu time(s) "
4578                       "in vain, giving up. Consider raising the value of "
4579                       "the slave_transaction_retries variable.", rli->trans_retries);
4580         }
4581       }
4582       else if ((exec_res && !temp_err) ||
4583                (opt_using_transactions &&
4584                 rli->get_group_relay_log_pos() == rli->get_event_relay_log_pos()))
4585       {
4586         /*
4587           Only reset the retry counter if the entire group succeeded
4588           or failed with a non-transient error.  On a successful
4589           event, the execution will proceed as usual; in the case of a
4590           non-transient error, the slave will stop with an error.
4591          */
4592         rli->trans_retries= 0; // restart from fresh
4593         DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %lu",
4594                             rli->trans_retries));
4595       }
4596     }
4597     if (exec_res)
4598       delete ev;
4599     DBUG_RETURN(exec_res);
4600   }
4601   mysql_mutex_unlock(&rli->data_lock);
4602   rli->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_READ_FAILURE,
4603               ER(ER_SLAVE_RELAY_LOG_READ_FAILURE), "\
4604 Could not parse relay log event entry. The possible reasons are: the master's \
4605 binary log is corrupted (you can check this by running 'mysqlbinlog' on the \
4606 binary log), the slave's relay log is corrupted (you can check this by running \
4607 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's \
4608 or slave's MySQL code. If you want to check the master's binary log or slave's \
4609 relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' \
4610 on this slave.\
4611 ");
4612   DBUG_RETURN(1);
4613 }
4614 
check_io_slave_killed(THD * thd,Master_info * mi,const char * info)4615 static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info)
4616 {
4617   if (io_slave_killed(thd, mi))
4618   {
4619     if (info && log_warnings)
4620       sql_print_information("%s", info);
4621     return TRUE;
4622   }
4623   return FALSE;
4624 }
4625 
4626 /**
4627   @brief Try to reconnect slave IO thread.
4628 
4629   @details Terminates current connection to master, sleeps for
4630   @c mi->connect_retry msecs and initiates new connection with
4631   @c safe_reconnect(). Variable pointed by @c retry_count is increased -
4632   if it exceeds @c mi->retry_count then connection is not re-established
4633   and function signals error.
4634   Unless @c suppres_warnings is TRUE, a warning is put in the server error log
4635   when reconnecting. The warning message and messages used to report errors
4636   are taken from @c messages array. In case @c mi->retry_count is exceeded,
4637   no messages are added to the log.
4638 
4639   @param[in]     thd                 Thread context.
4640   @param[in]     mysql               MySQL connection.
4641   @param[in]     mi                  Master connection information.
4642   @param[in,out] retry_count         Number of attempts to reconnect.
4643   @param[in]     suppress_warnings   TRUE when a normal net read timeout
4644                                      has caused to reconnecting.
4645   @param[in]     messages            Messages to print/log, see
4646                                      reconnect_messages[] array.
4647 
4648   @retval        0                   OK.
4649   @retval        1                   There was an error.
4650 */
4651 
try_to_reconnect(THD * thd,MYSQL * mysql,Master_info * mi,uint * retry_count,bool suppress_warnings,const char * messages[SLAVE_RECON_MSG_MAX])4652 static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi,
4653                             uint *retry_count, bool suppress_warnings,
4654                             const char *messages[SLAVE_RECON_MSG_MAX])
4655 {
4656   mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
4657   thd->proc_info= messages[SLAVE_RECON_MSG_WAIT];
4658 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
4659   thd->clear_active_vio();
4660 #endif
4661   end_server(mysql);
4662   DBUG_EXECUTE_IF("simulate_no_master_reconnect",
4663                    {
4664                      return 1;
4665                    });
4666   if ((*retry_count)++)
4667   {
4668     if (*retry_count > mi->retry_count)
4669       return 1;                             // Don't retry forever
4670     slave_sleep(thd, mi->connect_retry, io_slave_killed, mi);
4671   }
4672   if (check_io_slave_killed(thd, mi, messages[SLAVE_RECON_MSG_KILLED_WAITING]))
4673     return 1;
4674   thd->proc_info = messages[SLAVE_RECON_MSG_AFTER];
4675   if (!suppress_warnings)
4676   {
4677     char buf[256], llbuff[22];
4678     my_snprintf(buf, sizeof(buf), messages[SLAVE_RECON_MSG_FAILED],
4679                 mi->get_io_rpl_log_name(), llstr(mi->get_master_log_pos(),
4680                 llbuff));
4681     /*
4682       Raise a warining during registering on master/requesting dump.
4683       Log a message reading event.
4684     */
4685     if (messages[SLAVE_RECON_MSG_COMMAND][0])
4686     {
4687       mi->report(WARNING_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
4688                  ER(ER_SLAVE_MASTER_COM_FAILURE),
4689                  messages[SLAVE_RECON_MSG_COMMAND], buf);
4690     }
4691     else
4692     {
4693       sql_print_information("%s", buf);
4694     }
4695   }
4696   if (safe_reconnect(thd, mysql, mi, 1) || io_slave_killed(thd, mi))
4697   {
4698     if (log_warnings)
4699       sql_print_information("%s", messages[SLAVE_RECON_MSG_KILLED_AFTER]);
4700     return 1;
4701   }
4702   return 0;
4703 }
4704 
4705 
4706 /**
4707   Slave IO thread entry point.
4708 
4709   @param arg Pointer to Master_info struct that holds information for
4710   the IO thread.
4711 
4712   @return Always 0.
4713 */
handle_slave_io(void * arg)4714 pthread_handler_t handle_slave_io(void *arg)
4715 {
4716   THD *thd= NULL; // needs to be first for thread_stack
4717   bool thd_added= false;
4718   MYSQL *mysql;
4719   Master_info *mi = (Master_info*)arg;
4720   Relay_log_info *rli= mi->rli;
4721   char llbuff[22];
4722   uint retry_count;
4723   bool suppress_warnings;
4724   int ret;
4725   int binlog_version;
4726 #ifndef DBUG_OFF
4727   uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0;
4728 #endif
4729   // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
4730   my_thread_init();
4731   DBUG_ENTER("handle_slave_io");
4732 
4733   DBUG_ASSERT(mi->inited);
4734   mysql= NULL ;
4735   retry_count= 0;
4736 
4737   mysql_mutex_lock(&mi->run_lock);
4738   /* Inform waiting threads that slave has started */
4739   mi->slave_run_id++;
4740 
4741 #ifndef DBUG_OFF
4742   mi->events_until_exit = disconnect_slave_event_count;
4743 #endif
4744 
4745   thd= new THD; // note that contructor of THD uses DBUG_ !
4746   THD_CHECK_SENTRY(thd);
4747   mi->info_thd = thd;
4748 
4749   pthread_detach_this_thread();
4750   thd->thread_stack= (char*) &thd; // remember where our stack is
4751   mi->clear_error();
4752   if (init_slave_thread(thd, SLAVE_THD_IO))
4753   {
4754     mysql_cond_broadcast(&mi->start_cond);
4755     mysql_mutex_unlock(&mi->run_lock);
4756     sql_print_error("Failed during slave I/O thread initialization");
4757     goto err;
4758   }
4759 
4760   mysql_mutex_lock(&LOCK_thread_count);
4761   add_global_thread(thd);
4762   thd_added= true;
4763   mysql_mutex_unlock(&LOCK_thread_count);
4764 
4765   mi->slave_running = 1;
4766   mi->abort_slave = 0;
4767   mysql_mutex_unlock(&mi->run_lock);
4768   mysql_cond_broadcast(&mi->start_cond);
4769 
4770   DBUG_PRINT("master_info",("log_file_name: '%s'  position: %s",
4771                             mi->get_master_log_name(),
4772                             llstr(mi->get_master_log_pos(), llbuff)));
4773 
4774   /* This must be called before run any binlog_relay_io hooks */
4775   my_pthread_setspecific_ptr(RPL_MASTER_INFO, mi);
4776 
4777   if (RUN_HOOK(binlog_relay_io, thread_start, (thd, mi)))
4778   {
4779     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4780                ER(ER_SLAVE_FATAL_ERROR), "Failed to run 'thread_start' hook");
4781     goto err;
4782   }
4783 
4784   if (!(mi->mysql = mysql = mysql_init(NULL)))
4785   {
4786     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4787                ER(ER_SLAVE_FATAL_ERROR), "error in mysql_init()");
4788     goto err;
4789   }
4790 
4791   THD_STAGE_INFO(thd, stage_connecting_to_master);
4792   // we can get killed during safe_connect
4793   if (!safe_connect(thd, mysql, mi))
4794   {
4795     sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',"
4796                           "replication started in log '%s' at position %s",
4797                           mi->get_user(), mi->host, mi->port,
4798 			  mi->get_io_rpl_log_name(),
4799 			  llstr(mi->get_master_log_pos(), llbuff));
4800   }
4801   else
4802   {
4803     sql_print_information("Slave I/O thread killed while connecting to master");
4804     goto err;
4805   }
4806 
4807 connected:
4808 
4809     DBUG_EXECUTE_IF("dbug.before_get_running_status_yes",
4810                     {
4811                       const char act[]=
4812                         "now "
4813                         "wait_for signal.io_thread_let_running";
4814                       DBUG_ASSERT(opt_debug_sync_timeout > 0);
4815                       DBUG_ASSERT(!debug_sync_set_action(thd,
4816                                                          STRING_WITH_LEN(act)));
4817                     };);
4818     DBUG_EXECUTE_IF("dbug.calculate_sbm_after_previous_gtid_log_event",
4819                     {
4820                       /* Fake that thread started 3 minutes ago */
4821                       thd->start_time.tv_sec-=180;
4822                     };);
4823   DBUG_EXECUTE_IF("dbug.calculate_sbm_after_fake_rotate_log_event",
4824                   {
4825                     /* Fake that thread started 3 minutes ago */
4826                     thd->start_time.tv_sec-=180;
4827                   };);
4828   mysql_mutex_lock(&mi->run_lock);
4829   mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
4830   mysql_mutex_unlock(&mi->run_lock);
4831 
4832   thd->slave_net = &mysql->net;
4833   THD_STAGE_INFO(thd, stage_checking_master_version);
4834   ret= get_master_version_and_clock(mysql, mi);
4835   if (!ret)
4836     ret= get_master_uuid(mysql, mi);
4837   if (!ret)
4838     ret= io_thread_init_commands(mysql, mi);
4839 
4840   if (ret == 1)
4841     /* Fatal error */
4842     goto err;
4843 
4844   if (ret == 2)
4845   {
4846     if (check_io_slave_killed(mi->info_thd, mi, "Slave I/O thread killed"
4847                               "while calling get_master_version_and_clock(...)"))
4848       goto err;
4849     suppress_warnings= FALSE;
4850     /* Try to reconnect because the error was caused by a transient network problem */
4851     if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4852                              reconnect_messages[SLAVE_RECON_ACT_REG]))
4853       goto err;
4854     goto connected;
4855   }
4856 
4857   mysql_mutex_lock(&mi->data_lock);
4858   binlog_version= mi->get_mi_description_event()->binlog_version;
4859   mysql_mutex_unlock(&mi->data_lock);
4860 
4861   if (binlog_version > 1)
4862   {
4863     /*
4864       Register ourselves with the master.
4865     */
4866     THD_STAGE_INFO(thd, stage_registering_slave_on_master);
4867     if (register_slave_on_master(mysql, mi, &suppress_warnings))
4868     {
4869       if (!check_io_slave_killed(thd, mi, "Slave I/O thread killed "
4870                                 "while registering slave on master"))
4871       {
4872         sql_print_error("Slave I/O thread couldn't register on master");
4873         if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4874                              reconnect_messages[SLAVE_RECON_ACT_REG]))
4875           goto err;
4876       }
4877       else
4878         goto err;
4879       goto connected;
4880     }
4881     DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_REG",
4882       if (!retry_count_reg)
4883       {
4884         retry_count_reg++;
4885         sql_print_information("Forcing to reconnect slave I/O thread");
4886         if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4887                              reconnect_messages[SLAVE_RECON_ACT_REG]))
4888           goto err;
4889         goto connected;
4890       });
4891   }
4892 
4893   DBUG_PRINT("info",("Starting reading binary log from master"));
4894   while (!io_slave_killed(thd,mi))
4895   {
4896     THD_STAGE_INFO(thd, stage_requesting_binlog_dump);
4897     if (request_dump(thd, mysql, mi, &suppress_warnings))
4898     {
4899       sql_print_error("Failed on request_dump()");
4900       if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
4901 requesting master dump") ||
4902           try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4903                            reconnect_messages[SLAVE_RECON_ACT_DUMP]))
4904         goto err;
4905       goto connected;
4906     }
4907     DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_DUMP",
4908       if (!retry_count_dump)
4909       {
4910         retry_count_dump++;
4911         sql_print_information("Forcing to reconnect slave I/O thread");
4912         if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4913                              reconnect_messages[SLAVE_RECON_ACT_DUMP]))
4914           goto err;
4915         goto connected;
4916       });
4917     const char *event_buf;
4918 
4919     DBUG_ASSERT(mi->last_error().number == 0);
4920     while (!io_slave_killed(thd,mi))
4921     {
4922       ulong event_len;
4923       /*
4924          We say "waiting" because read_event() will wait if there's nothing to
4925          read. But if there's something to read, it will not wait. The
4926          important thing is to not confuse users by saying "reading" whereas
4927          we're in fact receiving nothing.
4928       */
4929       THD_STAGE_INFO(thd, stage_waiting_for_master_to_send_event);
4930       event_len= read_event(mysql, mi, &suppress_warnings);
4931       if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
4932 reading event"))
4933         goto err;
4934       DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT",
4935         if (!retry_count_event)
4936         {
4937           retry_count_event++;
4938           sql_print_information("Forcing to reconnect slave I/O thread");
4939           if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4940                                reconnect_messages[SLAVE_RECON_ACT_EVENT]))
4941             goto err;
4942           goto connected;
4943         });
4944 
4945       if (event_len == packet_error)
4946       {
4947         uint mysql_error_number= mysql_errno(mysql);
4948         switch (mysql_error_number) {
4949         case CR_NET_PACKET_TOO_LARGE:
4950           sql_print_error("\
4951 Log entry on master is longer than slave_max_allowed_packet (%lu) on \
4952 slave. If the entry is correct, restart the server with a higher value of \
4953 slave_max_allowed_packet",
4954                          slave_max_allowed_packet);
4955           mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE,
4956                      "%s", "Got a packet bigger than 'slave_max_allowed_packet' bytes");
4957           goto err;
4958         case ER_MASTER_FATAL_ERROR_READING_BINLOG:
4959           mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG,
4960                      ER(ER_MASTER_FATAL_ERROR_READING_BINLOG),
4961                      mysql_error_number, mysql_error(mysql));
4962           goto err;
4963         case ER_OUT_OF_RESOURCES:
4964           sql_print_error("\
4965 Stopping slave I/O thread due to out-of-memory error from master");
4966           mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES,
4967                      "%s", ER(ER_OUT_OF_RESOURCES));
4968           goto err;
4969         }
4970         if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4971                              reconnect_messages[SLAVE_RECON_ACT_EVENT]))
4972           goto err;
4973         goto connected;
4974       } // if (event_len == packet_error)
4975 
4976       retry_count=0;                    // ok event, reset retry counter
4977       THD_STAGE_INFO(thd, stage_queueing_master_event_to_the_relay_log);
4978       event_buf= (const char*)mysql->net.read_pos + 1;
4979       DBUG_PRINT("info", ("IO thread received event of type %s", Log_event::get_type_str((Log_event_type)event_buf[EVENT_TYPE_OFFSET])));
4980       if (RUN_HOOK(binlog_relay_io, after_read_event,
4981                    (thd, mi,(const char*)mysql->net.read_pos + 1,
4982                     event_len, &event_buf, &event_len)))
4983       {
4984         mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4985                    ER(ER_SLAVE_FATAL_ERROR),
4986                    "Failed to run 'after_read_event' hook");
4987         goto err;
4988       }
4989 
4990       /* XXX: 'synced' should be updated by queue_event to indicate
4991          whether event has been synced to disk */
4992       bool synced= 0;
4993       if (queue_event(mi, event_buf, event_len))
4994       {
4995         mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
4996                    ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
4997                    "could not queue event from master");
4998         goto err;
4999       }
5000       if (RUN_HOOK(binlog_relay_io, after_queue_event,
5001                    (thd, mi, event_buf, event_len, synced)))
5002       {
5003         mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5004                    ER(ER_SLAVE_FATAL_ERROR),
5005                    "Failed to run 'after_queue_event' hook");
5006         goto err;
5007       }
5008 
5009       mysql_mutex_lock(&mi->data_lock);
5010       if (flush_master_info(mi, FALSE))
5011       {
5012         mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5013                    ER(ER_SLAVE_FATAL_ERROR),
5014                    "Failed to flush master info.");
5015         mysql_mutex_unlock(&mi->data_lock);
5016         goto err;
5017       }
5018       mysql_mutex_unlock(&mi->data_lock);
5019 
5020       /*
5021         See if the relay logs take too much space.
5022         We don't lock mi->rli->log_space_lock here; this dirty read saves time
5023         and does not introduce any problem:
5024         - if mi->rli->ignore_log_space_limit is 1 but becomes 0 just after (so
5025         the clean value is 0), then we are reading only one more event as we
5026         should, and we'll block only at the next event. No big deal.
5027         - if mi->rli->ignore_log_space_limit is 0 but becomes 1 just after (so
5028         the clean value is 1), then we are going into wait_for_relay_log_space()
5029         for no reason, but this function will do a clean read, notice the clean
5030         value and exit immediately.
5031       */
5032 #ifndef DBUG_OFF
5033       {
5034         char llbuf1[22], llbuf2[22];
5035         DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
5036 ignore_log_space_limit=%d",
5037                             llstr(rli->log_space_limit,llbuf1),
5038                             llstr(rli->log_space_total,llbuf2),
5039                             (int) rli->ignore_log_space_limit));
5040       }
5041 #endif
5042 
5043       if (rli->log_space_limit && rli->log_space_limit <
5044           rli->log_space_total &&
5045           !rli->ignore_log_space_limit)
5046         if (wait_for_relay_log_space(rli))
5047         {
5048           sql_print_error("Slave I/O thread aborted while waiting for relay \
5049 log space");
5050           goto err;
5051         }
5052       DBUG_EXECUTE_IF("flush_after_reading_user_var_event",
5053                       {
5054                       if (event_buf[EVENT_TYPE_OFFSET] == USER_VAR_EVENT)
5055                       {
5056                       const char act[]= "now signal Reached wait_for signal.flush_complete_continue";
5057                       DBUG_ASSERT(opt_debug_sync_timeout > 0);
5058                       DBUG_ASSERT(!debug_sync_set_action(current_thd,
5059                                                          STRING_WITH_LEN(act)));
5060 
5061                       }
5062                       });
5063       DBUG_EXECUTE_IF("stop_io_after_reading_gtid_log_event",
5064         if (event_buf[EVENT_TYPE_OFFSET] == GTID_LOG_EVENT)
5065           thd->killed= THD::KILLED_NO_VALUE;
5066       );
5067       DBUG_EXECUTE_IF("stop_io_after_reading_query_log_event",
5068         if (event_buf[EVENT_TYPE_OFFSET] == QUERY_EVENT)
5069           thd->killed= THD::KILLED_NO_VALUE;
5070       );
5071       DBUG_EXECUTE_IF("stop_io_after_reading_user_var_log_event",
5072         if (event_buf[EVENT_TYPE_OFFSET] == USER_VAR_EVENT)
5073           thd->killed= THD::KILLED_NO_VALUE;
5074       );
5075       DBUG_EXECUTE_IF("stop_io_after_reading_table_map_event",
5076         if (event_buf[EVENT_TYPE_OFFSET] == TABLE_MAP_EVENT)
5077           thd->killed= THD::KILLED_NO_VALUE;
5078       );
5079       DBUG_EXECUTE_IF("stop_io_after_reading_xid_log_event",
5080         if (event_buf[EVENT_TYPE_OFFSET] == XID_EVENT)
5081           thd->killed= THD::KILLED_NO_VALUE;
5082       );
5083       DBUG_EXECUTE_IF("stop_io_after_reading_write_rows_log_event",
5084         if (event_buf[EVENT_TYPE_OFFSET] == WRITE_ROWS_EVENT)
5085           thd->killed= THD::KILLED_NO_VALUE;
5086       );
5087       /*
5088         After event is flushed to relay log file, memory used
5089         by thread's mem_root is not required any more.
5090         Hence adding free_root(thd->mem_root,...) to do the
5091         cleanup, otherwise a long running IO thread can
5092         cause OOM error.
5093       */
5094       free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
5095     }
5096   }
5097 
5098   // error = 0;
5099 err:
5100   // print the current replication position
5101   sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
5102                   mi->get_io_rpl_log_name(), llstr(mi->get_master_log_pos(), llbuff));
5103   (void) RUN_HOOK(binlog_relay_io, thread_stop, (thd, mi));
5104   thd->reset_query();
5105   thd->reset_db(NULL, 0);
5106   if (mysql)
5107   {
5108     /*
5109       Here we need to clear the active VIO before closing the
5110       connection with the master.  The reason is that THD::awake()
5111       might be called from terminate_slave_thread() because somebody
5112       issued a STOP SLAVE.  If that happends, the shutdown_active_vio()
5113       can be called in the middle of closing the VIO associated with
5114       the 'mysql' object, causing a crash.
5115     */
5116 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
5117     thd->clear_active_vio();
5118 #endif
5119     mysql_close(mysql);
5120     mi->mysql=0;
5121   }
5122   mysql_mutex_lock(&mi->data_lock);
5123   write_ignored_events_info_to_relay_log(thd, mi);
5124   mysql_mutex_unlock(&mi->data_lock);
5125   THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit);
5126   mysql_mutex_lock(&mi->run_lock);
5127   /*
5128     Clean information used to start slave in order to avoid
5129     security issues.
5130   */
5131   mi->reset_start_info();
5132   /* Forget the relay log's format */
5133   mysql_mutex_lock(&mi->data_lock);
5134   mi->set_mi_description_event(NULL);
5135   mysql_mutex_unlock(&mi->data_lock);
5136 
5137   DBUG_ASSERT(thd->net.buff != 0);
5138   net_end(&thd->net); // destructor will not free it, because net.vio is 0
5139 
5140   thd->release_resources();
5141   THD_CHECK_SENTRY(thd);
5142   if (thd_added)
5143     remove_global_thread(thd);
5144   delete thd;
5145 
5146   mi->abort_slave= 0;
5147   mi->slave_running= 0;
5148   mi->info_thd= 0;
5149   /*
5150     Note: the order of the two following calls (first broadcast, then unlock)
5151     is important. Otherwise a killer_thread can execute between the calls and
5152     delete the mi structure leading to a crash! (see BUG#25306 for details)
5153    */
5154   mysql_cond_broadcast(&mi->stop_cond);       // tell the world we are done
5155   DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
5156   mysql_mutex_unlock(&mi->run_lock);
5157   DBUG_LEAVE;                                   // Must match DBUG_ENTER()
5158   my_thread_end();
5159 #if OPENSSL_VERSION_NUMBER < 0x10100000L
5160   ERR_remove_thread_state(0);
5161 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
5162    pthread_exit(0);
5163   return(0);                                    // Avoid compiler warnings
5164 }
5165 
5166 /*
5167   Check the temporary directory used by commands like
5168   LOAD DATA INFILE.
5169  */
5170 static
check_temp_dir(char * tmp_file)5171 int check_temp_dir(char* tmp_file)
5172 {
5173   int fd;
5174   MY_DIR *dirp;
5175   char tmp_dir[FN_REFLEN];
5176   size_t tmp_dir_size;
5177 
5178   DBUG_ENTER("check_temp_dir");
5179 
5180   /*
5181     Get the directory from the temporary file.
5182   */
5183   dirname_part(tmp_dir, tmp_file, &tmp_dir_size);
5184 
5185   /*
5186     Check if the directory exists.
5187    */
5188   if (!(dirp=my_dir(tmp_dir,MYF(MY_WME))))
5189     DBUG_RETURN(1);
5190   my_dirend(dirp);
5191 
5192   /*
5193     Check permissions to create a file.
5194    */
5195   //append the server UUID to the temp file name.
5196   char *unique_tmp_file_name= (char*)my_malloc((FN_REFLEN+TEMP_FILE_MAX_LEN)*sizeof(char), MYF(0));
5197   sprintf(unique_tmp_file_name, "%s%s", tmp_file, server_uuid);
5198   if ((fd= mysql_file_create(key_file_misc,
5199                              unique_tmp_file_name, CREATE_MODE,
5200                              O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5201                              MYF(MY_WME))) < 0)
5202   DBUG_RETURN(1);
5203 
5204   /*
5205     Clean up.
5206    */
5207   mysql_file_close(fd, MYF(0));
5208 
5209   mysql_file_delete(key_file_misc, unique_tmp_file_name, MYF(0));
5210   my_free(unique_tmp_file_name);
5211   DBUG_RETURN(0);
5212 }
5213 
5214 /*
5215   Worker thread for the parallel execution of the replication events.
5216 */
handle_slave_worker(void * arg)5217 pthread_handler_t handle_slave_worker(void *arg)
5218 {
5219   THD *thd;                     /* needs to be first for thread_stack */
5220   bool thd_added= false;
5221   int error= 0;
5222   Slave_worker *w= (Slave_worker *) arg;
5223   Relay_log_info* rli= w->c_rli;
5224   ulong purge_cnt= 0;
5225   ulonglong purge_size= 0;
5226   struct slave_job_item _item, *job_item= &_item;
5227 
5228   my_thread_init();
5229   DBUG_ENTER("handle_slave_worker");
5230 
5231   thd= new THD;
5232   if (!thd)
5233   {
5234     sql_print_error("Failed during slave worker initialization");
5235     goto err;
5236   }
5237   w->info_thd= thd;
5238   thd->thread_stack = (char*)&thd;
5239 
5240   pthread_detach_this_thread();
5241   if (init_slave_thread(thd, SLAVE_THD_WORKER))
5242   {
5243     // todo make SQL thread killed
5244     sql_print_error("Failed during slave worker initialization");
5245     goto err;
5246   }
5247   thd->init_for_queries(w);
5248 
5249   mysql_mutex_lock(&LOCK_thread_count);
5250   add_global_thread(thd);
5251   thd_added= true;
5252   mysql_mutex_unlock(&LOCK_thread_count);
5253 
5254   if (w->update_is_transactional())
5255   {
5256     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5257                 "Error checking if the worker repository is transactional.");
5258     goto err;
5259   }
5260 
5261   mysql_mutex_lock(&w->jobs_lock);
5262   w->running_status= Slave_worker::RUNNING;
5263   mysql_cond_signal(&w->jobs_cond);
5264 
5265   mysql_mutex_unlock(&w->jobs_lock);
5266 
5267   DBUG_ASSERT(thd->is_slave_error == 0);
5268 
5269   while (!error)
5270   {
5271       error= slave_worker_exec_job(w, rli);
5272   }
5273 
5274   /*
5275      Cleanup after an error requires clear_error() go first.
5276      Otherwise assert(!all) in binlog_rollback()
5277   */
5278   thd->clear_error();
5279   w->cleanup_context(thd, error);
5280 
5281   mysql_mutex_lock(&w->jobs_lock);
5282 
5283   while(de_queue(&w->jobs, job_item))
5284   {
5285     purge_cnt++;
5286     purge_size += ((Log_event*) (job_item->data))->data_written;
5287     DBUG_ASSERT(job_item->data);
5288     delete static_cast<Log_event*>(job_item->data);
5289   }
5290 
5291   DBUG_ASSERT(w->jobs.len == 0);
5292 
5293   mysql_mutex_unlock(&w->jobs_lock);
5294 
5295   mysql_mutex_lock(&rli->pending_jobs_lock);
5296   rli->pending_jobs -= purge_cnt;
5297   rli->mts_pending_jobs_size -= purge_size;
5298   DBUG_ASSERT(rli->mts_pending_jobs_size < rli->mts_pending_jobs_size_max);
5299 
5300   mysql_mutex_unlock(&rli->pending_jobs_lock);
5301 
5302   /*
5303      In MTS case cleanup_after_session() has be called explicitly.
5304      TODO: to make worker thd be deleted before Slave_worker instance.
5305   */
5306   if (thd->rli_slave)
5307   {
5308     w->cleanup_after_session();
5309     thd->rli_slave= NULL;
5310   }
5311   mysql_mutex_lock(&w->jobs_lock);
5312 
5313   w->running_status= Slave_worker::NOT_RUNNING;
5314   if (log_warnings > 1)
5315     sql_print_information("Worker %lu statistics: "
5316                           "events processed = %lu "
5317                           "hungry waits = %lu "
5318                           "priv queue overfills = %llu ",
5319                           w->id, w->events_done, w->wq_size_waits_cnt,
5320                           w->jobs.waited_overfill);
5321   mysql_cond_signal(&w->jobs_cond);  // famous last goodbye
5322 
5323   mysql_mutex_unlock(&w->jobs_lock);
5324 
5325 err:
5326 
5327   if (thd)
5328   {
5329     /*
5330        The slave code is very bad. Notice that it is missing
5331        several clean up calls here. I've just added what was
5332        necessary to avoid valgrind errors.
5333 
5334        /Alfranio
5335     */
5336     DBUG_ASSERT(thd->net.buff != 0);
5337     net_end(&thd->net);
5338 
5339     /*
5340       to avoid close_temporary_tables() closing temp tables as those
5341       are Coordinator's burden.
5342     */
5343     thd->system_thread= NON_SYSTEM_THREAD;
5344     thd->release_resources();
5345     THD_CHECK_SENTRY(thd);
5346     if (thd_added)
5347       remove_global_thread(thd);
5348     delete thd;
5349   }
5350 
5351   my_thread_end();
5352 #if OPENSSL_VERSION_NUMBER < 0x10100000L
5353   ERR_remove_thread_state(0);
5354 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
5355   pthread_exit(0);
5356   DBUG_RETURN(0);
5357 }
5358 
5359 /**
5360    Orders jobs by comparing relay log information.
5361 */
5362 
mts_event_coord_cmp(LOG_POS_COORD * id1,LOG_POS_COORD * id2)5363 int mts_event_coord_cmp(LOG_POS_COORD *id1, LOG_POS_COORD *id2)
5364 {
5365   longlong filecmp= strcmp(id1->file_name, id2->file_name);
5366   longlong poscmp= id1->pos - id2->pos;
5367   return (filecmp < 0  ? -1 : (filecmp > 0  ?  1 :
5368          (poscmp  < 0  ? -1 : (poscmp  > 0  ?  1 : 0))));
5369 }
5370 
mts_recovery_groups(Relay_log_info * rli)5371 int mts_recovery_groups(Relay_log_info *rli)
5372 {
5373   Log_event *ev= NULL;
5374   const char *errmsg= NULL;
5375   bool error= FALSE;
5376   bool flag_group_seen_begin= FALSE;
5377   uint recovery_group_cnt= 0;
5378   bool not_reached_commit= true;
5379   DYNAMIC_ARRAY above_lwm_jobs;
5380   Slave_job_group job_worker;
5381   IO_CACHE log;
5382   File file;
5383   LOG_INFO linfo;
5384   my_off_t offset= 0;
5385   MY_BITMAP *groups= &rli->recovery_groups;
5386   THD *thd= current_thd;
5387 
5388   DBUG_ENTER("mts_recovery_groups");
5389 
5390   DBUG_ASSERT(rli->slave_parallel_workers == 0);
5391 
5392   /*
5393      Although mts_recovery_groups() is reentrant it returns
5394      early if the previous invocation raised any bit in
5395      recovery_groups bitmap.
5396   */
5397   if (rli->is_mts_recovery())
5398     DBUG_RETURN(0);
5399 
5400   /*
5401     Save relay log position to compare with worker's position.
5402   */
5403   LOG_POS_COORD cp=
5404   {
5405     (char *) rli->get_group_master_log_name(),
5406     rli->get_group_master_log_pos()
5407   };
5408 
5409   Format_description_log_event fdle(BINLOG_VERSION), *p_fdle= &fdle;
5410 
5411   if (!p_fdle->is_valid())
5412     DBUG_RETURN(TRUE);
5413 
5414   /*
5415     Gathers information on valuable workers and stores it in
5416     above_lwm_jobs in asc ordered by the master binlog coordinates.
5417   */
5418   my_init_dynamic_array(&above_lwm_jobs, sizeof(Slave_job_group),
5419                         rli->recovery_parallel_workers,
5420                         rli->recovery_parallel_workers);
5421 
5422   /*
5423     When info tables are used and autocommit= 0 we force a new
5424     transaction start to avoid table access deadlocks when START SLAVE
5425     is executed after STOP SLAVE with MTS enabled.
5426   */
5427   if (is_autocommit_off_and_infotables(thd))
5428   {
5429     if (trans_begin(thd))
5430     {
5431       error= TRUE;
5432       goto err;
5433     }
5434   }
5435 
5436   for (uint id= 0; id < rli->recovery_parallel_workers; id++)
5437   {
5438     Slave_worker *worker=
5439       Rpl_info_factory::create_worker(opt_rli_repository_id, id, rli, true);
5440 
5441     if (!worker)
5442     {
5443       if (is_autocommit_off_and_infotables(thd))
5444         trans_rollback(thd);
5445       error= TRUE;
5446       goto err;
5447     }
5448 
5449     LOG_POS_COORD w_last= { const_cast<char*>(worker->get_group_master_log_name()),
5450                             worker->get_group_master_log_pos() };
5451     if (mts_event_coord_cmp(&w_last, &cp) > 0)
5452     {
5453       /*
5454         Inserts information into a dynamic array for further processing.
5455         The jobs/workers are ordered by the last checkpoint positions
5456         workers have seen.
5457       */
5458       job_worker.worker= worker;
5459       job_worker.checkpoint_log_pos= worker->checkpoint_master_log_pos;
5460       job_worker.checkpoint_log_name= worker->checkpoint_master_log_name;
5461 
5462       insert_dynamic(&above_lwm_jobs, (uchar*) &job_worker);
5463     }
5464     else
5465     {
5466       /*
5467         Deletes the worker because its jobs are included in the latest
5468         checkpoint.
5469       */
5470       delete worker;
5471     }
5472   }
5473 
5474   /*
5475     When info tables are used and autocommit= 0 we force transaction
5476     commit to avoid table access deadlocks when START SLAVE is executed
5477     after STOP SLAVE with MTS enabled.
5478   */
5479   if (is_autocommit_off_and_infotables(thd))
5480   {
5481     if (trans_commit(thd))
5482     {
5483       error= TRUE;
5484       goto err;
5485     }
5486   }
5487 
5488   /*
5489     In what follows, the group Recovery Bitmap is constructed.
5490 
5491      seek(lwm);
5492 
5493      while(w= next(above_lwm_w))
5494        do
5495          read G
5496          if G == w->last_comm
5497            w.B << group_cnt++;
5498            RB |= w.B;
5499             break;
5500          else
5501            group_cnt++;
5502         while(!eof);
5503         continue;
5504   */
5505   DBUG_ASSERT(!rli->recovery_groups_inited);
5506 
5507   if (above_lwm_jobs.elements != 0)
5508   {
5509     bitmap_init(groups, NULL, MTS_MAX_BITS_IN_GROUP, FALSE);
5510     rli->recovery_groups_inited= true;
5511     bitmap_clear_all(groups);
5512   }
5513   rli->mts_recovery_group_cnt= 0;
5514   for (uint it_job= 0; it_job < above_lwm_jobs.elements; it_job++)
5515   {
5516     Slave_worker *w= ((Slave_job_group *)
5517                       dynamic_array_ptr(&above_lwm_jobs, it_job))->worker;
5518     LOG_POS_COORD w_last= { const_cast<char*>(w->get_group_master_log_name()),
5519                             w->get_group_master_log_pos() };
5520     bool checksum_detected= FALSE;
5521 
5522     sql_print_information("Slave: MTS group recovery relay log info based on Worker-Id %lu, "
5523                           "group_relay_log_name %s, group_relay_log_pos %llu "
5524                           "group_master_log_name %s, group_master_log_pos %llu",
5525                           w->id,
5526                           w->get_group_relay_log_name(),
5527                           w->get_group_relay_log_pos(),
5528                           w->get_group_master_log_name(),
5529                           w->get_group_master_log_pos());
5530 
5531     recovery_group_cnt= 0;
5532     not_reached_commit= true;
5533     if (rli->relay_log.find_log_pos(&linfo, rli->get_group_relay_log_name(), 1))
5534     {
5535       error= TRUE;
5536       sql_print_error("Error looking for %s.", rli->get_group_relay_log_name());
5537       goto err;
5538     }
5539     offset= rli->get_group_relay_log_pos();
5540     for (int checking= 0 ; not_reached_commit; checking++)
5541     {
5542       if ((file= open_binlog_file(&log, linfo.log_file_name, &errmsg)) < 0)
5543       {
5544         error= TRUE;
5545         sql_print_error("%s", errmsg);
5546         goto err;
5547       }
5548       /*
5549         Looking for the actual relay checksum algorithm that is present in
5550         a FD at head events of the relay log.
5551       */
5552       if (!checksum_detected)
5553       {
5554         int i= 0;
5555         while (i < 4 && (ev= Log_event::read_log_event(&log,
5556                (mysql_mutex_t*) 0, p_fdle, 0)))
5557         {
5558           if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
5559           {
5560             p_fdle->checksum_alg= ev->checksum_alg;
5561             checksum_detected= TRUE;
5562           }
5563           delete ev;
5564           i++;
5565         }
5566         if (!checksum_detected)
5567         {
5568           error= TRUE;
5569           sql_print_error("%s", "malformed or very old relay log which "
5570                           "does not have FormatDescriptor");
5571           goto err;
5572         }
5573       }
5574 
5575       my_b_seek(&log, offset);
5576 
5577       while (not_reached_commit &&
5578              (ev= Log_event::read_log_event(&log, 0, p_fdle,
5579                                             opt_slave_sql_verify_checksum)))
5580       {
5581         DBUG_ASSERT(ev->is_valid());
5582 
5583         if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
5584           p_fdle->checksum_alg= ev->checksum_alg;
5585 
5586         if (ev->get_type_code() == ROTATE_EVENT ||
5587             ev->get_type_code() == FORMAT_DESCRIPTION_EVENT ||
5588             ev->get_type_code() == PREVIOUS_GTIDS_LOG_EVENT)
5589         {
5590           delete ev;
5591           ev= NULL;
5592           continue;
5593         }
5594 
5595         DBUG_PRINT("mts", ("Event Recoverying relay log info "
5596                    "group_mster_log_name %s, event_master_log_pos %llu type code %u.",
5597                    linfo.log_file_name, ev->log_pos, ev->get_type_code()));
5598 
5599         if (ev->starts_group())
5600         {
5601           flag_group_seen_begin= true;
5602         }
5603         else if ((ev->ends_group() || !flag_group_seen_begin) &&
5604                  !is_gtid_event(ev))
5605         {
5606           int ret= 0;
5607           LOG_POS_COORD ev_coord= { (char *) rli->get_group_master_log_name(),
5608                                       ev->log_pos };
5609           flag_group_seen_begin= false;
5610           recovery_group_cnt++;
5611 
5612           sql_print_information("Slave: MTS group recovery relay log info "
5613                                 "group_master_log_name %s, "
5614                                 "event_master_log_pos %llu.",
5615                                 rli->get_group_master_log_name(), ev->log_pos);
5616           if ((ret= mts_event_coord_cmp(&ev_coord, &w_last)) == 0)
5617           {
5618 #ifndef DBUG_OFF
5619             for (uint i= 0; i <= w->checkpoint_seqno; i++)
5620             {
5621               if (bitmap_is_set(&w->group_executed, i))
5622                 DBUG_PRINT("mts", ("Bit %u is set.", i));
5623               else
5624                 DBUG_PRINT("mts", ("Bit %u is not set.", i));
5625             }
5626 #endif
5627             DBUG_PRINT("mts",
5628                        ("Doing a shift ini(%lu) end(%lu).",
5629                        (w->checkpoint_seqno + 1) - recovery_group_cnt,
5630                         w->checkpoint_seqno));
5631 
5632             for (uint i= (w->checkpoint_seqno + 1) - recovery_group_cnt,
5633                  j= 0; i <= w->checkpoint_seqno; i++, j++)
5634             {
5635               if (bitmap_is_set(&w->group_executed, i))
5636               {
5637                 DBUG_PRINT("mts", ("Setting bit %u.", j));
5638                 bitmap_fast_test_and_set(groups, j);
5639               }
5640             }
5641             not_reached_commit= false;
5642           }
5643           else
5644             DBUG_ASSERT(ret < 0);
5645         }
5646         delete ev;
5647         ev= NULL;
5648       }
5649       end_io_cache(&log);
5650       mysql_file_close(file, MYF(MY_WME));
5651       offset= BIN_LOG_HEADER_SIZE;
5652       if (not_reached_commit && rli->relay_log.find_next_log(&linfo, 1))
5653       {
5654          error= TRUE;
5655          sql_print_error("Error looking for file after %s.", linfo.log_file_name);
5656          goto err;
5657       }
5658     }
5659 
5660     rli->mts_recovery_group_cnt= (rli->mts_recovery_group_cnt < recovery_group_cnt ?
5661       recovery_group_cnt : rli->mts_recovery_group_cnt);
5662   }
5663 
5664   DBUG_ASSERT(!rli->recovery_groups_inited ||
5665               rli->mts_recovery_group_cnt <= groups->n_bits);
5666 
5667 err:
5668 
5669   for (uint it_job= 0; it_job < above_lwm_jobs.elements; it_job++)
5670   {
5671     get_dynamic(&above_lwm_jobs, (uchar *) &job_worker, it_job);
5672     delete job_worker.worker;
5673   }
5674 
5675   delete_dynamic(&above_lwm_jobs);
5676   if (rli->mts_recovery_group_cnt == 0)
5677     rli->clear_mts_recovery_groups();
5678 
5679   DBUG_RETURN(error ? ER_MTS_RECOVERY_FAILURE : 0);
5680 }
5681 
5682 /**
5683    Processing rli->gaq to find out the low-water-mark (lwm) coordinates
5684    which is stored into the cental recovery table.
5685 
5686    @param rli            pointer to Relay-log-info of Coordinator
5687    @param period         period of processing GAQ, normally derived from
5688                          @c mts_checkpoint_period
5689    @param force          if TRUE then hang in a loop till some progress
5690    @param need_data_lock False if rli->data_lock mutex is aquired by
5691                          the caller.
5692 
5693    @return FALSE success, TRUE otherwise
5694 */
mts_checkpoint_routine(Relay_log_info * rli,ulonglong period,bool force,bool need_data_lock)5695 bool mts_checkpoint_routine(Relay_log_info *rli, ulonglong period,
5696                             bool force, bool need_data_lock)
5697 {
5698   ulong cnt;
5699   bool error= FALSE;
5700   struct timespec curr_clock;
5701 
5702   DBUG_ENTER("checkpoint_routine");
5703 
5704 #ifndef DBUG_OFF
5705   if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
5706   {
5707     if (!rli->gaq->count_done(rli))
5708       DBUG_RETURN(FALSE);
5709   }
5710 #endif
5711 
5712   /*
5713     rli->checkpoint_group can have two possible values due to
5714     two possible status of the last (being scheduled) group.
5715   */
5716   DBUG_ASSERT(!rli->gaq->full() ||
5717               ((rli->checkpoint_seqno == rli->checkpoint_group -1 &&
5718                 rli->mts_group_status == Relay_log_info::MTS_IN_GROUP) ||
5719                rli->checkpoint_seqno == rli->checkpoint_group));
5720 
5721   /*
5722     Currently, the checkpoint routine is being called by the SQL Thread.
5723     For that reason, this function is called call from appropriate points
5724     in the SQL Thread's execution path and the elapsed time is calculated
5725     here to check if it is time to execute it.
5726   */
5727   set_timespec_nsec(curr_clock, 0);
5728   ulonglong diff= diff_timespec(curr_clock, rli->last_clock);
5729   if (!force && diff < period)
5730   {
5731     /*
5732       We do not need to execute the checkpoint now because
5733       the time elapsed is not enough.
5734     */
5735     DBUG_RETURN(FALSE);
5736   }
5737 
5738   do
5739   {
5740     cnt= rli->gaq->move_queue_head(&rli->workers);
5741 #ifndef DBUG_OFF
5742     if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0) &&
5743         cnt != opt_mts_checkpoint_period)
5744       sql_print_error("This an error cnt != mts_checkpoint_period");
5745 #endif
5746   } while (!sql_slave_killed(rli->info_thd, rli) &&
5747            cnt == 0 && force &&
5748            !DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0) &&
5749            (my_sleep(rli->mts_coordinator_basic_nap), 1));
5750   /*
5751     This checks how many consecutive jobs where processed.
5752     If this value is different than zero the checkpoint
5753     routine can proceed. Otherwise, there is nothing to be
5754     done.
5755   */
5756   if (cnt == 0)
5757     goto end;
5758 
5759 
5760   /* TODO:
5761      to turn the least occupied selection in terms of jobs pieces
5762   */
5763   for (uint i= 0; i < rli->workers.elements; i++)
5764   {
5765     Slave_worker *w_i;
5766     get_dynamic(&rli->workers, (uchar *) &w_i, i);
5767     set_dynamic(&rli->least_occupied_workers, (uchar*) &w_i->jobs.len, w_i->id);
5768   };
5769   sort_dynamic(&rli->least_occupied_workers, (qsort_cmp) ulong_cmp);
5770 
5771   if (need_data_lock)
5772     mysql_mutex_lock(&rli->data_lock);
5773   else
5774     mysql_mutex_assert_owner(&rli->data_lock);
5775 
5776   /*
5777     "Coordinator::commit_positions" {
5778 
5779     rli->gaq->lwm has been updated in move_queue_head() and
5780     to contain all but rli->group_master_log_name which
5781     is altered solely by Coordinator at special checkpoints.
5782   */
5783   rli->set_group_master_log_pos(rli->gaq->lwm.group_master_log_pos);
5784   rli->set_group_relay_log_pos(rli->gaq->lwm.group_relay_log_pos);
5785   DBUG_PRINT("mts", ("New checkpoint %llu %llu %s",
5786              rli->gaq->lwm.group_master_log_pos,
5787              rli->gaq->lwm.group_relay_log_pos,
5788              rli->gaq->lwm.group_relay_log_name));
5789 
5790   if (rli->gaq->lwm.group_relay_log_name[0] != 0)
5791     rli->set_group_relay_log_name(rli->gaq->lwm.group_relay_log_name);
5792 
5793   /*
5794      todo: uncomment notifies when UNTIL will be supported
5795 
5796      rli->notify_group_master_log_name_update();
5797      rli->notify_group_relay_log_name_update();
5798 
5799      Todo: optimize with if (wait_flag) broadcast
5800          waiter: set wait_flag; waits....; drops wait_flag;
5801   */
5802 
5803   error= rli->flush_info(TRUE);
5804 
5805   mysql_cond_broadcast(&rli->data_cond);
5806   if (need_data_lock)
5807     mysql_mutex_unlock(&rli->data_lock);
5808 
5809   /*
5810     We need to ensure that this is never called at this point when
5811     cnt is zero. This value means that the checkpoint information
5812     will be completely reset.
5813   */
5814   rli->reset_notified_checkpoint(cnt, rli->gaq->lwm.ts, need_data_lock);
5815 
5816   /* end-of "Coordinator::"commit_positions" */
5817 
5818 end:
5819 #ifndef DBUG_OFF
5820   if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
5821     DBUG_SUICIDE();
5822 #endif
5823   set_timespec_nsec(rli->last_clock, 0);
5824 
5825   DBUG_RETURN(error);
5826 }
5827 
5828 /**
5829    Instantiation of a Slave_worker and forking out a single Worker thread.
5830 
5831    @param  rli  Coordinator's Relay_log_info pointer
5832    @param  i    identifier of the Worker
5833 
5834    @return 0 suppress or 1 if fails
5835 */
slave_start_single_worker(Relay_log_info * rli,ulong i)5836 int slave_start_single_worker(Relay_log_info *rli, ulong i)
5837 {
5838   int error= 0;
5839   pthread_t th;
5840   Slave_worker *w= NULL;
5841 
5842   mysql_mutex_assert_owner(&rli->run_lock);
5843 
5844   if (!(w=
5845         Rpl_info_factory::create_worker(opt_rli_repository_id, i, rli, false)))
5846   {
5847     sql_print_error("Failed during slave worker thread create");
5848     error= 1;
5849     goto err;
5850   }
5851 
5852   if (w->init_worker(rli, i))
5853   {
5854     sql_print_error("Failed during slave worker thread create");
5855     error= 1;
5856     goto err;
5857   }
5858   set_dynamic(&rli->workers, (uchar*) &w, i);
5859 
5860   if (DBUG_EVALUATE_IF("mts_worker_thread_fails", i == 1, 0) ||
5861       (error= mysql_thread_create(key_thread_slave_worker, &th,
5862                                   &connection_attrib,
5863                                   handle_slave_worker, (void*) w)))
5864   {
5865     sql_print_error("Failed during slave worker thread create (errno= %d)",
5866                     error);
5867     error= 1;
5868     goto err;
5869   }
5870 
5871   mysql_mutex_lock(&w->jobs_lock);
5872   if (w->running_status == Slave_worker::NOT_RUNNING)
5873     mysql_cond_wait(&w->jobs_cond, &w->jobs_lock);
5874   mysql_mutex_unlock(&w->jobs_lock);
5875   // Least occupied inited with zero
5876   insert_dynamic(&rli->least_occupied_workers, (uchar*) &w->jobs.len);
5877 
5878 err:
5879   if (error && w)
5880   {
5881     delete w;
5882     /*
5883       Any failure after dynarray inserted must follow with deletion
5884       of just created item.
5885     */
5886     if (rli->workers.elements == i + 1)
5887       delete_dynamic_element(&rli->workers, i);
5888   }
5889   return error;
5890 }
5891 
5892 /**
5893    Initialization of the central rli members for Coordinator's role,
5894    communication channels such as Assigned Partition Hash (APH),
5895    and starting the Worker pool.
5896 
5897    @param  n   Number of configured Workers in the upcoming session.
5898 
5899    @return 0         success
5900            non-zero  as failure
5901 */
slave_start_workers(Relay_log_info * rli,ulong n,bool * mts_inited)5902 int slave_start_workers(Relay_log_info *rli, ulong n, bool *mts_inited)
5903 {
5904   uint i;
5905   int error= 0;
5906 
5907   mysql_mutex_assert_owner(&rli->run_lock);
5908 
5909   if (n == 0 && rli->mts_recovery_group_cnt == 0)
5910   {
5911     reset_dynamic(&rli->workers);
5912     goto end;
5913   }
5914 
5915   *mts_inited= true;
5916 
5917   /*
5918     The requested through argument number of Workers can be different
5919      from the previous time which ended with an error. Thereby
5920      the effective number of configured Workers is max of the two.
5921   */
5922   rli->init_workers(max(n, rli->recovery_parallel_workers));
5923 
5924   // CGAP dynarray holds id:s of partitions of the Current being executed Group
5925   my_init_dynamic_array(&rli->curr_group_assigned_parts,
5926                         sizeof(db_worker_hash_entry*),
5927                         SLAVE_INIT_DBS_IN_GROUP, 1);
5928   rli->last_assigned_worker= NULL;     // associated with curr_group_assigned
5929   my_init_dynamic_array(&rli->curr_group_da, sizeof(Log_event*), 8, 2);
5930   // Least_occupied_workers array to hold items size of Slave_jobs_queue::len
5931   my_init_dynamic_array(&rli->least_occupied_workers, sizeof(ulong), n, 0);
5932 
5933   /*
5934      GAQ  queue holds seqno:s of scheduled groups. C polls workers in
5935      @c opt_mts_checkpoint_period to update GAQ (see @c next_event())
5936      The length of GAQ is set to be equal to checkpoint_group.
5937      Notice, the size matters for mts_checkpoint_routine's progress loop.
5938   */
5939 
5940   rli->gaq= new Slave_committed_queue(rli->get_group_master_log_name(),
5941                                       sizeof(Slave_job_group),
5942                                       rli->checkpoint_group, n);
5943   if (!rli->gaq->inited)
5944     return 1;
5945 
5946   // length of WQ is actually constant though can be made configurable
5947   rli->mts_slave_worker_queue_len_max= mts_slave_worker_queue_len_max;
5948   rli->mts_pending_jobs_size= 0;
5949   rli->mts_pending_jobs_size_max= ::opt_mts_pending_jobs_size_max;
5950   rli->mts_wq_underrun_w_id= MTS_WORKER_UNDEF;
5951   rli->mts_wq_excess_cnt= 0;
5952   rli->mts_wq_overrun_cnt= 0;
5953   rli->mts_wq_oversize= FALSE;
5954   rli->mts_coordinator_basic_nap= mts_coordinator_basic_nap;
5955   rli->mts_worker_underrun_level= mts_worker_underrun_level;
5956   rli->curr_group_seen_begin= rli->curr_group_seen_gtid= false;
5957   rli->curr_group_isolated= FALSE;
5958   rli->checkpoint_seqno= 0;
5959   rli->mts_last_online_stat= my_time(0);
5960   rli->mts_group_status= Relay_log_info::MTS_NOT_IN_GROUP;
5961 
5962   if (init_hash_workers(n))  // MTS: mapping_db_to_worker
5963   {
5964     sql_print_error("Failed to init partitions hash");
5965     error= 1;
5966     goto err;
5967   }
5968 
5969   for (i= 0; i < n; i++)
5970   {
5971     if ((error= slave_start_single_worker(rli, i)))
5972       goto err;
5973     rli->slave_parallel_workers++;
5974   }
5975 
5976 end:
5977   // Effective end of the recovery right now when there is no gaps
5978   if (!error && rli->mts_recovery_group_cnt == 0)
5979   {
5980     if ((error= rli->mts_finalize_recovery()))
5981       (void) Rpl_info_factory::reset_workers(rli);
5982     if (!error)
5983       error= rli->flush_info(TRUE);
5984   }
5985 
5986 err:
5987   return error;
5988 }
5989 
5990 /*
5991    Ending Worker threads.
5992 
5993    Not in case Coordinator is killed itself, it first waits for
5994    Workers have finished their assignements, and then updates checkpoint.
5995    Workers are notified with setting KILLED status
5996    and waited for their acknowledgment as specified by
5997    worker's running_status.
5998    Coordinator finalizes with its MTS running status to reset few objects.
5999 */
slave_stop_workers(Relay_log_info * rli,bool * mts_inited)6000 void slave_stop_workers(Relay_log_info *rli, bool *mts_inited)
6001 {
6002   int i;
6003   THD *thd= rli->info_thd;
6004   if (!*mts_inited)
6005     return;
6006   else if (rli->slave_parallel_workers == 0)
6007     goto end;
6008 
6009   /*
6010     If request for stop slave is received notify worker
6011     to stop.
6012   */
6013   // Initialize worker exit count and max_updated_index to 0 during each stop.
6014   rli->exit_counter= 0;
6015   rli->max_updated_index= (rli->until_condition !=
6016                            Relay_log_info::UNTIL_NONE)?
6017                            rli->mts_groups_assigned:0;
6018 
6019   for (i= rli->workers.elements - 1; i >= 0; i--)
6020   {
6021     Slave_worker *w;
6022     struct slave_job_item item= {NULL}, *job_item= &item;
6023     get_dynamic((DYNAMIC_ARRAY*)&rli->workers, (uchar*) &w, i);
6024     mysql_mutex_lock(&w->jobs_lock);
6025     //Inform all workers to stop
6026     if (w->running_status != Slave_worker::RUNNING)
6027     {
6028       mysql_mutex_unlock(&w->jobs_lock);
6029       continue;
6030     }
6031 
6032     w->running_status= Slave_worker::STOP;
6033     (void) set_max_updated_index_on_stop(w, job_item);
6034     mysql_cond_signal(&w->jobs_cond);
6035 
6036     mysql_mutex_unlock(&w->jobs_lock);
6037 
6038     if (log_warnings > 1)
6039       sql_print_information("Notifying Worker %lu to exit, thd %p", w->id,
6040                             w->info_thd);
6041   }
6042 
6043   thd_proc_info(thd, "Waiting for workers to exit");
6044 
6045   for (i= rli->workers.elements - 1; i >= 0; i--)
6046   {
6047     Slave_worker *w= NULL;
6048     get_dynamic((DYNAMIC_ARRAY*)&rli->workers, (uchar*) &w, i);
6049 
6050     mysql_mutex_lock(&w->jobs_lock);
6051     while (w->running_status != Slave_worker::NOT_RUNNING)
6052     {
6053       PSI_stage_info old_stage;
6054       DBUG_ASSERT(w->running_status == Slave_worker::ERROR_LEAVING ||
6055                   w->running_status == Slave_worker::STOP ||
6056                   w->running_status == Slave_worker::STOP_ACCEPTED);
6057 
6058       thd->ENTER_COND(&w->jobs_cond, &w->jobs_lock,
6059                       &stage_slave_waiting_workers_to_exit, &old_stage);
6060       mysql_cond_wait(&w->jobs_cond, &w->jobs_lock);
6061       thd->EXIT_COND(&old_stage);
6062       mysql_mutex_lock(&w->jobs_lock);
6063     }
6064     mysql_mutex_unlock(&w->jobs_lock);
6065   }
6066 
6067   if (thd->killed == THD::NOT_KILLED)
6068     (void) mts_checkpoint_routine(rli, 0, false, true/*need_data_lock=true*/); // TODO:consider to propagate an error out of the function
6069 
6070   for (i= rli->workers.elements - 1; i >= 0; i--)
6071   {
6072     Slave_worker *w= NULL;
6073     get_dynamic((DYNAMIC_ARRAY*)&rli->workers, (uchar*) &w, i);
6074     delete_dynamic_element(&rli->workers, i);
6075     delete w;
6076   }
6077   if (log_warnings > 1)
6078     sql_print_information("Total MTS session statistics: "
6079                           "events processed = %llu; "
6080                           "worker queues filled over overrun level = %lu; "
6081                           "waited due a Worker queue full = %lu; "
6082                           "waited due the total size = %lu; "
6083                           "slept when Workers occupied = %lu ",
6084                           rli->mts_events_assigned, rli->mts_wq_overrun_cnt,
6085                           rli->mts_wq_overfill_cnt, rli->wq_size_waits_cnt,
6086                           rli->mts_wq_no_underrun_cnt);
6087 
6088   DBUG_ASSERT(rli->pending_jobs == 0);
6089   DBUG_ASSERT(rli->mts_pending_jobs_size == 0);
6090 
6091 end:
6092   rli->mts_group_status= Relay_log_info::MTS_NOT_IN_GROUP;
6093   destroy_hash_workers(rli);
6094   delete rli->gaq;
6095   delete_dynamic(&rli->least_occupied_workers);    // least occupied
6096 
6097   // Destroy buffered events of the current group prior to exit.
6098   for (uint i= 0; i < rli->curr_group_da.elements; i++)
6099     delete *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, i);
6100   delete_dynamic(&rli->curr_group_da);             // GCDA
6101 
6102   delete_dynamic(&rli->curr_group_assigned_parts); // GCAP
6103   rli->deinit_workers();
6104   rli->slave_parallel_workers= 0;
6105   *mts_inited= false;
6106 }
6107 
6108 
6109 /**
6110   Slave SQL thread entry point.
6111 
6112   @param arg Pointer to Relay_log_info object that holds information
6113   for the SQL thread.
6114 
6115   @return Always 0.
6116 */
handle_slave_sql(void * arg)6117 pthread_handler_t handle_slave_sql(void *arg)
6118 {
6119   THD *thd;                     /* needs to be first for thread_stack */
6120   bool thd_added= false;
6121   char llbuff[22],llbuff1[22];
6122   char saved_log_name[FN_REFLEN];
6123   char saved_master_log_name[FN_REFLEN];
6124   my_off_t saved_log_pos= 0;
6125   my_off_t saved_master_log_pos= 0;
6126   my_off_t saved_skip= 0;
6127 
6128   Relay_log_info* rli = ((Master_info*)arg)->rli;
6129   const char *errmsg;
6130   const char *error_string;
6131   bool mts_inited= false;
6132 
6133   // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
6134   my_thread_init();
6135   DBUG_ENTER("handle_slave_sql");
6136 
6137   DBUG_ASSERT(rli->inited);
6138   mysql_mutex_lock(&rli->run_lock);
6139   DBUG_ASSERT(!rli->slave_running);
6140   errmsg= 0;
6141   error_string= 0;
6142 #ifndef DBUG_OFF
6143   rli->events_until_exit = abort_slave_event_count;
6144 #endif
6145 
6146   thd = new THD; // note that contructor of THD uses DBUG_ !
6147   thd->thread_stack = (char*)&thd; // remember where our stack is
6148   rli->info_thd= thd;
6149 
6150   /* Inform waiting threads that slave has started */
6151   rli->slave_run_id++;
6152   rli->slave_running = 1;
6153   rli->reported_unsafe_warning= false;
6154   rli->sql_thread_kill_accepted= false;
6155 
6156   pthread_detach_this_thread();
6157   if (init_slave_thread(thd, SLAVE_THD_SQL))
6158   {
6159     /*
6160       TODO: this is currently broken - slave start and change master
6161       will be stuck if we fail here
6162     */
6163     mysql_cond_broadcast(&rli->start_cond);
6164     mysql_mutex_unlock(&rli->run_lock);
6165     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6166                 "Failed during slave thread initialization");
6167     goto err;
6168   }
6169   thd->init_for_queries(rli);
6170   thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
6171   set_thd_in_use_temporary_tables(rli);   // (re)set sql_thd in use for saved temp tables
6172 
6173   mysql_mutex_lock(&LOCK_thread_count);
6174   add_global_thread(thd);
6175   thd_added= true;
6176   mysql_mutex_unlock(&LOCK_thread_count);
6177 
6178   /* MTS: starting the worker pool */
6179   if (slave_start_workers(rli, rli->opt_slave_parallel_workers, &mts_inited) != 0)
6180   {
6181     mysql_cond_broadcast(&rli->start_cond);
6182     mysql_mutex_unlock(&rli->run_lock);
6183     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6184                 "Failed during slave workers initialization");
6185     goto err;
6186   }
6187   /*
6188     We are going to set slave_running to 1. Assuming slave I/O thread is
6189     alive and connected, this is going to make Seconds_Behind_Master be 0
6190     i.e. "caught up". Even if we're just at start of thread. Well it's ok, at
6191     the moment we start we can think we are caught up, and the next second we
6192     start receiving data so we realize we are not caught up and
6193     Seconds_Behind_Master grows. No big deal.
6194   */
6195   rli->abort_slave = 0;
6196 
6197   /*
6198     Reset errors for a clean start (otherwise, if the master is idle, the SQL
6199     thread may execute no Query_log_event, so the error will remain even
6200     though there's no problem anymore). Do not reset the master timestamp
6201     (imagine the slave has caught everything, the STOP SLAVE and START SLAVE:
6202     as we are not sure that we are going to receive a query, we want to
6203     remember the last master timestamp (to say how many seconds behind we are
6204     now.
6205     But the master timestamp is reset by RESET SLAVE & CHANGE MASTER.
6206   */
6207   rli->clear_error();
6208 
6209   if (rli->update_is_transactional())
6210   {
6211     mysql_cond_broadcast(&rli->start_cond);
6212     mysql_mutex_unlock(&rli->run_lock);
6213     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6214                 "Error checking if the relay log repository is transactional.");
6215     goto err;
6216   }
6217 
6218   if (!rli->is_transactional())
6219     rli->report(WARNING_LEVEL, 0,
6220     "If a crash happens this configuration does not guarantee that the relay "
6221     "log info will be consistent");
6222 
6223   mysql_mutex_unlock(&rli->run_lock);
6224   mysql_cond_broadcast(&rli->start_cond);
6225 
6226   DEBUG_SYNC(thd, "after_start_slave");
6227 
6228   //tell the I/O thread to take relay_log_space_limit into account from now on
6229   mysql_mutex_lock(&rli->log_space_lock);
6230   rli->ignore_log_space_limit= 0;
6231   mysql_mutex_unlock(&rli->log_space_lock);
6232   rli->trans_retries= 0; // start from "no error"
6233   DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries));
6234 
6235   if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
6236                               rli->get_group_relay_log_pos(),
6237                               true/*need_data_lock=true*/, &errmsg,
6238                               1 /*look for a description_event*/))
6239   {
6240     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6241                 "Error initializing relay log position: %s", errmsg);
6242     goto err;
6243   }
6244   THD_CHECK_SENTRY(thd);
6245 #ifndef DBUG_OFF
6246   {
6247     char llbuf1[22], llbuf2[22];
6248     DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
6249                         llstr(my_b_tell(rli->cur_log),llbuf1),
6250                         llstr(rli->get_event_relay_log_pos(),llbuf2)));
6251     DBUG_ASSERT(rli->get_event_relay_log_pos() >= BIN_LOG_HEADER_SIZE);
6252     /*
6253       Wonder if this is correct. I (Guilhem) wonder if my_b_tell() returns the
6254       correct position when it's called just after my_b_seek() (the questionable
6255       stuff is those "seek is done on next read" comments in the my_b_seek()
6256       source code).
6257       The crude reality is that this assertion randomly fails whereas
6258       replication seems to work fine. And there is no easy explanation why it
6259       fails (as we my_b_seek(rli->event_relay_log_pos) at the very end of
6260       init_relay_log_pos() called above). Maybe the assertion would be
6261       meaningful if we held rli->data_lock between the my_b_seek() and the
6262       DBUG_ASSERT().
6263     */
6264 #ifdef SHOULD_BE_CHECKED
6265     DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->get_event_relay_log_pos());
6266 #endif
6267   }
6268 #endif
6269   DBUG_ASSERT(rli->info_thd == thd);
6270 
6271 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
6272   /* engine specific hook, to be made generic */
6273   if (ndb_wait_setup_func && ndb_wait_setup_func(opt_ndb_wait_setup))
6274   {
6275     sql_print_warning("Slave SQL thread : NDB : Tables not available after %lu"
6276                       " seconds.  Consider increasing --ndb-wait-setup value",
6277                       opt_ndb_wait_setup);
6278   }
6279 #endif
6280 
6281   DBUG_PRINT("master_info",("log_file_name: %s  position: %s",
6282                             rli->get_group_master_log_name(),
6283                             llstr(rli->get_group_master_log_pos(),llbuff)));
6284   if (log_warnings)
6285     sql_print_information("Slave SQL thread initialized, starting replication in \
6286 log '%s' at position %s, relay log '%s' position: %s", rli->get_rpl_log_name(),
6287                     llstr(rli->get_group_master_log_pos(),llbuff),rli->get_group_relay_log_name(),
6288                     llstr(rli->get_group_relay_log_pos(),llbuff1));
6289 
6290   if (check_temp_dir(rli->slave_patternload_file))
6291   {
6292     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
6293                 "Unable to use slave's temporary directory %s - %s",
6294                 slave_load_tmpdir, thd->get_stmt_da()->message());
6295     goto err;
6296   }
6297 
6298   /* execute init_slave variable */
6299   if (opt_init_slave.length)
6300   {
6301     execute_init_command(thd, &opt_init_slave, &LOCK_sys_init_slave);
6302     if (thd->is_slave_error)
6303     {
6304       rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
6305                   "Slave SQL thread aborted. Can't execute init_slave query");
6306       goto err;
6307     }
6308   }
6309 
6310   /*
6311     First check until condition - probably there is nothing to execute. We
6312     do not want to wait for next event in this case.
6313   */
6314   mysql_mutex_lock(&rli->data_lock);
6315   if (rli->slave_skip_counter)
6316   {
6317     strmake(saved_log_name, rli->get_group_relay_log_name(), FN_REFLEN - 1);
6318     strmake(saved_master_log_name, rli->get_group_master_log_name(), FN_REFLEN - 1);
6319     saved_log_pos= rli->get_group_relay_log_pos();
6320     saved_master_log_pos= rli->get_group_master_log_pos();
6321     saved_skip= rli->slave_skip_counter;
6322   }
6323   if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
6324       rli->is_until_satisfied(thd, NULL))
6325   {
6326     mysql_mutex_unlock(&rli->data_lock);
6327     goto err;
6328   }
6329   mysql_mutex_unlock(&rli->data_lock);
6330 
6331   /* Read queries from the IO/THREAD until this thread is killed */
6332 
6333   while (!sql_slave_killed(thd,rli))
6334   {
6335     THD_STAGE_INFO(thd, stage_reading_event_from_the_relay_log);
6336     DBUG_ASSERT(rli->info_thd == thd);
6337     THD_CHECK_SENTRY(thd);
6338 
6339     if (saved_skip && rli->slave_skip_counter == 0)
6340     {
6341       sql_print_information("'SQL_SLAVE_SKIP_COUNTER=%ld' executed at "
6342         "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
6343         "master_log_pos='%ld' and new position at "
6344         "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
6345         "master_log_pos='%ld' ",
6346         (ulong) saved_skip, saved_log_name, (ulong) saved_log_pos,
6347         saved_master_log_name, (ulong) saved_master_log_pos,
6348         rli->get_group_relay_log_name(), (ulong) rli->get_group_relay_log_pos(),
6349         rli->get_group_master_log_name(), (ulong) rli->get_group_master_log_pos());
6350       saved_skip= 0;
6351     }
6352 
6353     if (exec_relay_log_event(thd,rli))
6354     {
6355       DBUG_PRINT("info", ("exec_relay_log_event() failed"));
6356       // do not scare the user if SQL thread was simply killed or stopped
6357       if (!sql_slave_killed(thd,rli))
6358       {
6359         /*
6360           retrieve as much info as possible from the thd and, error
6361           codes and warnings and print this to the error log as to
6362           allow the user to locate the error
6363         */
6364         uint32 const last_errno= rli->last_error().number;
6365 
6366         if (thd->is_error())
6367         {
6368           char const *const errmsg= thd->get_stmt_da()->message();
6369 
6370           DBUG_PRINT("info",
6371                      ("thd->get_stmt_da()->sql_errno()=%d; "
6372                       "rli->last_error.number=%d",
6373                       thd->get_stmt_da()->sql_errno(), last_errno));
6374           if (last_errno == 0)
6375           {
6376             /*
6377  	      This function is reporting an error which was not reported
6378  	      while executing exec_relay_log_event().
6379  	    */
6380             rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
6381                         "%s", errmsg);
6382           }
6383           else if (last_errno != thd->get_stmt_da()->sql_errno())
6384           {
6385             /*
6386              * An error was reported while executing exec_relay_log_event()
6387              * however the error code differs from what is in the thread.
6388              * This function prints out more information to help finding
6389              * what caused the problem.
6390              */
6391             sql_print_error("Slave (additional info): %s Error_code: %d",
6392                             errmsg, thd->get_stmt_da()->sql_errno());
6393           }
6394         }
6395 
6396         /* Print any warnings issued */
6397         Diagnostics_area::Sql_condition_iterator it=
6398           thd->get_stmt_da()->sql_conditions();
6399         const Sql_condition *err;
6400         /*
6401           Added controlled slave thread cancel for replication
6402           of user-defined variables.
6403         */
6404         bool udf_error = false;
6405         while ((err= it++))
6406         {
6407           if (err->get_sql_errno() == ER_CANT_OPEN_LIBRARY)
6408             udf_error = true;
6409           sql_print_warning("Slave: %s Error_code: %d", err->get_message_text(), err->get_sql_errno());
6410         }
6411         if (udf_error)
6412           error_string= "Error loading user-defined library, slave SQL "
6413             "thread aborted. Install the missing library, and restart the"
6414             " slave SQL thread with \"SLAVE START\".";
6415         else
6416           error_string= "Error running query, slave SQL thread aborted."
6417             " Fix the problem, and restart the slave SQL thread with "
6418             "\"SLAVE START\".";
6419       }
6420       goto err;
6421     }
6422   }
6423 
6424  err:
6425 
6426   slave_stop_workers(rli, &mts_inited); // stopping worker pool
6427   /* Thread stopped. Print the current replication position to the log */
6428   if (error_string)
6429     sql_print_error("%s We stopped at log '%s' position %s.", error_string,
6430                     rli->get_rpl_log_name(),
6431                     llstr(rli->get_group_master_log_pos(), llbuff));
6432   else
6433     sql_print_information("Slave SQL thread exiting, replication stopped in log"
6434                           " '%s' at position %s",
6435                           rli->get_rpl_log_name(),
6436                           llstr(rli->get_group_master_log_pos(), llbuff));
6437   rli->clear_mts_recovery_groups();
6438 
6439   /*
6440     Some events set some playgrounds, which won't be cleared because thread
6441     stops. Stopping of this thread may not be known to these events ("stop"
6442     request is detected only by the present function, not by events), so we
6443     must "proactively" clear playgrounds:
6444   */
6445   thd->clear_error();
6446   rli->cleanup_context(thd, 1);
6447   /*
6448     Some extra safety, which should not been needed (normally, event deletion
6449     should already have done these assignments (each event which sets these
6450     variables is supposed to set them to 0 before terminating)).
6451   */
6452   thd->catalog= 0;
6453   thd->reset_query();
6454   thd->reset_db(NULL, 0);
6455 
6456   THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit);
6457   mysql_mutex_lock(&rli->run_lock);
6458   /* We need data_lock, at least to wake up any waiting master_pos_wait() */
6459   mysql_mutex_lock(&rli->data_lock);
6460   DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
6461   /* When master_pos_wait() wakes up it will check this and terminate */
6462   rli->slave_running= 0;
6463   /* Forget the relay log's format */
6464   rli->set_rli_description_event(NULL);
6465   /* Wake up master_pos_wait() */
6466   mysql_mutex_unlock(&rli->data_lock);
6467   DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions"));
6468   mysql_cond_broadcast(&rli->data_cond);
6469   rli->ignore_log_space_limit= 0; /* don't need any lock */
6470   /* we die so won't remember charset - re-update them on next thread start */
6471   rli->cached_charset_invalidate();
6472   rli->save_temporary_tables = thd->temporary_tables;
6473 
6474   /*
6475     TODO: see if we can do this conditionally in next_event() instead
6476     to avoid unneeded position re-init
6477   */
6478   thd->temporary_tables = 0; // remove tempation from destructor to close them
6479   DBUG_ASSERT(thd->net.buff != 0);
6480   net_end(&thd->net); // destructor will not free it, because we are weird
6481   DBUG_ASSERT(rli->info_thd == thd);
6482   THD_CHECK_SENTRY(thd);
6483   rli->info_thd= 0;
6484   set_thd_in_use_temporary_tables(rli);  // (re)set info_thd in use for saved temp tables
6485 
6486   thd->release_resources();
6487   THD_CHECK_SENTRY(thd);
6488   if (thd_added)
6489     remove_global_thread(thd);
6490   delete thd;
6491  /*
6492   Note: the order of the broadcast and unlock calls below (first broadcast, then unlock)
6493   is important. Otherwise a killer_thread can execute between the calls and
6494   delete the mi structure leading to a crash! (see BUG#25306 for details)
6495  */
6496   mysql_cond_broadcast(&rli->stop_cond);
6497   DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
6498   mysql_mutex_unlock(&rli->run_lock);  // tell the world we are done
6499 
6500   DBUG_LEAVE;                            // Must match DBUG_ENTER()
6501   my_thread_end();
6502 #if OPENSSL_VERSION_NUMBER < 0x10100000L
6503   ERR_remove_thread_state(0);
6504 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
6505   pthread_exit(0);
6506   return 0;                             // Avoid compiler warnings
6507 }
6508 
6509 
6510 /*
6511   process_io_create_file()
6512 */
6513 
process_io_create_file(Master_info * mi,Create_file_log_event * cev)6514 static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
6515 {
6516   int error = 1;
6517   ulong num_bytes;
6518   bool cev_not_written;
6519   THD *thd = mi->info_thd;
6520   NET *net = &mi->mysql->net;
6521   DBUG_ENTER("process_io_create_file");
6522 
6523   mysql_mutex_assert_owner(&mi->data_lock);
6524 
6525   if (unlikely(!cev->is_valid()))
6526     DBUG_RETURN(1);
6527 
6528   if (!rpl_filter->db_ok(cev->db))
6529   {
6530     skip_load_data_infile(net);
6531     DBUG_RETURN(0);
6532   }
6533   DBUG_ASSERT(cev->inited_from_old);
6534   thd->file_id = cev->file_id = mi->file_id++;
6535   thd->server_id = cev->server_id;
6536   cev_not_written = 1;
6537 
6538   if (unlikely(net_request_file(net,cev->fname)))
6539   {
6540     sql_print_error("Slave I/O: failed requesting download of '%s'",
6541                     cev->fname);
6542     goto err;
6543   }
6544 
6545   /*
6546     This dummy block is so we could instantiate Append_block_log_event
6547     once and then modify it slightly instead of doing it multiple times
6548     in the loop
6549   */
6550   {
6551     Append_block_log_event aev(thd,0,0,0,0);
6552 
6553     for (;;)
6554     {
6555       if (unlikely((num_bytes=my_net_read(net)) == packet_error))
6556       {
6557         sql_print_error("Network read error downloading '%s' from master",
6558                         cev->fname);
6559         goto err;
6560       }
6561       if (unlikely(!num_bytes)) /* eof */
6562       {
6563 	/* 3.23 master wants it */
6564         net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0);
6565         /*
6566           If we wrote Create_file_log_event, then we need to write
6567           Execute_load_log_event. If we did not write Create_file_log_event,
6568           then this is an empty file and we can just do as if the LOAD DATA
6569           INFILE had not existed, i.e. write nothing.
6570         */
6571         if (unlikely(cev_not_written))
6572           break;
6573         Execute_load_log_event xev(thd,0,0);
6574         xev.log_pos = cev->log_pos;
6575         if (unlikely(mi->rli->relay_log.append_event(&xev, mi) != 0))
6576         {
6577           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
6578                      ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
6579                      "error writing Exec_load event to relay log");
6580           goto err;
6581         }
6582         mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
6583         break;
6584       }
6585       if (unlikely(cev_not_written))
6586       {
6587         cev->block = net->read_pos;
6588         cev->block_len = num_bytes;
6589         if (unlikely(mi->rli->relay_log.append_event(cev, mi) != 0))
6590         {
6591           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
6592                      ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
6593                      "error writing Create_file event to relay log");
6594           goto err;
6595         }
6596         cev_not_written=0;
6597         mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
6598       }
6599       else
6600       {
6601         aev.block = net->read_pos;
6602         aev.block_len = num_bytes;
6603         aev.log_pos = cev->log_pos;
6604         if (unlikely(mi->rli->relay_log.append_event(&aev, mi) != 0))
6605         {
6606           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
6607                      ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
6608                      "error writing Append_block event to relay log");
6609           goto err;
6610         }
6611         mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
6612       }
6613     }
6614   }
6615   error=0;
6616 err:
6617   DBUG_RETURN(error);
6618 }
6619 
6620 
6621 /**
6622   Used by the slave IO thread when it receives a rotate event from the
6623   master.
6624 
6625   Updates the master info with the place in the next binary log where
6626   we should start reading.  Rotate the relay log to avoid mixed-format
6627   relay logs.
6628 
6629   @param mi master_info for the slave
6630   @param rev The rotate log event read from the master
6631 
6632   @note The caller must hold mi->data_lock before invoking this function.
6633 
6634   @retval 0 ok
6635   @retval 1 error
6636 */
process_io_rotate(Master_info * mi,Rotate_log_event * rev)6637 static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
6638 {
6639   DBUG_ENTER("process_io_rotate");
6640   mysql_mutex_assert_owner(&mi->data_lock);
6641 
6642   if (unlikely(!rev->is_valid()))
6643     DBUG_RETURN(1);
6644 
6645   /* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
6646   memcpy(const_cast<char *>(mi->get_master_log_name()),
6647          rev->new_log_ident, rev->ident_len + 1);
6648   mi->set_master_log_pos(rev->pos);
6649   DBUG_PRINT("info", ("new (master_log_name, master_log_pos): ('%s', %lu)",
6650                       mi->get_master_log_name(), (ulong) mi->get_master_log_pos()));
6651 #ifndef DBUG_OFF
6652   /*
6653     If we do not do this, we will be getting the first
6654     rotate event forever, so we need to not disconnect after one.
6655   */
6656   if (disconnect_slave_event_count)
6657     mi->events_until_exit++;
6658 #endif
6659 
6660   /*
6661     If mi_description_event is format <4, there is conversion in the
6662     relay log to the slave's format (4). And Rotate can mean upgrade or
6663     nothing. If upgrade, it's to 5.0 or newer, so we will get a Format_desc, so
6664     no need to reset mi_description_event now. And if it's nothing (same
6665     master version as before), no need (still using the slave's format).
6666   */
6667   Format_description_log_event *old_fdle= mi->get_mi_description_event();
6668   if (old_fdle->binlog_version >= 4)
6669   {
6670     DBUG_ASSERT(old_fdle->checksum_alg ==
6671                 mi->rli->relay_log.relay_log_checksum_alg);
6672     Format_description_log_event *new_fdle= new
6673       Format_description_log_event(3);
6674     new_fdle->checksum_alg= mi->rli->relay_log.relay_log_checksum_alg;
6675     mi->set_mi_description_event(new_fdle);
6676   }
6677   /*
6678     Rotate the relay log makes binlog format detection easier (at next slave
6679     start or mysqlbinlog)
6680   */
6681   int ret= rotate_relay_log(mi, true/*need_log_space_lock=true*/);
6682   DBUG_RETURN(ret);
6683 }
6684 
6685 /**
6686   Reads a 3.23 event and converts it to the slave's format. This code was
6687   copied from MySQL 4.0.
6688 
6689   @note The caller must hold mi->data_lock before invoking this function.
6690 */
queue_binlog_ver_1_event(Master_info * mi,const char * buf,ulong event_len)6691 static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
6692                                     ulong event_len)
6693 {
6694   const char *errmsg = 0;
6695   ulong inc_pos;
6696   bool ignore_event= 0;
6697   char *tmp_buf = 0;
6698   Relay_log_info *rli= mi->rli;
6699   DBUG_ENTER("queue_binlog_ver_1_event");
6700 
6701   mysql_mutex_assert_owner(&mi->data_lock);
6702 
6703   /*
6704     If we get Load event, we need to pass a non-reusable buffer
6705     to read_log_event, so we do a trick
6706   */
6707   if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
6708   {
6709     if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME)))))
6710     {
6711       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6712                  ER(ER_SLAVE_FATAL_ERROR), "Memory allocation failed");
6713       DBUG_RETURN(1);
6714     }
6715     memcpy(tmp_buf,buf,event_len);
6716     /*
6717       Create_file constructor wants a 0 as last char of buffer, this 0 will
6718       serve as the string-termination char for the file's name (which is at the
6719       end of the buffer)
6720       We must increment event_len, otherwise the event constructor will not see
6721       this end 0, which leads to segfault.
6722     */
6723     tmp_buf[event_len++]=0;
6724     int4store(tmp_buf+EVENT_LEN_OFFSET, event_len);
6725     buf = (const char*)tmp_buf;
6726   }
6727   /*
6728     This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to
6729     send the loaded file, and write it to the relay log in the form of
6730     Append_block/Exec_load (the SQL thread needs the data, as that thread is not
6731     connected to the master).
6732   */
6733   Log_event *ev=
6734     Log_event::read_log_event(buf, event_len, &errmsg,
6735                               mi->get_mi_description_event(), 0);
6736   if (unlikely(!ev))
6737   {
6738     sql_print_error("Read invalid event from master: '%s',\
6739  master could be corrupt but a more likely cause of this is a bug",
6740                     errmsg);
6741     my_free((char*) tmp_buf);
6742     DBUG_RETURN(1);
6743   }
6744 
6745   mi->set_master_log_pos(ev->log_pos); /* 3.23 events don't contain log_pos */
6746   switch (ev->get_type_code()) {
6747   case STOP_EVENT:
6748     ignore_event= 1;
6749     inc_pos= event_len;
6750     break;
6751   case ROTATE_EVENT:
6752     if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
6753     {
6754       delete ev;
6755       DBUG_RETURN(1);
6756     }
6757     inc_pos= 0;
6758     break;
6759   case CREATE_FILE_EVENT:
6760     /*
6761       Yes it's possible to have CREATE_FILE_EVENT here, even if we're in
6762       queue_old_event() which is for 3.23 events which don't comprise
6763       CREATE_FILE_EVENT. This is because read_log_event() above has just
6764       transformed LOAD_EVENT into CREATE_FILE_EVENT.
6765     */
6766   {
6767     /* We come here when and only when tmp_buf != 0 */
6768     DBUG_ASSERT(tmp_buf != 0);
6769     inc_pos=event_len;
6770     ev->log_pos+= inc_pos;
6771     int error = process_io_create_file(mi,(Create_file_log_event*)ev);
6772     delete ev;
6773     mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
6774     DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
6775     my_free((char*)tmp_buf);
6776     DBUG_RETURN(error);
6777   }
6778   default:
6779     inc_pos= event_len;
6780     break;
6781   }
6782   if (likely(!ignore_event))
6783   {
6784     if (ev->log_pos)
6785       /*
6786          Don't do it for fake Rotate events (see comment in
6787       Log_event::Log_event(const char* buf...) in log_event.cc).
6788       */
6789       ev->log_pos+= event_len; /* make log_pos be the pos of the end of the event */
6790     if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
6791     {
6792       delete ev;
6793       DBUG_RETURN(1);
6794     }
6795     rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
6796   }
6797   delete ev;
6798   mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
6799   DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
6800   DBUG_RETURN(0);
6801 }
6802 
6803 /**
6804   Reads a 4.0 event and converts it to the slave's format. This code was copied
6805   from queue_binlog_ver_1_event(), with some affordable simplifications.
6806 
6807   @note The caller must hold mi->data_lock before invoking this function.
6808 */
queue_binlog_ver_3_event(Master_info * mi,const char * buf,ulong event_len)6809 static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
6810                                     ulong event_len)
6811 {
6812   const char *errmsg = 0;
6813   ulong inc_pos;
6814   char *tmp_buf = 0;
6815   Relay_log_info *rli= mi->rli;
6816   DBUG_ENTER("queue_binlog_ver_3_event");
6817 
6818   mysql_mutex_assert_owner(&mi->data_lock);
6819 
6820   /* read_log_event() will adjust log_pos to be end_log_pos */
6821   Log_event *ev=
6822     Log_event::read_log_event(buf, event_len, &errmsg,
6823                               mi->get_mi_description_event(), 0);
6824   if (unlikely(!ev))
6825   {
6826     sql_print_error("Read invalid event from master: '%s',\
6827  master could be corrupt but a more likely cause of this is a bug",
6828                     errmsg);
6829     my_free((char*) tmp_buf);
6830     DBUG_RETURN(1);
6831   }
6832   switch (ev->get_type_code()) {
6833   case STOP_EVENT:
6834     goto err;
6835   case ROTATE_EVENT:
6836     if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
6837     {
6838       delete ev;
6839       DBUG_RETURN(1);
6840     }
6841     inc_pos= 0;
6842     break;
6843   default:
6844     inc_pos= event_len;
6845     break;
6846   }
6847 
6848   if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
6849   {
6850     delete ev;
6851     DBUG_RETURN(1);
6852   }
6853   rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
6854   delete ev;
6855   mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
6856 err:
6857   DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
6858   DBUG_RETURN(0);
6859 }
6860 
6861 /*
6862   queue_old_event()
6863 
6864   Writes a 3.23 or 4.0 event to the relay log, after converting it to the 5.0
6865   (exactly, slave's) format. To do the conversion, we create a 5.0 event from
6866   the 3.23/4.0 bytes, then write this event to the relay log.
6867 
6868   TODO:
6869     Test this code before release - it has to be tested on a separate
6870     setup with 3.23 master or 4.0 master
6871 */
6872 
queue_old_event(Master_info * mi,const char * buf,ulong event_len)6873 static int queue_old_event(Master_info *mi, const char *buf,
6874                            ulong event_len)
6875 {
6876   DBUG_ENTER("queue_old_event");
6877 
6878   mysql_mutex_assert_owner(&mi->data_lock);
6879 
6880   switch (mi->get_mi_description_event()->binlog_version)
6881   {
6882   case 1:
6883       DBUG_RETURN(queue_binlog_ver_1_event(mi,buf,event_len));
6884   case 3:
6885       DBUG_RETURN(queue_binlog_ver_3_event(mi,buf,event_len));
6886   default: /* unsupported format; eg version 2 */
6887     DBUG_PRINT("info",("unsupported binlog format %d in queue_old_event()",
6888                        mi->get_mi_description_event()->binlog_version));
6889     DBUG_RETURN(1);
6890   }
6891 }
6892 
6893 /*
6894   queue_event()
6895 
6896   If the event is 3.23/4.0, passes it to queue_old_event() which will convert
6897   it. Otherwise, writes a 5.0 (or newer) event to the relay log. Then there is
6898   no format conversion, it's pure read/write of bytes.
6899   So a 5.0.0 slave's relay log can contain events in the slave's format or in
6900   any >=5.0.0 format.
6901 */
6902 
queue_event(Master_info * mi,const char * buf,ulong event_len)6903 static int queue_event(Master_info* mi,const char* buf, ulong event_len)
6904 {
6905   int error= 0;
6906   String error_msg;
6907   ulong inc_pos= 0;
6908   Relay_log_info *rli= mi->rli;
6909   mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
6910   ulong s_id;
6911   bool unlock_data_lock= TRUE;
6912   /*
6913     FD_q must have been prepared for the first R_a event
6914     inside get_master_version_and_clock()
6915     Show-up of FD:s affects checksum_alg at once because
6916     that changes FD_queue.
6917   */
6918   uint8 checksum_alg= mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF ?
6919     mi->checksum_alg_before_fd :
6920     mi->rli->relay_log.relay_log_checksum_alg;
6921 
6922   char *save_buf= NULL; // needed for checksumming the fake Rotate event
6923   char rot_buf[LOG_EVENT_HEADER_LEN + ROTATE_HEADER_LEN + FN_REFLEN];
6924   Gtid gtid= { 0, 0 };
6925   Gtid old_retrieved_gtid= { 0, 0 };
6926   Log_event_type event_type= (Log_event_type)buf[EVENT_TYPE_OFFSET];
6927 
6928   DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_OFF ||
6929               checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
6930               checksum_alg == BINLOG_CHECKSUM_ALG_CRC32);
6931 
6932   DBUG_ENTER("queue_event");
6933   /*
6934     FD_queue checksum alg description does not apply in a case of
6935     FD itself. The one carries both parts of the checksum data.
6936   */
6937   if (event_type == FORMAT_DESCRIPTION_EVENT)
6938   {
6939     checksum_alg= get_checksum_alg(buf, event_len);
6940   }
6941   else if (event_type == START_EVENT_V3)
6942   {
6943     // checksum behaviour is similar to the pre-checksum FD handling
6944     mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF;
6945     mysql_mutex_lock(&mi->data_lock);
6946     mi->get_mi_description_event()->checksum_alg=
6947       mi->rli->relay_log.relay_log_checksum_alg= checksum_alg=
6948       BINLOG_CHECKSUM_ALG_OFF;
6949     mysql_mutex_unlock(&mi->data_lock);
6950   }
6951 
6952   // does not hold always because of old binlog can work with NM
6953   // DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
6954 
6955   // should hold unless manipulations with RL. Tests that do that
6956   // will have to refine the clause.
6957   DBUG_ASSERT(mi->rli->relay_log.relay_log_checksum_alg !=
6958               BINLOG_CHECKSUM_ALG_UNDEF);
6959 
6960   // Emulate the network corruption
6961   DBUG_EXECUTE_IF("corrupt_queue_event",
6962     if (event_type != FORMAT_DESCRIPTION_EVENT)
6963     {
6964       char *debug_event_buf_c = (char*) buf;
6965       int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
6966       debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
6967       DBUG_PRINT("info", ("Corrupt the event at queue_event: byte on position %d", debug_cor_pos));
6968       DBUG_SET("");
6969     }
6970   );
6971 
6972   if (event_checksum_test((uchar *) buf, event_len, checksum_alg))
6973   {
6974     error= ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE;
6975     unlock_data_lock= FALSE;
6976     goto err;
6977   }
6978 
6979   mysql_mutex_lock(&mi->data_lock);
6980 
6981   if (mi->get_mi_description_event()->binlog_version < 4 &&
6982       event_type != FORMAT_DESCRIPTION_EVENT /* a way to escape */)
6983   {
6984     int ret= queue_old_event(mi,buf,event_len);
6985     mysql_mutex_unlock(&mi->data_lock);
6986     DBUG_RETURN(ret);
6987   }
6988 
6989   switch (event_type) {
6990   case STOP_EVENT:
6991     /*
6992       We needn't write this event to the relay log. Indeed, it just indicates a
6993       master server shutdown. The only thing this does is cleaning. But
6994       cleaning is already done on a per-master-thread basis (as the master
6995       server is shutting down cleanly, it has written all DROP TEMPORARY TABLE
6996       prepared statements' deletion are TODO only when we binlog prep stmts).
6997 
6998       We don't even increment mi->get_master_log_pos(), because we may be just after
6999       a Rotate event. Btw, in a few milliseconds we are going to have a Start
7000       event from the next binlog (unless the master is presently running
7001       without --log-bin).
7002     */
7003     goto err;
7004   case ROTATE_EVENT:
7005   {
7006     Rotate_log_event rev(buf, checksum_alg != BINLOG_CHECKSUM_ALG_OFF ?
7007                          event_len - BINLOG_CHECKSUM_LEN : event_len,
7008                          mi->get_mi_description_event());
7009 
7010     if (unlikely(process_io_rotate(mi, &rev)))
7011     {
7012       error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
7013       goto err;
7014     }
7015     /*
7016        Checksum special cases for the fake Rotate (R_f) event caused by the protocol
7017        of events generation and serialization in RL where Rotate of master is
7018        queued right next to FD of slave.
7019        Since it's only FD that carries the alg desc of FD_s has to apply to R_m.
7020        Two special rules apply only to the first R_f which comes in before any FD_m.
7021        The 2nd R_f should be compatible with the FD_s that must have taken over
7022        the last seen FD_m's (A).
7023 
7024        RSC_1: If OM \and fake Rotate \and slave is configured to
7025               to compute checksum for its first FD event for RL
7026               the fake Rotate gets checksummed here.
7027     */
7028     if (uint4korr(&buf[0]) == 0 && checksum_alg == BINLOG_CHECKSUM_ALG_OFF &&
7029         mi->rli->relay_log.relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
7030     {
7031       ha_checksum rot_crc= my_checksum(0L, NULL, 0);
7032       event_len += BINLOG_CHECKSUM_LEN;
7033       memcpy(rot_buf, buf, event_len - BINLOG_CHECKSUM_LEN);
7034       int4store(&rot_buf[EVENT_LEN_OFFSET],
7035                 uint4korr(rot_buf + EVENT_LEN_OFFSET) + BINLOG_CHECKSUM_LEN);
7036       rot_crc= my_checksum(rot_crc, (const uchar *) rot_buf,
7037                            event_len - BINLOG_CHECKSUM_LEN);
7038       int4store(&rot_buf[event_len - BINLOG_CHECKSUM_LEN], rot_crc);
7039       DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
7040       DBUG_ASSERT(mi->get_mi_description_event()->checksum_alg ==
7041                   mi->rli->relay_log.relay_log_checksum_alg);
7042       /* the first one */
7043       DBUG_ASSERT(mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF);
7044       save_buf= (char *) buf;
7045       buf= rot_buf;
7046     }
7047     else
7048       /*
7049         RSC_2: If NM \and fake Rotate \and slave does not compute checksum
7050         the fake Rotate's checksum is stripped off before relay-logging.
7051       */
7052       if (uint4korr(&buf[0]) == 0 && checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
7053           mi->rli->relay_log.relay_log_checksum_alg == BINLOG_CHECKSUM_ALG_OFF)
7054       {
7055         event_len -= BINLOG_CHECKSUM_LEN;
7056         memcpy(rot_buf, buf, event_len);
7057         int4store(&rot_buf[EVENT_LEN_OFFSET],
7058                   uint4korr(rot_buf + EVENT_LEN_OFFSET) - BINLOG_CHECKSUM_LEN);
7059         DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
7060         DBUG_ASSERT(mi->get_mi_description_event()->checksum_alg ==
7061                     mi->rli->relay_log.relay_log_checksum_alg);
7062         /* the first one */
7063         DBUG_ASSERT(mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF);
7064         save_buf= (char *) buf;
7065         buf= rot_buf;
7066       }
7067     /*
7068       Now the I/O thread has just changed its mi->get_master_log_name(), so
7069       incrementing mi->get_master_log_pos() is nonsense.
7070     */
7071     inc_pos= 0;
7072     break;
7073   }
7074   case FORMAT_DESCRIPTION_EVENT:
7075   {
7076     /*
7077       Create an event, and save it (when we rotate the relay log, we will have
7078       to write this event again).
7079     */
7080     /*
7081       We are the only thread which reads/writes mi_description_event.
7082       The relay_log struct does not move (though some members of it can
7083       change), so we needn't any lock (no rli->data_lock, no log lock).
7084     */
7085     const char* errmsg;
7086     // mark it as undefined that is irrelevant anymore
7087     mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF;
7088     Format_description_log_event *new_fdle=
7089       (Format_description_log_event*)
7090       Log_event::read_log_event(buf, event_len, &errmsg,
7091                                 mi->get_mi_description_event(), 1);
7092     if (new_fdle == NULL)
7093     {
7094       error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
7095       goto err;
7096     }
7097     if (new_fdle->checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
7098       new_fdle->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
7099     mi->set_mi_description_event(new_fdle);
7100 
7101     /* installing new value of checksum Alg for relay log */
7102     mi->rli->relay_log.relay_log_checksum_alg= new_fdle->checksum_alg;
7103 
7104     /*
7105        Though this does some conversion to the slave's format, this will
7106        preserve the master's binlog format version, and number of event types.
7107     */
7108     /*
7109        If the event was not requested by the slave (the slave did not ask for
7110        it), i.e. has end_log_pos=0, we do not increment mi->get_master_log_pos()
7111     */
7112     inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0;
7113     DBUG_PRINT("info",("binlog format is now %d",
7114                        mi->get_mi_description_event()->binlog_version));
7115 
7116   }
7117   break;
7118 
7119   case HEARTBEAT_LOG_EVENT:
7120   {
7121     /*
7122       HB (heartbeat) cannot come before RL (Relay)
7123     */
7124     char  llbuf[22];
7125     Heartbeat_log_event hb(buf,
7126                            mi->rli->relay_log.relay_log_checksum_alg
7127                            != BINLOG_CHECKSUM_ALG_OFF ?
7128                            event_len - BINLOG_CHECKSUM_LEN : event_len,
7129                            mi->get_mi_description_event());
7130     if (!hb.is_valid())
7131     {
7132       error= ER_SLAVE_HEARTBEAT_FAILURE;
7133       error_msg.append(STRING_WITH_LEN("inconsistent heartbeat event content;"));
7134       error_msg.append(STRING_WITH_LEN("the event's data: log_file_name "));
7135       error_msg.append(hb.get_log_ident(), (uint) strlen(hb.get_log_ident()));
7136       error_msg.append(STRING_WITH_LEN(" log_pos "));
7137       llstr(hb.log_pos, llbuf);
7138       error_msg.append(llbuf, strlen(llbuf));
7139       goto err;
7140     }
7141     mi->received_heartbeats++;
7142     mi->last_heartbeat= my_time(0);
7143 
7144 
7145     /*
7146       During GTID protocol, if the master skips transactions,
7147       a heartbeat event is sent to the slave at the end of last
7148       skipped transaction to update coordinates.
7149 
7150       I/O thread receives the heartbeat event and updates mi
7151       only if the received heartbeat position is greater than
7152       mi->get_master_log_pos(). This event is written to the
7153       relay log as an ignored Rotate event. SQL thread reads
7154       the rotate event only to update the coordinates corresponding
7155       to the last skipped transaction. Note that,
7156       we update only the positions and not the file names, as a ROTATE
7157       EVENT from the master prior to this will update the file name.
7158     */
7159     if (mi->is_auto_position()  && mi->get_master_log_pos() < hb.log_pos
7160         &&  mi->get_master_log_name() != NULL)
7161     {
7162 
7163       DBUG_ASSERT(memcmp(const_cast<char*>(mi->get_master_log_name()),
7164                          hb.get_log_ident(), hb.get_ident_len()) == 0);
7165 
7166       mi->set_master_log_pos(hb.log_pos);
7167 
7168       /*
7169          Put this heartbeat event in the relay log as a Rotate Event.
7170       */
7171       inc_pos= 0;
7172       memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(),
7173              FN_REFLEN);
7174       rli->ign_master_log_pos_end = mi->get_master_log_pos();
7175 
7176       if (write_ignored_events_info_to_relay_log(mi->info_thd, mi))
7177         goto err;
7178     }
7179 
7180     /*
7181        compare local and event's versions of log_file, log_pos.
7182 
7183        Heartbeat is sent only after an event corresponding to the corrdinates
7184        the heartbeat carries.
7185        Slave can not have a difference in coordinates except in the only
7186        special case when mi->get_master_log_name(), mi->get_master_log_pos() have never
7187        been updated by Rotate event i.e when slave does not have any history
7188        with the master (and thereafter mi->get_master_log_pos() is NULL).
7189 
7190        TODO: handling `when' for SHOW SLAVE STATUS' snds behind
7191     */
7192     if ((memcmp(const_cast<char *>(mi->get_master_log_name()),
7193                 hb.get_log_ident(), hb.get_ident_len())
7194          && mi->get_master_log_name() != NULL)
7195         || ((mi->get_master_log_pos() != hb.log_pos && gtid_mode == 0) ||
7196             /*
7197               When Gtid mode is on only monotocity can be claimed.
7198               Todo: enhance HB event with the skipped events size
7199               and to convert HB.pos  == MI.pos to HB.pos - HB.skip_size == MI.pos
7200             */
7201             (mi->get_master_log_pos() > hb.log_pos)))
7202     {
7203       /* missed events of heartbeat from the past */
7204       error= ER_SLAVE_HEARTBEAT_FAILURE;
7205       error_msg.append(STRING_WITH_LEN("heartbeat is not compatible with local info;"));
7206       error_msg.append(STRING_WITH_LEN("the event's data: log_file_name "));
7207       error_msg.append(hb.get_log_ident(), (uint) strlen(hb.get_log_ident()));
7208       error_msg.append(STRING_WITH_LEN(" log_pos "));
7209       llstr(hb.log_pos, llbuf);
7210       error_msg.append(llbuf, strlen(llbuf));
7211       goto err;
7212     }
7213     goto skip_relay_logging;
7214   }
7215   break;
7216 
7217   case PREVIOUS_GTIDS_LOG_EVENT:
7218   {
7219     /*
7220       This event does not have any meaning for the slave and
7221       was just sent to show the slave the master is making
7222       progress and avoid possible deadlocks.
7223       So at this point, the event is replaced by a rotate
7224       event what will make the slave to update what it knows
7225       about the master's coordinates.
7226     */
7227     inc_pos= 0;
7228     mi->set_master_log_pos(mi->get_master_log_pos() + event_len);
7229     memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(), FN_REFLEN);
7230     rli->ign_master_log_pos_end= mi->get_master_log_pos();
7231 
7232     if (write_ignored_events_info_to_relay_log(mi->info_thd, mi))
7233       goto err;
7234 
7235     goto skip_relay_logging;
7236   }
7237   break;
7238 
7239   case GTID_LOG_EVENT:
7240   {
7241     if (gtid_mode == 0)
7242     {
7243       error= ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF;
7244       goto err;
7245     }
7246     global_sid_lock->rdlock();
7247     Gtid_log_event gtid_ev(buf, checksum_alg != BINLOG_CHECKSUM_ALG_OFF ?
7248                            event_len - BINLOG_CHECKSUM_LEN : event_len,
7249                            mi->get_mi_description_event());
7250     gtid.sidno= gtid_ev.get_sidno(false);
7251     global_sid_lock->unlock();
7252     if (gtid.sidno < 0)
7253       goto err;
7254     gtid.gno= gtid_ev.get_gno();
7255     inc_pos= event_len;
7256   }
7257   break;
7258 
7259   case ANONYMOUS_GTID_LOG_EVENT:
7260 
7261   default:
7262     inc_pos= event_len;
7263   break;
7264   }
7265 
7266   /*
7267     Simulate an unknown ignorable log event by rewriting the write_rows log
7268     event and previous_gtids log event before writing them in relay log.
7269   */
7270   DBUG_EXECUTE_IF("simulate_unknown_ignorable_log_event",
7271     if (event_type == WRITE_ROWS_EVENT ||
7272         event_type == PREVIOUS_GTIDS_LOG_EVENT)
7273     {
7274       char *event_buf= const_cast<char*>(buf);
7275       /* Overwrite the log event type with an unknown type. */
7276       event_buf[EVENT_TYPE_OFFSET]= ENUM_END_EVENT + 1;
7277       /* Set LOG_EVENT_IGNORABLE_F for the log event. */
7278       int2store(event_buf + FLAGS_OFFSET,
7279                 uint2korr(event_buf + FLAGS_OFFSET) | LOG_EVENT_IGNORABLE_F);
7280     }
7281   );
7282 
7283   /*
7284      If this event is originating from this server, don't queue it.
7285      We don't check this for 3.23 events because it's simpler like this; 3.23
7286      will be filtered anyway by the SQL slave thread which also tests the
7287      server id (we must also keep this test in the SQL thread, in case somebody
7288      upgrades a 4.0 slave which has a not-filtered relay log).
7289 
7290      ANY event coming from ourselves can be ignored: it is obvious for queries;
7291      for STOP_EVENT/ROTATE_EVENT/START_EVENT: these cannot come from ourselves
7292      (--log-slave-updates would not log that) unless this slave is also its
7293      direct master (an unsupported, useless setup!).
7294   */
7295 
7296   mysql_mutex_lock(log_lock);
7297   s_id= uint4korr(buf + SERVER_ID_OFFSET);
7298 
7299   /*
7300     If server_id_bits option is set we need to mask out irrelevant bits
7301     when checking server_id, but we still put the full unmasked server_id
7302     into the Relay log so that it can be accessed when applying the event
7303   */
7304   s_id&= opt_server_id_mask;
7305 
7306   if ((s_id == ::server_id && !mi->rli->replicate_same_server_id) ||
7307       /*
7308         the following conjunction deals with IGNORE_SERVER_IDS, if set
7309         If the master is on the ignore list, execution of
7310         format description log events and rotate events is necessary.
7311       */
7312       (mi->ignore_server_ids->dynamic_ids.elements > 0 &&
7313        mi->shall_ignore_server_id(s_id) &&
7314        /* everything is filtered out from non-master */
7315        (s_id != mi->master_id ||
7316         /* for the master meta information is necessary */
7317         (event_type != FORMAT_DESCRIPTION_EVENT &&
7318          event_type != ROTATE_EVENT))))
7319   {
7320     /*
7321       Do not write it to the relay log.
7322       a) We still want to increment mi->get_master_log_pos(), so that we won't
7323       re-read this event from the master if the slave IO thread is now
7324       stopped/restarted (more efficient if the events we are ignoring are big
7325       LOAD DATA INFILE).
7326       b) We want to record that we are skipping events, for the information of
7327       the slave SQL thread, otherwise that thread may let
7328       rli->group_relay_log_pos stay too small if the last binlog's event is
7329       ignored.
7330       But events which were generated by this slave and which do not exist in
7331       the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
7332       mi->get_master_log_pos().
7333       If the event is originated remotely and is being filtered out by
7334       IGNORE_SERVER_IDS it increments mi->get_master_log_pos()
7335       as well as rli->group_relay_log_pos.
7336     */
7337     if (!(s_id == ::server_id && !mi->rli->replicate_same_server_id) ||
7338         (event_type != FORMAT_DESCRIPTION_EVENT &&
7339          event_type != ROTATE_EVENT &&
7340          event_type != STOP_EVENT))
7341     {
7342       mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
7343       memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(), FN_REFLEN);
7344       DBUG_ASSERT(rli->ign_master_log_name_end[0]);
7345       rli->ign_master_log_pos_end= mi->get_master_log_pos();
7346     }
7347     rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
7348     DBUG_PRINT("info", ("master_log_pos: %lu, event originating from %u server, ignored",
7349                         (ulong) mi->get_master_log_pos(), uint4korr(buf + SERVER_ID_OFFSET)));
7350   }
7351   else
7352   {
7353     DBUG_EXECUTE_IF("flush_after_reading_gtid_event",
7354                     if (event_type == GTID_LOG_EVENT && gtid.gno == 4)
7355                       DBUG_SET("+d,set_max_size_zero");
7356                    );
7357     DBUG_EXECUTE_IF("set_append_buffer_error",
7358                     if (event_type == GTID_LOG_EVENT && gtid.gno == 4)
7359                       DBUG_SET("+d,simulate_append_buffer_error");
7360                    );
7361     /*
7362       Add the GTID to the retrieved set before actually appending it to relay
7363       log. This will ensure that if a rotation happens at this point of time the
7364       new GTID will be reflected as part of Previous_Gtid set and
7365       Retrieved_Gtid_Set will not have any gaps.
7366     */
7367     if (event_type == GTID_LOG_EVENT)
7368     {
7369       global_sid_lock->rdlock();
7370       old_retrieved_gtid= *(mi->rli->get_last_retrieved_gtid());
7371       int ret= rli->add_logged_gtid(gtid.sidno, gtid.gno);
7372       if (!ret)
7373         rli->set_last_retrieved_gtid(gtid);
7374       global_sid_lock->unlock();
7375       if (ret != 0)
7376       {
7377         mysql_mutex_unlock(log_lock);
7378         goto err;
7379       }
7380     }
7381     /* write the event to the relay log */
7382     if (!DBUG_EVALUATE_IF("simulate_append_buffer_error", 1, 0) &&
7383        likely(rli->relay_log.append_buffer(buf, event_len, mi) == 0))
7384     {
7385       mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
7386       DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
7387       rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
7388     }
7389     else
7390     {
7391       if (event_type == GTID_LOG_EVENT)
7392       {
7393         global_sid_lock->rdlock();
7394         Gtid_set * retrieved_set= (const_cast<Gtid_set *>(mi->rli->get_gtid_set()));
7395         if (retrieved_set->_remove_gtid(gtid) != RETURN_STATUS_OK)
7396         {
7397           global_sid_lock->unlock();
7398           mysql_mutex_unlock(log_lock);
7399           goto err;
7400         }
7401         if (!old_retrieved_gtid.empty())
7402           rli->set_last_retrieved_gtid(old_retrieved_gtid);
7403         global_sid_lock->unlock();
7404       }
7405       error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
7406     }
7407     rli->ign_master_log_name_end[0]= 0; // last event is not ignored
7408     if (save_buf != NULL)
7409       buf= save_buf;
7410   }
7411   mysql_mutex_unlock(log_lock);
7412 
7413 skip_relay_logging:
7414 
7415 err:
7416   if (unlock_data_lock)
7417     mysql_mutex_unlock(&mi->data_lock);
7418   DBUG_PRINT("info", ("error: %d", error));
7419   if (error)
7420     mi->report(ERROR_LEVEL, error, ER(error),
7421                (error == ER_SLAVE_RELAY_LOG_WRITE_FAILURE)?
7422                "could not queue event from master" :
7423                error_msg.ptr());
7424   DBUG_RETURN(error);
7425 }
7426 
7427 /**
7428   Hook to detach the active VIO before closing a connection handle.
7429 
7430   The client API might close the connection (and associated data)
7431   in case it encounters a unrecoverable (network) error. This hook
7432   is called from the client code before the VIO handle is deleted
7433   allows the thread to detach the active vio so it does not point
7434   to freed memory.
7435 
7436   Other calls to THD::clear_active_vio throughout this module are
7437   redundant due to the hook but are left in place for illustrative
7438   purposes.
7439 */
7440 
slave_io_thread_detach_vio()7441 extern "C" void slave_io_thread_detach_vio()
7442 {
7443 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
7444   THD *thd= current_thd;
7445   if (thd && thd->slave_thread)
7446     thd->clear_active_vio();
7447 #endif
7448 }
7449 
7450 
7451 /*
7452   Try to connect until successful or slave killed
7453 
7454   SYNPOSIS
7455     safe_connect()
7456     thd                 Thread handler for slave
7457     mysql               MySQL connection handle
7458     mi                  Replication handle
7459 
7460   RETURN
7461     0   ok
7462     #   Error
7463 */
7464 
safe_connect(THD * thd,MYSQL * mysql,Master_info * mi)7465 static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi)
7466 {
7467   DBUG_ENTER("safe_connect");
7468 
7469   DBUG_RETURN(connect_to_master(thd, mysql, mi, 0, 0));
7470 }
7471 
7472 
7473 /*
7474   SYNPOSIS
7475     connect_to_master()
7476 
7477   IMPLEMENTATION
7478     Try to connect until successful or slave killed or we have retried
7479     mi->retry_count times
7480 */
7481 
connect_to_master(THD * thd,MYSQL * mysql,Master_info * mi,bool reconnect,bool suppress_warnings)7482 static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
7483                              bool reconnect, bool suppress_warnings)
7484 {
7485   int slave_was_killed= 0;
7486   int last_errno= -2;                           // impossible error
7487   ulong err_count=0;
7488   char llbuff[22];
7489   char password[MAX_PASSWORD_LENGTH + 1];
7490   int password_size= sizeof(password);
7491   DBUG_ENTER("connect_to_master");
7492   set_slave_max_allowed_packet(thd, mysql);
7493 #ifndef DBUG_OFF
7494   mi->events_until_exit = disconnect_slave_event_count;
7495 #endif
7496   ulong client_flag= CLIENT_REMEMBER_OPTIONS;
7497   if (opt_slave_compressed_protocol)
7498     client_flag|= CLIENT_COMPRESS;              /* We will use compression */
7499 
7500   mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
7501   mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
7502 
7503   if (mi->bind_addr[0])
7504   {
7505     DBUG_PRINT("info",("bind_addr: %s", mi->bind_addr));
7506     mysql_options(mysql, MYSQL_OPT_BIND, mi->bind_addr);
7507   }
7508 
7509 #ifdef HAVE_OPENSSL
7510   if (mi->ssl)
7511   {
7512     mysql_ssl_set(mysql,
7513                   mi->ssl_key[0]?mi->ssl_key:0,
7514                   mi->ssl_cert[0]?mi->ssl_cert:0,
7515                   mi->ssl_ca[0]?mi->ssl_ca:0,
7516                   mi->ssl_capath[0]?mi->ssl_capath:0,
7517                   mi->ssl_cipher[0]?mi->ssl_cipher:0);
7518     mysql_options(mysql, MYSQL_OPT_SSL_CRL,
7519                   mi->ssl_crl[0] ? mi->ssl_crl : 0);
7520     mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH,
7521                   mi->ssl_crlpath[0] ? mi->ssl_crlpath : 0);
7522     mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
7523                   &mi->ssl_verify_server_cert);
7524   }
7525 #endif
7526 
7527   /*
7528     If server's default charset is not supported (like utf16, utf32) as client
7529     charset, then set client charset to 'latin1' (default client charset).
7530   */
7531   if (is_supported_parser_charset(default_charset_info))
7532     mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset_info->csname);
7533   else
7534   {
7535     sql_print_information("'%s' can not be used as client character set. "
7536                           "'%s' will be used as default client character set "
7537                           "while connecting to master.",
7538                           default_charset_info->csname,
7539                           default_client_charset_info->csname);
7540     mysql_options(mysql, MYSQL_SET_CHARSET_NAME,
7541                   default_client_charset_info->csname);
7542   }
7543 
7544 
7545   /* This one is not strictly needed but we have it here for completeness */
7546   mysql_options(mysql, MYSQL_SET_CHARSET_DIR, (char *) charsets_dir);
7547 
7548   if (mi->is_start_plugin_auth_configured())
7549   {
7550     DBUG_PRINT("info", ("Slaving is using MYSQL_DEFAULT_AUTH %s",
7551                         mi->get_start_plugin_auth()));
7552     mysql_options(mysql, MYSQL_DEFAULT_AUTH, mi->get_start_plugin_auth());
7553   }
7554 
7555   if (mi->is_start_plugin_dir_configured())
7556   {
7557     DBUG_PRINT("info", ("Slaving is using MYSQL_PLUGIN_DIR %s",
7558                         mi->get_start_plugin_dir()));
7559     mysql_options(mysql, MYSQL_PLUGIN_DIR, mi->get_start_plugin_dir());
7560   }
7561   /* Set MYSQL_PLUGIN_DIR in case master asks for an external authentication plugin */
7562   else if (opt_plugin_dir_ptr && *opt_plugin_dir_ptr)
7563     mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir_ptr);
7564 
7565   if (!mi->is_start_user_configured())
7566     sql_print_warning("%s", ER(ER_INSECURE_CHANGE_MASTER));
7567 
7568   if (mi->get_password(password, &password_size))
7569   {
7570     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
7571                ER(ER_SLAVE_FATAL_ERROR),
7572                "Unable to configure password when attempting to "
7573                "connect to the master server. Connection attempt "
7574                "terminated.");
7575     DBUG_RETURN(1);
7576   }
7577 
7578   const char* user= mi->get_user();
7579   if (user == NULL || user[0] == 0)
7580   {
7581     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
7582                ER(ER_SLAVE_FATAL_ERROR),
7583                "Invalid (empty) username when attempting to "
7584                "connect to the master server. Connection attempt "
7585                "terminated.");
7586     DBUG_RETURN(1);
7587   }
7588 
7589   while (!(slave_was_killed = io_slave_killed(thd,mi))
7590          && (reconnect ? mysql_reconnect(mysql) != 0 :
7591              mysql_real_connect(mysql, mi->host, user,
7592                                 password, 0, mi->port, 0, client_flag) == 0))
7593   {
7594     /*
7595        SHOW SLAVE STATUS will display the number of retries which
7596        would be real retry counts instead of mi->retry_count for
7597        each connection attempt by 'Last_IO_Error' entry.
7598     */
7599     last_errno=mysql_errno(mysql);
7600     suppress_warnings= 0;
7601     mi->report(ERROR_LEVEL, last_errno,
7602                "error %s to master '%s@%s:%d'"
7603                " - retry-time: %d  retries: %lu",
7604                (reconnect ? "reconnecting" : "connecting"),
7605                mi->get_user(), mi->host, mi->port,
7606                mi->connect_retry, err_count + 1);
7607     /*
7608       By default we try forever. The reason is that failure will trigger
7609       master election, so if the user did not set mi->retry_count we
7610       do not want to have election triggered on the first failure to
7611       connect
7612     */
7613     if (++err_count == mi->retry_count)
7614     {
7615       slave_was_killed=1;
7616       break;
7617     }
7618     slave_sleep(thd, mi->connect_retry, io_slave_killed, mi);
7619   }
7620 
7621   if (!slave_was_killed)
7622   {
7623     mi->clear_error(); // clear possible left over reconnect error
7624     if (reconnect)
7625     {
7626       if (!suppress_warnings && log_warnings)
7627         sql_print_information("Slave: connected to master '%s@%s:%d',\
7628 replication resumed in log '%s' at position %s", mi->get_user(),
7629                         mi->host, mi->port,
7630                         mi->get_io_rpl_log_name(),
7631                         llstr(mi->get_master_log_pos(),llbuff));
7632     }
7633     else
7634     {
7635       general_log_print(thd, COM_CONNECT_OUT, "%s@%s:%d",
7636                         mi->get_user(), mi->host, mi->port);
7637     }
7638 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
7639     thd->set_active_vio(mysql->net.vio);
7640 #endif
7641   }
7642   mysql->reconnect= 1;
7643   DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed));
7644   DBUG_RETURN(slave_was_killed);
7645 }
7646 
7647 
7648 /*
7649   safe_reconnect()
7650 
7651   IMPLEMENTATION
7652     Try to connect until successful or slave killed or we have retried
7653     mi->retry_count times
7654 */
7655 
safe_reconnect(THD * thd,MYSQL * mysql,Master_info * mi,bool suppress_warnings)7656 static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
7657                           bool suppress_warnings)
7658 {
7659   DBUG_ENTER("safe_reconnect");
7660   DBUG_RETURN(connect_to_master(thd, mysql, mi, 1, suppress_warnings));
7661 }
7662 
7663 
7664 /*
7665   Called when we notice that the current "hot" log got rotated under our feet.
7666 */
7667 
reopen_relay_log(Relay_log_info * rli,const char ** errmsg)7668 static IO_CACHE *reopen_relay_log(Relay_log_info *rli, const char **errmsg)
7669 {
7670   DBUG_ENTER("reopen_relay_log");
7671   DBUG_ASSERT(rli->cur_log != &rli->cache_buf);
7672   DBUG_ASSERT(rli->cur_log_fd == -1);
7673 
7674   IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
7675   if ((rli->cur_log_fd=open_binlog_file(cur_log,rli->get_event_relay_log_name(),
7676                                         errmsg)) <0)
7677     DBUG_RETURN(0);
7678   /*
7679     We want to start exactly where we was before:
7680     relay_log_pos       Current log pos
7681     pending             Number of bytes already processed from the event
7682   */
7683   rli->set_event_relay_log_pos(max<ulonglong>(rli->get_event_relay_log_pos(),
7684                                               BIN_LOG_HEADER_SIZE));
7685   my_b_seek(cur_log,rli->get_event_relay_log_pos());
7686   DBUG_RETURN(cur_log);
7687 }
7688 
7689 
7690 /**
7691   Reads next event from the relay log.  Should be called from the
7692   slave SQL thread.
7693 
7694   @param rli Relay_log_info structure for the slave SQL thread.
7695 
7696   @return The event read, or NULL on error.  If an error occurs, the
7697   error is reported through the sql_print_information() or
7698   sql_print_error() functions.
7699 */
next_event(Relay_log_info * rli)7700 static Log_event* next_event(Relay_log_info* rli)
7701 {
7702   Log_event* ev;
7703   IO_CACHE* cur_log = rli->cur_log;
7704   mysql_mutex_t *log_lock = rli->relay_log.get_log_lock();
7705   const char* errmsg=0;
7706   THD* thd = rli->info_thd;
7707   DBUG_ENTER("next_event");
7708 
7709   DBUG_ASSERT(thd != 0);
7710 
7711 #ifndef DBUG_OFF
7712   if (abort_slave_event_count && !rli->events_until_exit--)
7713     DBUG_RETURN(0);
7714 #endif
7715 
7716   /*
7717     For most operations we need to protect rli members with data_lock,
7718     so we assume calling function acquired this mutex for us and we will
7719     hold it for the most of the loop below However, we will release it
7720     whenever it is worth the hassle,  and in the cases when we go into a
7721     mysql_cond_wait() with the non-data_lock mutex
7722   */
7723   mysql_mutex_assert_owner(&rli->data_lock);
7724 
7725   while (!sql_slave_killed(thd,rli))
7726   {
7727     /*
7728       We can have two kinds of log reading:
7729       hot_log:
7730         rli->cur_log points at the IO_CACHE of relay_log, which
7731         is actively being updated by the I/O thread. We need to be careful
7732         in this case and make sure that we are not looking at a stale log that
7733         has already been rotated. If it has been, we reopen the log.
7734 
7735       The other case is much simpler:
7736         We just have a read only log that nobody else will be updating.
7737     */
7738     bool hot_log;
7739     if ((hot_log = (cur_log != &rli->cache_buf)) ||
7740         DBUG_EVALUATE_IF("force_sql_thread_error", 1, 0))
7741     {
7742       DBUG_ASSERT(rli->cur_log_fd == -1); // foreign descriptor
7743       mysql_mutex_lock(log_lock);
7744 
7745       /*
7746         Reading xxx_file_id is safe because the log will only
7747         be rotated when we hold relay_log.LOCK_log
7748       */
7749       if (rli->relay_log.get_open_count() != rli->cur_log_old_open_count &&
7750           DBUG_EVALUATE_IF("force_sql_thread_error", 0, 1))
7751       {
7752         // The master has switched to a new log file; Reopen the old log file
7753         cur_log=reopen_relay_log(rli, &errmsg);
7754         mysql_mutex_unlock(log_lock);
7755         if (!cur_log)                           // No more log files
7756           goto err;
7757         hot_log=0;                              // Using old binary log
7758       }
7759     }
7760     /*
7761       As there is no guarantee that the relay is open (for example, an I/O
7762       error during a write by the slave I/O thread may have closed it), we
7763       have to test it.
7764     */
7765     if (!my_b_inited(cur_log) ||
7766         DBUG_EVALUATE_IF("force_sql_thread_error", 1, 0))
7767     {
7768       if (hot_log)
7769         mysql_mutex_unlock(log_lock);
7770       goto err;
7771     }
7772 #ifndef DBUG_OFF
7773     {
7774       DBUG_PRINT("info", ("assertion skip %lu file pos %lu event relay log pos %lu file %s\n",
7775         (ulong) rli->slave_skip_counter, (ulong) my_b_tell(cur_log),
7776         (ulong) rli->get_event_relay_log_pos(),
7777         rli->get_event_relay_log_name()));
7778 
7779       /* This is an assertion which sometimes fails, let's try to track it */
7780       char llbuf1[22], llbuf2[22];
7781       DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
7782                           llstr(my_b_tell(cur_log),llbuf1),
7783                           llstr(rli->get_event_relay_log_pos(),llbuf2)));
7784 
7785       DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
7786       DBUG_ASSERT(my_b_tell(cur_log) == rli->get_event_relay_log_pos() || rli->is_parallel_exec());
7787 
7788       DBUG_PRINT("info", ("next_event group master %s %lu group relay %s %lu event %s %lu\n",
7789         rli->get_group_master_log_name(),
7790         (ulong) rli->get_group_master_log_pos(),
7791         rli->get_group_relay_log_name(),
7792         (ulong) rli->get_group_relay_log_pos(),
7793         rli->get_event_relay_log_name(),
7794         (ulong) rli->get_event_relay_log_pos()));
7795     }
7796 #endif
7797     /*
7798       Relay log is always in new format - if the master is 3.23, the
7799       I/O thread will convert the format for us.
7800       A problem: the description event may be in a previous relay log. So if
7801       the slave has been shutdown meanwhile, we would have to look in old relay
7802       logs, which may even have been deleted. So we need to write this
7803       description event at the beginning of the relay log.
7804       When the relay log is created when the I/O thread starts, easy: the
7805       master will send the description event and we will queue it.
7806       But if the relay log is created by new_file(): then the solution is:
7807       MYSQL_BIN_LOG::open() will write the buffered description event.
7808     */
7809     if ((ev= Log_event::read_log_event(cur_log, 0,
7810                                        rli->get_rli_description_event(),
7811                                        opt_slave_sql_verify_checksum)))
7812     {
7813       DBUG_ASSERT(thd==rli->info_thd);
7814       /*
7815         read it while we have a lock, to avoid a mutex lock in
7816         inc_event_relay_log_pos()
7817       */
7818       rli->set_future_event_relay_log_pos(my_b_tell(cur_log));
7819       ev->future_event_relay_log_pos= rli->get_future_event_relay_log_pos();
7820 
7821       if (hot_log)
7822         mysql_mutex_unlock(log_lock);
7823 
7824       /*
7825          MTS checkpoint in the successful read branch
7826       */
7827       bool force= (rli->checkpoint_seqno > (rli->checkpoint_group - 1));
7828       if (rli->is_parallel_exec() && (opt_mts_checkpoint_period != 0 || force))
7829       {
7830         ulonglong period= static_cast<ulonglong>(opt_mts_checkpoint_period * 1000000ULL);
7831         mysql_mutex_unlock(&rli->data_lock);
7832         /*
7833           At this point the coordinator has is delegating jobs to workers and
7834           the checkpoint routine must be periodically invoked.
7835         */
7836         (void) mts_checkpoint_routine(rli, period, force, true/*need_data_lock=true*/); // TODO: ALFRANIO ERROR
7837         DBUG_ASSERT(!force ||
7838                     (force && (rli->checkpoint_seqno <= (rli->checkpoint_group - 1))) ||
7839                     sql_slave_killed(thd, rli));
7840         mysql_mutex_lock(&rli->data_lock);
7841       }
7842       DBUG_RETURN(ev);
7843     }
7844     DBUG_ASSERT(thd==rli->info_thd);
7845     if (opt_reckless_slave)                     // For mysql-test
7846       cur_log->error = 0;
7847     if (cur_log->error < 0)
7848     {
7849       errmsg = "slave SQL thread aborted because of I/O error";
7850       if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
7851         /*
7852           MTS group status is set to MTS_KILLED_GROUP, whenever a read event
7853           error happens and there was already a non-terminal event scheduled.
7854         */
7855         rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
7856       if (hot_log)
7857         mysql_mutex_unlock(log_lock);
7858       goto err;
7859     }
7860     if (!cur_log->error) /* EOF */
7861     {
7862       /*
7863         On a hot log, EOF means that there are no more updates to
7864         process and we must block until I/O thread adds some and
7865         signals us to continue
7866       */
7867       if (hot_log)
7868       {
7869         /*
7870           We say in Seconds_Behind_Master that we have "caught up". Note that
7871           for example if network link is broken but I/O slave thread hasn't
7872           noticed it (slave_net_timeout not elapsed), then we'll say "caught
7873           up" whereas we're not really caught up. Fixing that would require
7874           internally cutting timeout in smaller pieces in network read, no
7875           thanks. Another example: SQL has caught up on I/O, now I/O has read
7876           a new event and is queuing it; the false "0" will exist until SQL
7877           finishes executing the new event; it will be look abnormal only if
7878           the events have old timestamps (then you get "many", 0, "many").
7879 
7880           Transient phases like this can be fixed with implemeting
7881           Heartbeat event which provides the slave the status of the
7882           master at time the master does not have any new update to send.
7883           Seconds_Behind_Master would be zero only when master has no
7884           more updates in binlog for slave. The heartbeat can be sent
7885           in a (small) fraction of slave_net_timeout. Until it's done
7886           rli->last_master_timestamp is temporarely (for time of
7887           waiting for the following event) reset whenever EOF is
7888           reached.
7889         */
7890 
7891         /* shows zero while it is sleeping (and until the next event
7892            is about to be executed).  Note, in MTS case
7893            Seconds_Behind_Master resetting follows slightly different
7894            schema where reaching EOF is not enough.  The status
7895            parameter is updated per some number of processed group of
7896            events. The number can't be greater than
7897            @@global.slave_checkpoint_group and anyway SBM updating
7898            rate does not exceed @@global.slave_checkpoint_period.
7899            Notice that SBM is set to a new value after processing the
7900            terminal event (e.g Commit) of a group.  Coordinator resets
7901            SBM when notices no more groups left neither to read from
7902            Relay-log nor to process by Workers.
7903         */
7904         if (!rli->is_parallel_exec())
7905           rli->last_master_timestamp= 0;
7906 
7907         DBUG_ASSERT(rli->relay_log.get_open_count() ==
7908                     rli->cur_log_old_open_count);
7909 
7910         if (rli->ign_master_log_name_end[0])
7911         {
7912           /* We generate and return a Rotate, to make our positions advance */
7913           DBUG_PRINT("info",("seeing an ignored end segment"));
7914           ev= new Rotate_log_event(rli->ign_master_log_name_end,
7915                                    0, rli->ign_master_log_pos_end,
7916                                    Rotate_log_event::DUP_NAME);
7917           rli->ign_master_log_name_end[0]= 0;
7918           mysql_mutex_unlock(log_lock);
7919           if (unlikely(!ev))
7920           {
7921             errmsg= "Slave SQL thread failed to create a Rotate event "
7922               "(out of memory?), SHOW SLAVE STATUS may be inaccurate";
7923             goto err;
7924           }
7925           ev->server_id= 0; // don't be ignored by slave SQL thread
7926           DBUG_RETURN(ev);
7927         }
7928 
7929         /*
7930           We can, and should release data_lock while we are waiting for
7931           update. If we do not, show slave status will block
7932         */
7933         mysql_mutex_unlock(&rli->data_lock);
7934 
7935         /*
7936           Possible deadlock :
7937           - the I/O thread has reached log_space_limit
7938           - the SQL thread has read all relay logs, but cannot purge for some
7939           reason:
7940             * it has already purged all logs except the current one
7941             * there are other logs than the current one but they're involved in
7942             a transaction that finishes in the current one (or is not finished)
7943           Solution :
7944           Wake up the possibly waiting I/O thread, and set a boolean asking
7945           the I/O thread to temporarily ignore the log_space_limit
7946           constraint, because we do not want the I/O thread to block because of
7947           space (it's ok if it blocks for any other reason (e.g. because the
7948           master does not send anything). Then the I/O thread stops waiting
7949           and reads one more event and starts honoring log_space_limit again.
7950 
7951           If the SQL thread needs more events to be able to rotate the log (it
7952           might need to finish the current group first), then it can ask for one
7953           more at a time. Thus we don't outgrow the relay log indefinitely,
7954           but rather in a controlled manner, until the next rotate.
7955 
7956           When the SQL thread starts it sets ignore_log_space_limit to false.
7957           We should also reset ignore_log_space_limit to 0 when the user does
7958           RESET SLAVE, but in fact, no need as RESET SLAVE requires that the slave
7959           be stopped, and the SQL thread sets ignore_log_space_limit to 0 when
7960           it stops.
7961         */
7962         mysql_mutex_lock(&rli->log_space_lock);
7963 
7964         /*
7965           If we have reached the limit of the relay space and we
7966           are going to sleep, waiting for more events:
7967 
7968           1. If outside a group, SQL thread asks the IO thread
7969              to force a rotation so that the SQL thread purges
7970              logs next time it processes an event (thus space is
7971              freed).
7972 
7973           2. If in a group, SQL thread asks the IO thread to
7974              ignore the limit and queues yet one more event
7975              so that the SQL thread finishes the group and
7976              is are able to rotate and purge sometime soon.
7977          */
7978         if (rli->log_space_limit &&
7979             rli->log_space_limit < rli->log_space_total)
7980         {
7981           /* force rotation if not in an unfinished group */
7982           if (!rli->is_parallel_exec())
7983           {
7984             rli->sql_force_rotate_relay= !rli->is_in_group();
7985           }
7986           else
7987           {
7988             rli->sql_force_rotate_relay=
7989               (rli->mts_group_status != Relay_log_info::MTS_IN_GROUP);
7990           }
7991           /* ask for one more event */
7992           rli->ignore_log_space_limit= true;
7993         }
7994 
7995         /*
7996           If the I/O thread is blocked, unblock it.  Ok to broadcast
7997           after unlock, because the mutex is only destroyed in
7998           ~Relay_log_info(), i.e. when rli is destroyed, and rli will
7999           not be destroyed before we exit the present function.
8000         */
8001         mysql_mutex_unlock(&rli->log_space_lock);
8002         mysql_cond_broadcast(&rli->log_space_cond);
8003         // Note that wait_for_update_relay_log unlocks lock_log !
8004 
8005         if (rli->is_parallel_exec() && (opt_mts_checkpoint_period != 0 ||
8006             DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0)))
8007         {
8008           int ret= 0;
8009           struct timespec waittime;
8010           ulonglong period= static_cast<ulonglong>(opt_mts_checkpoint_period * 1000000ULL);
8011           ulong signal_cnt= rli->relay_log.signal_cnt;
8012 
8013           mysql_mutex_unlock(log_lock);
8014           do
8015           {
8016             /*
8017               At this point the coordinator has no job to delegate to workers.
8018               However, workers are executing their assigned jobs and as such
8019               the checkpoint routine must be periodically invoked.
8020             */
8021             (void) mts_checkpoint_routine(rli, period, false, true/*need_data_lock=true*/); // TODO: ALFRANIO ERROR
8022             mysql_mutex_lock(log_lock);
8023             // More to the empty relay-log all assigned events done so reset it.
8024             if (rli->gaq->empty())
8025               rli->last_master_timestamp= 0;
8026 
8027             if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
8028               period= 10000000ULL;
8029 
8030             set_timespec_nsec(waittime, period);
8031             ret= rli->relay_log.wait_for_update_relay_log(thd, &waittime);
8032           } while ((ret == ETIMEDOUT || ret == ETIME) /* todo:remove */ &&
8033                    signal_cnt == rli->relay_log.signal_cnt && !thd->killed);
8034         }
8035         else
8036         {
8037           rli->relay_log.wait_for_update_relay_log(thd, NULL);
8038         }
8039 
8040         // re-acquire data lock since we released it earlier
8041         mysql_mutex_lock(&rli->data_lock);
8042         continue;
8043       }
8044       /*
8045         If the log was not hot, we need to move to the next log in
8046         sequence. The next log could be hot or cold, we deal with both
8047         cases separately after doing some common initialization
8048       */
8049       end_io_cache(cur_log);
8050       DBUG_ASSERT(rli->cur_log_fd >= 0);
8051       mysql_file_close(rli->cur_log_fd, MYF(MY_WME));
8052       rli->cur_log_fd = -1;
8053 
8054       if (relay_log_purge)
8055       {
8056         /*
8057           purge_first_log will properly set up relay log coordinates in rli.
8058           If the group's coordinates are equal to the event's coordinates
8059           (i.e. the relay log was not rotated in the middle of a group),
8060           we can purge this relay log too.
8061           We do ulonglong and string comparisons, this may be slow but
8062           - purging the last relay log is nice (it can save 1GB of disk), so we
8063           like to detect the case where we can do it, and given this,
8064           - I see no better detection method
8065           - purge_first_log is not called that often
8066         */
8067         if (rli->relay_log.purge_first_log
8068             (rli,
8069              rli->get_group_relay_log_pos() == rli->get_event_relay_log_pos()
8070              && !strcmp(rli->get_group_relay_log_name(),rli->get_event_relay_log_name())))
8071         {
8072           errmsg = "Error purging processed logs";
8073           goto err;
8074         }
8075         DBUG_PRINT("info", ("next_event group master %s %lu  group relay %s %lu event %s %lu\n",
8076           rli->get_group_master_log_name(),
8077           (ulong) rli->get_group_master_log_pos(),
8078           rli->get_group_relay_log_name(),
8079           (ulong) rli->get_group_relay_log_pos(),
8080           rli->get_event_relay_log_name(),
8081           (ulong) rli->get_event_relay_log_pos()));
8082       }
8083       else
8084       {
8085         /*
8086           If hot_log is set, then we already have a lock on
8087           LOCK_log.  If not, we have to get the lock.
8088 
8089           According to Sasha, the only time this code will ever be executed
8090           is if we are recovering from a bug.
8091         */
8092         if (rli->relay_log.find_next_log(&rli->linfo, !hot_log))
8093         {
8094           errmsg = "error switching to the next log";
8095           goto err;
8096         }
8097         rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
8098         rli->set_event_relay_log_name(rli->linfo.log_file_name);
8099         /*
8100           We may update the worker here but this is not extremlly
8101           necessary. /Alfranio
8102         */
8103         rli->flush_info();
8104       }
8105 
8106       /* Reset the relay-log-change-notified status of  Slave Workers */
8107       if (rli->is_parallel_exec())
8108       {
8109         DBUG_PRINT("info", ("next_event: MTS group relay log changes to %s %lu\n",
8110                             rli->get_group_relay_log_name(),
8111                             (ulong) rli->get_group_relay_log_pos()));
8112         rli->reset_notified_relay_log_change();
8113       }
8114 
8115       /*
8116         Now we want to open this next log. To know if it's a hot log (the one
8117         being written by the I/O thread now) or a cold log, we can use
8118         is_active(); if it is hot, we use the I/O cache; if it's cold we open
8119         the file normally. But if is_active() reports that the log is hot, this
8120         may change between the test and the consequence of the test. So we may
8121         open the I/O cache whereas the log is now cold, which is nonsense.
8122         To guard against this, we need to have LOCK_log.
8123       */
8124 
8125       DBUG_PRINT("info",("hot_log: %d",hot_log));
8126       if (!hot_log) /* if hot_log, we already have this mutex */
8127         mysql_mutex_lock(log_lock);
8128       if (rli->relay_log.is_active(rli->linfo.log_file_name))
8129       {
8130 #ifdef EXTRA_DEBUG
8131         if (log_warnings)
8132           sql_print_information("next log '%s' is currently active",
8133                                 rli->linfo.log_file_name);
8134 #endif
8135         rli->cur_log= cur_log= rli->relay_log.get_log_file();
8136         rli->cur_log_old_open_count= rli->relay_log.get_open_count();
8137         DBUG_ASSERT(rli->cur_log_fd == -1);
8138 
8139         /*
8140            When the SQL thread is [stopped and] (re)started the
8141            following may happen:
8142 
8143            1. Log was hot at stop time and remains hot at restart
8144 
8145               SQL thread reads again from hot_log (SQL thread was
8146               reading from the active log when it was stopped and the
8147               very same log is still active on SQL thread restart).
8148 
8149               In this case, my_b_seek is performed on cur_log, while
8150               cur_log points to relay_log.get_log_file();
8151 
8152            2. Log was hot at stop time but got cold before restart
8153 
8154               The log was hot when SQL thread stopped, but it is not
8155               anymore when the SQL thread restarts.
8156 
8157               In this case, the SQL thread reopens the log, using
8158               cache_buf, ie, cur_log points to &cache_buf, and thence
8159               its coordinates are reset.
8160 
8161            3. Log was already cold at stop time
8162 
8163               The log was not hot when the SQL thread stopped, and, of
8164               course, it will not be hot when it restarts.
8165 
8166               In this case, the SQL thread opens the cold log again,
8167               using cache_buf, ie, cur_log points to &cache_buf, and
8168               thence its coordinates are reset.
8169 
8170            4. Log was hot at stop time, DBA changes to previous cold
8171               log and restarts SQL thread
8172 
8173               The log was hot when the SQL thread was stopped, but the
8174               user changed the coordinates of the SQL thread to
8175               restart from a previous cold log.
8176 
8177               In this case, at start time, cur_log points to a cold
8178               log, opened using &cache_buf as cache, and coordinates
8179               are reset. However, as it moves on to the next logs, it
8180               will eventually reach the hot log. If the hot log is the
8181               same at the time the SQL thread was stopped, then
8182               coordinates were not reset - the cur_log will point to
8183               relay_log.get_log_file(), and not a freshly opened
8184               IO_CACHE through cache_buf. For this reason we need to
8185               deploy a my_b_seek before calling check_binlog_magic at
8186               this point of the code (see: BUG#55263 for more
8187               details).
8188 
8189           NOTES:
8190             - We must keep the LOCK_log to read the 4 first bytes, as
8191               this is a hot log (same as when we call read_log_event()
8192               above: for a hot log we take the mutex).
8193 
8194             - Because of scenario #4 above, we need to have a
8195               my_b_seek here. Otherwise, we might hit the assertion
8196               inside check_binlog_magic.
8197         */
8198 
8199         my_b_seek(cur_log, (my_off_t) 0);
8200         if (check_binlog_magic(cur_log,&errmsg))
8201         {
8202           if (!hot_log)
8203             mysql_mutex_unlock(log_lock);
8204           goto err;
8205         }
8206         if (!hot_log)
8207           mysql_mutex_unlock(log_lock);
8208         continue;
8209       }
8210       if (!hot_log)
8211         mysql_mutex_unlock(log_lock);
8212       /*
8213         if we get here, the log was not hot, so we will have to open it
8214         ourselves. We are sure that the log is still not hot now (a log can get
8215         from hot to cold, but not from cold to hot). No need for LOCK_log.
8216       */
8217 #ifdef EXTRA_DEBUG
8218       if (log_warnings)
8219         sql_print_information("next log '%s' is not active",
8220                               rli->linfo.log_file_name);
8221 #endif
8222       // open_binlog_file() will check the magic header
8223       if ((rli->cur_log_fd=open_binlog_file(cur_log,rli->linfo.log_file_name,
8224                                             &errmsg)) <0)
8225         goto err;
8226     }
8227     else
8228     {
8229       /*
8230         Read failed with a non-EOF error.
8231         TODO: come up with something better to handle this error
8232       */
8233       if (hot_log)
8234         mysql_mutex_unlock(log_lock);
8235       sql_print_error("Slave SQL thread: I/O error reading \
8236 event(errno: %d  cur_log->error: %d)",
8237                       my_errno,cur_log->error);
8238       // set read position to the beginning of the event
8239       my_b_seek(cur_log,rli->get_event_relay_log_pos());
8240       /* otherwise, we have had a partial read */
8241       errmsg = "Aborting slave SQL thread because of partial event read";
8242       break;                                    // To end of function
8243     }
8244   }
8245   if (!errmsg && log_warnings)
8246   {
8247     sql_print_information("Error reading relay log event: %s",
8248                           "slave SQL thread was killed");
8249     DBUG_RETURN(0);
8250   }
8251 
8252 err:
8253   if (errmsg)
8254     sql_print_error("Error reading relay log event: %s", errmsg);
8255   DBUG_RETURN(0);
8256 }
8257 
8258 /*
8259   Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation
8260   because of size is simpler because when we do it we already have all relevant
8261   locks; here we don't, so this function is mainly taking locks).
8262   Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file()
8263   is void).
8264 */
8265 
rotate_relay_log(Master_info * mi,bool need_log_space_lock)8266 int rotate_relay_log(Master_info* mi, bool need_log_space_lock)
8267 {
8268   DBUG_ENTER("rotate_relay_log");
8269 
8270   mysql_mutex_assert_owner(&mi->data_lock);
8271   DBUG_EXECUTE_IF("crash_before_rotate_relaylog", DBUG_SUICIDE(););
8272 
8273   Relay_log_info* rli= mi->rli;
8274   int error= 0;
8275 
8276   /*
8277      We need to test inited because otherwise, new_file() will attempt to lock
8278      LOCK_log, which may not be inited (if we're not a slave).
8279   */
8280   if (!rli->inited)
8281   {
8282     DBUG_PRINT("info", ("rli->inited == 0"));
8283     goto end;
8284   }
8285 
8286   /* If the relay log is closed, new_file() will do nothing. */
8287   error= rli->relay_log.new_file(mi->get_mi_description_event());
8288   if (error != 0)
8289     goto end;
8290 
8291   /*
8292     We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately
8293     be counted, so imagine a succession of FLUSH LOGS  and assume the slave
8294     threads are started:
8295     relay_log_space decreases by the size of the deleted relay log, but does
8296     not increase, so flush-after-flush we may become negative, which is wrong.
8297     Even if this will be corrected as soon as a query is replicated on the
8298     slave (because the I/O thread will then call harvest_bytes_written() which
8299     will harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange
8300     output in SHOW SLAVE STATUS meanwhile. So we harvest now.
8301     If the log is closed, then this will just harvest the last writes, probably
8302     0 as they probably have been harvested.
8303   */
8304   rli->relay_log.harvest_bytes_written(rli, need_log_space_lock);
8305 end:
8306   DBUG_RETURN(error);
8307 }
8308 
8309 
8310 /**
8311    Detects, based on master's version (as found in the relay log), if master
8312    has a certain bug.
8313    @param rli Relay_log_info which tells the master's version
8314    @param bug_id Number of the bug as found in bugs.mysql.com
8315    @param report bool report error message, default TRUE
8316 
8317    @param pred Predicate function that will be called with @c param to
8318    check for the bug. If the function return @c true, the bug is present,
8319    otherwise, it is not.
8320 
8321    @param param  State passed to @c pred function.
8322 
8323    @return TRUE if master has the bug, FALSE if it does not.
8324 */
rpl_master_has_bug(const Relay_log_info * rli,uint bug_id,bool report,bool (* pred)(const void *),const void * param)8325 bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report,
8326                         bool (*pred)(const void *), const void *param)
8327 {
8328   struct st_version_range_for_one_bug {
8329     uint        bug_id;
8330     const uchar introduced_in[3]; // first version with bug
8331     const uchar fixed_in[3];      // first version with fix
8332   };
8333   static struct st_version_range_for_one_bug versions_for_all_bugs[]=
8334   {
8335     {24432, { 5, 0, 24 }, { 5, 0, 38 } },
8336     {24432, { 5, 1, 12 }, { 5, 1, 17 } },
8337     {33029, { 5, 0,  0 }, { 5, 0, 58 } },
8338     {33029, { 5, 1,  0 }, { 5, 1, 12 } },
8339     {37426, { 5, 1,  0 }, { 5, 1, 26 } },
8340   };
8341   const uchar *master_ver=
8342     rli->get_rli_description_event()->server_version_split;
8343 
8344   DBUG_ASSERT(sizeof(rli->get_rli_description_event()->server_version_split) == 3);
8345 
8346   for (uint i= 0;
8347        i < sizeof(versions_for_all_bugs)/sizeof(*versions_for_all_bugs);i++)
8348   {
8349     const uchar *introduced_in= versions_for_all_bugs[i].introduced_in,
8350       *fixed_in= versions_for_all_bugs[i].fixed_in;
8351     if ((versions_for_all_bugs[i].bug_id == bug_id) &&
8352         (memcmp(introduced_in, master_ver, 3) <= 0) &&
8353         (memcmp(fixed_in,      master_ver, 3) >  0) &&
8354         (pred == NULL || (*pred)(param)))
8355     {
8356       enum loglevel report_level= INFORMATION_LEVEL;
8357       if (!report)
8358 	return TRUE;
8359       // a short message for SHOW SLAVE STATUS (message length constraints)
8360       my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from"
8361                       " http://bugs.mysql.com/bug.php?id=%u"
8362                       " so slave stops; check error log on slave"
8363                       " for more info", MYF(0), bug_id);
8364       // a verbose message for the error log
8365       if (!ignored_error_code(ER_UNKNOWN_ERROR))
8366       {
8367         report_level= ERROR_LEVEL;
8368         current_thd->is_slave_error= 1;
8369       }
8370       /* In case of ignored errors report warnings only if log_warnings > 1. */
8371       else if (log_warnings > 1)
8372         report_level= WARNING_LEVEL;
8373 
8374       if (report_level != INFORMATION_LEVEL)
8375         rli->report(report_level, ER_UNKNOWN_ERROR,
8376                     "According to the master's version ('%s'),"
8377                     " it is probable that master suffers from this bug:"
8378                     " http://bugs.mysql.com/bug.php?id=%u"
8379                     " and thus replicating the current binary log event"
8380                     " may make the slave's data become different from the"
8381                     " master's data."
8382                     " To take no risk, slave refuses to replicate"
8383                     " this event and stops."
8384                     " We recommend that all updates be stopped on the"
8385                     " master and slave, that the data of both be"
8386                     " manually synchronized,"
8387                     " that master's binary logs be deleted,"
8388                     " that master be upgraded to a version at least"
8389                     " equal to '%d.%d.%d'. Then replication can be"
8390                     " restarted.",
8391                     rli->get_rli_description_event()->server_version,
8392                     bug_id,
8393                     fixed_in[0], fixed_in[1], fixed_in[2]);
8394       return TRUE;
8395     }
8396   }
8397   return FALSE;
8398 }
8399 
8400 /**
8401    BUG#33029, For all 5.0 up to 5.0.58 exclusive, and 5.1 up to 5.1.12
8402    exclusive, if one statement in a SP generated AUTO_INCREMENT value
8403    by the top statement, all statements after it would be considered
8404    generated AUTO_INCREMENT value by the top statement, and a
8405    erroneous INSERT_ID value might be associated with these statement,
8406    which could cause duplicate entry error and stop the slave.
8407 
8408    Detect buggy master to work around.
8409  */
rpl_master_erroneous_autoinc(THD * thd)8410 bool rpl_master_erroneous_autoinc(THD *thd)
8411 {
8412   if (active_mi != NULL && active_mi->rli->info_thd == thd)
8413   {
8414     Relay_log_info *rli= active_mi->rli;
8415     DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
8416     return rpl_master_has_bug(rli, 33029, FALSE, NULL, NULL);
8417   }
8418   return FALSE;
8419 }
8420 
8421 /**
8422   a copy of active_mi->rli->slave_skip_counter, for showing in SHOW VARIABLES,
8423   INFORMATION_SCHEMA.GLOBAL_VARIABLES and @@sql_slave_skip_counter without
8424   taking all the mutexes needed to access active_mi->rli->slave_skip_counter
8425   properly.
8426 */
8427 uint sql_slave_skip_counter;
8428 
8429 /**
8430   Execute a START SLAVE statement.
8431 
8432   @param thd Pointer to THD object for the client thread executing the
8433   statement.
8434 
8435   @param mi Pointer to Master_info object for the slave's IO thread.
8436 
8437   @param net_report If true, saves the exit status into Diagnostics_area.
8438 
8439   @retval 0 success
8440   @retval 1 error
8441 */
start_slave(THD * thd,Master_info * mi,bool net_report)8442 int start_slave(THD* thd , Master_info* mi,  bool net_report)
8443 {
8444   int slave_errno= 0;
8445   int thread_mask;
8446   DBUG_ENTER("start_slave");
8447 
8448   if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0))
8449     DBUG_RETURN(1);
8450 
8451   if (thd->lex->slave_connection.user ||
8452       thd->lex->slave_connection.password)
8453   {
8454 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8455     if (thd->vio_ok() && !thd->net.vio->ssl_arg)
8456       push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8457                    ER_INSECURE_PLAIN_TEXT,
8458                    ER(ER_INSECURE_PLAIN_TEXT));
8459 #endif
8460 #if !defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8461     push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8462                  ER_INSECURE_PLAIN_TEXT,
8463                  ER(ER_INSECURE_PLAIN_TEXT));
8464 #endif
8465   }
8466 
8467   lock_slave_threads(mi);  // this allows us to cleanly read slave_running
8468   // Get a mask of _stopped_ threads
8469   init_thread_mask(&thread_mask,mi,1 /* inverse */);
8470   /*
8471     Below we will start all stopped threads.  But if the user wants to
8472     start only one thread, do as if the other thread was running (as we
8473     don't wan't to touch the other thread), so set the bit to 0 for the
8474     other thread
8475   */
8476   if (thd->lex->slave_thd_opt)
8477     thread_mask&= thd->lex->slave_thd_opt;
8478   if (thread_mask) //some threads are stopped, start them
8479   {
8480     if (global_init_info(mi, false, thread_mask))
8481       slave_errno=ER_MASTER_INFO;
8482     else if (server_id_supplied && *mi->host)
8483     {
8484       /*
8485         If we will start IO thread we need to take care of possible
8486         options provided through the START SLAVE if there is any.
8487       */
8488       if (thread_mask & SLAVE_IO)
8489       {
8490         if (thd->lex->slave_connection.user)
8491         {
8492           mi->set_start_user_configured(true);
8493           mi->set_user(thd->lex->slave_connection.user);
8494         }
8495         if (thd->lex->slave_connection.password)
8496         {
8497           mi->set_start_user_configured(true);
8498           mi->set_password(thd->lex->slave_connection.password,
8499                            strlen(thd->lex->slave_connection.password));
8500         }
8501         if (thd->lex->slave_connection.plugin_auth)
8502           mi->set_plugin_auth(thd->lex->slave_connection.plugin_auth);
8503         if (thd->lex->slave_connection.plugin_dir)
8504           mi->set_plugin_dir(thd->lex->slave_connection.plugin_dir);
8505       }
8506 
8507       /*
8508         If we will start SQL thread we will care about UNTIL options If
8509         not and they are specified we will ignore them and warn user
8510         about this fact.
8511       */
8512       if (thread_mask & SLAVE_SQL)
8513       {
8514         /*
8515           To cache the MTS system var values and used them in the following
8516           runtime. The system var:s can change meanwhile but having no other
8517           effects.
8518         */
8519         mi->rli->opt_slave_parallel_workers= opt_mts_slave_parallel_workers;
8520 #ifndef DBUG_OFF
8521         if (!DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
8522 #endif
8523           mi->rli->checkpoint_group= opt_mts_checkpoint_group;
8524 
8525         mysql_mutex_lock(&mi->rli->data_lock);
8526 
8527         if (thd->lex->mi.pos)
8528         {
8529           if (thd->lex->mi.relay_log_pos)
8530             slave_errno= ER_BAD_SLAVE_UNTIL_COND;
8531           mi->rli->until_condition= Relay_log_info::UNTIL_MASTER_POS;
8532           mi->rli->until_log_pos= thd->lex->mi.pos;
8533           /*
8534              We don't check thd->lex->mi.log_file_name for NULL here
8535              since it is checked in sql_yacc.yy
8536           */
8537           strmake(mi->rli->until_log_name, thd->lex->mi.log_file_name,
8538                   sizeof(mi->rli->until_log_name)-1);
8539         }
8540         else if (thd->lex->mi.relay_log_pos)
8541         {
8542           if (thd->lex->mi.pos)
8543             slave_errno= ER_BAD_SLAVE_UNTIL_COND;
8544           mi->rli->until_condition= Relay_log_info::UNTIL_RELAY_POS;
8545           mi->rli->until_log_pos= thd->lex->mi.relay_log_pos;
8546           strmake(mi->rli->until_log_name, thd->lex->mi.relay_log_name,
8547                   sizeof(mi->rli->until_log_name)-1);
8548         }
8549         else if (thd->lex->mi.gtid)
8550         {
8551           global_sid_lock->wrlock();
8552           mi->rli->clear_until_condition();
8553           if (mi->rli->until_sql_gtids.add_gtid_text(thd->lex->mi.gtid)
8554               != RETURN_STATUS_OK)
8555             slave_errno= ER_BAD_SLAVE_UNTIL_COND;
8556           else {
8557             mi->rli->until_condition=
8558               LEX_MASTER_INFO::UNTIL_SQL_BEFORE_GTIDS == thd->lex->mi.gtid_until_condition
8559               ? Relay_log_info::UNTIL_SQL_BEFORE_GTIDS
8560               : Relay_log_info::UNTIL_SQL_AFTER_GTIDS;
8561             if ((mi->rli->until_condition ==
8562                Relay_log_info::UNTIL_SQL_AFTER_GTIDS) &&
8563                mi->rli->opt_slave_parallel_workers != 0)
8564             {
8565               mi->rli->opt_slave_parallel_workers= 0;
8566               push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
8567                                   ER_MTS_FEATURE_IS_NOT_SUPPORTED,
8568                                   ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED),
8569                                   "UNTIL condtion",
8570                                   "Slave is started in the sequential execution mode.");
8571             }
8572           }
8573           global_sid_lock->unlock();
8574         }
8575         else if (thd->lex->mi.until_after_gaps)
8576         {
8577             mi->rli->until_condition= Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS;
8578             mi->rli->opt_slave_parallel_workers=
8579               mi->rli->recovery_parallel_workers;
8580         }
8581         else
8582           mi->rli->clear_until_condition();
8583 
8584         if (mi->rli->until_condition == Relay_log_info::UNTIL_MASTER_POS ||
8585             mi->rli->until_condition == Relay_log_info::UNTIL_RELAY_POS)
8586         {
8587           /* Preparing members for effective until condition checking */
8588           const char *p= fn_ext(mi->rli->until_log_name);
8589           char *p_end;
8590           if (*p)
8591           {
8592             //p points to '.'
8593             mi->rli->until_log_name_extension= strtoul(++p,&p_end, 10);
8594             /*
8595               p_end points to the first invalid character. If it equals
8596               to p, no digits were found, error. If it contains '\0' it
8597               means  conversion went ok.
8598             */
8599             if (p_end==p || *p_end)
8600               slave_errno=ER_BAD_SLAVE_UNTIL_COND;
8601           }
8602           else
8603             slave_errno=ER_BAD_SLAVE_UNTIL_COND;
8604 
8605           /* mark the cached result of the UNTIL comparison as "undefined" */
8606           mi->rli->until_log_names_cmp_result=
8607             Relay_log_info::UNTIL_LOG_NAMES_CMP_UNKNOWN;
8608 
8609           /* Issuing warning then started without --skip-slave-start */
8610           if (!opt_skip_slave_start)
8611             push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8612                          ER_MISSING_SKIP_SLAVE,
8613                          ER(ER_MISSING_SKIP_SLAVE));
8614           if (mi->rli->opt_slave_parallel_workers != 0)
8615           {
8616             mi->rli->opt_slave_parallel_workers= 0;
8617             push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
8618                                 ER_MTS_FEATURE_IS_NOT_SUPPORTED,
8619                                 ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED),
8620                                 "UNTIL condtion",
8621                                 "Slave is started in the sequential execution mode.");
8622           }
8623         }
8624 
8625         mysql_mutex_unlock(&mi->rli->data_lock);
8626 
8627         /* MTS technical limitation no support of trans retry */
8628         if (mi->rli->opt_slave_parallel_workers != 0 && slave_trans_retries != 0)
8629         {
8630           push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
8631                               ER_MTS_FEATURE_IS_NOT_SUPPORTED,
8632                               ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED),
8633                               "slave_transaction_retries",
8634                               "In the event of a transient failure, the slave will "
8635                               "not retry the transaction and will stop.");
8636         }
8637       }
8638       else if (thd->lex->mi.pos || thd->lex->mi.relay_log_pos || thd->lex->mi.gtid)
8639         push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED,
8640                      ER(ER_UNTIL_COND_IGNORED));
8641 
8642       if (!slave_errno)
8643         slave_errno = start_slave_threads(false/*need_lock_slave=false*/,
8644                                           true/*wait_for_start=true*/,
8645                                           mi,
8646                                           thread_mask);
8647     }
8648     else
8649       slave_errno = ER_BAD_SLAVE;
8650   }
8651   else
8652   {
8653     /* no error if all threads are already started, only a warning */
8654     push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_RUNNING,
8655                  ER(ER_SLAVE_WAS_RUNNING));
8656   }
8657 
8658   /*
8659     Clean up start information if there was an attempt to start
8660     the IO thread to avoid any security issue.
8661   */
8662   if (slave_errno &&
8663       (thread_mask & SLAVE_IO) == SLAVE_IO)
8664     mi->reset_start_info();
8665 
8666   unlock_slave_threads(mi);
8667 
8668   if (slave_errno)
8669   {
8670     if (net_report)
8671       my_message(slave_errno, ER(slave_errno), MYF(0));
8672     DBUG_RETURN(1);
8673   }
8674   else if (net_report)
8675     my_ok(thd);
8676 
8677   DBUG_RETURN(0);
8678 }
8679 
8680 
8681 /**
8682   Execute a STOP SLAVE statement.
8683 
8684   @param thd Pointer to THD object for the client thread executing the
8685   statement.
8686 
8687   @param mi Pointer to Master_info object for the slave's IO thread.
8688 
8689   @param net_report If true, saves the exit status into Diagnostics_area.
8690 
8691   @retval 0 success
8692   @retval 1 error
8693 */
stop_slave(THD * thd,Master_info * mi,bool net_report)8694 int stop_slave(THD* thd, Master_info* mi, bool net_report )
8695 {
8696   DBUG_ENTER("stop_slave");
8697 
8698   int slave_errno;
8699   if (!thd)
8700     thd = current_thd;
8701 
8702   if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0))
8703     DBUG_RETURN(1);
8704   THD_STAGE_INFO(thd, stage_killing_slave);
8705   int thread_mask;
8706   lock_slave_threads(mi);
8707   // Get a mask of _running_ threads
8708   init_thread_mask(&thread_mask,mi,0 /* not inverse*/);
8709   /*
8710     Below we will stop all running threads.
8711     But if the user wants to stop only one thread, do as if the other thread
8712     was stopped (as we don't wan't to touch the other thread), so set the
8713     bit to 0 for the other thread
8714   */
8715   if (thd->lex->slave_thd_opt)
8716     thread_mask &= thd->lex->slave_thd_opt;
8717 
8718   if (thread_mask)
8719   {
8720     slave_errno= terminate_slave_threads(mi,thread_mask,
8721                                          false/*need_lock_term=false*/);
8722   }
8723   else
8724   {
8725     //no error if both threads are already stopped, only a warning
8726     slave_errno= 0;
8727     push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_NOT_RUNNING,
8728                  ER(ER_SLAVE_WAS_NOT_RUNNING));
8729   }
8730   unlock_slave_threads(mi);
8731 
8732   if (slave_errno)
8733   {
8734     if ((slave_errno == ER_STOP_SLAVE_SQL_THREAD_TIMEOUT) ||
8735         (slave_errno == ER_STOP_SLAVE_IO_THREAD_TIMEOUT))
8736     {
8737       push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, slave_errno,
8738                    ER(slave_errno));
8739       sql_print_warning("%s",ER(slave_errno));
8740     }
8741     if (net_report)
8742       my_message(slave_errno, ER(slave_errno), MYF(0));
8743     DBUG_RETURN(1);
8744   }
8745   else if (net_report)
8746     my_ok(thd);
8747 
8748   DBUG_RETURN(0);
8749 }
8750 
8751 
8752 /**
8753   Execute a RESET SLAVE statement.
8754 
8755   @param thd Pointer to THD object of the client thread executing the
8756   statement.
8757 
8758   @param mi Pointer to Master_info object for the slave.
8759 
8760   @retval 0 success
8761   @retval 1 error
8762 */
reset_slave(THD * thd,Master_info * mi)8763 int reset_slave(THD *thd, Master_info* mi)
8764 {
8765   int thread_mask= 0, error= 0;
8766   uint sql_errno=ER_UNKNOWN_ERROR;
8767   const char* errmsg= "Unknown error occured while reseting slave";
8768   DBUG_ENTER("reset_slave");
8769 
8770   lock_slave_threads(mi);
8771   init_thread_mask(&thread_mask,mi,0 /* not inverse */);
8772   if (thread_mask) // We refuse if any slave thread is running
8773   {
8774     sql_errno= ER_SLAVE_MUST_STOP;
8775     error=1;
8776     goto err;
8777   }
8778 
8779   ha_reset_slave(thd);
8780 
8781   // delete relay logs, clear relay log coordinates
8782   if ((error= mi->rli->purge_relay_logs(thd,
8783                                         1 /* just reset */,
8784                                         &errmsg)))
8785   {
8786     sql_errno= ER_RELAY_LOG_FAIL;
8787     goto err;
8788   }
8789 
8790   /* Clear master's log coordinates and associated information */
8791   DBUG_ASSERT(!mi->rli || !mi->rli->slave_running); // none writes in rli table
8792   mi->clear_in_memory_info(thd->lex->reset_slave_info.all);
8793 
8794   if (remove_info(mi))
8795   {
8796     error= 1;
8797     goto err;
8798   }
8799 
8800   (void) RUN_HOOK(binlog_relay_io, after_reset_slave, (thd, mi));
8801 err:
8802   unlock_slave_threads(mi);
8803   if (error)
8804     my_error(sql_errno, MYF(0), errmsg);
8805   DBUG_RETURN(error);
8806 }
8807 
8808 /**
8809   Execute a CHANGE MASTER statement. MTS workers info tables data are removed
8810   in the successful branch (i.e. there are no gaps in the execution history).
8811 
8812   @param thd Pointer to THD object for the client thread executing the
8813   statement.
8814 
8815   @param mi Pointer to Master_info object belonging to the slave's IO
8816   thread.
8817 
8818   @retval FALSE success
8819   @retval TRUE error
8820 */
change_master(THD * thd,Master_info * mi)8821 bool change_master(THD* thd, Master_info* mi)
8822 {
8823   int thread_mask;
8824   const char* errmsg= 0;
8825   bool need_relay_log_purge= 1;
8826   char *var_master_log_name= NULL, *var_group_master_log_name= NULL;
8827   bool ret= false;
8828   char saved_host[HOSTNAME_LENGTH + 1], saved_bind_addr[HOSTNAME_LENGTH + 1];
8829   uint saved_port= 0;
8830   char saved_log_name[FN_REFLEN];
8831   my_off_t saved_log_pos= 0;
8832   my_bool save_relay_log_purge= relay_log_purge;
8833   bool mts_remove_workers= false;
8834 
8835   DBUG_ENTER("change_master");
8836 
8837   lock_slave_threads(mi);
8838   init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
8839   LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
8840   if (thread_mask) // We refuse if any slave thread is running
8841   {
8842     my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0));
8843     ret= true;
8844     goto err;
8845   }
8846   thread_mask= SLAVE_IO | SLAVE_SQL;
8847 
8848   THD_STAGE_INFO(thd, stage_changing_master);
8849   /*
8850     We need to check if there is an empty master_host. Otherwise
8851     change master succeeds, a master.info file is created containing
8852     empty master_host string and when issuing: start slave; an error
8853     is thrown stating that the server is not configured as slave.
8854     (See BUG#28796).
8855   */
8856   if(lex_mi->host && !*lex_mi->host)
8857   {
8858     my_error(ER_WRONG_ARGUMENTS, MYF(0), "MASTER_HOST");
8859     unlock_slave_threads(mi);
8860     DBUG_RETURN(TRUE);
8861   }
8862   if (global_init_info(mi, false, thread_mask))
8863   {
8864     my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
8865     ret= true;
8866     goto err;
8867   }
8868   if (mi->rli->mts_recovery_group_cnt)
8869   {
8870     /*
8871       Change-Master can't be done if there is a mts group gap.
8872       That requires mts-recovery which START SLAVE provides.
8873     */
8874     DBUG_ASSERT(mi->rli->recovery_parallel_workers);
8875 
8876     my_message(ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS,
8877                ER(ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS), MYF(0));
8878     ret= true;
8879     goto err;
8880   }
8881   else
8882   {
8883     /*
8884       Lack of mts group gaps makes Workers info stale
8885       regardless of need_relay_log_purge computation.
8886     */
8887     if (mi->rli->recovery_parallel_workers)
8888       mts_remove_workers= true;
8889   }
8890   /*
8891     We cannot specify auto position and set either the coordinates
8892     on master or slave. If we try to do so, an error message is
8893     printed out.
8894   */
8895   if (lex_mi->log_file_name != NULL || lex_mi->pos != 0 ||
8896       lex_mi->relay_log_name != NULL || lex_mi->relay_log_pos != 0)
8897   {
8898     if (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE ||
8899         (lex_mi->auto_position != LEX_MASTER_INFO::LEX_MI_DISABLE &&
8900          mi->is_auto_position()))
8901     {
8902       my_message(ER_BAD_SLAVE_AUTO_POSITION,
8903                  ER(ER_BAD_SLAVE_AUTO_POSITION), MYF(0));
8904       ret= true;
8905       goto err;
8906     }
8907   }
8908 
8909   // CHANGE MASTER TO MASTER_AUTO_POSITION = 1 requires GTID_MODE = ON
8910   if (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE && gtid_mode != 3)
8911   {
8912     my_message(ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON,
8913                ER(ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON), MYF(0));
8914     ret= true;
8915     goto err;
8916   }
8917 
8918   /*
8919     Data lock not needed since we have already stopped the running threads,
8920     and we have the hold on the run locks which will keep all threads that
8921     could possibly modify the data structures from running
8922   */
8923 
8924   /*
8925     Before processing the command, save the previous state.
8926   */
8927   strmake(saved_host, mi->host, HOSTNAME_LENGTH);
8928   strmake(saved_bind_addr, mi->bind_addr, HOSTNAME_LENGTH);
8929   saved_port= mi->port;
8930   strmake(saved_log_name, mi->get_master_log_name(), FN_REFLEN - 1);
8931   saved_log_pos= mi->get_master_log_pos();
8932 
8933   /*
8934     If the user specified host or port without binlog or position,
8935     reset binlog's name to FIRST and position to 4.
8936   */
8937 
8938   if ((lex_mi->host && strcmp(lex_mi->host, mi->host)) ||
8939       (lex_mi->port && lex_mi->port != mi->port))
8940   {
8941     /*
8942       This is necessary because the primary key, i.e. host or port, has
8943       changed.
8944 
8945       The repository does not support direct changes on the primary key,
8946       so the row is dropped and re-inserted with a new primary key. If we
8947       don't do that, the master info repository we will end up with several
8948       rows.
8949     */
8950     if (mi->clean_info())
8951     {
8952       ret= true;
8953       goto err;
8954     }
8955     mi->master_uuid[0]= 0;
8956     mi->master_id= 0;
8957   }
8958 
8959   if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
8960   {
8961     var_master_log_name= const_cast<char*>(mi->get_master_log_name());
8962     var_master_log_name[0]= '\0';
8963     mi->set_master_log_pos(BIN_LOG_HEADER_SIZE);
8964   }
8965 
8966   if (lex_mi->log_file_name)
8967     mi->set_master_log_name(lex_mi->log_file_name);
8968   if (lex_mi->pos)
8969   {
8970     mi->set_master_log_pos(lex_mi->pos);
8971   }
8972   DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
8973 
8974   if (lex_mi->user || lex_mi->password)
8975   {
8976 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8977     if (thd->vio_ok() && !thd->net.vio->ssl_arg)
8978       push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8979                    ER_INSECURE_PLAIN_TEXT,
8980                    ER(ER_INSECURE_PLAIN_TEXT));
8981 #endif
8982 #if !defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8983     push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8984                  ER_INSECURE_PLAIN_TEXT,
8985                  ER(ER_INSECURE_PLAIN_TEXT));
8986 #endif
8987     push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8988                  ER_INSECURE_CHANGE_MASTER,
8989                  ER(ER_INSECURE_CHANGE_MASTER));
8990   }
8991 
8992   if (lex_mi->user)
8993     mi->set_user(lex_mi->user);
8994 
8995   if (lex_mi->password)
8996   {
8997     if (mi->set_password(lex_mi->password, strlen(lex_mi->password)))
8998     {
8999       /*
9000         After implementing WL#5769, we should create a better error message
9001         to denote that the call may have failed due to an error while trying
9002         to encrypt/store the password in a secure key store.
9003       */
9004       my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
9005       ret= false;
9006       goto err;
9007     }
9008   }
9009   if (lex_mi->host)
9010     strmake(mi->host, lex_mi->host, sizeof(mi->host)-1);
9011   if (lex_mi->bind_addr)
9012     strmake(mi->bind_addr, lex_mi->bind_addr, sizeof(mi->bind_addr)-1);
9013   if (lex_mi->port)
9014     mi->port = lex_mi->port;
9015   if (lex_mi->connect_retry)
9016     mi->connect_retry = lex_mi->connect_retry;
9017   if (lex_mi->retry_count_opt !=  LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9018     mi->retry_count = lex_mi->retry_count;
9019   if (lex_mi->heartbeat_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9020     mi->heartbeat_period = lex_mi->heartbeat_period;
9021   else
9022     mi->heartbeat_period= min<float>(SLAVE_MAX_HEARTBEAT_PERIOD,
9023                                      (slave_net_timeout/2.0));
9024   mi->received_heartbeats= LL(0); // counter lives until master is CHANGEd
9025   /*
9026     reset the last time server_id list if the current CHANGE MASTER
9027     is mentioning IGNORE_SERVER_IDS= (...)
9028   */
9029   if (lex_mi->repl_ignore_server_ids_opt == LEX_MASTER_INFO::LEX_MI_ENABLE)
9030     reset_dynamic(&(mi->ignore_server_ids->dynamic_ids));
9031   for (uint i= 0; i < lex_mi->repl_ignore_server_ids.elements; i++)
9032   {
9033     ulong s_id;
9034     get_dynamic(&lex_mi->repl_ignore_server_ids, (uchar*) &s_id, i);
9035     if (s_id == ::server_id && replicate_same_server_id)
9036     {
9037       my_error(ER_SLAVE_IGNORE_SERVER_IDS, MYF(0), static_cast<int>(s_id));
9038       ret= TRUE;
9039       goto err;
9040     }
9041     else
9042     {
9043       if (bsearch((const ulong *) &s_id,
9044                   mi->ignore_server_ids->dynamic_ids.buffer,
9045                   mi->ignore_server_ids->dynamic_ids.elements, sizeof(ulong),
9046                   (int (*) (const void*, const void*))
9047                   change_master_server_id_cmp) == NULL)
9048         insert_dynamic(&(mi->ignore_server_ids->dynamic_ids), (uchar*) &s_id);
9049     }
9050   }
9051   sort_dynamic(&(mi->ignore_server_ids->dynamic_ids), (qsort_cmp) change_master_server_id_cmp);
9052 
9053   if (lex_mi->ssl != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9054     mi->ssl= (lex_mi->ssl == LEX_MASTER_INFO::LEX_MI_ENABLE);
9055 
9056   if (lex_mi->sql_delay != -1)
9057     mi->rli->set_sql_delay(lex_mi->sql_delay);
9058 
9059   if (lex_mi->ssl_verify_server_cert != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9060     mi->ssl_verify_server_cert=
9061       (lex_mi->ssl_verify_server_cert == LEX_MASTER_INFO::LEX_MI_ENABLE);
9062 
9063   if (lex_mi->ssl_ca)
9064     strmake(mi->ssl_ca, lex_mi->ssl_ca, sizeof(mi->ssl_ca)-1);
9065   if (lex_mi->ssl_capath)
9066     strmake(mi->ssl_capath, lex_mi->ssl_capath, sizeof(mi->ssl_capath)-1);
9067   if (lex_mi->ssl_cert)
9068     strmake(mi->ssl_cert, lex_mi->ssl_cert, sizeof(mi->ssl_cert)-1);
9069   if (lex_mi->ssl_cipher)
9070     strmake(mi->ssl_cipher, lex_mi->ssl_cipher, sizeof(mi->ssl_cipher)-1);
9071   if (lex_mi->ssl_key)
9072     strmake(mi->ssl_key, lex_mi->ssl_key, sizeof(mi->ssl_key)-1);
9073   if (lex_mi->ssl_crl)
9074     strmake(mi->ssl_crl, lex_mi->ssl_crl, sizeof(mi->ssl_crl)-1);
9075   if (lex_mi->ssl_crlpath)
9076     strmake(mi->ssl_crlpath, lex_mi->ssl_crlpath, sizeof(mi->ssl_crlpath)-1);
9077 #ifndef HAVE_OPENSSL
9078   if (lex_mi->ssl || lex_mi->ssl_ca || lex_mi->ssl_capath ||
9079       lex_mi->ssl_cert || lex_mi->ssl_cipher || lex_mi->ssl_key ||
9080       lex_mi->ssl_verify_server_cert || lex_mi->ssl_crl || lex_mi->ssl_crlpath)
9081     push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
9082                  ER_SLAVE_IGNORED_SSL_PARAMS, ER(ER_SLAVE_IGNORED_SSL_PARAMS));
9083 #endif
9084 
9085   if (lex_mi->relay_log_name)
9086   {
9087     need_relay_log_purge= 0;
9088     char relay_log_name[FN_REFLEN];
9089 
9090     mi->rli->relay_log.make_log_name(relay_log_name, lex_mi->relay_log_name);
9091     mi->rli->set_group_relay_log_name(relay_log_name);
9092     mi->rli->set_event_relay_log_name(relay_log_name);
9093   }
9094 
9095   if (lex_mi->relay_log_pos)
9096   {
9097     need_relay_log_purge= 0;
9098     mi->rli->set_group_relay_log_pos(lex_mi->relay_log_pos);
9099     mi->rli->set_event_relay_log_pos(lex_mi->relay_log_pos);
9100   }
9101 
9102   /*
9103     If user did specify neither host nor port nor any log name nor any log
9104     pos, i.e. he specified only user/password/master_connect_retry, he probably
9105     wants replication to resume from where it had left, i.e. from the
9106     coordinates of the **SQL** thread (imagine the case where the I/O is ahead
9107     of the SQL; restarting from the coordinates of the I/O would lose some
9108     events which is probably unwanted when you are just doing minor changes
9109     like changing master_connect_retry).
9110     A side-effect is that if only the I/O thread was started, this thread may
9111     restart from ''/4 after the CHANGE MASTER. That's a minor problem (it is a
9112     much more unlikely situation than the one we are fixing here).
9113     Note: coordinates of the SQL thread must be read here, before the
9114     'if (need_relay_log_purge)' block which resets them.
9115   */
9116   if (!lex_mi->host && !lex_mi->port &&
9117       !lex_mi->log_file_name && !lex_mi->pos &&
9118       need_relay_log_purge)
9119    {
9120      /*
9121        Sometimes mi->rli->master_log_pos == 0 (it happens when the SQL thread is
9122        not initialized), so we use a max().
9123        What happens to mi->rli->master_log_pos during the initialization stages
9124        of replication is not 100% clear, so we guard against problems using
9125        max().
9126       */
9127      mi->set_master_log_pos(max<ulonglong>(BIN_LOG_HEADER_SIZE,
9128                                            mi->rli->get_group_master_log_pos()));
9129      mi->set_master_log_name(mi->rli->get_group_master_log_name());
9130   }
9131 
9132   /*
9133     Sets if the slave should connect to the master and look for
9134     GTIDs.
9135   */
9136   if (lex_mi->auto_position != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9137     mi->set_auto_position(
9138       (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE));
9139 
9140   /*
9141     Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never
9142     a slave before).
9143   */
9144   if (flush_master_info(mi, true))
9145   {
9146     my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file");
9147     ret= TRUE;
9148     goto err;
9149   }
9150   if (need_relay_log_purge)
9151   {
9152     relay_log_purge= 1;
9153     THD_STAGE_INFO(thd, stage_purging_old_relay_logs);
9154     if (mi->rli->purge_relay_logs(thd,
9155                                   0 /* not only reset, but also reinit */,
9156                                   &errmsg))
9157     {
9158       my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg);
9159       ret= TRUE;
9160       goto err;
9161     }
9162   }
9163   else
9164   {
9165     const char* msg;
9166     relay_log_purge= 0;
9167     /* Relay log is already initialized */
9168 
9169     if (mi->rli->init_relay_log_pos(mi->rli->get_group_relay_log_name(),
9170                                     mi->rli->get_group_relay_log_pos(),
9171                                     true/*need_data_lock=true*/,
9172                                     &msg, 0))
9173     {
9174       my_error(ER_RELAY_LOG_INIT, MYF(0), msg);
9175       ret= TRUE;
9176       goto err;
9177     }
9178   }
9179   relay_log_purge= save_relay_log_purge;
9180 
9181   /*
9182     Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block,
9183     so restore them to good values. If we left them to ''/0, that would work;
9184     but that would fail in the case of 2 successive CHANGE MASTER (without a
9185     START SLAVE in between): because first one would set the coords in mi to
9186     the good values of those in rli, the set those in rli to ''/0, then
9187     second CHANGE MASTER would set the coords in mi to those of rli, i.e. to
9188     ''/0: we have lost all copies of the original good coordinates.
9189     That's why we always save good coords in rli.
9190   */
9191   if (need_relay_log_purge)
9192   {
9193     mi->rli->set_group_master_log_pos(mi->get_master_log_pos());
9194     DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
9195     mi->rli->set_group_master_log_name(mi->get_master_log_name());
9196   }
9197   var_group_master_log_name=  const_cast<char *>(mi->rli->get_group_master_log_name());
9198   if (!var_group_master_log_name[0]) // uninitialized case
9199     mi->rli->set_group_master_log_pos(0);
9200 
9201   mysql_mutex_lock(&mi->rli->data_lock);
9202   mi->rli->abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */
9203   /* Clear the errors, for a clean start */
9204   mi->rli->clear_error();
9205   mi->rli->clear_until_condition();
9206 
9207   sql_print_information("'CHANGE MASTER TO executed'. "
9208     "Previous state master_host='%s', master_port= %u, master_log_file='%s', "
9209     "master_log_pos= %ld, master_bind='%s'. "
9210     "New state master_host='%s', master_port= %u, master_log_file='%s', "
9211     "master_log_pos= %ld, master_bind='%s'.",
9212     saved_host, saved_port, saved_log_name, (ulong) saved_log_pos,
9213     saved_bind_addr, mi->host, mi->port, mi->get_master_log_name(),
9214     (ulong) mi->get_master_log_pos(), mi->bind_addr);
9215 
9216   /*
9217     If we don't write new coordinates to disk now, then old will remain in
9218     relay-log.info until START SLAVE is issued; but if mysqld is shutdown
9219     before START SLAVE, then old will remain in relay-log.info, and will be the
9220     in-memory value at restart (thus causing errors, as the old relay log does
9221     not exist anymore).
9222 
9223     Notice that the rli table is available exclusively as slave is not
9224     running.
9225   */
9226   DBUG_ASSERT(!mi->rli->slave_running);
9227   if ((ret= mi->rli->flush_info(true)))
9228     my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush relay info file.");
9229   mysql_cond_broadcast(&mi->data_cond);
9230   mysql_mutex_unlock(&mi->rli->data_lock);
9231 
9232 err:
9233   unlock_slave_threads(mi);
9234   if (ret == FALSE)
9235   {
9236     if (!mts_remove_workers)
9237       my_ok(thd);
9238     else
9239       if (!Rpl_info_factory::reset_workers(mi->rli))
9240         my_ok(thd);
9241       else
9242         my_error(ER_MTS_RESET_WORKERS, MYF(0));
9243   }
9244   DBUG_RETURN(ret);
9245 }
9246 /**
9247   @} (end of group Replication)
9248 */
9249 #endif /* HAVE_REPLICATION */
9250