1 /* Copyright (c) 2000, 2020, 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 #ifdef HAVE_REPLICATION
35 #include "rpl_slave.h"
36 
37 #include "my_bitmap.h"                         // MY_BITMAP
38 #include "my_thread_local.h"                   // thread_local_key_t
39 #include "mysql.h"                             // MYSQL
40 #include "sql_common.h"                        // end_server
41 #include "auth_common.h"                       // any_db
42 #include "debug_sync.h"                        // DEBUG_SYNC
43 #include "dynamic_ids.h"                       // Server_ids
44 #include "log.h"                               // sql_print_error
45 #include "log_event.h"                         // Rotate_log_event
46 #include "mysqld.h"                            // ER
47 #include "mysqld_thd_manager.h"                // Global_THD_manager
48 #include "rpl_constants.h"                     // BINLOG_FLAGS_INFO_SIZE
49 #include "rpl_handler.h"                       // RUN_HOOK
50 #include "rpl_info_factory.h"                  // Rpl_info_factory
51 #include "rpl_msr.h"                           // Multisource_info
52 #include "rpl_rli.h"                           // Relay_log_info
53 #include "rpl_rli_pdb.h"                       // Slave_worker
54 #include "rpl_slave_commit_order_manager.h"    // Commit_order_manager
55 #include "sql_class.h"                         // THD
56 #include "sql_parse.h"                         // execute_init_command
57 #include "sql_plugin.h"                        // opt_plugin_dir_ptr
58 #include "transaction.h"                       // trans_begin
59 #include "tztime.h"                            // Time_zone
60 #include "rpl_group_replication.h"
61 
62 // Sic: Must be after mysqld.h to get the right ER macro.
63 #include "errmsg.h"                            // CR_*
64 
65 #include "pfs_file_provider.h"
66 #include "mysql/psi/mysql_file.h"
67 
68 #include <signal.h>
69 #include <algorithm>
70 
71 using std::min;
72 using std::max;
73 using binary_log::checksum_crc32;
74 using binary_log::Log_event_header;
75 
76 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
77 
78 /*
79   a parameter of sql_slave_killed() to defer the killed status
80 */
81 #define SLAVE_WAIT_GROUP_DONE 60
82 bool use_slave_mask = 0;
83 MY_BITMAP slave_error_mask;
84 char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE];
85 
86 char* slave_load_tmpdir = 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 
131 /*
132   When slave thread exits, we need to remember the temporary tables so we
133   can re-use them on slave start.
134 
135   TODO: move the vars below under Master_info
136 */
137 
138 int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
139 
140 static thread_local_key_t RPL_MASTER_INFO;
141 
142 enum enum_slave_reconnect_actions
143 {
144   SLAVE_RECON_ACT_REG= 0,
145   SLAVE_RECON_ACT_DUMP= 1,
146   SLAVE_RECON_ACT_EVENT= 2,
147   SLAVE_RECON_ACT_MAX
148 };
149 
150 enum enum_slave_reconnect_messages
151 {
152   SLAVE_RECON_MSG_WAIT= 0,
153   SLAVE_RECON_MSG_KILLED_WAITING= 1,
154   SLAVE_RECON_MSG_AFTER= 2,
155   SLAVE_RECON_MSG_FAILED= 3,
156   SLAVE_RECON_MSG_COMMAND= 4,
157   SLAVE_RECON_MSG_KILLED_AFTER= 5,
158   SLAVE_RECON_MSG_MAX
159 };
160 
161 static const char *reconnect_messages[SLAVE_RECON_ACT_MAX][SLAVE_RECON_MSG_MAX]=
162 {
163   {
164     "Waiting to reconnect after a failed registration on master",
165     "Slave I/O thread killed while waiting to reconnect after a failed \
166 registration on master",
167     "Reconnecting after a failed registration on master",
168     "failed registering on master, reconnecting to try again, \
169 log '%s' at position %s",
170     "COM_REGISTER_SLAVE",
171     "Slave I/O thread killed during or after reconnect"
172   },
173   {
174     "Waiting to reconnect after a failed binlog dump request",
175     "Slave I/O thread killed while retrying master dump",
176     "Reconnecting after a failed binlog dump request",
177     "failed dump request, reconnecting to try again, log '%s' at position %s",
178     "COM_BINLOG_DUMP",
179     "Slave I/O thread killed during or after reconnect"
180   },
181   {
182     "Waiting to reconnect after a failed master event read",
183     "Slave I/O thread killed while waiting to reconnect after a failed read",
184     "Reconnecting after a failed master event read",
185     "Slave I/O thread: Failed reading log event, reconnecting to retry, \
186 log '%s' at position %s",
187     "",
188     "Slave I/O thread killed during or after a reconnect done to recover from \
189 failed read"
190   }
191 };
192 
193 enum enum_slave_apply_event_and_update_pos_retval
194 {
195   SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK= 0,
196   SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR= 1,
197   SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR= 2,
198   SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR= 3,
199   SLAVE_APPLY_EVENT_AND_UPDATE_POS_MAX
200 };
201 
202 
203 static int process_io_rotate(Master_info* mi, Rotate_log_event* rev);
204 static int process_io_create_file(Master_info* mi, Create_file_log_event* cev);
205 static bool wait_for_relay_log_space(Relay_log_info* rli);
206 static inline bool io_slave_killed(THD* thd,Master_info* mi);
207 static inline bool is_autocommit_off_and_infotables(THD* thd);
208 static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
209 static void print_slave_skip_errors(void);
210 static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi);
211 static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
212                           bool suppress_warnings);
213 static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
214                              bool reconnect, bool suppress_warnings);
215 static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi);
216 static int get_master_uuid(MYSQL *mysql, Master_info *mi);
217 int io_thread_init_commands(MYSQL *mysql, Master_info *mi);
218 static Log_event* next_event(Relay_log_info* rli);
219 bool queue_event(Master_info* mi,const char* buf,ulong event_len);
220 static int terminate_slave_thread(THD *thd,
221                                   mysql_mutex_t *term_lock,
222                                   mysql_cond_t *term_cond,
223                                   volatile uint *slave_running,
224                                   ulong *stop_wait_timeout,
225                                   bool need_lock_term);
226 static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info);
227 int slave_worker_exec_job_group(Slave_worker *w, Relay_log_info *rli);
228 static int mts_event_coord_cmp(LOG_POS_COORD *id1, LOG_POS_COORD *id2);
229 
230 static int check_slave_sql_config_conflict(const Relay_log_info *rli);
231 
232 /*
233   Applier thread InnoDB priority.
234   When two transactions conflict inside InnoDB, the one with
235   greater priority wins.
236 
237   @param thd       Thread handler for slave
238   @param priority  Thread priority
239 */
set_thd_tx_priority(THD * thd,int priority)240 static void set_thd_tx_priority(THD* thd, int priority)
241 {
242   DBUG_ENTER("set_thd_tx_priority");
243   DBUG_ASSERT(thd->system_thread == SYSTEM_THREAD_SLAVE_SQL ||
244               thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER);
245 
246   thd->thd_tx_priority= priority;
247   DBUG_EXECUTE_IF("dbug_set_high_prio_sql_thread",
248   {
249     thd->thd_tx_priority= 1;
250   });
251 
252   DBUG_VOID_RETURN;
253 }
254 
255 /*
256   Function to set the slave's max_allowed_packet based on the value
257   of slave_max_allowed_packet.
258 
259     @in_param    thd    Thread handler for slave
260     @in_param    mysql  MySQL connection handle
261 */
262 
set_slave_max_allowed_packet(THD * thd,MYSQL * mysql)263 static void set_slave_max_allowed_packet(THD *thd, MYSQL *mysql)
264 {
265   DBUG_ENTER("set_slave_max_allowed_packet");
266   // thd and mysql must be valid
267   DBUG_ASSERT(thd && mysql);
268 
269   thd->variables.max_allowed_packet= slave_max_allowed_packet;
270   /*
271     Adding MAX_LOG_EVENT_HEADER_LEN to the max_packet_size on the I/O
272     thread and the mysql->option max_allowed_packet, since a
273     replication event can become this much  larger than
274     the corresponding packet (query) sent from client to master.
275   */
276   thd->get_protocol_classic()->set_max_packet_size(
277     slave_max_allowed_packet + MAX_LOG_EVENT_HEADER);
278   /*
279     Skipping the setting of mysql->net.max_packet size to slave
280     max_allowed_packet since this is done during mysql_real_connect.
281   */
282   mysql->options.max_allowed_packet=
283     slave_max_allowed_packet+MAX_LOG_EVENT_HEADER;
284   DBUG_VOID_RETURN;
285 }
286 
287 /*
288   Find out which replications threads are running
289 
290   SYNOPSIS
291     init_thread_mask()
292     mask                Return value here
293     mi                  master_info for slave
294     inverse             If set, returns which threads are not running
295 
296   IMPLEMENTATION
297     Get a bit mask for which threads are running so that we can later restart
298     these threads.
299 
300   RETURN
301     mask        If inverse == 0, running threads
302                 If inverse == 1, stopped threads
303 */
304 
init_thread_mask(int * mask,Master_info * mi,bool inverse)305 void init_thread_mask(int* mask, Master_info* mi, bool inverse)
306 {
307   bool set_io = mi->slave_running, set_sql = mi->rli->slave_running;
308   int tmp_mask=0;
309   DBUG_ENTER("init_thread_mask");
310 
311   if (set_io)
312     tmp_mask |= SLAVE_IO;
313   if (set_sql)
314     tmp_mask |= SLAVE_SQL;
315   if (inverse)
316     tmp_mask^= (SLAVE_IO | SLAVE_SQL);
317   *mask = tmp_mask;
318   DBUG_VOID_RETURN;
319 }
320 
321 
322 /*
323   lock_slave_threads()
324 */
325 
lock_slave_threads(Master_info * mi)326 void lock_slave_threads(Master_info* mi)
327 {
328   DBUG_ENTER("lock_slave_threads");
329 
330   //protection against mixed locking order (see header)
331   mi->channel_assert_some_wrlock();
332 
333   //TODO: see if we can do this without dual mutex
334   mysql_mutex_lock(&mi->run_lock);
335   mysql_mutex_lock(&mi->rli->run_lock);
336   DBUG_VOID_RETURN;
337 }
338 
339 
340 /*
341   unlock_slave_threads()
342 */
343 
unlock_slave_threads(Master_info * mi)344 void unlock_slave_threads(Master_info* mi)
345 {
346   DBUG_ENTER("unlock_slave_threads");
347 
348   //TODO: see if we can do this without dual mutex
349   mysql_mutex_unlock(&mi->rli->run_lock);
350   mysql_mutex_unlock(&mi->run_lock);
351   DBUG_VOID_RETURN;
352 }
353 
354 #ifdef HAVE_PSI_INTERFACE
355 
356 static PSI_memory_key key_memory_rli_mts_coor;
357 
358 static PSI_thread_key key_thread_slave_io, key_thread_slave_sql, key_thread_slave_worker;
359 
360 static PSI_thread_info all_slave_threads[]=
361 {
362   { &key_thread_slave_io, "slave_io", PSI_FLAG_GLOBAL},
363   { &key_thread_slave_sql, "slave_sql", PSI_FLAG_GLOBAL},
364   { &key_thread_slave_worker, "slave_worker", PSI_FLAG_GLOBAL}
365 };
366 
367 static PSI_memory_info all_slave_memory[]=
368 {
369   { &key_memory_rli_mts_coor, "Relay_log_info::mts_coor", 0}
370 };
371 
init_slave_psi_keys(void)372 static void init_slave_psi_keys(void)
373 {
374   const char* category= "sql";
375   int count;
376 
377   count= array_elements(all_slave_threads);
378   mysql_thread_register(category, all_slave_threads, count);
379 
380   count= array_elements(all_slave_memory);
381   mysql_memory_register(category, all_slave_memory, count);
382 }
383 #endif /* HAVE_PSI_INTERFACE */
384 
385 /* Initialize slave structures */
386 
init_slave()387 int init_slave()
388 {
389   DBUG_ENTER("init_slave");
390   int error= 0;
391   int thread_mask= SLAVE_SQL | SLAVE_IO;
392   Master_info *mi= NULL;
393 
394 #ifdef HAVE_PSI_INTERFACE
395   init_slave_psi_keys();
396 #endif
397 
398   /*
399     This is called when mysqld starts. Before client connections are
400     accepted. However bootstrap may conflict with us if it does START SLAVE.
401     So it's safer to take the lock.
402   */
403   channel_map.wrlock();
404 
405   if (my_create_thread_local_key(&RPL_MASTER_INFO, NULL))
406     DBUG_RETURN(1);
407 
408   /*
409     Create slave info objects by reading repositories of individual
410     channels and add them into channel_map
411   */
412   if ((error= Rpl_info_factory::create_slave_info_objects(opt_mi_repository_id,
413                                                           opt_rli_repository_id,
414                                                           thread_mask,
415                                                           &channel_map)))
416     sql_print_error("Failed to create or recover replication info repositories.");
417 
418 #ifndef DBUG_OFF
419   /* @todo: Print it for all the channels */
420   {
421     Master_info *default_mi;
422     default_mi= channel_map.get_default_channel_mi();
423     if (default_mi && default_mi->rli)
424     {
425       DBUG_PRINT("info", ("init group master %s %lu  group relay %s %lu event %s %lu\n",
426                           default_mi->rli->get_group_master_log_name(),
427                           (ulong) default_mi->rli->get_group_master_log_pos(),
428                           default_mi->rli->get_group_relay_log_name(),
429                           (ulong) default_mi->rli->get_group_relay_log_pos(),
430                           default_mi->rli->get_event_relay_log_name(),
431                           (ulong) default_mi->rli->get_event_relay_log_pos()));
432     }
433   }
434 #endif
435 
436   if (get_gtid_mode(GTID_MODE_LOCK_CHANNEL_MAP) == GTID_MODE_OFF)
437   {
438     for (mi_map::iterator it= channel_map.begin(); it != channel_map.end(); it++)
439     {
440       Master_info *mi= it->second;
441       if (mi != NULL && mi->is_auto_position())
442       {
443         sql_print_warning("Detected misconfiguration: replication channel "
444                           "'%.192s' was configured with AUTO_POSITION = 1, "
445                           "but the server was started with --gtid-mode=off. "
446                           "Either reconfigure replication using "
447                           "CHANGE MASTER TO MASTER_AUTO_POSITION = 0 "
448                           "FOR CHANNEL '%.192s', or change GTID_MODE to some "
449                           "value other than OFF, before starting the slave "
450                           "receiver thread.",
451                           mi->get_channel(), mi->get_channel());
452       }
453     }
454   }
455 
456   if (check_slave_sql_config_conflict(NULL))
457   {
458     error= 1;
459     goto err;
460   }
461 
462   /*
463     Loop through the channel_map and start slave threads for each channel.
464   */
465   if (!opt_skip_slave_start)
466   {
467     for (mi_map::iterator it= channel_map.begin(); it!=channel_map.end(); it++)
468     {
469       mi= it->second;
470 
471       /* If server id is not set, start_slave_thread() will say it */
472       if (mi && mi->host[0] && mi->rli->inited)
473       {
474         /* same as in start_slave() cache the global var values into rli's members */
475         mi->rli->opt_slave_parallel_workers= opt_mts_slave_parallel_workers;
476         mi->rli->checkpoint_group= opt_mts_checkpoint_group;
477         if (mts_parallel_option == MTS_PARALLEL_TYPE_DB_NAME)
478           mi->rli->channel_mts_submode = MTS_PARALLEL_TYPE_DB_NAME;
479         else
480           mi->rli->channel_mts_submode = MTS_PARALLEL_TYPE_LOGICAL_CLOCK;
481         if (start_slave_threads(true/*need_lock_slave=true*/,
482                                 false/*wait_for_start=false*/,
483                                 mi,
484                                 thread_mask))
485         {
486           sql_print_error("Failed to start slave threads for channel '%s'",
487                           mi->get_channel());
488         }
489       }
490       else
491       {
492         sql_print_information("Failed to start slave threads for channel '%s'",
493                               mi->get_channel());
494       }
495     }
496   }
497 
498 err:
499 
500   channel_map.unlock();
501   if (error)
502     sql_print_information("Some of the channels are not created/initialized "
503                           "properly. Check for additional messages above. "
504                           "You will not be able to start replication on those "
505                           "channels until the issue is resolved and "
506                           "the server restarted.");
507   DBUG_RETURN(error);
508 }
509 
510 
511 /**
512    Function to start a slave for all channels.
513    Used in Multisource replication.
514    @param[in]        THD           THD object of the client.
515 
516    @retval false success
517    @retval true error
518 
519     @todo: It is good to continue to start other channels
520            when a slave start failed for other channels.
521 
522     @todo: The problem with the below code is if the slave is already
523            stared, we would multple warnings called
524            "Slave was already running" for each channel.
525            A nice warning message  would be to add
526            "Slave for channel '%s" was already running"
527            but error messages are in different languages and cannot be tampered
528            with so, we have to handle it case by case basis, whether
529            only default channel exists or not and properly continue with
530            starting other channels if one channel fails clearly giving
531            an error message by displaying failed channels.
532 */
start_slave(THD * thd)533 bool start_slave(THD *thd)
534 {
535 
536   DBUG_ENTER("start_slave(THD)");
537   Master_info *mi;
538   bool channel_configured, error= false;
539 
540   if (channel_map.get_num_instances() == 1)
541   {
542     mi= channel_map.get_default_channel_mi();
543     DBUG_ASSERT(mi);
544     if (start_slave(thd, &thd->lex->slave_connection,
545                     &thd->lex->mi, thd->lex->slave_thd_opt, mi, true))
546       DBUG_RETURN(true);
547   }
548   else
549   {
550     /*
551       Users cannot start more than one channel's applier thread
552       if sql_slave_skip_counter > 0. It throws an error to the session.
553     */
554     mysql_mutex_lock(&LOCK_sql_slave_skip_counter);
555     /* sql_slave_skip_counter > 0 && !(START SLAVE IO_THREAD) */
556     if (sql_slave_skip_counter > 0 && !(thd->lex->slave_thd_opt & SLAVE_IO))
557     {
558       my_error(ER_SLAVE_CHANNEL_SQL_SKIP_COUNTER, MYF(0));
559       mysql_mutex_unlock(&LOCK_sql_slave_skip_counter);
560       DBUG_RETURN(true);
561     }
562     mysql_mutex_unlock(&LOCK_sql_slave_skip_counter);
563 
564     for (mi_map::iterator it= channel_map.begin(); it!= channel_map.end(); it++)
565     {
566       mi= it->second;
567 
568       channel_configured= mi && // Master_info exists
569                           (mi->inited || mi->reset) // It is inited or was reset
570                           && mi->host[0]; // host is set
571 
572       if (channel_configured)
573       {
574         if (start_slave(thd, &thd->lex->slave_connection,
575                         &thd->lex->mi,
576                         thd->lex->slave_thd_opt, mi, true))
577         {
578           sql_print_error("Slave: Could not start slave for channel '%s'."
579                           " operation discontinued", mi->get_channel());
580           error= true;
581         }
582       }
583     }
584   }
585   if (!error)
586   {
587     /* no error */
588     my_ok(thd);
589   }
590   DBUG_RETURN(error);
591 }
592 
593 
594 /**
595    Function to stop a slave for all channels.
596    Used in Multisource replication.
597    @param[in]        THD           THD object of the client.
598 
599    @return
600     @retval           0            success
601     @retval           1           error
602 
603     @todo: It is good to continue to stop other channels
604            when a slave start failed for other channels.
605 */
stop_slave(THD * thd)606 int stop_slave(THD *thd)
607 {
608   DBUG_ENTER("stop_slave(THD)");
609   bool push_temp_table_warning= true;
610   Master_info *mi=0;
611   int error= 0;
612   bool channel_configured;
613 
614   if (channel_map.get_num_instances() == 1)
615   {
616     mi= channel_map.get_default_channel_mi();
617 
618     DBUG_ASSERT(!strcmp(mi->get_channel(),
619                         channel_map.get_default_channel()));
620 
621     error= stop_slave(thd, mi, 1,
622                       false /*for_one_channel*/, &push_temp_table_warning);
623   }
624   else
625   {
626     for(mi_map::iterator it= channel_map.begin(); it!= channel_map.end(); it++)
627     {
628       mi= it->second;
629 
630       channel_configured= mi && mi->host[0];
631 
632       if (channel_configured)
633       {
634         if (stop_slave(thd, mi, 1,
635                        false /*for_one_channel*/, &push_temp_table_warning))
636         {
637           sql_print_error("Slave: Could not stop slave for channel '%s'"
638                           " operation discontinued", mi->get_channel());
639           error= 1;
640         }
641       }
642     }
643   }
644 
645   if (!error)
646   {
647     /* no error */
648     my_ok(thd);
649   }
650 
651   DBUG_RETURN(error);
652 }
653 
654 
655 /**
656   Entry point to the START SLAVE command. The function
657   decides to start replication threads on several channels
658   or a single given channel.
659 
660   @param[in]   thd        the client thread carrying the command.
661 
662   @return
663     @retval      false      ok
664     @retval      true       not ok.
665 */
start_slave_cmd(THD * thd)666 bool start_slave_cmd(THD *thd)
667 {
668   DBUG_ENTER("start_slave_cmd");
669 
670   Master_info *mi;
671   LEX *lex= thd->lex;
672   bool res= true;  /* default, an error */
673 
674   DEBUG_SYNC(thd, "begin_start_slave");
675 
676   channel_map.wrlock();
677 
678   if (!is_slave_configured())
679   {
680     my_message(ER_SLAVE_CONFIGURATION, ER(ER_SLAVE_CONFIGURATION), MYF(0));
681     goto err;
682   }
683 
684 
685   if (!lex->mi.for_channel)
686   {
687     /*
688       If slave_until options are provided when multiple channels exist
689       without explicitly providing FOR CHANNEL clause, error out.
690     */
691     if (lex->mi.slave_until && channel_map.get_num_instances() > 1)
692     {
693       my_error(ER_SLAVE_MULTIPLE_CHANNELS_CMD, MYF(0));
694       goto err;
695     }
696 
697     res= start_slave(thd);
698   }
699   else
700   {
701     mi= channel_map.get_mi(lex->mi.channel);
702 
703     /*
704       If the channel being used is a group replication channel we need to
705       disable this command here as, in some cases, group replication does not
706       support them.
707 
708       For channel group_replication_applier we disable START SLAVE [IO_THREAD]
709       command.
710 
711       For channel group_replication_recovery we disable START SLAVE command
712       and its two thread variants.
713     */
714     if (mi &&
715         channel_map.is_group_replication_channel_name(mi->get_channel()) &&
716         ((!thd->lex->slave_thd_opt || (thd->lex->slave_thd_opt & SLAVE_IO)) ||
717          (!(channel_map.is_group_replication_channel_name(mi->get_channel(), true))
718           && (thd->lex->slave_thd_opt & SLAVE_SQL))))
719     {
720       const char *command= "START SLAVE FOR CHANNEL";
721       if (thd->lex->slave_thd_opt & SLAVE_IO)
722         command= "START SLAVE IO_THREAD FOR CHANNEL";
723       else if (thd->lex->slave_thd_opt & SLAVE_SQL)
724         command= "START SLAVE SQL_THREAD FOR CHANNEL";
725 
726       my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
727                command, mi->get_channel(), command);
728 
729       goto err;
730     }
731 
732     if (mi)
733       res= start_slave(thd, &thd->lex->slave_connection,
734                        &thd->lex->mi, thd->lex->slave_thd_opt, mi, true);
735     else if (strcmp(channel_map.get_default_channel(), lex->mi.channel))
736       my_error(ER_SLAVE_CHANNEL_DOES_NOT_EXIST, MYF(0), lex->mi.channel);
737 
738     if (!res)
739       my_ok(thd);
740 
741   }
742 err:
743   channel_map.unlock();
744   DBUG_RETURN(res);
745 }
746 
747 
748 /**
749   Entry point for the STOP SLAVE command. This function stops replication
750   threads for all channels or a single channel based on the  command
751   options supplied.
752 
753   @param[in]     thd         the client thread.
754 
755   @return
756    @retval       false            ok
757    @retval       true             not ok.
758 */
stop_slave_cmd(THD * thd)759 bool stop_slave_cmd(THD *thd)
760 {
761   DBUG_ENTER("stop_slave_cmd");
762 
763   Master_info* mi;
764   bool push_temp_table_warning= true;
765   LEX *lex= thd->lex;
766   bool res= true;    /*default, an error */
767 
768   channel_map.rdlock();
769 
770   if (!is_slave_configured())
771   {
772     my_message(ER_SLAVE_CONFIGURATION, ER(ER_SLAVE_CONFIGURATION), MYF(0));
773     channel_map.unlock();
774     DBUG_RETURN(res= true);
775   }
776 
777   if (!lex->mi.for_channel)
778     res= stop_slave(thd);
779   else
780   {
781     mi= channel_map.get_mi(lex->mi.channel);
782 
783     /*
784       If the channel being used is a group replication channel we need to
785       disable this command here as, in some cases, group replication does not
786       support them.
787 
788       For channel group_replication_applier we disable STOP SLAVE [IO_THREAD]
789       command.
790 
791       For channel group_replication_recovery we disable STOP SLAVE command
792       and its two thread variants.
793     */
794     if (mi &&
795         channel_map.is_group_replication_channel_name(mi->get_channel()) &&
796         ((!thd->lex->slave_thd_opt || (thd->lex->slave_thd_opt & SLAVE_IO)) ||
797          (!(channel_map.is_group_replication_channel_name(mi->get_channel(), true))
798           && (thd->lex->slave_thd_opt & SLAVE_SQL))))
799     {
800       const char *command= "STOP SLAVE FOR CHANNEL";
801       if (thd->lex->slave_thd_opt & SLAVE_IO)
802         command= "STOP SLAVE IO_THREAD FOR CHANNEL";
803       else if (thd->lex->slave_thd_opt & SLAVE_SQL)
804         command= "STOP SLAVE SQL_THREAD FOR CHANNEL";
805 
806       my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
807                command, mi->get_channel(), command);
808 
809       channel_map.unlock();
810       DBUG_RETURN(true);
811     }
812 
813     if (mi)
814       res= stop_slave(thd, mi, 1 /*net report */,
815                       true /*for_one_channel*/, &push_temp_table_warning);
816     else if (strcmp(channel_map.get_default_channel(), lex->mi.channel))
817       my_error(ER_SLAVE_CHANNEL_DOES_NOT_EXIST, MYF(0), lex->mi.channel);
818   }
819 
820   channel_map.unlock();
821 
822   DBUG_RETURN(res);
823 }
824 
825 /**
826    Parse the given relay log and identify the rotate event from the master.
827    Ignore the Format description event, Previous_gtid log event, ignorable
828    event and Stop event within the relay log as they are generated by slave.
829    When a rotate event is found check if it is a rotate that is originated from
830    the master based on the server_id. Ignore the event if the rotate is from
831    slave or if it is a fake rotate event. If any other events are encountered
832    apart from the above events generate an error. From the rotate event
833    extract the master's binary log name and position.
834 
835    @param filename
836           Relay log name which needs to be parsed.
837 
838    @param[OUT] master_log_file
839           Set the master_log_file to the log file name that is extracted from
840           rotate event. The master_log_file should contain string of len
841           FN_REFLEN.
842 
843    @param[OUT] master_log_pos
844           Set the master_log_pos to the log position extracted from rotate
845           event.
846 
847    @retval FOUND_ROTATE: When rotate event is found in the relay log
848    @retval NOT_FOUND_ROTATE: When rotate event is not found in the relay log
849    @retval ERROR: On error
850  */
851 enum enum_read_rotate_from_relay_log_status
852 { FOUND_ROTATE, NOT_FOUND_ROTATE, ERROR };
853 
854 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)855 read_rotate_from_relay_log(char *filename, char *master_log_file,
856                            my_off_t *master_log_pos)
857 {
858   DBUG_ENTER("read_rotate_from_relay_log");
859   /*
860     Create a Format_description_log_event that is used to read the
861     first event of the log.
862    */
863   Format_description_log_event fd_ev(BINLOG_VERSION), *fd_ev_p= &fd_ev;
864   DBUG_ASSERT(fd_ev.is_valid());
865   IO_CACHE log;
866   const char *errmsg= NULL;
867   File file= open_binlog_file(&log, filename, &errmsg);
868   if (file < 0)
869   {
870     sql_print_error("Error during --relay-log-recovery: %s", errmsg);
871     DBUG_RETURN(ERROR);
872   }
873   my_b_seek(&log, BIN_LOG_HEADER_SIZE);
874   Log_event *ev= NULL;
875   bool done= false;
876   enum_read_rotate_from_relay_log_status ret= NOT_FOUND_ROTATE;
877   while (!done &&
878          (ev= Log_event::read_log_event(&log, 0, fd_ev_p, opt_slave_sql_verify_checksum)) !=
879          NULL)
880   {
881     DBUG_PRINT("info", ("Read event of type %s", ev->get_type_str()));
882     switch (ev->get_type_code())
883     {
884     case binary_log::FORMAT_DESCRIPTION_EVENT:
885       if (fd_ev_p != &fd_ev)
886         delete fd_ev_p;
887       fd_ev_p= (Format_description_log_event *)ev;
888       break;
889     case binary_log::ROTATE_EVENT:
890       /*
891         Check for rotate event from the master. Ignore the ROTATE event if it
892         is a fake rotate event with server_id=0.
893        */
894       if (ev->server_id && ev->server_id != ::server_id)
895       {
896         Rotate_log_event *rotate_ev= (Rotate_log_event *)ev;
897         DBUG_ASSERT(FN_REFLEN >= rotate_ev->ident_len + 1);
898         memcpy(master_log_file, rotate_ev->new_log_ident, rotate_ev->ident_len + 1);
899         *master_log_pos= rotate_ev->pos;
900         ret= FOUND_ROTATE;
901         done= true;
902       }
903       break;
904     case binary_log::PREVIOUS_GTIDS_LOG_EVENT:
905       break;
906     case binary_log::IGNORABLE_LOG_EVENT:
907       break;
908     case binary_log::STOP_EVENT:
909       break;
910     default:
911       sql_print_error("Error during --relay-log-recovery: Could not locate "
912                       "rotate event from the master.");
913       ret= ERROR;
914       done= true;
915       break;
916     }
917     if (ev != fd_ev_p)
918       delete ev;
919   }
920   if (log.error < 0)
921   {
922     sql_print_error("Error during --relay-log-recovery: Error reading events from relay log: %d",
923                     log.error);
924     DBUG_RETURN(ERROR);
925   }
926 
927   if (fd_ev_p != &fd_ev)
928   {
929     delete fd_ev_p;
930     fd_ev_p= &fd_ev;
931   }
932 
933   if (mysql_file_close(file, MYF(MY_WME)))
934     DBUG_RETURN(ERROR);
935   if (end_io_cache(&log))
936   {
937     sql_print_error("Error during --relay-log-recovery: Error while freeing "
938                     "IO_CACHE object");
939     DBUG_RETURN(ERROR);
940   }
941   DBUG_RETURN(ret);
942 }
943 
944 /**
945    Reads relay logs one by one starting from the first relay log. Looks for
946    the first rotate event from the master. If rotate is not found in the relay
947    log search continues to next relay log. If rotate event from master is
948    found then the extracted master_log_file and master_log_pos are used to set
949    rli->group_master_log_name and rli->group_master_log_pos. If an error has
950    occurred the error code is retuned back.
951 
952    @param rli
953           Relay_log_info object to read relay log files and to set
954           group_master_log_name and group_master_log_pos.
955 
956    @retval 0 Success - Rotate event was found
957    @retval 1 Failure - Found some events replicated but no rotate event was found
958    @retval 2 When no rotate event from master was found. This can happen when
959              slave server was restarted immediately after executing CHANGE MASTER
960  */
961 static int
find_first_relay_log_with_rotate_from_master(Relay_log_info * rli)962 find_first_relay_log_with_rotate_from_master(Relay_log_info* rli)
963 {
964   DBUG_ENTER("find_first_relay_log_with_rotate_from_master");
965   int error= 0;
966   LOG_INFO linfo;
967   bool got_rotate_from_master= false;
968   int pos;
969   char master_log_file[FN_REFLEN];
970   my_off_t master_log_pos= 0;
971 
972   if (channel_map.is_group_replication_channel_name(rli->get_channel()))
973   {
974     sql_print_information("Relay log recovery skipped for group replication "
975                           "channel.");
976     goto err;
977   }
978 
979   for (pos= rli->relay_log.find_log_pos(&linfo, NULL, true);
980        !pos;
981        pos= rli->relay_log.find_next_log(&linfo, true))
982   {
983     switch (read_rotate_from_relay_log(linfo.log_file_name, master_log_file,
984                                        &master_log_pos))
985     {
986     case ERROR:
987       error= 1;
988       break;
989     case FOUND_ROTATE:
990       got_rotate_from_master= true;
991       break;
992     case NOT_FOUND_ROTATE:
993       break;
994     }
995     if (error || got_rotate_from_master)
996       break;
997   }
998   if (pos== LOG_INFO_IO)
999   {
1000     error= 1;
1001     sql_print_error("Error during --relay-log-recovery: Could not read "
1002                     "relay log index file due to an IO error.");
1003     goto err;
1004   }
1005   if (pos== LOG_INFO_EOF)
1006   {
1007     error= 2;
1008     sql_print_warning("Error during --relay-log-recovery: Could not locate "
1009                       "rotate event from master in relay log file.");
1010     sql_print_warning("Server was not able to find a rotate event from master "
1011                       "server to initialize relay log recovery for channel "
1012                       "'%s'. Skipping relay log recovery for the channel.",
1013                       rli->mi->get_channel());
1014     goto err;
1015   }
1016   if (!error && got_rotate_from_master)
1017   {
1018     rli->set_group_master_log_name(master_log_file);
1019     rli->set_group_master_log_pos(master_log_pos);
1020   }
1021 err:
1022   DBUG_RETURN(error);
1023 }
1024 
1025 /*
1026   Updates the master info based on the information stored in the
1027   relay info and ignores relay logs previously retrieved by the IO
1028   thread, which thus starts fetching again based on to the
1029   master_log_pos and master_log_name. Eventually, the old
1030   relay logs will be purged by the normal purge mechanism.
1031 
1032   When GTID's are enabled the "Retrieved GTID" set should be cleared
1033   so that partial read events are discarded and they are
1034   fetched once again
1035 
1036   @param mi    pointer to Master_info instance
1037 */
recover_relay_log(Master_info * mi)1038 static void recover_relay_log(Master_info *mi)
1039 {
1040   Relay_log_info *rli=mi->rli;
1041   // Set Receiver Thread's positions as per the recovered Applier Thread.
1042   mi->set_master_log_pos(max<ulonglong>(BIN_LOG_HEADER_SIZE,
1043                                         rli->get_group_master_log_pos()));
1044   mi->set_master_log_name(rli->get_group_master_log_name());
1045 
1046   sql_print_warning("Recovery from master pos %ld and file %s%s. "
1047                     "Previous relay log pos and relay log file had "
1048                     "been set to %lld, %s respectively.",
1049                     (ulong) mi->get_master_log_pos(), mi->get_master_log_name(),
1050                     mi->get_for_channel_str(),
1051                     rli->get_group_relay_log_pos(), rli->get_group_relay_log_name());
1052 
1053   // Start with a fresh relay log.
1054   rli->set_group_relay_log_name(rli->relay_log.get_log_fname());
1055   rli->set_event_relay_log_name(rli->relay_log.get_log_fname());
1056   rli->set_group_relay_log_pos(BIN_LOG_HEADER_SIZE);
1057   rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
1058   /*
1059     Clear the retrieved GTID set so that events that are written partially
1060     will be fetched again.
1061   */
1062   if (get_gtid_mode(GTID_MODE_LOCK_NONE) == GTID_MODE_ON &&
1063       !channel_map.is_group_replication_channel_name(rli->get_channel()))
1064   {
1065     global_sid_lock->wrlock();
1066     (const_cast<Gtid_set *>(rli->get_gtid_set()))->clear();
1067     global_sid_lock->unlock();
1068   }
1069 }
1070 
1071 
1072 /*
1073   Updates the master info based on the information stored in the
1074   relay info and ignores relay logs previously retrieved by the IO
1075   thread, which thus starts fetching again based on to the
1076   master_log_pos and master_log_name. Eventually, the old
1077   relay logs will be purged by the normal purge mechanism.
1078 
1079   There can be a special case where rli->group_master_log_name and
1080   rli->group_master_log_pos are not intialized, as the sql thread was never
1081   started at all. In those cases all the existing relay logs are parsed
1082   starting from the first one and the initial rotate event that was received
1083   from the master is identified. From the rotate event master_log_name and
1084   master_log_pos are extracted and they are set to rli->group_master_log_name
1085   and rli->group_master_log_pos.
1086 
1087   In the feature, we should improve this routine in order to avoid throwing
1088   away logs that are safely stored in the disk. Note also that this recovery
1089   routine relies on the correctness of the relay-log.info and only tolerates
1090   coordinate problems in master.info.
1091 
1092   In this function, there is no need for a mutex as the caller
1093   (i.e. init_slave) already has one acquired.
1094 
1095   Specifically, the following structures are updated:
1096 
1097   1 - mi->master_log_pos  <-- rli->group_master_log_pos
1098   2 - mi->master_log_name <-- rli->group_master_log_name
1099   3 - It moves the relay log to the new relay log file, by
1100       rli->group_relay_log_pos  <-- BIN_LOG_HEADER_SIZE;
1101       rli->event_relay_log_pos  <-- BIN_LOG_HEADER_SIZE;
1102       rli->group_relay_log_name <-- rli->relay_log.get_log_fname();
1103       rli->event_relay_log_name <-- rli->relay_log.get_log_fname();
1104 
1105    If there is an error, it returns (1), otherwise returns (0).
1106  */
init_recovery(Master_info * mi,const char ** errmsg)1107 int init_recovery(Master_info* mi, const char** errmsg)
1108 {
1109   DBUG_ENTER("init_recovery");
1110 
1111   int error= 0;
1112   Relay_log_info *rli= mi->rli;
1113   char *group_master_log_name= NULL;
1114 
1115   /* Set the recovery_parallel_workers to 0 if Auto Position is enabled. */
1116   bool is_gtid_with_autopos_on=
1117       ((get_gtid_mode(GTID_MODE_LOCK_NONE) == GTID_MODE_ON &&
1118         mi->is_auto_position())
1119            ? true
1120            : false);
1121   if (is_gtid_with_autopos_on)
1122     rli->recovery_parallel_workers = 0;
1123 
1124   if (rli->recovery_parallel_workers)
1125   {
1126     /*
1127       This is not idempotent and a crash after this function and before
1128       the recovery is actually done may lead the system to an inconsistent
1129       state.
1130 
1131       This may happen because the gap is not persitent stored anywhere
1132       and eventually old relay log files will be removed and further
1133       calculations on the gaps will be impossible.
1134 
1135       We need to improve this. /Alfranio.
1136     */
1137     error= mts_recovery_groups(rli);
1138     if (rli->mts_recovery_group_cnt)
1139       DBUG_RETURN(error);
1140   }
1141 
1142   group_master_log_name= const_cast<char *>(rli->get_group_master_log_name());
1143   if (!error)
1144   {
1145     bool run_relay_log_recovery = 1;
1146     if (!group_master_log_name[0])
1147     {
1148       if (rli->replicate_same_server_id)
1149       {
1150         error= 1;
1151         sql_print_error("Error during --relay-log-recovery: "
1152                         "replicate_same_server_id is in use and sql thread's "
1153                         "positions are not initialized, hence relay log "
1154                         "recovery cannot happen.");
1155         DBUG_RETURN(error);
1156       }
1157       error= find_first_relay_log_with_rotate_from_master(rli);
1158       if (error == 2)
1159       {
1160         // No events from the master on relay log - skip relay log recovery
1161         run_relay_log_recovery = false;
1162         error = 0;
1163       }
1164       else if (error)
1165         DBUG_RETURN(error);
1166     }
1167     if (run_relay_log_recovery)
1168       recover_relay_log(mi);
1169   }
1170   DBUG_RETURN(error);
1171 }
1172 
1173 /*
1174   Relay log recovery in the case of MTS, is handled by the following function.
1175   Gaps in MTS execution are filled using implicit execution of
1176   START SLAVE UNTIL SQL_AFTER_MTS_GAPS call. Once slave reaches a consistent
1177   gapless state receiver thread's positions are initialized to applier thread's
1178   positions and the old relay logs are discarded. This completes the recovery
1179   process.
1180 
1181   @param mi    pointer to Master_info instance.
1182 
1183   @retval 0 success
1184   @retval 1 error
1185 */
fill_mts_gaps_and_recover(Master_info * mi)1186 static inline int fill_mts_gaps_and_recover(Master_info* mi)
1187 {
1188   DBUG_ENTER("fill_mts_gaps_and_recover");
1189   Relay_log_info *rli= mi->rli;
1190   int recovery_error= 0;
1191   rli->is_relay_log_recovery= FALSE;
1192   rli->until_condition= Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS;
1193   rli->opt_slave_parallel_workers= rli->recovery_parallel_workers;
1194   rli->channel_mts_submode= (mts_parallel_option ==
1195                              MTS_PARALLEL_TYPE_DB_NAME) ?
1196                              MTS_PARALLEL_TYPE_DB_NAME :
1197                              MTS_PARALLEL_TYPE_LOGICAL_CLOCK;
1198   sql_print_information("MTS recovery: starting coordinator thread to fill MTS "
1199                         "gaps.");
1200   recovery_error= start_slave_thread(
1201 #ifdef HAVE_PSI_INTERFACE
1202                                      key_thread_slave_sql,
1203 #endif
1204                                      handle_slave_sql, &rli->run_lock,
1205                                      &rli->run_lock,
1206                                      &rli->start_cond,
1207                                      &rli->slave_running,
1208                                      &rli->slave_run_id,
1209                                      mi);
1210 
1211   if (recovery_error)
1212   {
1213     sql_print_warning("MTS recovery: failed to start the coordinator "
1214                       "thread. Check the error log for additional"
1215                       " details.");
1216     goto err;
1217   }
1218   mysql_mutex_lock(&rli->run_lock);
1219   mysql_cond_wait(&rli->stop_cond, &rli->run_lock);
1220   mysql_mutex_unlock(&rli->run_lock);
1221   if (rli->until_condition != Relay_log_info::UNTIL_DONE)
1222   {
1223     sql_print_warning("MTS recovery: automatic recovery failed. Either the "
1224                       "slave server had stopped due to an error during an "
1225                       "earlier session or relay logs are corrupted."
1226                       "Fix the cause of the slave side error and restart the "
1227                       "slave server or consider using RESET SLAVE.");
1228     goto err;
1229   }
1230 
1231   /*
1232     We need a mutex while we are changing master info parameters to
1233     keep other threads from reading bogus info
1234   */
1235   mysql_mutex_lock(&mi->data_lock);
1236   mysql_mutex_lock(&rli->data_lock);
1237   recover_relay_log(mi);
1238 
1239   const char* msg;
1240   if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
1241                               rli->get_group_relay_log_pos(),
1242                               false/*need_data_lock=false*/,
1243                               &msg, 0))
1244   {
1245     char llbuf[22];
1246     sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s).",
1247                     rli->get_group_relay_log_name(),
1248                     llstr(rli->get_group_relay_log_pos(), llbuf));
1249 
1250     recovery_error=1;
1251     mysql_mutex_unlock(&mi->data_lock);
1252     mysql_mutex_unlock(&rli->data_lock);
1253     goto err;
1254   }
1255   if (mi->flush_info(true) || rli->flush_info(true))
1256   {
1257     recovery_error= 1;
1258     mysql_mutex_unlock(&mi->data_lock);
1259     mysql_mutex_unlock(&rli->data_lock);
1260     goto err;
1261   }
1262   rli->inited=1;
1263   rli->error_on_rli_init_info= false;
1264   mysql_mutex_unlock(&mi->data_lock);
1265   mysql_mutex_unlock(&rli->data_lock);
1266   sql_print_information("MTS recovery: completed successfully.\n");
1267   DBUG_RETURN(recovery_error);
1268 err:
1269   /*
1270     If recovery failed means we failed to initialize rli object in the case
1271     of MTS. We should not allow the START SLAVE command to work as we do in
1272     the case of STS. i.e if init_recovery call fails then we set inited=0.
1273   */
1274   rli->end_info();
1275   rli->inited=0;
1276   rli->error_on_rli_init_info= true;
1277   DBUG_RETURN(recovery_error);
1278 }
1279 
1280 
1281 
load_mi_and_rli_from_repositories(Master_info * mi,bool ignore_if_no_info,int thread_mask)1282 int load_mi_and_rli_from_repositories(Master_info* mi,
1283                                       bool ignore_if_no_info,
1284                                       int thread_mask)
1285 {
1286   DBUG_ENTER("init_info");
1287   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
1288   int init_error= 0;
1289   enum_return_check check_return= ERROR_CHECKING_REPOSITORY;
1290   THD *thd= current_thd;
1291 
1292   /*
1293     We need a mutex while we are changing master info parameters to
1294     keep other threads from reading bogus info
1295   */
1296   mysql_mutex_lock(&mi->data_lock);
1297   mysql_mutex_lock(&mi->rli->data_lock);
1298 
1299   /*
1300     When info tables are used and autocommit= 0 we force a new
1301     transaction start to avoid table access deadlocks when START SLAVE
1302     is executed after RESET SLAVE.
1303   */
1304   if (is_autocommit_off_and_infotables(thd))
1305   {
1306     if (trans_begin(thd))
1307     {
1308       init_error= 1;
1309       goto end;
1310     }
1311   }
1312 
1313   /*
1314     This takes care of the startup dependency between the master_info
1315     and relay_info. It initializes the master info if the SLAVE_IO
1316     thread is being started and the relay log info if either the
1317     SLAVE_SQL thread is being started or was not initialized as it is
1318     required by the SLAVE_IO thread.
1319   */
1320   check_return= mi->check_info();
1321   if (check_return == ERROR_CHECKING_REPOSITORY)
1322   {
1323     init_error= 1;
1324     goto end;
1325   }
1326 
1327   if (!(ignore_if_no_info && check_return == REPOSITORY_DOES_NOT_EXIST))
1328   {
1329     if ((thread_mask & SLAVE_IO) != 0 && mi->mi_init_info())
1330       init_error= 1;
1331   }
1332 
1333   check_return= mi->rli->check_info();
1334   if (check_return == ERROR_CHECKING_REPOSITORY)
1335   {
1336     init_error= 1;
1337     goto end;
1338   }
1339   if (!(ignore_if_no_info && check_return == REPOSITORY_DOES_NOT_EXIST))
1340   {
1341     if (((thread_mask & SLAVE_SQL) != 0 || !(mi->rli->inited))
1342         && mi->rli->rli_init_info())
1343       init_error= 1;
1344   }
1345 
1346   DBUG_EXECUTE_IF("enable_mts_worker_failure_init",
1347                   {DBUG_SET("+d,mts_worker_thread_init_fails");});
1348 end:
1349   /*
1350     When info tables are used and autocommit= 0 we force transaction
1351     commit to avoid table access deadlocks when START SLAVE is executed
1352     after RESET SLAVE.
1353   */
1354   if (is_autocommit_off_and_infotables(thd))
1355     if (trans_commit(thd))
1356       init_error= 1;
1357 
1358   mysql_mutex_unlock(&mi->rli->data_lock);
1359   mysql_mutex_unlock(&mi->data_lock);
1360 
1361   /*
1362     Handling MTS Relay-log recovery after successful initialization of mi and
1363     rli objects.
1364 
1365     MTS Relay-log recovery is handled by SSUG command. In order to start the
1366     slave applier thread rli needs to be inited and mi->rli->data_lock should
1367     be in released state. Hence we do the MTS recovery at this point of time
1368     where both conditions are satisfied.
1369   */
1370   if (!init_error && mi->rli->is_relay_log_recovery
1371       && mi->rli->mts_recovery_group_cnt)
1372     init_error= fill_mts_gaps_and_recover(mi);
1373   DBUG_RETURN(init_error);
1374 }
1375 
end_info(Master_info * mi)1376 void end_info(Master_info* mi)
1377 {
1378   DBUG_ENTER("end_info");
1379   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
1380 
1381   /*
1382     The previous implementation was not acquiring locks.  We do the same here.
1383     However, this is quite strange.
1384   */
1385   mi->end_info();
1386   mi->rli->end_info();
1387 
1388   DBUG_VOID_RETURN;
1389 }
1390 
remove_info(Master_info * mi)1391 int remove_info(Master_info* mi)
1392 {
1393   int error= 1;
1394   DBUG_ENTER("remove_info");
1395   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
1396 
1397   /*
1398     The previous implementation was not acquiring locks.
1399     We do the same here. However, this is quite strange.
1400   */
1401   /*
1402     Reset errors (the idea is that we forget about the
1403     old master).
1404   */
1405   mi->clear_error();
1406   mi->rli->clear_error();
1407   if (mi->rli->workers_array_initialized)
1408   {
1409     for(size_t i= 0; i < mi->rli->get_worker_count(); i++)
1410     {
1411       mi->rli->get_worker(i)->clear_error();
1412     }
1413   }
1414   mi->rli->clear_until_condition();
1415   mi->rli->clear_sql_delay();
1416 
1417   mi->end_info();
1418   mi->rli->end_info();
1419 
1420   if (mi->remove_info() || Rpl_info_factory::reset_workers(mi->rli) ||
1421       mi->rli->remove_info())
1422     goto err;
1423 
1424   error= 0;
1425 
1426 err:
1427   DBUG_RETURN(error);
1428 }
1429 
flush_master_info(Master_info * mi,bool force)1430 int flush_master_info(Master_info* mi, bool force)
1431 {
1432   DBUG_ENTER("flush_master_info");
1433   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
1434   /*
1435     The previous implementation was not acquiring locks.
1436     We do the same here. However, this is quite strange.
1437   */
1438   /*
1439     With the appropriate recovery process, we will not need to flush
1440     the content of the current log.
1441 
1442     For now, we flush the relay log BEFORE the master.info file, because
1443     if we crash, we will get a duplicate event in the relay log at restart.
1444     If we change the order, there might be missing events.
1445 
1446     If we don't do this and the slave server dies when the relay log has
1447     some parts (its last kilobytes) in memory only, with, say, from master's
1448     position 100 to 150 in memory only (not on disk), and with position 150
1449     in master.info, there will be missing information. When the slave restarts,
1450     the I/O thread will fetch binlogs from 150, so in the relay log we will
1451     have "[0, 100] U [150, infinity[" and nobody will notice it, so the SQL
1452     thread will jump from 100 to 150, and replication will silently break.
1453   */
1454   mysql_mutex_t *log_lock= mi->rli->relay_log.get_log_lock();
1455 
1456   mysql_mutex_lock(log_lock);
1457 
1458   int err=  (mi->rli->flush_current_log() ||
1459              mi->flush_info(force));
1460 
1461   mysql_mutex_unlock(log_lock);
1462 
1463   DBUG_RETURN (err);
1464 }
1465 
1466 /**
1467   Convert slave skip errors bitmap into a printable string.
1468 */
1469 
print_slave_skip_errors(void)1470 static void print_slave_skip_errors(void)
1471 {
1472   /*
1473     To be safe, we want 10 characters of room in the buffer for a number
1474     plus terminators. Also, we need some space for constant strings.
1475     10 characters must be sufficient for a number plus {',' | '...'}
1476     plus a NUL terminator. That is a max 6 digit number.
1477   */
1478   const size_t MIN_ROOM= 10;
1479   DBUG_ENTER("print_slave_skip_errors");
1480   DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
1481   DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
1482 
1483   if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
1484   {
1485     /* purecov: begin tested */
1486     memcpy(slave_skip_error_names, STRING_WITH_LEN("OFF"));
1487     /* purecov: end */
1488   }
1489   else if (bitmap_is_set_all(&slave_error_mask))
1490   {
1491     /* purecov: begin tested */
1492     memcpy(slave_skip_error_names, STRING_WITH_LEN("ALL"));
1493     /* purecov: end */
1494   }
1495   else
1496   {
1497     char *buff= slave_skip_error_names;
1498     char *bend= buff + sizeof(slave_skip_error_names);
1499     int  errnum;
1500 
1501     for (errnum= 0; errnum < MAX_SLAVE_ERROR; errnum++)
1502     {
1503       if (bitmap_is_set(&slave_error_mask, errnum))
1504       {
1505         if (buff + MIN_ROOM >= bend)
1506           break; /* purecov: tested */
1507         buff= int10_to_str(errnum, buff, 10);
1508         *buff++= ',';
1509       }
1510     }
1511     if (buff != slave_skip_error_names)
1512       buff--; // Remove last ','
1513     /*
1514       The range for client side error is [2000-2999]
1515       so if the errnum doesn't lie in that and if less
1516       than MAX_SLAVE_ERROR[10000] we enter the if loop.
1517     */
1518     if (errnum < MAX_SLAVE_ERROR &&
1519         (errnum < CR_MIN_ERROR || errnum > CR_MAX_ERROR))
1520     {
1521       /* Couldn't show all errors */
1522       buff= my_stpcpy(buff, "..."); /* purecov: tested */
1523     }
1524     *buff=0;
1525   }
1526   DBUG_PRINT("init", ("error_names: '%s'", slave_skip_error_names));
1527   DBUG_VOID_RETURN;
1528 }
1529 
1530 /**
1531  Change arg to the string with the nice, human-readable skip error values.
1532    @param slave_skip_errors_ptr
1533           The pointer to be changed
1534 */
set_slave_skip_errors(char ** slave_skip_errors_ptr)1535 void set_slave_skip_errors(char** slave_skip_errors_ptr)
1536 {
1537   DBUG_ENTER("set_slave_skip_errors");
1538   print_slave_skip_errors();
1539   *slave_skip_errors_ptr= slave_skip_error_names;
1540   DBUG_VOID_RETURN;
1541 }
1542 
1543 /**
1544   Init function to set up array for errors that should be skipped for slave
1545 */
init_slave_skip_errors()1546 static void init_slave_skip_errors()
1547 {
1548   DBUG_ENTER("init_slave_skip_errors");
1549   DBUG_ASSERT(!use_slave_mask); // not already initialized
1550 
1551   if (bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0))
1552   {
1553     fprintf(stderr, "Badly out of memory, please check your system status\n");
1554     exit(MYSQLD_ABORT_EXIT);
1555   }
1556   use_slave_mask = 1;
1557   DBUG_VOID_RETURN;
1558 }
1559 
add_slave_skip_errors(const uint * errors,uint n_errors)1560 static void add_slave_skip_errors(const uint* errors, uint n_errors)
1561 {
1562   DBUG_ENTER("add_slave_skip_errors");
1563   DBUG_ASSERT(errors);
1564   DBUG_ASSERT(use_slave_mask);
1565 
1566   for (uint i = 0; i < n_errors; i++)
1567   {
1568     const uint err_code = errors[i];
1569     /*
1570       The range for client side error is [2000-2999]
1571       so if the err_code doesn't lie in that and if less
1572       than MAX_SLAVE_ERROR[10000] we enter the if loop.
1573     */
1574     if (err_code < MAX_SLAVE_ERROR &&
1575         (err_code < CR_MIN_ERROR || err_code > CR_MAX_ERROR))
1576        bitmap_set_bit(&slave_error_mask, err_code);
1577   }
1578   DBUG_VOID_RETURN;
1579 }
1580 
1581 /*
1582   Add errors that should be skipped for slave
1583 
1584   SYNOPSIS
1585     add_slave_skip_errors()
1586     arg         List of errors numbers to be added to skip, separated with ','
1587 
1588   NOTES
1589     Called from get_options() in mysqld.cc on start-up
1590 */
1591 
add_slave_skip_errors(const char * arg)1592 void add_slave_skip_errors(const char* arg)
1593 {
1594   const char *p= NULL;
1595   /*
1596     ALL is only valid when nothing else is provided.
1597   */
1598   const uchar SKIP_ALL[]= "all";
1599   size_t SIZE_SKIP_ALL= strlen((const char *) SKIP_ALL) + 1;
1600   /*
1601     IGNORE_DDL_ERRORS can be combined with other parameters
1602     but must be the first one provided.
1603   */
1604   const uchar SKIP_DDL_ERRORS[]= "ddl_exist_errors";
1605   size_t SIZE_SKIP_DDL_ERRORS= strlen((const char *) SKIP_DDL_ERRORS);
1606   DBUG_ENTER("add_slave_skip_errors");
1607 
1608   // initialize mask if not done yet
1609   if (!use_slave_mask)
1610     init_slave_skip_errors();
1611 
1612   for (; my_isspace(system_charset_info,*arg); ++arg)
1613     /* empty */;
1614   if (!my_strnncoll(system_charset_info, (uchar*)arg, SIZE_SKIP_ALL,
1615                     SKIP_ALL, SIZE_SKIP_ALL))
1616   {
1617     bitmap_set_all(&slave_error_mask);
1618     DBUG_VOID_RETURN;
1619   }
1620   if (!my_strnncoll(system_charset_info, (uchar*)arg, SIZE_SKIP_DDL_ERRORS,
1621                     SKIP_DDL_ERRORS, SIZE_SKIP_DDL_ERRORS))
1622   {
1623     // DDL errors to be skipped for relaxed 'exist' handling
1624     const uint ddl_errors[] = {
1625       // error codes with create/add <schema object>
1626       ER_DB_CREATE_EXISTS, ER_TABLE_EXISTS_ERROR, ER_DUP_KEYNAME,
1627       ER_MULTIPLE_PRI_KEY,
1628       // error codes with change/rename <schema object>
1629       ER_BAD_FIELD_ERROR, ER_NO_SUCH_TABLE, ER_DUP_FIELDNAME,
1630       // error codes with drop <schema object>
1631       ER_DB_DROP_EXISTS, ER_BAD_TABLE_ERROR, ER_CANT_DROP_FIELD_OR_KEY
1632     };
1633 
1634     add_slave_skip_errors(ddl_errors,
1635                           sizeof(ddl_errors)/sizeof(ddl_errors[0]));
1636     /*
1637       After processing the SKIP_DDL_ERRORS, the pointer is
1638       increased to the position after the comma.
1639     */
1640     if (strlen(arg) > SIZE_SKIP_DDL_ERRORS + 1)
1641       arg+= SIZE_SKIP_DDL_ERRORS + 1;
1642   }
1643   for (p= arg ; *p; )
1644   {
1645     long err_code;
1646     if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
1647       break;
1648     if (err_code < MAX_SLAVE_ERROR)
1649        bitmap_set_bit(&slave_error_mask,(uint)err_code);
1650     while (!my_isdigit(system_charset_info,*p) && *p)
1651       p++;
1652   }
1653   DBUG_VOID_RETURN;
1654 }
1655 
set_thd_in_use_temporary_tables(Relay_log_info * rli)1656 static void set_thd_in_use_temporary_tables(Relay_log_info *rli)
1657 {
1658   TABLE *table;
1659 
1660   for (table= rli->save_temporary_tables ; table ; table= table->next)
1661   {
1662     table->in_use= rli->info_thd;
1663     if (table->file != NULL)
1664     {
1665       /*
1666         Since we are stealing opened temporary tables from one thread to another,
1667         we need to let the performance schema know that,
1668         for aggregates per thread to work properly.
1669       */
1670       table->file->unbind_psi();
1671       table->file->rebind_psi();
1672     }
1673   }
1674 }
1675 
terminate_slave_threads(Master_info * mi,int thread_mask,ulong stop_wait_timeout,bool need_lock_term)1676 int terminate_slave_threads(Master_info* mi, int thread_mask,
1677                             ulong stop_wait_timeout, bool need_lock_term)
1678 {
1679   DBUG_ENTER("terminate_slave_threads");
1680 
1681   if (!mi->inited)
1682     DBUG_RETURN(0); /* successfully do nothing */
1683   int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
1684   mysql_mutex_t *sql_lock = &mi->rli->run_lock, *io_lock = &mi->run_lock;
1685   mysql_mutex_t *log_lock= mi->rli->relay_log.get_log_lock();
1686   /*
1687     Set it to a variable, so the value is shared by both stop methods.
1688     This guarantees that the user defined value for the timeout value is for
1689     the time the 2 threads take to shutdown, and not the time of each thread
1690     stop operation.
1691   */
1692   ulong total_stop_wait_timeout= stop_wait_timeout;
1693 
1694   if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
1695   {
1696     DBUG_PRINT("info",("Terminating SQL thread"));
1697     mi->rli->abort_slave= 1;
1698     if ((error=terminate_slave_thread(mi->rli->info_thd, sql_lock,
1699                                       &mi->rli->stop_cond,
1700                                       &mi->rli->slave_running,
1701                                       &total_stop_wait_timeout,
1702                                       need_lock_term)) &&
1703         !force_all)
1704     {
1705       if (error == 1)
1706       {
1707         DBUG_RETURN(ER_STOP_SLAVE_SQL_THREAD_TIMEOUT);
1708       }
1709       DBUG_RETURN(error);
1710     }
1711     mysql_mutex_lock(log_lock);
1712 
1713     DBUG_PRINT("info",("Flushing relay-log info file."));
1714     if (current_thd)
1715       THD_STAGE_INFO(current_thd, stage_flushing_relay_log_info_file);
1716 
1717     /*
1718       Flushes the relay log info regardles of the sync_relay_log_info option.
1719     */
1720     if (mi->rli->flush_info(TRUE))
1721     {
1722       mysql_mutex_unlock(log_lock);
1723       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1724     }
1725 
1726     mysql_mutex_unlock(log_lock);
1727   }
1728   if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
1729   {
1730     DBUG_PRINT("info",("Terminating IO thread"));
1731     mi->abort_slave=1;
1732     DBUG_EXECUTE_IF("pause_after_queue_event",
1733                     {
1734                       const char act[]=
1735                         "now SIGNAL reached_stopping_io_thread";
1736                       DBUG_ASSERT(!debug_sync_set_action(current_thd,
1737                                                          STRING_WITH_LEN(act)));
1738                     };);
1739     if ((error=terminate_slave_thread(mi->info_thd,io_lock,
1740                                       &mi->stop_cond,
1741                                       &mi->slave_running,
1742                                       &total_stop_wait_timeout,
1743                                       need_lock_term)) &&
1744         !force_all)
1745     {
1746       if (error == 1)
1747       {
1748         DBUG_RETURN(ER_STOP_SLAVE_IO_THREAD_TIMEOUT);
1749       }
1750       DBUG_RETURN(error);
1751     }
1752     mysql_mutex_lock(log_lock);
1753 
1754     DBUG_PRINT("info",("Flushing relay log and master info repository."));
1755     if (current_thd)
1756       THD_STAGE_INFO(current_thd, stage_flushing_relay_log_and_master_info_repository);
1757 
1758     /*
1759       Flushes the master info regardles of the sync_master_info option.
1760     */
1761     if (mi->flush_info(TRUE))
1762     {
1763       mysql_mutex_unlock(log_lock);
1764       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1765     }
1766 
1767     /*
1768       Flushes the relay log regardles of the sync_relay_log option.
1769     */
1770     if (mi->rli->relay_log.is_open() &&
1771         mi->rli->relay_log.flush_and_sync(true))
1772     {
1773       mysql_mutex_unlock(log_lock);
1774       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1775     }
1776 
1777     mysql_mutex_unlock(log_lock);
1778   }
1779   DBUG_RETURN(0);
1780 }
1781 
1782 
1783 /**
1784    Wait for a slave thread to terminate.
1785 
1786    This function is called after requesting the thread to terminate
1787    (by setting @c abort_slave member of @c Relay_log_info or @c
1788    Master_info structure to 1). Termination of the thread is
1789    controlled with the the predicate <code>*slave_running</code>.
1790 
1791    Function will acquire @c term_lock before waiting on the condition
1792    unless @c need_lock_term is false in which case the mutex should be
1793    owned by the caller of this function and will remain acquired after
1794    return from the function.
1795 
1796    @param term_lock
1797           Associated lock to use when waiting for @c term_cond
1798 
1799    @param term_cond
1800           Condition that is signalled when the thread has terminated
1801 
1802    @param slave_running
1803           Pointer to predicate to check for slave thread termination
1804 
1805    @param stop_wait_timeout
1806           A pointer to a variable that denotes the time the thread has
1807           to stop before we time out and throw an error.
1808 
1809    @param need_lock_term
1810           If @c false the lock will not be acquired before waiting on
1811           the condition. In this case, it is assumed that the calling
1812           function acquires the lock before calling this function.
1813 
1814    @retval 0 All OK, 1 on "STOP SLAVE" command timeout, ER_SLAVE_CHANNEL_NOT_RUNNING otherwise.
1815 
1816    @note  If the executing thread has to acquire term_lock
1817           (need_lock_term is true, the negative running status does not
1818           represent any issue therefore no error is reported.
1819 
1820  */
1821 static int
terminate_slave_thread(THD * thd,mysql_mutex_t * term_lock,mysql_cond_t * term_cond,volatile uint * slave_running,ulong * stop_wait_timeout,bool need_lock_term)1822 terminate_slave_thread(THD *thd,
1823                        mysql_mutex_t *term_lock,
1824                        mysql_cond_t *term_cond,
1825                        volatile uint *slave_running,
1826                        ulong *stop_wait_timeout,
1827                        bool need_lock_term)
1828 {
1829   DBUG_ENTER("terminate_slave_thread");
1830   if (need_lock_term)
1831   {
1832     mysql_mutex_lock(term_lock);
1833   }
1834   else
1835   {
1836     mysql_mutex_assert_owner(term_lock);
1837   }
1838   if (!*slave_running)
1839   {
1840     if (need_lock_term)
1841     {
1842       /*
1843         if run_lock (term_lock) is acquired locally then either
1844         slave_running status is fine
1845       */
1846       mysql_mutex_unlock(term_lock);
1847       DBUG_RETURN(0);
1848     }
1849     else
1850     {
1851       DBUG_RETURN(ER_SLAVE_CHANNEL_NOT_RUNNING);
1852     }
1853   }
1854   DBUG_ASSERT(thd != 0);
1855   THD_CHECK_SENTRY(thd);
1856 
1857   /*
1858     Is is critical to test if the slave is running. Otherwise, we might
1859     be referening freed memory trying to kick it
1860   */
1861 
1862   while (*slave_running)                        // Should always be true
1863   {
1864     DBUG_PRINT("loop", ("killing slave thread"));
1865 
1866     mysql_mutex_lock(&thd->LOCK_thd_data);
1867     /*
1868       Error codes from pthread_kill are:
1869       EINVAL: invalid signal number (can't happen)
1870       ESRCH: thread already killed (can happen, should be ignored)
1871     */
1872 #ifndef _WIN32
1873     int err MY_ATTRIBUTE((unused))= pthread_kill(thd->real_id, SIGUSR1);
1874     DBUG_ASSERT(err != EINVAL);
1875 #endif
1876     thd->awake(THD::NOT_KILLED);
1877     mysql_mutex_unlock(&thd->LOCK_thd_data);
1878 
1879     /*
1880       There is a small chance that slave thread might miss the first
1881       alarm. To protect againts it, resend the signal until it reacts
1882     */
1883     struct timespec abstime;
1884     set_timespec(&abstime,2);
1885 #ifndef DBUG_OFF
1886     int error=
1887 #endif
1888       mysql_cond_timedwait(term_cond, term_lock, &abstime);
1889     if ((*stop_wait_timeout) >= 2)
1890       (*stop_wait_timeout)= (*stop_wait_timeout) - 2;
1891     else if (*slave_running)
1892     {
1893       if (need_lock_term)
1894         mysql_mutex_unlock(term_lock);
1895       DBUG_RETURN (1);
1896     }
1897     DBUG_ASSERT(error == ETIMEDOUT || error == 0);
1898   }
1899 
1900   DBUG_ASSERT(*slave_running == 0);
1901 
1902   if (need_lock_term)
1903     mysql_mutex_unlock(term_lock);
1904   DBUG_RETURN(0);
1905 }
1906 
1907 
start_slave_thread(PSI_thread_key thread_key,my_start_routine 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)1908 bool start_slave_thread(
1909 #ifdef HAVE_PSI_INTERFACE
1910                         PSI_thread_key thread_key,
1911 #endif
1912                         my_start_routine h_func, mysql_mutex_t *start_lock,
1913                         mysql_mutex_t *cond_lock,
1914                         mysql_cond_t *start_cond,
1915                         volatile uint *slave_running,
1916                         volatile ulong *slave_run_id,
1917                         Master_info* mi)
1918 {
1919   bool is_error= false;
1920   my_thread_handle th;
1921   ulong start_id;
1922   DBUG_ENTER("start_slave_thread");
1923 
1924   if (start_lock)
1925     mysql_mutex_lock(start_lock);
1926   if (!server_id)
1927   {
1928     if (start_cond)
1929       mysql_cond_broadcast(start_cond);
1930     sql_print_error("Server id not set, will not start slave%s",
1931                     mi->get_for_channel_str());
1932     my_error(ER_BAD_SLAVE, MYF(0));
1933     goto err;
1934   }
1935 
1936   if (*slave_running)
1937   {
1938     if (start_cond)
1939       mysql_cond_broadcast(start_cond);
1940     my_error(ER_SLAVE_CHANNEL_MUST_STOP, MYF(0), mi->get_channel());
1941     goto err;
1942   }
1943   start_id= *slave_run_id;
1944   DBUG_PRINT("info", ("Creating new slave thread"));
1945   if (mysql_thread_create(thread_key, &th, &connection_attrib, h_func,
1946                           (void*)mi))
1947   {
1948     sql_print_error("Can't create slave thread%s.", mi->get_for_channel_str());
1949     my_error(ER_SLAVE_THREAD, MYF(0));
1950     goto err;
1951   }
1952   if (start_cond && cond_lock) // caller has cond_lock
1953   {
1954     THD* thd = current_thd;
1955     while (start_id == *slave_run_id && thd != NULL)
1956     {
1957       DBUG_PRINT("sleep",("Waiting for slave thread to start"));
1958       PSI_stage_info saved_stage= {0, "", 0};
1959       thd->ENTER_COND(start_cond, cond_lock,
1960                       & stage_waiting_for_slave_thread_to_start,
1961                       & saved_stage);
1962       /*
1963         It is not sufficient to test this at loop bottom. We must test
1964         it after registering the mutex in enter_cond(). If the kill
1965         happens after testing of thd->killed and before the mutex is
1966         registered, we could otherwise go waiting though thd->killed is
1967         set.
1968       */
1969       if (!thd->killed)
1970         mysql_cond_wait(start_cond, cond_lock);
1971       mysql_mutex_unlock(cond_lock);
1972       DEBUG_SYNC(thd, "start_slave_thread_after_signal_on_start_cond");
1973       thd->EXIT_COND(& saved_stage);
1974       mysql_mutex_lock(cond_lock); // re-acquire it
1975       if (thd->killed)
1976       {
1977         int error= thd->killed_errno();
1978         my_message(error, ER(error), MYF(0));
1979         goto err;
1980       }
1981     }
1982   }
1983 
1984   goto end;
1985 err:
1986   is_error= true;
1987 end:
1988 
1989   if (start_lock)
1990     mysql_mutex_unlock(start_lock);
1991   DBUG_RETURN(is_error);
1992 }
1993 
1994 
1995 /*
1996   start_slave_threads()
1997 
1998   NOTES
1999     SLAVE_FORCE_ALL is not implemented here on purpose since it does not make
2000     sense to do that for starting a slave--we always care if it actually
2001     started the threads that were not previously running
2002 */
2003 
start_slave_threads(bool need_lock_slave,bool wait_for_start,Master_info * mi,int thread_mask)2004 bool start_slave_threads(bool need_lock_slave, bool wait_for_start,
2005                          Master_info* mi, int thread_mask)
2006 {
2007   mysql_mutex_t *lock_io=0, *lock_sql=0, *lock_cond_io=0, *lock_cond_sql=0;
2008   mysql_cond_t* cond_io=0, *cond_sql=0;
2009   bool is_error= 0;
2010   DBUG_ENTER("start_slave_threads");
2011   DBUG_EXECUTE_IF("uninitialized_master-info_structure",
2012                    mi->inited= FALSE;);
2013 
2014   if (!mi->inited || !mi->rli->inited)
2015   {
2016     int error= (!mi->inited ? ER_SLAVE_MI_INIT_REPOSITORY :
2017                 ER_SLAVE_RLI_INIT_REPOSITORY);
2018     Rpl_info *info= (!mi->inited ?  mi : static_cast<Rpl_info *>(mi->rli));
2019     const char* prefix= current_thd ? ER(error) : ER_DEFAULT(error);
2020     info->report(ERROR_LEVEL, error, prefix, NULL);
2021     my_error(error, MYF(0));
2022     DBUG_RETURN(true);
2023   }
2024 
2025   if (mi->is_auto_position() && (thread_mask & SLAVE_IO) &&
2026       get_gtid_mode(GTID_MODE_LOCK_NONE) == GTID_MODE_OFF)
2027   {
2028     my_error(ER_CANT_USE_AUTO_POSITION_WITH_GTID_MODE_OFF, MYF(0),
2029              mi->get_for_channel_str());
2030     DBUG_RETURN(true);
2031   }
2032 
2033   if (need_lock_slave)
2034   {
2035     lock_io = &mi->run_lock;
2036     lock_sql = &mi->rli->run_lock;
2037   }
2038   if (wait_for_start)
2039   {
2040     cond_io = &mi->start_cond;
2041     cond_sql = &mi->rli->start_cond;
2042     lock_cond_io = &mi->run_lock;
2043     lock_cond_sql = &mi->rli->run_lock;
2044   }
2045 
2046   if (thread_mask & SLAVE_IO)
2047     is_error= start_slave_thread(
2048 #ifdef HAVE_PSI_INTERFACE
2049                                  key_thread_slave_io,
2050 #endif
2051                                  handle_slave_io, lock_io, lock_cond_io,
2052                                  cond_io,
2053                                  &mi->slave_running, &mi->slave_run_id,
2054                                  mi);
2055   if (!is_error && (thread_mask & SLAVE_SQL))
2056   {
2057     /*
2058       MTS-recovery gaps gathering is placed onto common execution path
2059       for either START-SLAVE and --skip-start-slave= 0
2060     */
2061     if (mi->rli->recovery_parallel_workers != 0)
2062     {
2063       if (mts_recovery_groups(mi->rli))
2064       {
2065         is_error= true;
2066         my_error(ER_MTS_RECOVERY_FAILURE, MYF(0));
2067       }
2068     }
2069     if (!is_error)
2070       is_error= start_slave_thread(
2071 #ifdef HAVE_PSI_INTERFACE
2072                                    key_thread_slave_sql,
2073 #endif
2074                                    handle_slave_sql, lock_sql, lock_cond_sql,
2075                                    cond_sql,
2076                                    &mi->rli->slave_running,
2077                                    &mi->rli->slave_run_id,
2078                                    mi);
2079     if (is_error)
2080       terminate_slave_threads(mi, thread_mask & SLAVE_IO,
2081                               rpl_stop_slave_timeout, need_lock_slave);
2082   }
2083   DBUG_RETURN(is_error);
2084 }
2085 
2086 /*
2087   Release slave threads at time of executing shutdown.
2088 
2089   SYNOPSIS
2090     end_slave()
2091 */
2092 
end_slave()2093 void end_slave()
2094 {
2095   DBUG_ENTER("end_slave");
2096 
2097   Master_info *mi= 0;
2098 
2099   /*
2100     This is called when the server terminates, in close_connections().
2101     It terminates slave threads. However, some CHANGE MASTER etc may still be
2102     running presently. If a START SLAVE was in progress, the mutex lock below
2103     will make us wait until slave threads have started, and START SLAVE
2104     returns, then we terminate them here.
2105   */
2106   channel_map.wrlock();
2107 
2108   /* traverse through the map and terminate the threads */
2109   for(mi_map::iterator it= channel_map.begin(); it!=channel_map.end(); it++)
2110   {
2111     mi= it->second;
2112 
2113     if (mi)
2114       terminate_slave_threads(mi,SLAVE_FORCE_ALL,
2115                               rpl_stop_slave_timeout);
2116   }
2117   channel_map.unlock();
2118   DBUG_VOID_RETURN;
2119 }
2120 
2121 /**
2122    Free all resources used by slave threads at time of executing shutdown.
2123    The routine must be called after all possible users of channel_map
2124    have left.
2125 
2126 */
delete_slave_info_objects()2127 void delete_slave_info_objects()
2128 {
2129   DBUG_ENTER("delete_slave_info_objects");
2130 
2131   Master_info *mi= 0;
2132 
2133   channel_map.wrlock();
2134 
2135   for (mi_map::iterator it= channel_map.begin(); it!=channel_map.end(); it++)
2136   {
2137     mi= it->second;
2138 
2139     if (mi)
2140     {
2141       mi->channel_wrlock();
2142       end_info(mi);
2143       if (mi->rli)
2144         delete mi->rli;
2145       delete mi;
2146       it->second= 0;
2147     }
2148   }
2149 
2150   //Clean other types of channel
2151   for (mi_map::iterator it= channel_map.begin(GROUP_REPLICATION_CHANNEL);
2152        it!=channel_map.end(GROUP_REPLICATION_CHANNEL); it++)
2153   {
2154     mi= it->second;
2155 
2156     if (mi)
2157     {
2158       mi->channel_wrlock();
2159       end_info(mi);
2160       if (mi->rli)
2161         delete mi->rli;
2162       delete mi;
2163       it->second= 0;
2164     }
2165   }
2166 
2167   channel_map.unlock();
2168 
2169   DBUG_VOID_RETURN;
2170 }
2171 
2172 /**
2173    Check if multi-statement transaction mode and master and slave info
2174    repositories are set to table.
2175 
2176    @param THD    THD object
2177 
2178    @retval true  Success
2179    @retval false Failure
2180 */
is_autocommit_off_and_infotables(THD * thd)2181 static bool is_autocommit_off_and_infotables(THD* thd)
2182 {
2183   DBUG_ENTER("is_autocommit_off_and_infotables");
2184   DBUG_RETURN((thd && thd->in_multi_stmt_transaction_mode() &&
2185                (opt_mi_repository_id == INFO_REPOSITORY_TABLE ||
2186                 opt_rli_repository_id == INFO_REPOSITORY_TABLE))?
2187               true : false);
2188 }
2189 
io_slave_killed(THD * thd,Master_info * mi)2190 static bool io_slave_killed(THD* thd, Master_info* mi)
2191 {
2192   DBUG_ENTER("io_slave_killed");
2193 
2194   DBUG_ASSERT(mi->info_thd == thd);
2195   DBUG_ASSERT(mi->slave_running); // tracking buffer overrun
2196   DBUG_RETURN(mi->abort_slave || abort_loop || thd->killed);
2197 }
2198 
2199 /**
2200    The function analyzes a possible killed status and makes
2201    a decision whether to accept it or not.
2202    Normally upon accepting the sql thread goes to shutdown.
2203    In the event of deferring decision @rli->last_event_start_time waiting
2204    timer is set to force the killed status be accepted upon its expiration.
2205 
2206    Notice Multi-Threaded-Slave behaves similarly in that when it's being
2207    stopped and the current group of assigned events has not yet scheduled
2208    completely, Coordinator defers to accept to leave its read-distribute
2209    state. The above timeout ensures waiting won't last endlessly, and in
2210    such case an error is reported.
2211 
2212    @param thd   pointer to a THD instance
2213    @param rli   pointer to Relay_log_info instance
2214 
2215    @return TRUE the killed status is recognized, FALSE a possible killed
2216            status is deferred.
2217 */
sql_slave_killed(THD * thd,Relay_log_info * rli)2218 bool sql_slave_killed(THD* thd, Relay_log_info* rli)
2219 {
2220   bool is_parallel_warn= FALSE;
2221 
2222   DBUG_ENTER("sql_slave_killed");
2223 
2224   DBUG_ASSERT(rli->info_thd == thd);
2225   DBUG_ASSERT(rli->slave_running == 1);
2226   if (rli->sql_thread_kill_accepted)
2227     DBUG_RETURN(true);
2228   DBUG_EXECUTE_IF("stop_when_mts_in_group", rli->abort_slave = 1;
2229                   DBUG_SET("-d,stop_when_mts_in_group");
2230                   DBUG_SET("-d,simulate_stop_when_mts_in_group");
2231                   DBUG_RETURN(false););
2232   if (abort_loop || thd->killed || rli->abort_slave)
2233   {
2234     rli->sql_thread_kill_accepted= true;
2235     is_parallel_warn= (rli->is_parallel_exec() &&
2236                        (rli->is_mts_in_group() || thd->killed));
2237     /*
2238       Slave can execute stop being in one of two MTS or Single-Threaded mode.
2239       The modes define different criteria to accept the stop.
2240       In particular that relates to the concept of groupping.
2241       Killed Coordinator thread expects the worst so it warns on
2242       possible consistency issue.
2243     */
2244     if (is_parallel_warn ||
2245         (!rli->is_parallel_exec() &&
2246          thd->get_transaction()->cannot_safely_rollback(
2247              Transaction_ctx::SESSION) &&
2248          rli->is_in_group()))
2249     {
2250       char msg_stopped[]=
2251         "... Slave SQL Thread stopped with incomplete event group "
2252         "having non-transactional changes. "
2253         "If the group consists solely of row-based events, you can try "
2254         "to restart the slave with --slave-exec-mode=IDEMPOTENT, which "
2255         "ignores duplicate key, key not found, and similar errors (see "
2256         "documentation for details).";
2257       char msg_stopped_mts[]=
2258         "... The slave coordinator and worker threads are stopped, possibly "
2259         "leaving data in inconsistent state. A restart should "
2260         "restore consistency automatically, although using non-transactional "
2261         "storage for data or info tables or DDL queries could lead to problems. "
2262         "In such cases you have to examine your data (see documentation for "
2263         "details).";
2264 
2265       if (rli->abort_slave)
2266       {
2267         DBUG_PRINT("info", ("Request to stop slave SQL Thread received while "
2268                             "applying an MTS group or a group that "
2269                             "has non-transactional "
2270                             "changes; waiting for completion of the group ... "));
2271 
2272         /*
2273           Slave sql thread shutdown in face of unfinished group modified
2274           Non-trans table is handled via a timer. The slave may eventually
2275           give out to complete the current group and in that case there
2276           might be issues at consequent slave restart, see the error message.
2277           WL#2975 offers a robust solution requiring to store the last exectuted
2278           event's coordinates along with the group's coordianates
2279           instead of waiting with @c last_event_start_time the timer.
2280         */
2281 
2282         if (rli->last_event_start_time == 0)
2283           rli->last_event_start_time= my_time(0);
2284         rli->sql_thread_kill_accepted= difftime(my_time(0),
2285                                                rli->last_event_start_time) <=
2286                                                SLAVE_WAIT_GROUP_DONE ?
2287                                                FALSE : TRUE;
2288 
2289         DBUG_EXECUTE_IF("stop_slave_middle_group",
2290                         DBUG_EXECUTE_IF("incomplete_group_in_relay_log",
2291                                         rli->sql_thread_kill_accepted= TRUE;);); // time is over
2292 
2293         if (!rli->sql_thread_kill_accepted && !rli->reported_unsafe_warning)
2294         {
2295           rli->report(WARNING_LEVEL, 0,
2296                       !is_parallel_warn ?
2297                       "Request to stop slave SQL Thread received while "
2298                       "applying a group that has non-transactional "
2299                       "changes; waiting for completion of the group ... "
2300                       :
2301                       "Coordinator thread of multi-threaded slave is being "
2302                       "stopped in the middle of assigning a group of events; "
2303                       "deferring to exit until the group completion ... ");
2304           rli->reported_unsafe_warning= true;
2305         }
2306       }
2307       if (rli->sql_thread_kill_accepted)
2308       {
2309         rli->last_event_start_time= 0;
2310         if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
2311         {
2312           rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
2313         }
2314         if (is_parallel_warn)
2315           rli->report(!rli->is_error() ? ERROR_LEVEL :
2316                       WARNING_LEVEL,    // an error was reported by Worker
2317                       ER_MTS_INCONSISTENT_DATA,
2318                       ER(ER_MTS_INCONSISTENT_DATA),
2319                       msg_stopped_mts);
2320         else
2321           rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
2322                       ER(ER_SLAVE_FATAL_ERROR), msg_stopped);
2323       }
2324     }
2325   }
2326   DBUG_RETURN(rli->sql_thread_kill_accepted);
2327 }
2328 
2329 
2330 /*
2331   skip_load_data_infile()
2332 
2333   NOTES
2334     This is used to tell a 3.23 master to break send_file()
2335 */
2336 
skip_load_data_infile(NET * net)2337 void skip_load_data_infile(NET *net)
2338 {
2339   DBUG_ENTER("skip_load_data_infile");
2340 
2341   (void)net_request_file(net, "/dev/null");
2342   (void)my_net_read(net);                               // discard response
2343   (void)net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0); // ok
2344   DBUG_VOID_RETURN;
2345 }
2346 
2347 
net_request_file(NET * net,const char * fname)2348 bool net_request_file(NET* net, const char* fname)
2349 {
2350   DBUG_ENTER("net_request_file");
2351   DBUG_RETURN(net_write_command(net, 251, (uchar*) fname, strlen(fname),
2352                                 (uchar*) "", 0));
2353 }
2354 
2355 /*
2356   From other comments and tests in code, it looks like
2357   sometimes Query_log_event and Load_log_event can have db == 0
2358   (see rewrite_db() above for example)
2359   (cases where this happens are unclear; it may be when the master is 3.23).
2360 */
2361 
print_slave_db_safe(const char * db)2362 const char *print_slave_db_safe(const char* db)
2363 {
2364   DBUG_ENTER("*print_slave_db_safe");
2365 
2366   DBUG_RETURN((db ? db : ""));
2367 }
2368 
2369 /*
2370   Check if the error is caused by network.
2371   @param[in]   errorno   Number of the error.
2372   RETURNS:
2373   TRUE         network error
2374   FALSE        not network error
2375 */
2376 
is_network_error(uint errorno)2377 static bool is_network_error(uint errorno)
2378 {
2379   return errorno == CR_CONNECTION_ERROR ||
2380       errorno == CR_CONN_HOST_ERROR ||
2381       errorno == CR_SERVER_GONE_ERROR ||
2382       errorno == CR_SERVER_LOST ||
2383       errorno == ER_CON_COUNT_ERROR ||
2384       errorno == ER_SERVER_SHUTDOWN ||
2385       errorno == ER_NET_READ_INTERRUPTED ||
2386       errorno == ER_NET_WRITE_INTERRUPTED;
2387 }
2388 
2389 
2390 /**
2391   Execute an initialization query for the IO thread.
2392 
2393   If there is an error, then this function calls mysql_free_result;
2394   otherwise the MYSQL object holds the result after this call.  If
2395   there is an error other than allowed_error, then this function
2396   prints a message and returns -1.
2397 
2398   @param mysql MYSQL object.
2399   @param query Query string.
2400   @param allowed_error Allowed error code, or 0 if no errors are allowed.
2401   @param[out] master_res If this is not NULL and there is no error, then
2402   mysql_store_result() will be called and the result stored in this pointer.
2403   @param[out] master_row If this is not NULL and there is no error, then
2404   mysql_fetch_row() will be called and the result stored in this pointer.
2405 
2406   @retval COMMAND_STATUS_OK No error.
2407   @retval COMMAND_STATUS_ALLOWED_ERROR There was an error and the
2408   error code was 'allowed_error'.
2409   @retval COMMAND_STATUS_ERROR There was an error and the error code
2410   was not 'allowed_error'.
2411 */
2412 enum enum_command_status
2413 { COMMAND_STATUS_OK, COMMAND_STATUS_ERROR, COMMAND_STATUS_ALLOWED_ERROR };
2414 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)2415 io_thread_init_command(Master_info *mi, const char *query, int allowed_error,
2416                        MYSQL_RES **master_res= NULL,
2417                        MYSQL_ROW *master_row= NULL)
2418 {
2419   DBUG_ENTER("io_thread_init_command");
2420   DBUG_PRINT("info", ("IO thread initialization command: '%s'", query));
2421   MYSQL *mysql= mi->mysql;
2422   int ret= mysql_real_query(mysql, query, static_cast<ulong>(strlen(query)));
2423   if (io_slave_killed(mi->info_thd, mi))
2424   {
2425     sql_print_information("The slave IO thread%s was killed while executing "
2426                           "initialization query '%s'",
2427                           mi->get_for_channel_str(), query);
2428     mysql_free_result(mysql_store_result(mysql));
2429     DBUG_RETURN(COMMAND_STATUS_ERROR);
2430   }
2431   if (ret != 0)
2432   {
2433     int err= mysql_errno(mysql);
2434     mysql_free_result(mysql_store_result(mysql));
2435     if (!err || err != allowed_error)
2436     {
2437       mi->report(is_network_error(err) ? WARNING_LEVEL : ERROR_LEVEL, err,
2438                  "The slave IO thread stops because the initialization query "
2439                  "'%s' failed with error '%s'.",
2440                  query, mysql_error(mysql));
2441       DBUG_RETURN(COMMAND_STATUS_ERROR);
2442     }
2443     DBUG_RETURN(COMMAND_STATUS_ALLOWED_ERROR);
2444   }
2445   if (master_res != NULL)
2446   {
2447     if ((*master_res= mysql_store_result(mysql)) == NULL)
2448     {
2449       mi->report(WARNING_LEVEL, mysql_errno(mysql),
2450                  "The slave IO thread stops because the initialization query "
2451                  "'%s' did not return any result.",
2452                  query);
2453       DBUG_RETURN(COMMAND_STATUS_ERROR);
2454     }
2455     if (master_row != NULL)
2456     {
2457       if ((*master_row= mysql_fetch_row(*master_res)) == NULL)
2458       {
2459         mysql_free_result(*master_res);
2460         mi->report(WARNING_LEVEL, mysql_errno(mysql),
2461                    "The slave IO thread stops because the initialization query "
2462                    "'%s' did not return any row.",
2463                    query);
2464         DBUG_RETURN(COMMAND_STATUS_ERROR);
2465       }
2466     }
2467   }
2468   else
2469     DBUG_ASSERT(master_row == NULL);
2470   DBUG_RETURN(COMMAND_STATUS_OK);
2471 }
2472 
2473 
2474 /**
2475   Set user variables after connecting to the master.
2476 
2477   @param  mysql MYSQL to request uuid from master.
2478   @param  mi    Master_info to set master_uuid
2479 
2480   @return 0: Success, 1: Fatal error, 2: Transient network error.
2481  */
io_thread_init_commands(MYSQL * mysql,Master_info * mi)2482 int io_thread_init_commands(MYSQL *mysql, Master_info *mi)
2483 {
2484   char query[256];
2485   int ret= 0;
2486   DBUG_EXECUTE_IF("fake_5_5_version_slave", return ret;);
2487 
2488   sprintf(query, "SET @slave_uuid= '%s'", server_uuid);
2489   if (mysql_real_query(mysql, query, static_cast<ulong>(strlen(query)))
2490       && !check_io_slave_killed(mi->info_thd, mi, NULL))
2491     goto err;
2492 
2493   mysql_free_result(mysql_store_result(mysql));
2494   return ret;
2495 
2496 err:
2497   if (mysql_errno(mysql) && is_network_error(mysql_errno(mysql)))
2498   {
2499     mi->report(WARNING_LEVEL, mysql_errno(mysql),
2500                "The initialization command '%s' failed with the following"
2501                " error: '%s'.", query, mysql_error(mysql));
2502     ret= 2;
2503   }
2504   else
2505   {
2506     char errmsg[512];
2507     const char *errmsg_fmt=
2508       "The slave I/O thread stops because a fatal error is encountered "
2509       "when it tries to send query to master(query: %s).";
2510 
2511     sprintf(errmsg, errmsg_fmt, query);
2512     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
2513                errmsg);
2514     ret= 1;
2515   }
2516   mysql_free_result(mysql_store_result(mysql));
2517   return ret;
2518 }
2519 
2520 /**
2521   Get master's uuid on connecting.
2522 
2523   @param  mysql MYSQL to request uuid from master.
2524   @param  mi    Master_info to set master_uuid
2525 
2526   @return 0: Success, 1: Fatal error, 2: Transient network error.
2527 */
get_master_uuid(MYSQL * mysql,Master_info * mi)2528 static int get_master_uuid(MYSQL *mysql, Master_info *mi)
2529 {
2530   const char *errmsg;
2531   MYSQL_RES *master_res= NULL;
2532   MYSQL_ROW master_row= NULL;
2533   int ret= 0;
2534   char query_buf[]= "SELECT @@GLOBAL.SERVER_UUID";
2535 
2536   DBUG_EXECUTE_IF("dbug.return_null_MASTER_UUID",
2537                   {
2538                     mi->master_uuid[0]= 0;
2539                     return 0;
2540                   };);
2541 
2542   DBUG_EXECUTE_IF("dbug.before_get_MASTER_UUID",
2543                   {
2544                     const char act[]= "now wait_for signal.get_master_uuid";
2545                     DBUG_ASSERT(opt_debug_sync_timeout > 0);
2546                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
2547                                                        STRING_WITH_LEN(act)));
2548                   };);
2549 
2550   DBUG_EXECUTE_IF("dbug.simulate_busy_io",
2551                   {
2552                     const char act[]= "now signal Reached wait_for signal.got_stop_slave";
2553                     DBUG_ASSERT(opt_debug_sync_timeout > 0);
2554                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
2555                                                        STRING_WITH_LEN(act)));
2556                   };);
2557 #ifndef DBUG_OFF
2558   DBUG_EXECUTE_IF("dbug.simulate_no_such_var_server_uuid",
2559 		  {
2560 		    query_buf[strlen(query_buf) - 1]= '_'; // currupt the last char
2561 		  });
2562 #endif
2563   if (!mysql_real_query(mysql, STRING_WITH_LEN(query_buf)) &&
2564       (master_res= mysql_store_result(mysql)) &&
2565       (master_row= mysql_fetch_row(master_res)))
2566   {
2567     if (!strcmp(::server_uuid, master_row[0]) &&
2568         !mi->rli->replicate_same_server_id)
2569     {
2570       errmsg= "The slave I/O thread stops because master and slave have equal "
2571               "MySQL server UUIDs; these UUIDs must be different for "
2572               "replication to work.";
2573       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
2574                  errmsg);
2575       // Fatal error
2576       ret= 1;
2577     }
2578     else
2579     {
2580       if (mi->master_uuid[0] != 0 && strcmp(mi->master_uuid, master_row[0]))
2581         sql_print_warning("The master's UUID has changed, although this should"
2582                           " not happen unless you have changed it manually."
2583                           " The old UUID was %s.",
2584                           mi->master_uuid);
2585       strncpy(mi->master_uuid, master_row[0], UUID_LENGTH);
2586       mi->master_uuid[UUID_LENGTH]= 0;
2587     }
2588   }
2589   else if (mysql_errno(mysql) != ER_UNKNOWN_SYSTEM_VARIABLE)
2590   {
2591     if (is_network_error(mysql_errno(mysql)))
2592     {
2593       mi->report(WARNING_LEVEL, mysql_errno(mysql),
2594                  "Get master SERVER_UUID failed with error: %s",
2595                  mysql_error(mysql));
2596       ret= 2;
2597     }
2598     else
2599     {
2600       /* Fatal error */
2601       errmsg= "The slave I/O thread stops because a fatal error is encountered "
2602         "when it tries to get the value of SERVER_UUID variable from master.";
2603       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
2604                  errmsg);
2605       ret= 1;
2606     }
2607   }
2608   else
2609   {
2610     mi->master_uuid[0]= 0;
2611     mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2612                "Unknown system variable 'SERVER_UUID' on master. "
2613                "A probable cause is that the variable is not supported on the "
2614                "master (version: %s), even though it is on the slave (version: %s)",
2615                mysql->server_version, server_version);
2616   }
2617 
2618   if (master_res)
2619     mysql_free_result(master_res);
2620   return ret;
2621 }
2622 
2623 
2624 /**
2625   Determine, case-sensitively, if short_string is equal to
2626   long_string, or a true prefix of long_string, or not a prefix.
2627 
2628   @retval 0 short_string is not a prefix of long_string.
2629   @retval 1 short_string is a true prefix of long_string (not equal).
2630   @retval 2 short_string is equal to long_string.
2631 */
is_str_prefix_case(const char * short_string,const char * long_string)2632 static int is_str_prefix_case(const char *short_string, const char *long_string)
2633 {
2634   int i;
2635   for (i= 0; short_string[i]; i++)
2636     if (my_toupper(system_charset_info, short_string[i]) !=
2637         my_toupper(system_charset_info, long_string[i]))
2638       return 0;
2639   return long_string[i] ? 1 : 2;
2640 }
2641 
2642 /*
2643   Note that we rely on the master's version (3.23, 4.0.14 etc) instead of
2644   relying on the binlog's version. This is not perfect: imagine an upgrade
2645   of the master without waiting that all slaves are in sync with the master;
2646   then a slave could be fooled about the binlog's format. This is what happens
2647   when people upgrade a 3.23 master to 4.0 without doing RESET MASTER: 4.0
2648   slaves are fooled. So we do this only to distinguish between 3.23 and more
2649   recent masters (it's too late to change things for 3.23).
2650 
2651   RETURNS
2652   0       ok
2653   1       error
2654   2       transient network problem, the caller should try to reconnect
2655 */
2656 
get_master_version_and_clock(MYSQL * mysql,Master_info * mi)2657 static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
2658 {
2659   char err_buff[MAX_SLAVE_ERRMSG];
2660   const char* errmsg= 0;
2661   int err_code= 0;
2662   int version_number=0;
2663   version_number= atoi(mysql->server_version);
2664 
2665   MYSQL_RES *master_res= 0;
2666   MYSQL_ROW master_row;
2667   DBUG_ENTER("get_master_version_and_clock");
2668 
2669   /*
2670     Free old mi_description_event (that is needed if we are in
2671     a reconnection).
2672   */
2673   DBUG_EXECUTE_IF("unrecognized_master_version",
2674                  {
2675                    version_number= 1;
2676                  };);
2677   mysql_mutex_lock(&mi->data_lock);
2678   mi->set_mi_description_event(NULL);
2679 
2680   if (!my_isdigit(&my_charset_bin,*mysql->server_version))
2681   {
2682     errmsg = "Master reported unrecognized MySQL version";
2683     err_code= ER_SLAVE_FATAL_ERROR;
2684     sprintf(err_buff, ER(err_code), errmsg);
2685   }
2686   else
2687   {
2688     /*
2689       Note the following switch will bug when we have MySQL branch 30 ;)
2690     */
2691     switch (version_number)
2692     {
2693     case 0:
2694     case 1:
2695     case 2:
2696       errmsg = "Master reported unrecognized MySQL version";
2697       err_code= ER_SLAVE_FATAL_ERROR;
2698       sprintf(err_buff, ER(err_code), errmsg);
2699       break;
2700     case 3:
2701       mi->set_mi_description_event(new
2702         Format_description_log_event(1, mysql->server_version));
2703       break;
2704     case 4:
2705       mi->set_mi_description_event(new
2706         Format_description_log_event(3, mysql->server_version));
2707       break;
2708     default:
2709       /*
2710         Master is MySQL >=5.0. Give a default Format_desc event, so that we can
2711         take the early steps (like tests for "is this a 3.23 master") which we
2712         have to take before we receive the real master's Format_desc which will
2713         override this one. Note that the Format_desc we create below is garbage
2714         (it has the format of the *slave*); it's only good to help know if the
2715         master is 3.23, 4.0, etc.
2716       */
2717       mi->set_mi_description_event(new
2718         Format_description_log_event(4, mysql->server_version));
2719       break;
2720     }
2721   }
2722 
2723   /*
2724      This does not mean that a 5.0 slave will be able to read a 5.5 master; but
2725      as we don't know yet, we don't want to forbid this for now. If a 5.0 slave
2726      can't read a 5.5 master, this will show up when the slave can't read some
2727      events sent by the master, and there will be error messages.
2728   */
2729 
2730   if (errmsg)
2731   {
2732     /* unlock the mutex on master info structure */
2733     mysql_mutex_unlock(&mi->data_lock);
2734     goto err;
2735   }
2736 
2737   /* as we are here, we tried to allocate the event */
2738   if (mi->get_mi_description_event() == NULL)
2739   {
2740     mysql_mutex_unlock(&mi->data_lock);
2741     errmsg= "default Format_description_log_event";
2742     err_code= ER_SLAVE_CREATE_EVENT_FAILURE;
2743     sprintf(err_buff, ER(err_code), errmsg);
2744     goto err;
2745   }
2746 
2747   if (mi->get_mi_description_event()->binlog_version < 4 &&
2748       opt_slave_sql_verify_checksum)
2749   {
2750     sql_print_warning("Found a master with MySQL server version older than "
2751                       "5.0. With checksums enabled on the slave, replication "
2752                       "might not work correctly. To ensure correct "
2753                       "replication, restart the slave server with "
2754                       "--slave_sql_verify_checksum=0.");
2755   }
2756   /*
2757     FD_q's (A) is set initially from RL's (A): FD_q.(A) := RL.(A).
2758     It's necessary to adjust FD_q.(A) at this point because in the following
2759     course FD_q is going to be dumped to RL.
2760     Generally FD_q is derived from a received FD_m (roughly FD_q := FD_m)
2761     in queue_event and the master's (A) is installed.
2762     At one step with the assignment the Relay-Log's checksum alg is set to
2763     a new value: RL.(A) := FD_q.(A). If the slave service is stopped
2764     the last time assigned RL.(A) will be passed over to the restarting
2765     service (to the current execution point).
2766     RL.A is a "codec" to verify checksum in queue_event() almost all the time
2767     the first fake Rotate event.
2768     Starting from this point IO thread will executes the following checksum
2769     warmup sequence  of actions:
2770 
2771     FD_q.A := RL.A,
2772     A_m^0 := master.@@global.binlog_checksum,
2773     {queue_event(R_f): verifies(R_f, A_m^0)},
2774     {queue_event(FD_m): verifies(FD_m, FD_m.A), dump(FD_q), rotate(RL),
2775                         FD_q := FD_m, RL.A := FD_q.A)}
2776 
2777     See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg
2778     docs lines (binlog.h).
2779     In above A_m^0 - the value of master's
2780     @@binlog_checksum determined in the upcoming handshake (stored in
2781     mi->checksum_alg_before_fd).
2782 
2783 
2784     After the warm-up sequence IO gets to "normal" checksum verification mode
2785     to use RL.A in
2786 
2787     {queue_event(E_m): verifies(E_m, RL.A)}
2788 
2789     until it has received a new FD_m.
2790   */
2791   mi->get_mi_description_event()->common_footer->checksum_alg=
2792     mi->rli->relay_log.relay_log_checksum_alg;
2793 
2794   DBUG_ASSERT(mi->get_mi_description_event()->common_footer->checksum_alg !=
2795               binary_log::BINLOG_CHECKSUM_ALG_UNDEF);
2796   DBUG_ASSERT(mi->rli->relay_log.relay_log_checksum_alg !=
2797               binary_log::BINLOG_CHECKSUM_ALG_UNDEF);
2798 
2799   mysql_mutex_unlock(&mi->data_lock);
2800 
2801   /*
2802     Compare the master and slave's clock. Do not die if master's clock is
2803     unavailable (very old master not supporting UNIX_TIMESTAMP()?).
2804   */
2805 
2806   DBUG_EXECUTE_IF("dbug.before_get_UNIX_TIMESTAMP",
2807                   {
2808                     const char act[]=
2809                       "now "
2810                       "wait_for signal.get_unix_timestamp";
2811                     DBUG_ASSERT(opt_debug_sync_timeout > 0);
2812                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
2813                                                        STRING_WITH_LEN(act)));
2814                   };);
2815 
2816   master_res= NULL;
2817   if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
2818       (master_res= mysql_store_result(mysql)) &&
2819       (master_row= mysql_fetch_row(master_res)))
2820   {
2821     mysql_mutex_lock(&mi->data_lock);
2822     mi->clock_diff_with_master=
2823       (long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
2824     DBUG_EXECUTE_IF("dbug.mts.force_clock_diff_eq_0",
2825       mi->clock_diff_with_master= 0;);
2826     mysql_mutex_unlock(&mi->data_lock);
2827   }
2828   else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2829     goto slave_killed_err;
2830   else if (is_network_error(mysql_errno(mysql)))
2831   {
2832     mi->report(WARNING_LEVEL, mysql_errno(mysql),
2833                "Get master clock failed with error: %s", mysql_error(mysql));
2834     goto network_err;
2835   }
2836   else
2837   {
2838     mysql_mutex_lock(&mi->data_lock);
2839     mi->clock_diff_with_master= 0; /* The "most sensible" value */
2840     mysql_mutex_unlock(&mi->data_lock);
2841     sql_print_warning("\"SELECT UNIX_TIMESTAMP()\" failed on master, "
2842                       "do not trust column Seconds_Behind_Master of SHOW "
2843                       "SLAVE STATUS. Error: %s (%d)",
2844                       mysql_error(mysql), mysql_errno(mysql));
2845   }
2846   if (master_res)
2847   {
2848     mysql_free_result(master_res);
2849     master_res= NULL;
2850   }
2851 
2852   /*
2853     Check that the master's server id and ours are different. Because if they
2854     are equal (which can result from a simple copy of master's datadir to slave,
2855     thus copying some my.cnf), replication will work but all events will be
2856     skipped.
2857     Do not die if SELECT @@SERVER_ID fails on master (very old master?).
2858     Note: we could have put a @@SERVER_ID in the previous SELECT
2859     UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters.
2860   */
2861   DBUG_EXECUTE_IF("dbug.before_get_SERVER_ID",
2862                   {
2863                     const char act[]=
2864                       "now "
2865                       "wait_for signal.get_server_id";
2866                     DBUG_ASSERT(opt_debug_sync_timeout > 0);
2867                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
2868                                                        STRING_WITH_LEN(act)));
2869                   };);
2870   master_res= NULL;
2871   master_row= NULL;
2872   DBUG_EXECUTE_IF("get_master_server_id.ER_NET_READ_INTERRUPTED",
2873                   {
2874                     DBUG_SET("+d,inject_ER_NET_READ_INTERRUPTED");
2875                     DBUG_SET("-d,get_master_server_id."
2876                              "ER_NET_READ_INTERRUPTED");
2877                   });
2878   if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.SERVER_ID")) &&
2879       (master_res= mysql_store_result(mysql)) &&
2880       (master_row= mysql_fetch_row(master_res)))
2881   {
2882     if ((::server_id == (mi->master_id= strtoul(master_row[0], 0, 10))) &&
2883         !mi->rli->replicate_same_server_id)
2884     {
2885       errmsg= "The slave I/O thread stops because master and slave have equal \
2886 MySQL server ids; these ids must be different for replication to work (or \
2887 the --replicate-same-server-id option must be used on slave but this does \
2888 not always make sense; please check the manual before using it).";
2889       err_code= ER_SLAVE_FATAL_ERROR;
2890       sprintf(err_buff, ER(err_code), errmsg);
2891       goto err;
2892     }
2893   }
2894   else if (mysql_errno(mysql) != ER_UNKNOWN_SYSTEM_VARIABLE)
2895   {
2896     if (check_io_slave_killed(mi->info_thd, mi, NULL))
2897       goto slave_killed_err;
2898     else if (is_network_error(mysql_errno(mysql)))
2899     {
2900       mi->report(WARNING_LEVEL, mysql_errno(mysql),
2901                  "Get master SERVER_ID failed with error: %s", mysql_error(mysql));
2902       goto network_err;
2903     }
2904     /* Fatal error */
2905     errmsg= "The slave I/O thread stops because a fatal error is encountered \
2906 when it try to get the value of SERVER_ID variable from master.";
2907     err_code= mysql_errno(mysql);
2908     sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2909     goto err;
2910   }
2911   else
2912   {
2913     mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2914                "Unknown system variable 'SERVER_ID' on master, \
2915 maybe it is a *VERY OLD MASTER*.");
2916   }
2917   if (master_res)
2918   {
2919     mysql_free_result(master_res);
2920     master_res= NULL;
2921   }
2922   if (mi->master_id == 0 && mi->ignore_server_ids->dynamic_ids.size() > 0)
2923   {
2924     errmsg= "Slave configured with server id filtering could not detect the master server id.";
2925     err_code= ER_SLAVE_FATAL_ERROR;
2926     sprintf(err_buff, ER(err_code), errmsg);
2927     goto err;
2928   }
2929 
2930   /*
2931     Check that the master's global character_set_server and ours are the same.
2932     Not fatal if query fails (old master?).
2933     Note that we don't check for equality of global character_set_client and
2934     collation_connection (neither do we prevent their setting in
2935     set_var.cc). That's because from what I (Guilhem) have tested, the global
2936     values of these 2 are never used (new connections don't use them).
2937     We don't test equality of global collation_database either as it's is
2938     going to be deprecated (made read-only) in 4.1 very soon.
2939     The test is only relevant if master < 5.0.3 (we'll test only if it's older
2940     than the 5 branch; < 5.0.3 was alpha...), as >= 5.0.3 master stores
2941     charset info in each binlog event.
2942     We don't do it for 3.23 because masters <3.23.50 hang on
2943     SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). So finally we
2944     test only if master is 4.x.
2945   */
2946 
2947   /* redundant with rest of code but safer against later additions */
2948   if (*mysql->server_version == '3')
2949     goto err;
2950 
2951   if (*mysql->server_version == '4')
2952   {
2953     master_res= NULL;
2954     if (!mysql_real_query(mysql,
2955                           STRING_WITH_LEN("SELECT @@GLOBAL.COLLATION_SERVER")) &&
2956         (master_res= mysql_store_result(mysql)) &&
2957         (master_row= mysql_fetch_row(master_res)))
2958     {
2959       if (strcmp(master_row[0], global_system_variables.collation_server->name))
2960       {
2961         errmsg= "The slave I/O thread stops because master and slave have \
2962 different values for the COLLATION_SERVER global variable. The values must \
2963 be equal for the Statement-format replication to work";
2964         err_code= ER_SLAVE_FATAL_ERROR;
2965         sprintf(err_buff, ER(err_code), errmsg);
2966         goto err;
2967       }
2968     }
2969     else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2970       goto slave_killed_err;
2971     else if (is_network_error(mysql_errno(mysql)))
2972     {
2973       mi->report(WARNING_LEVEL, mysql_errno(mysql),
2974                  "Get master COLLATION_SERVER failed with error: %s", mysql_error(mysql));
2975       goto network_err;
2976     }
2977     else if (mysql_errno(mysql) != ER_UNKNOWN_SYSTEM_VARIABLE)
2978     {
2979       /* Fatal error */
2980       errmsg= "The slave I/O thread stops because a fatal error is encountered \
2981 when it try to get the value of COLLATION_SERVER global variable from master.";
2982       err_code= mysql_errno(mysql);
2983       sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2984       goto err;
2985     }
2986     else
2987       mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2988                  "Unknown system variable 'COLLATION_SERVER' on master, \
2989 maybe it is a *VERY OLD MASTER*. *NOTE*: slave may experience \
2990 inconsistency if replicated data deals with collation.");
2991 
2992     if (master_res)
2993     {
2994       mysql_free_result(master_res);
2995       master_res= NULL;
2996     }
2997   }
2998 
2999   /*
3000     Perform analogous check for time zone. Theoretically we also should
3001     perform check here to verify that SYSTEM time zones are the same on
3002     slave and master, but we can't rely on value of @@system_time_zone
3003     variable (it is time zone abbreviation) since it determined at start
3004     time and so could differ for slave and master even if they are really
3005     in the same system time zone. So we are omiting this check and just
3006     relying on documentation. Also according to Monty there are many users
3007     who are using replication between servers in various time zones. Hence
3008     such check will broke everything for them. (And now everything will
3009     work for them because by default both their master and slave will have
3010     'SYSTEM' time zone).
3011     This check is only necessary for 4.x masters (and < 5.0.4 masters but
3012     those were alpha).
3013   */
3014   if (*mysql->server_version == '4')
3015   {
3016     master_res= NULL;
3017     if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) &&
3018         (master_res= mysql_store_result(mysql)) &&
3019         (master_row= mysql_fetch_row(master_res)))
3020     {
3021       if (strcmp(master_row[0],
3022                  global_system_variables.time_zone->get_name()->ptr()))
3023       {
3024         errmsg= "The slave I/O thread stops because master and slave have \
3025 different values for the TIME_ZONE global variable. The values must \
3026 be equal for the Statement-format replication to work";
3027         err_code= ER_SLAVE_FATAL_ERROR;
3028         sprintf(err_buff, ER(err_code), errmsg);
3029         goto err;
3030       }
3031     }
3032     else if (check_io_slave_killed(mi->info_thd, mi, NULL))
3033       goto slave_killed_err;
3034     else if (is_network_error(mysql_errno(mysql)))
3035     {
3036       mi->report(WARNING_LEVEL, mysql_errno(mysql),
3037                  "Get master TIME_ZONE failed with error: %s", mysql_error(mysql));
3038       goto network_err;
3039     }
3040     else
3041     {
3042       /* Fatal error */
3043       errmsg= "The slave I/O thread stops because a fatal error is encountered \
3044 when it try to get the value of TIME_ZONE global variable from master.";
3045       err_code= mysql_errno(mysql);
3046       sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
3047       goto err;
3048     }
3049     if (master_res)
3050     {
3051       mysql_free_result(master_res);
3052       master_res= NULL;
3053     }
3054   }
3055 
3056   if (mi->heartbeat_period != 0.0)
3057   {
3058     char llbuf[22];
3059     const char query_format[]= "SET @master_heartbeat_period= %s";
3060     char query[sizeof(query_format) - 2 + sizeof(llbuf)];
3061     /*
3062        the period is an ulonglong of nano-secs.
3063     */
3064     llstr((ulonglong) (mi->heartbeat_period*1000000000UL), llbuf);
3065     sprintf(query, query_format, llbuf);
3066 
3067     if (mysql_real_query(mysql, query, static_cast<ulong>(strlen(query))))
3068     {
3069       if (check_io_slave_killed(mi->info_thd, mi, NULL))
3070         goto slave_killed_err;
3071 
3072       if (is_network_error(mysql_errno(mysql)))
3073       {
3074         mi->report(WARNING_LEVEL, mysql_errno(mysql),
3075                    "SET @master_heartbeat_period to master failed with error: %s",
3076                    mysql_error(mysql));
3077         mysql_free_result(mysql_store_result(mysql));
3078         goto network_err;
3079       }
3080       else
3081       {
3082         /* Fatal error */
3083         errmsg= "The slave I/O thread stops because a fatal error is encountered "
3084           " when it tries to SET @master_heartbeat_period on master.";
3085         err_code= ER_SLAVE_FATAL_ERROR;
3086         sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
3087         mysql_free_result(mysql_store_result(mysql));
3088         goto err;
3089       }
3090     }
3091     mysql_free_result(mysql_store_result(mysql));
3092   }
3093 
3094   /*
3095     Querying if master is capable to checksum and notifying it about own
3096     CRC-awareness. The master's side instant value of @@global.binlog_checksum
3097     is stored in the dump thread's uservar area as well as cached locally
3098     to become known in consensus by master and slave.
3099   */
3100   if (DBUG_EVALUATE_IF("simulate_slave_unaware_checksum", 0, 1))
3101   {
3102     int rc;
3103     const char query[]= "SET @master_binlog_checksum= @@global.binlog_checksum";
3104     master_res= NULL;
3105     //initially undefined
3106     mi->checksum_alg_before_fd= binary_log::BINLOG_CHECKSUM_ALG_UNDEF;
3107     /*
3108       @c checksum_alg_before_fd is queried from master in this block.
3109       If master is old checksum-unaware the value stays undefined.
3110       Once the first FD will be received its alg descriptor will replace
3111       the being queried one.
3112     */
3113     rc= mysql_real_query(mysql, query, static_cast<ulong>(strlen(query)));
3114     if (rc != 0)
3115     {
3116       mi->checksum_alg_before_fd= binary_log::BINLOG_CHECKSUM_ALG_OFF;
3117       if (check_io_slave_killed(mi->info_thd, mi, NULL))
3118         goto slave_killed_err;
3119 
3120       if (mysql_errno(mysql) == ER_UNKNOWN_SYSTEM_VARIABLE)
3121       {
3122         // this is tolerable as OM -> NS is supported
3123         mi->report(WARNING_LEVEL, mysql_errno(mysql),
3124                    "Notifying master by %s failed with "
3125                    "error: %s", query, mysql_error(mysql));
3126       }
3127       else
3128       {
3129         if (is_network_error(mysql_errno(mysql)))
3130         {
3131           mi->report(WARNING_LEVEL, mysql_errno(mysql),
3132                      "Notifying master by %s failed with "
3133                      "error: %s", query, mysql_error(mysql));
3134           mysql_free_result(mysql_store_result(mysql));
3135           goto network_err;
3136         }
3137         else
3138         {
3139           errmsg= "The slave I/O thread stops because a fatal error is encountered "
3140             "when it tried to SET @master_binlog_checksum on master.";
3141           err_code= ER_SLAVE_FATAL_ERROR;
3142           sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
3143           mysql_free_result(mysql_store_result(mysql));
3144           goto err;
3145         }
3146       }
3147     }
3148     else
3149     {
3150       mysql_free_result(mysql_store_result(mysql));
3151       if (!mysql_real_query(mysql,
3152                             STRING_WITH_LEN("SELECT @master_binlog_checksum")) &&
3153           (master_res= mysql_store_result(mysql)) &&
3154           (master_row= mysql_fetch_row(master_res)) &&
3155           (master_row[0] != NULL))
3156       {
3157         mi->checksum_alg_before_fd= static_cast<enum_binlog_checksum_alg>
3158           (find_type(master_row[0], &binlog_checksum_typelib, 1) - 1);
3159 
3160        DBUG_EXECUTE_IF("undefined_algorithm_on_slave",
3161         mi->checksum_alg_before_fd = binary_log::BINLOG_CHECKSUM_ALG_UNDEF;);
3162        if(mi->checksum_alg_before_fd == binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
3163        {
3164          errmsg= "The slave I/O thread was stopped because a fatal error is encountered "
3165                  "The checksum algorithm used by master is unknown to slave.";
3166          err_code= ER_SLAVE_FATAL_ERROR;
3167          sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
3168          mysql_free_result(mysql_store_result(mysql));
3169          goto err;
3170        }
3171 
3172         // valid outcome is either of
3173         DBUG_ASSERT(mi->checksum_alg_before_fd ==
3174                     binary_log::BINLOG_CHECKSUM_ALG_OFF ||
3175                     mi->checksum_alg_before_fd ==
3176                     binary_log::BINLOG_CHECKSUM_ALG_CRC32);
3177       }
3178       else if (check_io_slave_killed(mi->info_thd, mi, NULL))
3179         goto slave_killed_err;
3180       else if (is_network_error(mysql_errno(mysql)))
3181       {
3182         mi->report(WARNING_LEVEL, mysql_errno(mysql),
3183                    "Get master BINLOG_CHECKSUM failed with error: %s", mysql_error(mysql));
3184         goto network_err;
3185       }
3186       else
3187       {
3188         errmsg= "The slave I/O thread stops because a fatal error is encountered "
3189           "when it tried to SELECT @master_binlog_checksum.";
3190         err_code= ER_SLAVE_FATAL_ERROR;
3191         sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
3192         mysql_free_result(mysql_store_result(mysql));
3193         goto err;
3194       }
3195     }
3196     if (master_res)
3197     {
3198       mysql_free_result(master_res);
3199       master_res= NULL;
3200     }
3201   }
3202   else
3203     mi->checksum_alg_before_fd= binary_log::BINLOG_CHECKSUM_ALG_OFF;
3204 
3205   if (DBUG_EVALUATE_IF("simulate_slave_unaware_gtid", 0, 1))
3206   {
3207     enum_gtid_mode master_gtid_mode= GTID_MODE_OFF;
3208     enum_gtid_mode slave_gtid_mode= get_gtid_mode(GTID_MODE_LOCK_NONE);
3209     switch (io_thread_init_command(mi, "SELECT @@GLOBAL.GTID_MODE",
3210                                    ER_UNKNOWN_SYSTEM_VARIABLE,
3211                                    &master_res, &master_row))
3212     {
3213     case COMMAND_STATUS_ERROR:
3214       DBUG_RETURN(2);
3215     case COMMAND_STATUS_ALLOWED_ERROR:
3216       // master is old and does not have @@GLOBAL.GTID_MODE
3217       master_gtid_mode= GTID_MODE_OFF;
3218       break;
3219     case COMMAND_STATUS_OK:
3220     {
3221       bool error= false;
3222       const char *master_gtid_mode_string= master_row[0];
3223       DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_on_something",
3224                       { master_gtid_mode_string= "on_something"; });
3225       DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_off_something",
3226                       { master_gtid_mode_string= "off_something"; });
3227       DBUG_EXECUTE_IF("simulate_master_has_unknown_gtid_mode",
3228                       { master_gtid_mode_string= "Krakel Spektakel"; });
3229       master_gtid_mode= get_gtid_mode(master_gtid_mode_string, &error);
3230       if (error)
3231       {
3232         // For potential future compatibility, allow unknown
3233         // GTID_MODEs that begin with ON/OFF (treating them as ON/OFF
3234         // respectively).
3235         enum_gtid_mode mode= GTID_MODE_OFF;
3236         for (int i= 0; i < 2; i++)
3237         {
3238           switch (is_str_prefix_case(get_gtid_mode_string(mode),
3239                                      master_gtid_mode_string))
3240           {
3241           case 0: // is not a prefix; continue loop
3242             break;
3243           case 1: // is a true prefix, i.e. not equal
3244             mi->report(WARNING_LEVEL, ER_UNKNOWN_ERROR,
3245                        "The master uses an unknown GTID_MODE '%s'. "
3246                        "Treating it as '%s'.",
3247                        master_gtid_mode_string,
3248                        get_gtid_mode_string(mode));
3249             // fall through
3250           case 2: // is equal
3251             error= false;
3252             master_gtid_mode= mode;
3253             break;
3254           }
3255           mode= GTID_MODE_ON;
3256         }
3257       }
3258       if (error)
3259       {
3260         mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3261                    "The slave IO thread stops because the master has "
3262                    "an unknown @@GLOBAL.GTID_MODE '%s'.",
3263                    master_gtid_mode_string);
3264         mysql_free_result(master_res);
3265         DBUG_RETURN(1);
3266       }
3267       mysql_free_result(master_res);
3268       break;
3269     }
3270     }
3271     if ((slave_gtid_mode == GTID_MODE_OFF &&
3272          master_gtid_mode >= GTID_MODE_ON_PERMISSIVE) ||
3273         (slave_gtid_mode == GTID_MODE_ON &&
3274          master_gtid_mode <= GTID_MODE_OFF_PERMISSIVE))
3275     {
3276       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3277                  "The replication receiver thread cannot start because "
3278                  "the master has GTID_MODE = %.192s and this server has "
3279                  "GTID_MODE = %.192s.",
3280                  get_gtid_mode_string(master_gtid_mode),
3281                  get_gtid_mode_string(slave_gtid_mode));
3282       DBUG_RETURN(1);
3283     }
3284     if (mi->is_auto_position() && master_gtid_mode != GTID_MODE_ON)
3285     {
3286       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3287                  "The replication receiver thread cannot start in "
3288                  "AUTO_POSITION mode: the master has GTID_MODE = %.192s "
3289                  "instead of ON.",
3290                  get_gtid_mode_string(master_gtid_mode));
3291       DBUG_RETURN(1);
3292     }
3293   }
3294 
3295 err:
3296   if (errmsg)
3297   {
3298     if (master_res)
3299       mysql_free_result(master_res);
3300     DBUG_ASSERT(err_code != 0);
3301     mi->report(ERROR_LEVEL, err_code, "%s", err_buff);
3302     DBUG_RETURN(1);
3303   }
3304 
3305   DBUG_RETURN(0);
3306 
3307 network_err:
3308   if (master_res)
3309     mysql_free_result(master_res);
3310   DBUG_RETURN(2);
3311 
3312 slave_killed_err:
3313   if (master_res)
3314     mysql_free_result(master_res);
3315   DBUG_RETURN(2);
3316 }
3317 
wait_for_relay_log_space(Relay_log_info * rli)3318 static bool wait_for_relay_log_space(Relay_log_info* rli)
3319 {
3320   bool slave_killed=0;
3321   Master_info* mi = rli->mi;
3322   PSI_stage_info old_stage;
3323   THD* thd = mi->info_thd;
3324   DBUG_ENTER("wait_for_relay_log_space");
3325 
3326   mysql_mutex_lock(&rli->log_space_lock);
3327   thd->ENTER_COND(&rli->log_space_cond,
3328                   &rli->log_space_lock,
3329                   &stage_waiting_for_relay_log_space,
3330                   &old_stage);
3331   while (rli->log_space_limit < rli->log_space_total &&
3332          !(slave_killed=io_slave_killed(thd,mi)) &&
3333          !rli->ignore_log_space_limit)
3334     mysql_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
3335 
3336   /*
3337     Makes the IO thread read only one event at a time
3338     until the SQL thread is able to purge the relay
3339     logs, freeing some space.
3340 
3341     Therefore, once the SQL thread processes this next
3342     event, it goes to sleep (no more events in the queue),
3343     sets ignore_log_space_limit=true and wakes the IO thread.
3344     However, this event may have been enough already for
3345     the SQL thread to purge some log files, freeing
3346     rli->log_space_total .
3347 
3348     This guarantees that the SQL and IO thread move
3349     forward only one event at a time (to avoid deadlocks),
3350     when the relay space limit is reached. It also
3351     guarantees that when the SQL thread is prepared to
3352     rotate (to be able to purge some logs), the IO thread
3353     will know about it and will rotate.
3354 
3355     NOTE: The ignore_log_space_limit is only set when the SQL
3356           thread sleeps waiting for events.
3357 
3358    */
3359   if (rli->ignore_log_space_limit)
3360   {
3361 #ifndef DBUG_OFF
3362     {
3363       char llbuf1[22], llbuf2[22];
3364       DBUG_PRINT("info", ("log_space_limit=%s "
3365                           "log_space_total=%s "
3366                           "ignore_log_space_limit=%d "
3367                           "sql_force_rotate_relay=%d",
3368                         llstr(rli->log_space_limit,llbuf1),
3369                         llstr(rli->log_space_total,llbuf2),
3370                         (int) rli->ignore_log_space_limit,
3371                         (int) rli->sql_force_rotate_relay));
3372     }
3373 #endif
3374     if (rli->sql_force_rotate_relay)
3375     {
3376       mysql_mutex_lock(&mi->data_lock);
3377       rotate_relay_log(mi, false/*need_log_space_lock=false*/);
3378       mysql_mutex_unlock(&mi->data_lock);
3379       rli->sql_force_rotate_relay= false;
3380     }
3381 
3382     rli->ignore_log_space_limit= false;
3383   }
3384 
3385   mysql_mutex_unlock(&rli->log_space_lock);
3386   thd->EXIT_COND(&old_stage);
3387   DBUG_RETURN(slave_killed);
3388 }
3389 
3390 
3391 /*
3392   Builds a Rotate from the ignored events' info and writes it to relay log.
3393 
3394   The caller must hold mi->data_lock before invoking this function.
3395 
3396   @param thd pointer to I/O Thread's Thd.
3397   @param mi  point to I/O Thread metadata class.
3398   @param force_flush_mi_info when true, do not respect sync period and flush
3399                              information.
3400                              when false, flush will only happen if it is time to
3401                              flush.
3402 
3403   @return 0 if everything went fine, 1 otherwise.
3404 */
write_ignored_events_info_to_relay_log(THD * thd,Master_info * mi,bool force_flush_mi_info)3405 static int write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi,
3406                                                   bool force_flush_mi_info)
3407 {
3408   Relay_log_info *rli= mi->rli;
3409   mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
3410   int error= 0;
3411   DBUG_ENTER("write_ignored_events_info_to_relay_log");
3412 
3413   DBUG_ASSERT(thd == mi->info_thd);
3414   mysql_mutex_assert_owner(&mi->data_lock);
3415   mysql_mutex_lock(log_lock);
3416   if (rli->ign_master_log_name_end[0])
3417   {
3418     DBUG_PRINT("info",("writing a Rotate event to track down ignored events"));
3419     Rotate_log_event *ev= new Rotate_log_event(rli->ign_master_log_name_end,
3420                                                0, rli->ign_master_log_pos_end,
3421                                                Rotate_log_event::DUP_NAME);
3422     if (mi->get_mi_description_event() != NULL)
3423       ev->common_footer->checksum_alg=
3424                    mi->get_mi_description_event()->common_footer->checksum_alg;
3425 
3426     rli->ign_master_log_name_end[0]= 0;
3427     /* can unlock before writing as slave SQL thd will soon see our Rotate */
3428     mysql_mutex_unlock(log_lock);
3429     if (likely((bool)ev))
3430     {
3431       ev->server_id= 0; // don't be ignored by slave SQL thread
3432       if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
3433         mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
3434                    ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
3435                    "failed to write a Rotate event"
3436                    " to the relay log, SHOW SLAVE STATUS may be"
3437                    " inaccurate");
3438       rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
3439       if (flush_master_info(mi, force_flush_mi_info))
3440       {
3441         error= 1;
3442         sql_print_error("Failed to flush master info file.");
3443       }
3444       delete ev;
3445     }
3446     else
3447     {
3448       error= 1;
3449       mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE,
3450                  ER(ER_SLAVE_CREATE_EVENT_FAILURE),
3451                  "Rotate_event (out of memory?),"
3452                  " SHOW SLAVE STATUS may be inaccurate");
3453     }
3454   }
3455   else
3456     mysql_mutex_unlock(log_lock);
3457 
3458   DBUG_RETURN(error);
3459 }
3460 
3461 
register_slave_on_master(MYSQL * mysql,Master_info * mi,bool * suppress_warnings)3462 int register_slave_on_master(MYSQL* mysql, Master_info *mi,
3463                              bool *suppress_warnings)
3464 {
3465   uchar buf[1024], *pos= buf;
3466   size_t report_host_len=0, report_user_len=0, report_password_len=0;
3467   DBUG_ENTER("register_slave_on_master");
3468 
3469   *suppress_warnings= FALSE;
3470   if (report_host)
3471     report_host_len= strlen(report_host);
3472   if (report_host_len > HOSTNAME_LENGTH)
3473   {
3474     sql_print_warning("The length of report_host is %zu. "
3475                       "It is larger than the max length(%d), so this "
3476                       "slave cannot be registered to the master%s.",
3477                       report_host_len, HOSTNAME_LENGTH,
3478                       mi->get_for_channel_str());
3479     DBUG_RETURN(0);
3480   }
3481 
3482   if (report_user)
3483     report_user_len= strlen(report_user);
3484   if (report_user_len > USERNAME_LENGTH)
3485   {
3486     sql_print_warning("The length of report_user is %zu. "
3487                       "It is larger than the max length(%d), so this "
3488                       "slave cannot be registered to the master%s.",
3489                       report_user_len, USERNAME_LENGTH, mi->get_for_channel_str());
3490     DBUG_RETURN(0);
3491   }
3492 
3493   if (report_password)
3494     report_password_len= strlen(report_password);
3495   if (report_password_len > MAX_PASSWORD_LENGTH)
3496   {
3497     sql_print_warning("The length of report_password is %zu. "
3498                       "It is larger than the max length(%d), so this "
3499                       "slave cannot be registered to the master%s.",
3500                       report_password_len, MAX_PASSWORD_LENGTH,
3501                       mi->get_for_channel_str());
3502     DBUG_RETURN(0);
3503   }
3504 
3505   int4store(pos, server_id); pos+= 4;
3506   pos= net_store_data(pos, (uchar*) report_host, report_host_len);
3507   pos= net_store_data(pos, (uchar*) report_user, report_user_len);
3508   pos= net_store_data(pos, (uchar*) report_password, report_password_len);
3509   int2store(pos, (uint16) report_port); pos+= 2;
3510   /*
3511     Fake rpl_recovery_rank, which was removed in BUG#13963,
3512     so that this server can register itself on old servers,
3513     see BUG#49259.
3514    */
3515   int4store(pos, /* rpl_recovery_rank */ 0);    pos+= 4;
3516   /* The master will fill in master_id */
3517   int4store(pos, 0);                    pos+= 4;
3518 
3519   if (simple_command(mysql, COM_REGISTER_SLAVE, buf, (size_t) (pos- buf), 0))
3520   {
3521     if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
3522     {
3523       *suppress_warnings= TRUE;                 // Suppress reconnect warning
3524     }
3525     else if (!check_io_slave_killed(mi->info_thd, mi, NULL))
3526     {
3527       char buf[256];
3528       my_snprintf(buf, sizeof(buf), "%s (Errno: %d)", mysql_error(mysql),
3529                   mysql_errno(mysql));
3530       mi->report(ERROR_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
3531                  ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_REGISTER_SLAVE", buf);
3532     }
3533     DBUG_RETURN(1);
3534   }
3535   DBUG_EXECUTE_IF("simulate_register_slave_killed", {
3536     mi->abort_slave = 1;
3537     DBUG_RETURN(1);
3538   };);
3539   DBUG_RETURN(0);
3540 }
3541 
3542 
3543 /**
3544     Function that fills the metadata required for SHOW SLAVE STATUS.
3545     This function shall be used in two cases:
3546      1) SHOW SLAVE STATUS FOR ALL CHANNELS
3547      2) SHOW SLAVE STATUS for a channel
3548 
3549      @param[in,out]  field_list        field_list to fill the metadata
3550      @param[in]      io_gtid_set_size  the size to be allocated to store
3551                                        the retrieved gtid set
3552      @param[in]      sql_gtid_set_size the size to be allocated to store
3553                                        the executed gtid set
3554 
3555      @TODO: return a bool after adding catching the exceptions to the
3556             push_back() methods for field_list
3557 */
3558 
show_slave_status_metadata(List<Item> & field_list,int io_gtid_set_size,int sql_gtid_set_size)3559 void show_slave_status_metadata(List<Item> &field_list,
3560                                 int io_gtid_set_size, int sql_gtid_set_size)
3561 {
3562 
3563   field_list.push_back(new Item_empty_string("Slave_IO_State", 14));
3564   field_list.push_back(new Item_empty_string("Master_Host",
3565                                              HOSTNAME_LENGTH+1));
3566   field_list.push_back(new Item_empty_string("Master_User",
3567                                              USERNAME_LENGTH+1));
3568   field_list.push_back(new Item_return_int("Master_Port", 7,MYSQL_TYPE_LONG));
3569   field_list.push_back(new Item_return_int("Connect_Retry", 10,
3570                                            MYSQL_TYPE_LONG));
3571   field_list.push_back(new Item_empty_string("Master_Log_File", FN_REFLEN));
3572   field_list.push_back(new Item_return_int("Read_Master_Log_Pos", 10,
3573                                            MYSQL_TYPE_LONGLONG));
3574   field_list.push_back(new Item_empty_string("Relay_Log_File", FN_REFLEN));
3575   field_list.push_back(new Item_return_int("Relay_Log_Pos", 10,
3576                                            MYSQL_TYPE_LONGLONG));
3577   field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
3578                                              FN_REFLEN));
3579   field_list.push_back(new Item_empty_string("Slave_IO_Running", 3));
3580   field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3));
3581   field_list.push_back(new Item_empty_string("Replicate_Do_DB", 20));
3582   field_list.push_back(new Item_empty_string("Replicate_Ignore_DB", 20));
3583   field_list.push_back(new Item_empty_string("Replicate_Do_Table", 20));
3584   field_list.push_back(new Item_empty_string("Replicate_Ignore_Table", 23));
3585   field_list.push_back(new Item_empty_string("Replicate_Wild_Do_Table", 24));
3586   field_list.push_back(new Item_empty_string("Replicate_Wild_Ignore_Table",
3587                                              28));
3588   field_list.push_back(new Item_return_int("Last_Errno", 4, MYSQL_TYPE_LONG));
3589   field_list.push_back(new Item_empty_string("Last_Error", 20));
3590   field_list.push_back(new Item_return_int("Skip_Counter", 10,
3591                                            MYSQL_TYPE_LONG));
3592   field_list.push_back(new Item_return_int("Exec_Master_Log_Pos", 10,
3593                                            MYSQL_TYPE_LONGLONG));
3594   field_list.push_back(new Item_return_int("Relay_Log_Space", 10,
3595                                            MYSQL_TYPE_LONGLONG));
3596   field_list.push_back(new Item_empty_string("Until_Condition", 6));
3597   field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN));
3598   field_list.push_back(new Item_return_int("Until_Log_Pos", 10,
3599                                            MYSQL_TYPE_LONGLONG));
3600   field_list.push_back(new Item_empty_string("Master_SSL_Allowed", 7));
3601   field_list.push_back(new Item_empty_string("Master_SSL_CA_File", FN_REFLEN));
3602   field_list.push_back(new Item_empty_string("Master_SSL_CA_Path", FN_REFLEN));
3603   field_list.push_back(new Item_empty_string("Master_SSL_Cert", FN_REFLEN));
3604   field_list.push_back(new Item_empty_string("Master_SSL_Cipher", FN_REFLEN));
3605   field_list.push_back(new Item_empty_string("Master_SSL_Key", FN_REFLEN));
3606   field_list.push_back(new Item_return_int("Seconds_Behind_Master", 10,
3607                                            MYSQL_TYPE_LONGLONG));
3608   field_list.push_back(new Item_empty_string("Master_SSL_Verify_Server_Cert",
3609                                              3));
3610   field_list.push_back(new Item_return_int("Last_IO_Errno", 4, MYSQL_TYPE_LONG));
3611   field_list.push_back(new Item_empty_string("Last_IO_Error", 20));
3612   field_list.push_back(new Item_return_int("Last_SQL_Errno", 4, MYSQL_TYPE_LONG));
3613   field_list.push_back(new Item_empty_string("Last_SQL_Error", 20));
3614   field_list.push_back(new Item_empty_string("Replicate_Ignore_Server_Ids",
3615                                              FN_REFLEN));
3616   field_list.push_back(new Item_return_int("Master_Server_Id", sizeof(ulong),
3617                                            MYSQL_TYPE_LONG));
3618   field_list.push_back(new Item_empty_string("Master_UUID", UUID_LENGTH));
3619   field_list.push_back(new Item_empty_string("Master_Info_File",
3620                                              2 * FN_REFLEN));
3621   field_list.push_back(new Item_return_int("SQL_Delay", 10, MYSQL_TYPE_LONG));
3622   field_list.push_back(new Item_return_int("SQL_Remaining_Delay", 8, MYSQL_TYPE_LONG));
3623   field_list.push_back(new Item_empty_string("Slave_SQL_Running_State", 20));
3624   field_list.push_back(new Item_return_int("Master_Retry_Count", 10,
3625                                            MYSQL_TYPE_LONGLONG));
3626   field_list.push_back(new Item_empty_string("Master_Bind", HOSTNAME_LENGTH+1));
3627   field_list.push_back(new Item_empty_string("Last_IO_Error_Timestamp", 20));
3628   field_list.push_back(new Item_empty_string("Last_SQL_Error_Timestamp", 20));
3629   field_list.push_back(new Item_empty_string("Master_SSL_Crl", FN_REFLEN));
3630   field_list.push_back(new Item_empty_string("Master_SSL_Crlpath", FN_REFLEN));
3631   field_list.push_back(new Item_empty_string("Retrieved_Gtid_Set",
3632                                              io_gtid_set_size));
3633   field_list.push_back(new Item_empty_string("Executed_Gtid_Set",
3634                                              sql_gtid_set_size));
3635   field_list.push_back(new Item_return_int("Auto_Position", sizeof(ulong),
3636                                            MYSQL_TYPE_LONG));
3637   field_list.push_back(new Item_empty_string("Replicate_Rewrite_DB", 24));
3638   field_list.push_back(new Item_empty_string("Channel_Name", CHANNEL_NAME_LENGTH));
3639   field_list.push_back(new Item_empty_string("Master_TLS_Version", FN_REFLEN));
3640 
3641 }
3642 
3643 
3644 /**
3645     Send the data to the client of a Master_info during show_slave_status()
3646     This function has to be called after calling show_slave_status_metadata().
3647     Just before sending the data, thd->get_protocol() is prepared to (re)send;
3648 
3649     @param[in]     thd         client thread
3650     @param[in]     mi          the master info. In the case of multisource
3651                                replication, this master info corresponds to a
3652                                 channel.
3653 
3654     @param[in]     io_gtid_set_buffer    buffer related to Retrieved GTID set
3655                                           for each channel.
3656     @param[in]     sql_gtid_set_buffer   buffer related to Executed GTID set
3657                                            for each channel.
3658     @return
3659      @retval        0     success
3660      @retval        1     Error
3661 */
3662 
show_slave_status_send_data(THD * thd,Master_info * mi,char * io_gtid_set_buffer,char * sql_gtid_set_buffer)3663 bool show_slave_status_send_data(THD *thd, Master_info *mi,
3664                                  char* io_gtid_set_buffer,
3665                                  char* sql_gtid_set_buffer)
3666 {
3667   DBUG_ENTER("show_slave_status_send_data");
3668 
3669   Protocol *protocol = thd->get_protocol();
3670   char* slave_sql_running_state= NULL;
3671 
3672   DBUG_PRINT("info",("host is set: '%s'", mi->host));
3673 
3674   protocol->start_row();
3675 
3676   /*
3677     slave_running can be accessed without run_lock but not other
3678     non-volatile members like mi->info_thd or rli->info_thd, for
3679     them either info_thd_lock or run_lock hold is required.
3680   */
3681   mysql_mutex_lock(&mi->info_thd_lock);
3682   protocol->store(mi->info_thd ? mi->info_thd->get_proc_info() : "",
3683                   &my_charset_bin);
3684   mysql_mutex_unlock(&mi->info_thd_lock);
3685 
3686   mysql_mutex_lock(&mi->rli->info_thd_lock);
3687   slave_sql_running_state= const_cast<char *>(mi->rli->info_thd ? mi->rli->info_thd->get_proc_info() : "");
3688   mysql_mutex_unlock(&mi->rli->info_thd_lock);
3689 
3690   mysql_mutex_lock(&mi->data_lock);
3691   mysql_mutex_lock(&mi->rli->data_lock);
3692   mysql_mutex_lock(&mi->err_lock);
3693   mysql_mutex_lock(&mi->rli->err_lock);
3694 
3695   DEBUG_SYNC(thd, "wait_after_lock_active_mi_and_rli_data_lock_is_acquired");
3696   protocol->store(mi->host, &my_charset_bin);
3697   protocol->store(mi->get_user(), &my_charset_bin);
3698   protocol->store((uint32) mi->port);
3699   protocol->store((uint32) mi->connect_retry);
3700   protocol->store(mi->get_master_log_name(), &my_charset_bin);
3701   protocol->store((ulonglong) mi->get_master_log_pos());
3702   protocol->store(mi->rli->get_group_relay_log_name() +
3703                   dirname_length(mi->rli->get_group_relay_log_name()),
3704                   &my_charset_bin);
3705   protocol->store((ulonglong) mi->rli->get_group_relay_log_pos());
3706   protocol->store(mi->rli->get_group_master_log_name(), &my_charset_bin);
3707   protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
3708                   "Yes" : (mi->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT ?
3709                            "Connecting" : "No"), &my_charset_bin);
3710   protocol->store(mi->rli->slave_running ? "Yes":"No", &my_charset_bin);
3711   store(protocol, rpl_filter->get_do_db());
3712   store(protocol, rpl_filter->get_ignore_db());
3713 
3714   char buf[256];
3715   String tmp(buf, sizeof(buf), &my_charset_bin);
3716   rpl_filter->get_do_table(&tmp);
3717   protocol->store(&tmp);
3718   rpl_filter->get_ignore_table(&tmp);
3719   protocol->store(&tmp);
3720   rpl_filter->get_wild_do_table(&tmp);
3721   protocol->store(&tmp);
3722   rpl_filter->get_wild_ignore_table(&tmp);
3723   protocol->store(&tmp);
3724 
3725   protocol->store(mi->rli->last_error().number);
3726   protocol->store(mi->rli->last_error().message, &my_charset_bin);
3727   protocol->store((uint32) mi->rli->slave_skip_counter);
3728   protocol->store((ulonglong) mi->rli->get_group_master_log_pos());
3729   protocol->store((ulonglong) mi->rli->log_space_total);
3730 
3731 
3732   const char *until_type= "";
3733 
3734   switch (mi->rli->until_condition)
3735   {
3736   case Relay_log_info::UNTIL_NONE:
3737     until_type= "None";
3738     break;
3739   case Relay_log_info::UNTIL_MASTER_POS:
3740     until_type= "Master";
3741     break;
3742   case Relay_log_info::UNTIL_RELAY_POS:
3743     until_type= "Relay";
3744     break;
3745   case Relay_log_info::UNTIL_SQL_BEFORE_GTIDS:
3746     until_type= "SQL_BEFORE_GTIDS";
3747     break;
3748   case Relay_log_info::UNTIL_SQL_AFTER_GTIDS:
3749     until_type= "SQL_AFTER_GTIDS";
3750     break;
3751   case Relay_log_info::UNTIL_SQL_VIEW_ID:
3752     until_type= "SQL_VIEW_ID";
3753     break;
3754   case Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS:
3755     until_type= "SQL_AFTER_MTS_GAPS";
3756     break;
3757   case Relay_log_info::UNTIL_DONE:
3758     until_type= "DONE";
3759     break;
3760   default:
3761     DBUG_ASSERT(0);
3762   }
3763   protocol->store(until_type, &my_charset_bin);
3764   protocol->store(mi->rli->until_log_name, &my_charset_bin);
3765   protocol->store((ulonglong) mi->rli->until_log_pos);
3766 
3767 #ifdef HAVE_OPENSSL
3768   protocol->store(mi->ssl? "Yes":"No", &my_charset_bin);
3769 #else
3770   protocol->store(mi->ssl? "Ignored":"No", &my_charset_bin);
3771 #endif
3772   protocol->store(mi->ssl_ca, &my_charset_bin);
3773   protocol->store(mi->ssl_capath, &my_charset_bin);
3774   protocol->store(mi->ssl_cert, &my_charset_bin);
3775   protocol->store(mi->ssl_cipher, &my_charset_bin);
3776   protocol->store(mi->ssl_key, &my_charset_bin);
3777 
3778   /*
3779      The pseudo code to compute Seconds_Behind_Master:
3780      if (SQL thread is running)
3781      {
3782        if (SQL thread processed all the available relay log)
3783        {
3784          if (IO thread is running)
3785             print 0;
3786          else
3787             print NULL;
3788        }
3789         else
3790           compute Seconds_Behind_Master;
3791       }
3792       else
3793        print NULL;
3794   */
3795 
3796   if (mi->rli->slave_running)
3797   {
3798     /*
3799        Check if SQL thread is at the end of relay log
3800        Checking should be done using two conditions
3801        condition1: compare the log positions and
3802        condition2: compare the file names (to handle rotation case)
3803     */
3804     if ((mi->get_master_log_pos() == mi->rli->get_group_master_log_pos()) &&
3805         (!strcmp(mi->get_master_log_name(), mi->rli->get_group_master_log_name())))
3806     {
3807       if (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT)
3808         protocol->store(0LL);
3809       else
3810         protocol->store_null();
3811     }
3812     else
3813     {
3814       long time_diff= ((long)(time(0) - mi->rli->last_master_timestamp)
3815                        - mi->clock_diff_with_master);
3816       /*
3817         Apparently on some systems time_diff can be <0. Here are possible
3818         reasons related to MySQL:
3819         - the master is itself a slave of another master whose time is ahead.
3820         - somebody used an explicit SET TIMESTAMP on the master.
3821         Possible reason related to granularity-to-second of time functions
3822         (nothing to do with MySQL), which can explain a value of -1:
3823         assume the master's and slave's time are perfectly synchronized, and
3824         that at slave's connection time, when the master's timestamp is read,
3825         it is at the very end of second 1, and (a very short time later) when
3826         the slave's timestamp is read it is at the very beginning of second
3827         2. Then the recorded value for master is 1 and the recorded value for
3828         slave is 2. At SHOW SLAVE STATUS time, assume that the difference
3829         between timestamp of slave and rli->last_master_timestamp is 0
3830         (i.e. they are in the same second), then we get 0-(2-1)=-1 as a result.
3831         This confuses users, so we don't go below 0: hence the max().
3832 
3833         last_master_timestamp == 0 (an "impossible" timestamp 1970) is a
3834         special marker to say "consider we have caught up".
3835       */
3836       protocol->store((longlong)(mi->rli->last_master_timestamp ?
3837                                    max(0L, time_diff) : 0));
3838     }
3839   }
3840   else
3841   {
3842     protocol->store_null();
3843   }
3844   protocol->store(mi->ssl_verify_server_cert? "Yes":"No", &my_charset_bin);
3845 
3846   // Last_IO_Errno
3847   protocol->store(mi->last_error().number);
3848   // Last_IO_Error
3849   protocol->store(mi->last_error().message, &my_charset_bin);
3850   // Last_SQL_Errno
3851   protocol->store(mi->rli->last_error().number);
3852   // Last_SQL_Error
3853   protocol->store(mi->rli->last_error().message, &my_charset_bin);
3854   // Replicate_Ignore_Server_Ids
3855   {
3856     char buff[FN_REFLEN];
3857     ulong i, cur_len;
3858     for (i= 0, buff[0]= 0, cur_len= 0;
3859          i < mi->ignore_server_ids->dynamic_ids.size(); i++)
3860     {
3861       ulong s_id, slen;
3862       char sbuff[FN_REFLEN];
3863       s_id= mi->ignore_server_ids->dynamic_ids[i];
3864       slen= sprintf(sbuff, (i == 0 ? "%lu" : ", %lu"), s_id);
3865       if (cur_len + slen + 4 > FN_REFLEN)
3866       {
3867         /*
3868           break the loop whenever remained space could not fit
3869           ellipses on the next cycle
3870         */
3871         sprintf(buff + cur_len, "...");
3872         break;
3873       }
3874       cur_len += sprintf(buff + cur_len, "%s", sbuff);
3875     }
3876     protocol->store(buff, &my_charset_bin);
3877   }
3878   // Master_Server_id
3879   protocol->store((uint32) mi->master_id);
3880   protocol->store(mi->master_uuid, &my_charset_bin);
3881   // Master_Info_File
3882   protocol->store(mi->get_description_info(), &my_charset_bin);
3883   // SQL_Delay
3884   protocol->store((uint32) mi->rli->get_sql_delay());
3885   // SQL_Remaining_Delay
3886   if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name)
3887   {
3888     time_t t= my_time(0), sql_delay_end= mi->rli->get_sql_delay_end();
3889     protocol->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0));
3890   }
3891   else
3892     protocol->store_null();
3893   // Slave_SQL_Running_State
3894   protocol->store(slave_sql_running_state, &my_charset_bin);
3895   // Master_Retry_Count
3896   protocol->store((ulonglong) mi->retry_count);
3897   // Master_Bind
3898   protocol->store(mi->bind_addr, &my_charset_bin);
3899   // Last_IO_Error_Timestamp
3900   protocol->store(mi->last_error().timestamp, &my_charset_bin);
3901   // Last_SQL_Error_Timestamp
3902   protocol->store(mi->rli->last_error().timestamp, &my_charset_bin);
3903   // Master_Ssl_Crl
3904   protocol->store(mi->ssl_crl, &my_charset_bin);
3905   // Master_Ssl_Crlpath
3906   protocol->store(mi->ssl_crlpath, &my_charset_bin);
3907   // Retrieved_Gtid_Set
3908   protocol->store(io_gtid_set_buffer, &my_charset_bin);
3909   // Executed_Gtid_Set
3910   protocol->store(sql_gtid_set_buffer, &my_charset_bin);
3911   // Auto_Position
3912   protocol->store(mi->is_auto_position() ? 1 : 0);
3913   // Replicate_Rewrite_DB
3914   rpl_filter->get_rewrite_db(&tmp);
3915   protocol->store(&tmp);
3916   // channel_name
3917   protocol->store(mi->get_channel(), &my_charset_bin);
3918   // Master_TLS_Version
3919   protocol->store(mi->tls_version, &my_charset_bin);
3920 
3921   mysql_mutex_unlock(&mi->rli->err_lock);
3922   mysql_mutex_unlock(&mi->err_lock);
3923   mysql_mutex_unlock(&mi->rli->data_lock);
3924   mysql_mutex_unlock(&mi->data_lock);
3925 
3926   DBUG_RETURN(false);
3927 }
3928 
3929 
3930 /**
3931    Method to the show the replication status in all channels.
3932 
3933    @param[in]       thd        the client thread
3934 
3935    @return
3936      @retval        0           success
3937      @retval        1           Error
3938 
3939 */
show_slave_status(THD * thd)3940 bool show_slave_status(THD *thd)
3941 {
3942   List<Item> field_list;
3943   Protocol *protocol= thd->get_protocol();
3944   int sql_gtid_set_size= 0, io_gtid_set_size= 0;
3945   Master_info *mi= NULL;
3946   char* sql_gtid_set_buffer= NULL;
3947   char** io_gtid_set_buffer_array;
3948   /*
3949     We need the maximum size of the retrieved gtid set (i.e io_gtid_set_size).
3950     This size is needed to reserve the place in show_slave_status_metadata().
3951     So, we travel all the mi's and find out the maximum size of io_gtid_set_size
3952     and pass it through show_slave_status_metadata()
3953   */
3954   int max_io_gtid_set_size= io_gtid_set_size;
3955   uint idx;
3956   uint num_io_gtid_sets;
3957   bool ret= true;
3958 
3959   DBUG_ENTER("show_slave_status(THD)");
3960 
3961   channel_map.assert_some_lock();
3962 
3963   num_io_gtid_sets= channel_map.get_num_instances();
3964 
3965 
3966   io_gtid_set_buffer_array=
3967     (char**)my_malloc(key_memory_show_slave_status_io_gtid_set,
3968                       num_io_gtid_sets * sizeof(char*), MYF(MY_WME));
3969 
3970   if (io_gtid_set_buffer_array == NULL)
3971      DBUG_RETURN(true);
3972 
3973   global_sid_lock->wrlock();
3974 
3975   const Gtid_set *sql_gtid_set= gtid_state->get_executed_gtids();
3976   sql_gtid_set_size= sql_gtid_set->to_string(&sql_gtid_set_buffer);
3977 
3978   idx= 0;
3979   for (mi_map::iterator it= channel_map.begin(); it!=channel_map.end(); it++)
3980   {
3981     mi= it->second;
3982     /*
3983       The following statement is needed because, when mi->host[0]=0
3984       we don't alloc memory for retried_gtid_set. However, we try
3985       to free it at the end, causing a crash. To be on safeside,
3986       we initialize it to NULL, so that my_free() takes care of it.
3987     */
3988     io_gtid_set_buffer_array[idx]= NULL;
3989 
3990     if (mi != NULL && mi->host[0])
3991     {
3992       const Gtid_set*  io_gtid_set= mi->rli->get_gtid_set();
3993 
3994       /*
3995          @todo: a single memory allocation improves speed,
3996          instead of doing it for each loop
3997       */
3998 
3999       if ((io_gtid_set_size=
4000            io_gtid_set->to_string(&io_gtid_set_buffer_array[idx])) < 0)
4001       {
4002         my_eof(thd);
4003         my_free(sql_gtid_set_buffer);
4004 
4005         for (uint i= 0; i < idx -1; i++)
4006         {
4007           my_free(io_gtid_set_buffer_array[i]);
4008         }
4009         my_free(io_gtid_set_buffer_array);
4010 
4011         global_sid_lock->unlock();
4012         DBUG_RETURN(true);
4013       }
4014       else
4015         max_io_gtid_set_size= max_io_gtid_set_size > io_gtid_set_size ?
4016                               max_io_gtid_set_size : io_gtid_set_size;
4017     }
4018     idx++;
4019   }
4020   global_sid_lock->unlock();
4021 
4022 
4023   show_slave_status_metadata(field_list, max_io_gtid_set_size,
4024                              sql_gtid_set_size);
4025 
4026   if (thd->send_result_metadata(&field_list,
4027                                 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
4028   {
4029     goto err;
4030   }
4031 
4032   /* Run through each mi */
4033 
4034   idx=0;
4035   for (mi_map::iterator it= channel_map.begin(); it!=channel_map.end(); it++)
4036   {
4037     mi= it->second;
4038 
4039     if (mi != NULL && mi->host[0])
4040     {
4041       if (show_slave_status_send_data(thd, mi, io_gtid_set_buffer_array[idx],
4042                                  sql_gtid_set_buffer))
4043         goto err;
4044 
4045       if (protocol->end_row())
4046         goto err;
4047     }
4048     idx++;
4049   }
4050 
4051   ret= false;
4052 err:
4053   my_eof(thd);
4054   for (uint i= 0; i < num_io_gtid_sets; i++)
4055   {
4056     my_free(io_gtid_set_buffer_array[i]);
4057   }
4058   my_free(io_gtid_set_buffer_array);
4059   my_free(sql_gtid_set_buffer);
4060 
4061   DBUG_RETURN(ret);
4062 
4063 }
4064 
4065 
4066 /**
4067   Execute a SHOW SLAVE STATUS statement.
4068 
4069   @param thd Pointer to THD object for the client thread executing the
4070   statement.
4071 
4072   @param mi Pointer to Master_info object for the IO thread.
4073 
4074   @retval FALSE success
4075   @retval TRUE failure
4076 
4077   Currently, show slave status works for a channel too, in multisource
4078   replication. But using performance schema tables is better.
4079 
4080 */
show_slave_status(THD * thd,Master_info * mi)4081 bool show_slave_status(THD* thd, Master_info* mi)
4082 {
4083   List<Item> field_list;
4084   Protocol *protocol= thd->get_protocol();
4085   char *sql_gtid_set_buffer= NULL, *io_gtid_set_buffer= NULL;
4086   int sql_gtid_set_size= 0, io_gtid_set_size= 0;
4087   DBUG_ENTER("show_slave_status(THD, Master_info)");
4088 
4089   if (mi != NULL)
4090   {
4091     global_sid_lock->wrlock();
4092     const Gtid_set* sql_gtid_set= gtid_state->get_executed_gtids();
4093     const Gtid_set* io_gtid_set= mi->rli->get_gtid_set();
4094     if ((sql_gtid_set_size= sql_gtid_set->to_string(&sql_gtid_set_buffer)) < 0 ||
4095         (io_gtid_set_size= io_gtid_set->to_string(&io_gtid_set_buffer)) < 0)
4096     {
4097       my_eof(thd);
4098       my_free(sql_gtid_set_buffer);
4099       my_free(io_gtid_set_buffer);
4100       global_sid_lock->unlock();
4101       DBUG_RETURN(true);
4102     }
4103     global_sid_lock->unlock();
4104   }
4105 
4106   /* Fill the metadata required for show slave status. */
4107 
4108   show_slave_status_metadata(field_list, io_gtid_set_size, sql_gtid_set_size);
4109 
4110   if (thd->send_result_metadata(&field_list,
4111                                 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
4112   {
4113     my_free(sql_gtid_set_buffer);
4114     my_free(io_gtid_set_buffer);
4115     DBUG_RETURN(true);
4116   }
4117 
4118   if (mi != NULL && mi->host[0])
4119   {
4120 
4121     if (show_slave_status_send_data(thd, mi,
4122                                     io_gtid_set_buffer, sql_gtid_set_buffer))
4123       DBUG_RETURN(true);
4124 
4125     if (protocol->end_row())
4126     {
4127       my_free(sql_gtid_set_buffer);
4128       my_free(io_gtid_set_buffer);
4129       DBUG_RETURN(true);
4130     }
4131   }
4132   my_eof(thd);
4133   my_free(sql_gtid_set_buffer);
4134   my_free(io_gtid_set_buffer);
4135   DBUG_RETURN(false);
4136 }
4137 
4138 
4139 /**
4140   Entry point for SHOW SLAVE STATUS command. Function displayes
4141   the slave status for all channels or for a single channel
4142   based on the FOR CHANNEL  clause.
4143 
4144   @param[in]       thd          the client thread.
4145 
4146   @return
4147     @retval        false          ok
4148     @retval        true          not ok
4149 */
show_slave_status_cmd(THD * thd)4150 bool show_slave_status_cmd(THD *thd)
4151 {
4152   Master_info *mi= 0;
4153   LEX *lex= thd->lex;
4154   bool res;
4155 
4156   DBUG_ENTER("show_slave_status_cmd");
4157 
4158   channel_map.rdlock();
4159 
4160   if (!lex->mi.for_channel)
4161     res= show_slave_status(thd);
4162   else
4163   {
4164     /* when mi is 0, i.e mi doesn't exist, SSS will return an empty set */
4165     mi= channel_map.get_mi(lex->mi.channel);
4166 
4167     /*
4168       If the channel being used is a group replication applier channel we
4169       need to disable the SHOW SLAVE STATUS commannd as its output is not
4170       compatible with this command.
4171     */
4172     if (mi && channel_map.is_group_replication_channel_name(mi->get_channel(),
4173                                                             true))
4174     {
4175       my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
4176                "SHOW SLAVE STATUS", mi->get_channel());
4177       channel_map.unlock();
4178       DBUG_RETURN(true);
4179     }
4180 
4181     res= show_slave_status(thd, mi);
4182   }
4183 
4184   channel_map.unlock();
4185 
4186   DBUG_RETURN(res);
4187 }
4188 
4189 
set_slave_thread_options(THD * thd)4190 void set_slave_thread_options(THD* thd)
4191 {
4192   DBUG_ENTER("set_slave_thread_options");
4193   /*
4194      It's nonsense to constrain the slave threads with max_join_size; if a
4195      query succeeded on master, we HAVE to execute it. So set
4196      OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
4197      (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
4198      SELECT examining more than 4 billion rows would still fail (yes, because
4199      when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
4200      only for client threads.
4201   */
4202   ulonglong options= thd->variables.option_bits | OPTION_BIG_SELECTS;
4203   if (opt_log_slave_updates)
4204     options|= OPTION_BIN_LOG;
4205   else
4206     options&= ~OPTION_BIN_LOG;
4207   thd->variables.option_bits= options;
4208   thd->variables.completion_type= 0;
4209 
4210   /* Do not track GTIDs for slave threads to avoid performance issues. */
4211   thd->variables.session_track_gtids= OFF;
4212   thd->rpl_thd_ctx.session_gtids_ctx()
4213       .update_tracking_activeness_from_session_variable(thd);
4214 
4215   /*
4216     Set autocommit= 1 when info tables are used and autocommit == 0 to
4217     avoid trigger asserts on mysql_execute_command(THD *thd) caused by
4218     info tables updates which do not commit, like Rotate, Stop and
4219     skipped events handling.
4220   */
4221   if ((thd->variables.option_bits & OPTION_NOT_AUTOCOMMIT) &&
4222       (opt_mi_repository_id == INFO_REPOSITORY_TABLE ||
4223        opt_rli_repository_id == INFO_REPOSITORY_TABLE))
4224   {
4225     thd->variables.option_bits|= OPTION_AUTOCOMMIT;
4226     thd->variables.option_bits&= ~OPTION_NOT_AUTOCOMMIT;
4227     thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
4228   }
4229 
4230   /*
4231     Set thread InnoDB high priority.
4232   */
4233   DBUG_EXECUTE_IF("dbug_set_high_prio_sql_thread",
4234     {
4235       if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL ||
4236           thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER)
4237         thd->thd_tx_priority= 1;
4238     });
4239 
4240   DBUG_VOID_RETURN;
4241 }
4242 
set_slave_thread_default_charset(THD * thd,Relay_log_info const * rli)4243 void set_slave_thread_default_charset(THD* thd, Relay_log_info const *rli)
4244 {
4245   DBUG_ENTER("set_slave_thread_default_charset");
4246 
4247   thd->variables.character_set_client=
4248     global_system_variables.character_set_client;
4249   thd->variables.collation_connection=
4250     global_system_variables.collation_connection;
4251   thd->variables.collation_server=
4252     global_system_variables.collation_server;
4253   thd->update_charset();
4254 
4255   /*
4256     We use a const cast here since the conceptual (and externally
4257     visible) behavior of the function is to set the default charset of
4258     the thread.  That the cache has to be invalidated is a secondary
4259     effect.
4260    */
4261   const_cast<Relay_log_info*>(rli)->cached_charset_invalidate();
4262   DBUG_VOID_RETURN;
4263 }
4264 
4265 /*
4266   init_slave_thread()
4267 */
4268 
init_slave_thread(THD * thd,SLAVE_THD_TYPE thd_type)4269 static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
4270 {
4271   DBUG_ENTER("init_slave_thread");
4272 #if !defined(DBUG_OFF)
4273   int simulate_error= 0;
4274 #endif
4275   thd->system_thread= (thd_type == SLAVE_THD_WORKER) ?
4276     SYSTEM_THREAD_SLAVE_WORKER : (thd_type == SLAVE_THD_SQL) ?
4277     SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
4278   thd->security_context()->skip_grants();
4279   thd->get_protocol_classic()->init_net(0);
4280   thd->slave_thread = 1;
4281   thd->enable_slow_log= opt_log_slow_slave_statements;
4282   set_slave_thread_options(thd);
4283 
4284   /*
4285     Replication threads are:
4286     - background threads in the server, not user sessions,
4287     - yet still assigned a PROCESSLIST_ID,
4288       for historical reasons (displayed in SHOW PROCESSLIST).
4289   */
4290   thd->set_new_thread_id();
4291 
4292 #ifdef HAVE_PSI_INTERFACE
4293   /*
4294     Populate the PROCESSLIST_ID in the instrumentation.
4295   */
4296   struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)();
4297   PSI_THREAD_CALL(set_thread_id)(psi, thd->thread_id());
4298 #endif /* HAVE_PSI_INTERFACE */
4299 
4300   DBUG_EXECUTE_IF("simulate_io_slave_error_on_init",
4301                   simulate_error|= (1 << SLAVE_THD_IO););
4302   DBUG_EXECUTE_IF("simulate_sql_slave_error_on_init",
4303                   simulate_error|= (1 << SLAVE_THD_SQL););
4304 #if !defined(DBUG_OFF)
4305   if (thd->store_globals() || simulate_error & (1<< thd_type))
4306 #else
4307   if (thd->store_globals())
4308 #endif
4309   {
4310     DBUG_RETURN(-1);
4311   }
4312 
4313   if (thd_type == SLAVE_THD_SQL)
4314   {
4315     THD_STAGE_INFO(thd, stage_waiting_for_the_next_event_in_relay_log);
4316   }
4317   else
4318   {
4319     THD_STAGE_INFO(thd, stage_waiting_for_master_update);
4320   }
4321   thd->set_time();
4322   /* Do not use user-supplied timeout value for system threads. */
4323   thd->variables.lock_wait_timeout= LONG_TIMEOUT;
4324   DBUG_RETURN(0);
4325 }
4326 
4327 
4328 /**
4329   Sleep for a given amount of time or until killed.
4330 
4331   @param thd        Thread context of the current thread.
4332   @param seconds    The number of seconds to sleep.
4333   @param func       Function object to check if the thread has been killed.
4334   @param info       The Rpl_info object associated with this sleep.
4335 
4336   @retval True if the thread has been killed, false otherwise.
4337 */
4338 template <typename killed_func, typename rpl_info>
slave_sleep(THD * thd,time_t seconds,killed_func func,rpl_info info)4339 static inline bool slave_sleep(THD *thd, time_t seconds,
4340                                killed_func func, rpl_info info)
4341 {
4342   bool ret;
4343   struct timespec abstime;
4344   mysql_mutex_t *lock= &info->sleep_lock;
4345   mysql_cond_t *cond= &info->sleep_cond;
4346 
4347   /* Absolute system time at which the sleep time expires. */
4348   set_timespec(&abstime, seconds);
4349 
4350   mysql_mutex_lock(lock);
4351   thd->ENTER_COND(cond, lock, NULL, NULL);
4352 
4353   while (! (ret= func(thd, info)))
4354   {
4355     int error= mysql_cond_timedwait(cond, lock, &abstime);
4356     if (error == ETIMEDOUT || error == ETIME)
4357       break;
4358   }
4359 
4360   mysql_mutex_unlock(lock);
4361   thd->EXIT_COND(NULL);
4362 
4363   return ret;
4364 }
4365 
request_dump(THD * thd,MYSQL * mysql,Master_info * mi,bool * suppress_warnings)4366 static int request_dump(THD *thd, MYSQL* mysql, Master_info* mi,
4367                         bool *suppress_warnings)
4368 {
4369   DBUG_ENTER("request_dump");
4370 
4371   const size_t BINLOG_NAME_INFO_SIZE= strlen(mi->get_master_log_name());
4372   int error= 1;
4373   size_t command_size= 0;
4374   enum_server_command command= mi->is_auto_position() ?
4375     COM_BINLOG_DUMP_GTID : COM_BINLOG_DUMP;
4376   uchar* command_buffer= NULL;
4377   ushort binlog_flags= 0;
4378 
4379   if (RUN_HOOK(binlog_relay_io,
4380                before_request_transmit,
4381                (thd, mi, binlog_flags)))
4382     goto err;
4383 
4384   *suppress_warnings= false;
4385   if (command == COM_BINLOG_DUMP_GTID)
4386   {
4387     // get set of GTIDs
4388     Sid_map sid_map(NULL/*no lock needed*/);
4389     Gtid_set gtid_executed(&sid_map);
4390     global_sid_lock->wrlock();
4391     gtid_state->dbug_print();
4392 
4393     if (gtid_executed.add_gtid_set(mi->rli->get_gtid_set()) != RETURN_STATUS_OK ||
4394         gtid_executed.add_gtid_set(gtid_state->get_executed_gtids()) !=
4395         RETURN_STATUS_OK)
4396     {
4397       global_sid_lock->unlock();
4398       goto err;
4399     }
4400     global_sid_lock->unlock();
4401 
4402     // allocate buffer
4403     size_t encoded_data_size= gtid_executed.get_encoded_length();
4404     size_t allocation_size=
4405       ::BINLOG_FLAGS_INFO_SIZE + ::BINLOG_SERVER_ID_INFO_SIZE +
4406       ::BINLOG_NAME_SIZE_INFO_SIZE + BINLOG_NAME_INFO_SIZE +
4407       ::BINLOG_POS_INFO_SIZE + ::BINLOG_DATA_SIZE_INFO_SIZE +
4408       encoded_data_size + 1;
4409     if (!(command_buffer= (uchar *) my_malloc(key_memory_rpl_slave_command_buffer,
4410                                               allocation_size, MYF(MY_WME))))
4411       goto err;
4412     uchar* ptr_buffer= command_buffer;
4413 
4414     DBUG_PRINT("info", ("Do I know something about the master? (binary log's name %s - auto position %d).",
4415                mi->get_master_log_name(), mi->is_auto_position()));
4416     /*
4417       Note: binlog_flags is always 0.  However, in versions up to 5.6
4418       RC, the master would check the lowest bit and do something
4419       unexpected if it was set; in early versions of 5.6 it would also
4420       use the two next bits.  Therefore, for backward compatibility,
4421       if we ever start to use the flags, we should leave the three
4422       lowest bits unused.
4423     */
4424     int2store(ptr_buffer, binlog_flags);
4425     ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE;
4426     int4store(ptr_buffer, server_id);
4427     ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE;
4428     int4store(ptr_buffer, static_cast<uint32>(BINLOG_NAME_INFO_SIZE));
4429     ptr_buffer+= ::BINLOG_NAME_SIZE_INFO_SIZE;
4430     memset(ptr_buffer, 0, BINLOG_NAME_INFO_SIZE);
4431     ptr_buffer+= BINLOG_NAME_INFO_SIZE;
4432     int8store(ptr_buffer, 4LL);
4433     ptr_buffer+= ::BINLOG_POS_INFO_SIZE;
4434 
4435     int4store(ptr_buffer, static_cast<uint32>(encoded_data_size));
4436     ptr_buffer+= ::BINLOG_DATA_SIZE_INFO_SIZE;
4437     gtid_executed.encode(ptr_buffer);
4438     ptr_buffer+= encoded_data_size;
4439 
4440     command_size= ptr_buffer - command_buffer;
4441     DBUG_ASSERT(command_size == (allocation_size - 1));
4442   }
4443   else
4444   {
4445     size_t allocation_size= ::BINLOG_POS_OLD_INFO_SIZE +
4446       BINLOG_NAME_INFO_SIZE + ::BINLOG_FLAGS_INFO_SIZE +
4447       ::BINLOG_SERVER_ID_INFO_SIZE + 1;
4448     if (!(command_buffer= (uchar *) my_malloc(key_memory_rpl_slave_command_buffer,
4449                                               allocation_size, MYF(MY_WME))))
4450       goto err;
4451     uchar* ptr_buffer= command_buffer;
4452 
4453     int4store(ptr_buffer, DBUG_EVALUATE_IF("request_master_log_pos_3", 3,
4454                                            static_cast<uint32>(mi->get_master_log_pos())));
4455     ptr_buffer+= ::BINLOG_POS_OLD_INFO_SIZE;
4456     // See comment regarding binlog_flags above.
4457     int2store(ptr_buffer, binlog_flags);
4458     ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE;
4459     int4store(ptr_buffer, server_id);
4460     ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE;
4461     memcpy(ptr_buffer, mi->get_master_log_name(), BINLOG_NAME_INFO_SIZE);
4462     ptr_buffer+= BINLOG_NAME_INFO_SIZE;
4463 
4464     command_size= ptr_buffer - command_buffer;
4465     DBUG_ASSERT(command_size == (allocation_size - 1));
4466   }
4467 
4468   if (simple_command(mysql, command, command_buffer, command_size, 1))
4469   {
4470     /*
4471       Something went wrong, so we will just reconnect and retry later
4472       in the future, we should do a better error analysis, but for
4473       now we just fill up the error log :-)
4474     */
4475     if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
4476       *suppress_warnings= true;                 // Suppress reconnect warning
4477     else
4478       sql_print_error("Error on %s: %d  %s, will retry in %d secs",
4479                       command_name[command].str,
4480                       mysql_errno(mysql), mysql_error(mysql),
4481                       mi->connect_retry);
4482     goto err;
4483   }
4484   error= 0;
4485 
4486 err:
4487   my_free(command_buffer);
4488   DBUG_RETURN(error);
4489 }
4490 
4491 
4492 /*
4493   Read one event from the master
4494 
4495   SYNOPSIS
4496     read_event()
4497     mysql               MySQL connection
4498     mi                  Master connection information
4499     suppress_warnings   TRUE when a normal net read timeout has caused us to
4500                         try a reconnect.  We do not want to print anything to
4501                         the error log in this case because this a anormal
4502                         event in an idle server.
4503 
4504     RETURN VALUES
4505     'packet_error'      Error
4506     number              Length of packet
4507 */
4508 
read_event(MYSQL * mysql,Master_info * mi,bool * suppress_warnings)4509 static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings)
4510 {
4511   ulong len;
4512   DBUG_ENTER("read_event");
4513 
4514   *suppress_warnings= FALSE;
4515   /*
4516     my_real_read() will time us out
4517     We check if we were told to die, and if not, try reading again
4518   */
4519 #ifndef DBUG_OFF
4520   if (disconnect_slave_event_count && !(mi->events_until_exit--))
4521     DBUG_RETURN(packet_error);
4522 #endif
4523 
4524   len= cli_safe_read(mysql, NULL);
4525   if (len == packet_error || (long) len < 1)
4526   {
4527     if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
4528     {
4529       /*
4530         We are trying a normal reconnect after a read timeout;
4531         we suppress prints to .err file as long as the reconnect
4532         happens without problems
4533       */
4534       *suppress_warnings= TRUE;
4535     }
4536     else
4537     {
4538       if (!mi->abort_slave)
4539       {
4540         sql_print_error("Error reading packet from server%s: %s (server_errno=%d)",
4541                         mi->get_for_channel_str(), mysql_error(mysql),
4542                         mysql_errno(mysql));
4543       }
4544     }
4545     DBUG_RETURN(packet_error);
4546   }
4547 
4548   /* Check if eof packet */
4549   if (len < 8 && mysql->net.read_pos[0] == 254)
4550   {
4551      sql_print_information("Slave%s: received end packet from server due to dump "
4552                            "thread being killed on master. Dump threads are "
4553                            "killed for example during master shutdown, "
4554                            "explicitly by a user, or when the master receives "
4555                            "a binlog send request from a duplicate server "
4556                            "UUID <%s> : Error %s", mi->get_for_channel_str(),
4557                            ::server_uuid,
4558                            mysql_error(mysql));
4559      DBUG_RETURN(packet_error);
4560   }
4561 
4562   DBUG_PRINT("exit", ("len: %lu  net->read_pos[4]: %d",
4563                       len, mysql->net.read_pos[4]));
4564   DBUG_RETURN(len - 1);
4565 }
4566 
4567 
4568 /**
4569   If this is a lagging slave (specified with CHANGE MASTER TO MASTER_DELAY = X), delays accordingly. Also unlocks rli->data_lock.
4570 
4571   Design note: this is the place to unlock rli->data_lock. The lock
4572   must be held when reading delay info from rli, but it should not be
4573   held while sleeping.
4574 
4575   @param ev Event that is about to be executed.
4576 
4577   @param thd The sql thread's THD object.
4578 
4579   @param rli The sql thread's Relay_log_info structure.
4580 
4581   @retval 0 If the delay timed out and the event shall be executed.
4582 
4583   @retval nonzero If the delay was interrupted and the event shall be skipped.
4584 */
sql_delay_event(Log_event * ev,THD * thd,Relay_log_info * rli)4585 static int sql_delay_event(Log_event *ev, THD *thd, Relay_log_info *rli)
4586 {
4587   time_t sql_delay= rli->get_sql_delay();
4588 
4589   DBUG_ENTER("sql_delay_event");
4590   mysql_mutex_assert_owner(&rli->data_lock);
4591   DBUG_ASSERT(!rli->belongs_to_client());
4592 
4593   int type= ev->get_type_code();
4594   if (sql_delay && type != binary_log::ROTATE_EVENT &&
4595       type != binary_log::FORMAT_DESCRIPTION_EVENT &&
4596       type != binary_log::START_EVENT_V3)
4597   {
4598     // The time when we should execute the event.
4599     time_t sql_delay_end=
4600       ev->common_header->when.tv_sec + rli->mi->clock_diff_with_master + sql_delay;
4601     // The current time.
4602     time_t now= my_time(0);
4603     // The time we will have to sleep before executing the event.
4604     time_t nap_time= 0;
4605     if (sql_delay_end > now)
4606       nap_time= sql_delay_end - now;
4607 
4608     DBUG_PRINT("info", ("sql_delay= %lu "
4609                         "ev->when= %lu "
4610                         "rli->mi->clock_diff_with_master= %lu "
4611                         "now= %ld "
4612                         "sql_delay_end= %ld "
4613                         "nap_time= %ld",
4614                         sql_delay, (long) ev->common_header->when.tv_sec,
4615                         rli->mi->clock_diff_with_master,
4616                         (long)now, (long)sql_delay_end, (long)nap_time));
4617 
4618     if (sql_delay_end > now)
4619     {
4620       DBUG_PRINT("info", ("delaying replication event %lu secs",
4621                           nap_time));
4622       rli->start_sql_delay(sql_delay_end);
4623       mysql_mutex_unlock(&rli->data_lock);
4624       DBUG_RETURN(slave_sleep(thd, nap_time, sql_slave_killed, rli));
4625     }
4626   }
4627 
4628   mysql_mutex_unlock(&rli->data_lock);
4629 
4630   DBUG_RETURN(0);
4631 }
4632 
4633 
4634 /**
4635   Applies the given event and advances the relay log position.
4636 
4637   This is needed by the sql thread to execute events from the binlog,
4638   and by clients executing BINLOG statements.  Conceptually, this
4639   function does:
4640 
4641   @code
4642     ev->apply_event(rli);
4643     ev->update_pos(rli);
4644   @endcode
4645 
4646   It also does the following maintainance:
4647 
4648    - Initializes the thread's server_id and time; and the event's
4649      thread.
4650 
4651    - If !rli->belongs_to_client() (i.e., if it belongs to the slave
4652      sql thread instead of being used for executing BINLOG
4653      statements), it does the following things: (1) skips events if it
4654      is needed according to the server id or slave_skip_counter; (2)
4655      unlocks rli->data_lock; (3) sleeps if required by 'CHANGE MASTER
4656      TO MASTER_DELAY=X'; (4) maintains the running state of the sql
4657      thread (rli->thread_state).
4658 
4659    - Reports errors as needed.
4660 
4661   @param ptr_ev a pointer to a reference to the event to apply.
4662 
4663   @param thd The client thread that executes the event (i.e., the
4664   slave sql thread if called from a replication slave, or the client
4665   thread if called to execute a BINLOG statement).
4666 
4667   @param rli The relay log info (i.e., the slave's rli if called from
4668   a replication slave, or the client's thd->rli_fake if called to
4669   execute a BINLOG statement).
4670 
4671   @note MTS can store NULL to @c ptr_ev location to indicate
4672         the event is taken over by a Worker.
4673 
4674   @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK
4675           OK.
4676 
4677   @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR
4678           Error calling ev->apply_event().
4679 
4680   @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR
4681           No error calling ev->apply_event(), but error calling
4682           ev->update_pos().
4683 
4684   @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR
4685           append_item_to_jobs() failed, thread was killed while waiting
4686           for successful enqueue on worker.
4687 */
4688 enum enum_slave_apply_event_and_update_pos_retval
apply_event_and_update_pos(Log_event ** ptr_ev,THD * thd,Relay_log_info * rli)4689 apply_event_and_update_pos(Log_event** ptr_ev, THD* thd, Relay_log_info* rli)
4690 {
4691   int exec_res= 0;
4692   bool skip_event= FALSE;
4693   Log_event *ev= *ptr_ev;
4694   Log_event::enum_skip_reason reason= Log_event::EVENT_SKIP_NOT;
4695 
4696   DBUG_ENTER("apply_event_and_update_pos");
4697 
4698   DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)",
4699                            ev->get_type_str(), ev->get_type_code(),
4700                            ev->server_id));
4701   DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
4702                       FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT),
4703                       FLAGSTR(thd->variables.option_bits, OPTION_BEGIN),
4704                       (ulong) rli->last_event_start_time));
4705 
4706   /*
4707     Execute the event to change the database and update the binary
4708     log coordinates, but first we set some data that is needed for
4709     the thread.
4710 
4711     The event will be executed unless it is supposed to be skipped.
4712 
4713     Queries originating from this server must be skipped.  Low-level
4714     events (Format_description_log_event, Rotate_log_event,
4715     Stop_log_event) from this server must also be skipped. But for
4716     those we don't want to modify 'group_master_log_pos', because
4717     these events did not exist on the master.
4718     Format_description_log_event is not completely skipped.
4719 
4720     Skip queries specified by the user in 'slave_skip_counter'.  We
4721     can't however skip events that has something to do with the log
4722     files themselves.
4723 
4724     Filtering on own server id is extremely important, to ignore
4725     execution of events created by the creation/rotation of the relay
4726     log (remember that now the relay log starts with its Format_desc,
4727     has a Rotate etc).
4728   */
4729   /*
4730      Set the unmasked and actual server ids from the event
4731    */
4732   thd->server_id = ev->server_id; // use the original server id for logging
4733   thd->unmasked_server_id = ev->common_header->unmasked_server_id;
4734   thd->set_time();                            // time the query
4735   thd->lex->set_current_select(0);
4736   if (!ev->common_header->when.tv_sec)
4737     my_micro_time_to_timeval(my_micro_time(), &ev->common_header->when);
4738   ev->thd = thd; // because up to this point, ev->thd == 0
4739 
4740   if (!(rli->is_mts_recovery() && bitmap_is_set(&rli->recovery_groups,
4741                                                 rli->mts_recovery_index)))
4742   {
4743     reason= ev->shall_skip(rli);
4744   }
4745 #ifndef DBUG_OFF
4746   if (rli->is_mts_recovery())
4747   {
4748     DBUG_PRINT("mts", ("Mts is recovering %d, number of bits set %d, "
4749                        "bitmap is set %d, index %lu.\n",
4750                        rli->is_mts_recovery(),
4751                        bitmap_bits_set(&rli->recovery_groups),
4752                        bitmap_is_set(&rli->recovery_groups,
4753                                      rli->mts_recovery_index),
4754                        rli->mts_recovery_index));
4755   }
4756 #endif
4757   if (reason == Log_event::EVENT_SKIP_COUNT)
4758   {
4759     --rli->slave_skip_counter;
4760     skip_event= TRUE;
4761   }
4762   set_timespec_nsec(&rli->ts_exec[0], 0);
4763   rli->stats_read_time += diff_timespec(&rli->ts_exec[0], &rli->ts_exec[1]);
4764 
4765   if (reason == Log_event::EVENT_SKIP_NOT)
4766   {
4767     // Sleeps if needed, and unlocks rli->data_lock.
4768     if (sql_delay_event(ev, thd, rli))
4769       DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK);
4770 
4771     exec_res= ev->apply_event(rli);
4772 
4773     DBUG_EXECUTE_IF("simulate_stop_when_mts_in_group",
4774                     if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP
4775                         && rli->curr_group_seen_begin)
4776                     DBUG_SET("+d,stop_when_mts_in_group"););
4777 
4778     if (!exec_res && (ev->worker != rli))
4779     {
4780       if (ev->worker)
4781       {
4782         Slave_job_item item= {ev, rli->get_event_relay_log_number(),
4783                               rli->get_event_start_pos() };
4784         Slave_job_item *job_item= &item;
4785         Slave_worker *w= (Slave_worker *) ev->worker;
4786         // specially marked group typically with OVER_MAX_DBS_IN_EVENT_MTS db:s
4787         bool need_sync= ev->is_mts_group_isolated();
4788 
4789         // all events except BEGIN-query must be marked with a non-NULL Worker
4790         DBUG_ASSERT(((Slave_worker*) ev->worker) == rli->last_assigned_worker);
4791 
4792         DBUG_PRINT("Log_event::apply_event:",
4793                    ("-> job item data %p to W_%lu", job_item->data, w->id));
4794 
4795         // Reset mts in-group state
4796         if (rli->mts_group_status == Relay_log_info::MTS_END_GROUP)
4797         {
4798           // CGAP cleanup
4799           rli->curr_group_assigned_parts.clear();
4800           // reset the B-group and Gtid-group marker
4801           rli->curr_group_seen_begin= rli->curr_group_seen_gtid= false;
4802           rli->last_assigned_worker= NULL;
4803         }
4804         /*
4805            Stroring GAQ index of the group that the event belongs to
4806            in the event. Deferred events are handled similarly below.
4807         */
4808         ev->mts_group_idx= rli->gaq->assigned_group_index;
4809 
4810         bool append_item_to_jobs_error= false;
4811         if (rli->curr_group_da.size() > 0)
4812         {
4813           /*
4814             the current event sorted out which partion the current group
4815             belongs to. It's time now to processed deferred array events.
4816           */
4817           for (uint i= 0; i < rli->curr_group_da.size(); i++)
4818           {
4819             Slave_job_item da_item= rli->curr_group_da[i];
4820             DBUG_PRINT("mts", ("Assigning job %llu to worker %lu",
4821                       (da_item.data)->common_header->log_pos, w->id));
4822             da_item.data->mts_group_idx=
4823               rli->gaq->assigned_group_index; // similarly to above
4824             if (!append_item_to_jobs_error)
4825               append_item_to_jobs_error= append_item_to_jobs(&da_item, w, rli);
4826             if (append_item_to_jobs_error)
4827               delete da_item.data;
4828           }
4829           rli->curr_group_da.clear();
4830         }
4831         if (append_item_to_jobs_error)
4832           DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR);
4833 
4834         DBUG_PRINT("mts", ("Assigning job %llu to worker %lu\n",
4835                    job_item->data->common_header->log_pos, w->id));
4836 
4837         /* Notice `ev' instance can be destoyed after `append()' */
4838         if (append_item_to_jobs(job_item, w, rli))
4839           DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR);
4840         if (need_sync)
4841         {
4842           /*
4843             combination of over-max db:s and end of the current group
4844             forces to wait for the assigned groups completion by assigned
4845             to the event worker.
4846             Indeed MTS group status could be safely set to MTS_NOT_IN_GROUP
4847             after wait_() returns.
4848             No need to know a possible error out of synchronization call.
4849           */
4850           (void)rli->current_mts_submode->wait_for_workers_to_finish(rli);
4851         }
4852 
4853       }
4854       *ptr_ev= NULL; // announcing the event is passed to w-worker
4855 
4856       if (rli->is_parallel_exec() && rli->mts_events_assigned % 1024 == 1)
4857       {
4858         time_t my_now= my_time(0);
4859 
4860         if ((my_now - rli->mts_last_online_stat) >=
4861             mts_online_stat_period)
4862         {
4863           sql_print_information("Multi-threaded slave statistics%s: "
4864                                 "seconds elapsed = %lu; "
4865                                 "events assigned = %llu; "
4866                                 "worker queues filled over overrun level = %lu; "
4867                                 "waited due a Worker queue full = %lu; "
4868                                 "waited due the total size = %lu; "
4869                                 "waited at clock conflicts = %llu "
4870                                 "waited (count) when Workers occupied = %lu "
4871                                 "waited when Workers occupied = %llu",
4872                                 rli->get_for_channel_str(),
4873                                 static_cast<unsigned long>
4874                                 (my_now - rli->mts_last_online_stat),
4875                                 rli->mts_events_assigned,
4876                                 rli->mts_wq_overrun_cnt,
4877                                 rli->mts_wq_overfill_cnt,
4878                                 rli->wq_size_waits_cnt,
4879                                 rli->mts_total_wait_overlap,
4880                                 rli->mts_wq_no_underrun_cnt,
4881                                 rli->mts_total_wait_worker_avail);
4882           rli->mts_last_online_stat= my_now;
4883         }
4884       }
4885     }
4886   }
4887   else
4888     mysql_mutex_unlock(&rli->data_lock);
4889 
4890   set_timespec_nsec(&rli->ts_exec[1], 0);
4891   rli->stats_exec_time += diff_timespec(&rli->ts_exec[1], &rli->ts_exec[0]);
4892 
4893   DBUG_PRINT("info", ("apply_event error = %d", exec_res));
4894   if (exec_res == 0)
4895   {
4896     /*
4897       Positions are not updated here when an XID is processed. To make
4898       a slave crash-safe, positions must be updated while processing a
4899       XID event and as such do not need to be updated here again.
4900 
4901       However, if the event needs to be skipped, this means that it
4902       will not be processed and then positions need to be updated here.
4903 
4904       See sql/rpl_rli.h for further details.
4905     */
4906     int error= 0;
4907     if (*ptr_ev &&
4908         (ev->get_type_code() != binary_log::XID_EVENT ||
4909          skip_event || (rli->is_mts_recovery() && !is_gtid_event(ev) &&
4910          (ev->ends_group() || !rli->mts_recovery_group_seen_begin) &&
4911           bitmap_is_set(&rli->recovery_groups, rli->mts_recovery_index))))
4912     {
4913 #ifndef DBUG_OFF
4914       /*
4915         This only prints information to the debug trace.
4916 
4917         TODO: Print an informational message to the error log?
4918       */
4919       static const char *const explain[] = {
4920         // EVENT_SKIP_NOT,
4921         "not skipped",
4922         // EVENT_SKIP_IGNORE,
4923         "skipped because event should be ignored",
4924         // EVENT_SKIP_COUNT
4925         "skipped because event skip counter was non-zero"
4926       };
4927       DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
4928                           MY_TEST(thd->variables.option_bits & OPTION_BEGIN),
4929                           rli->get_flag(Relay_log_info::IN_STMT)));
4930       DBUG_PRINT("skip_event", ("%s event was %s",
4931                                 ev->get_type_str(), explain[reason]));
4932 #endif
4933 
4934       error= ev->update_pos(rli);
4935       /*
4936         Slave skips an event if the slave_skip_counter is greater than zero.
4937         We have to free thd's mem_root here after we update the positions
4938         in the repository table if the event is a skipped event.
4939         Otherwise, imagine a situation where slave_skip_counter is big number
4940         and slave is skipping the events and updating the repository.
4941         All the memory used while these operations are going on is never
4942         freed unless slave starts executing the events (after slave_skip_counter
4943         becomes zero).
4944 
4945         Hence we free thd's mem_root here if it is a skipped event.
4946         (freeing mem_root generally happens from Query_log_event::do_apply_event
4947         or Rows_log_event::do_apply_event when they find the end of
4948         the group event).
4949       */
4950       if (skip_event)
4951         free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
4952 
4953 #ifndef DBUG_OFF
4954       DBUG_PRINT("info", ("update_pos error = %d", error));
4955       if (!rli->belongs_to_client())
4956       {
4957         char buf[22];
4958         DBUG_PRINT("info", ("group %s %s",
4959                             llstr(rli->get_group_relay_log_pos(), buf),
4960                             rli->get_group_relay_log_name()));
4961         DBUG_PRINT("info", ("event %s %s",
4962                             llstr(rli->get_event_relay_log_pos(), buf),
4963                             rli->get_event_relay_log_name()));
4964       }
4965 #endif
4966     }
4967     else
4968     {
4969       /*
4970         INTVAR_EVENT, RAND_EVENT, USER_VAR_EVENT and ROWS_QUERY_LOG_EVENT are
4971         deferred event. It means ev->worker is NULL.
4972       */
4973       DBUG_ASSERT(*ptr_ev == ev || rli->is_parallel_exec() ||
4974 		  (!ev->worker &&
4975 		   (ev->get_type_code() == binary_log::INTVAR_EVENT ||
4976 		    ev->get_type_code() == binary_log::RAND_EVENT ||
4977 		    ev->get_type_code() == binary_log::USER_VAR_EVENT ||
4978                     ev->get_type_code() == binary_log::ROWS_QUERY_LOG_EVENT)));
4979 
4980       rli->inc_event_relay_log_pos();
4981     }
4982 
4983     if (!error && rli->is_mts_recovery() &&
4984         ev->get_type_code() != binary_log::ROTATE_EVENT &&
4985         ev->get_type_code() != binary_log::FORMAT_DESCRIPTION_EVENT &&
4986         ev->get_type_code() != binary_log::PREVIOUS_GTIDS_LOG_EVENT)
4987     {
4988       if (ev->starts_group())
4989       {
4990         rli->mts_recovery_group_seen_begin= true;
4991       }
4992       else if ((ev->ends_group() || !rli->mts_recovery_group_seen_begin) &&
4993                !is_gtid_event(ev))
4994       {
4995         rli->mts_recovery_index++;
4996         if (--rli->mts_recovery_group_cnt == 0)
4997         {
4998           rli->mts_recovery_index= 0;
4999           sql_print_information("Slave%s: MTS Recovery has completed at "
5000                                 "relay log %s, position %llu "
5001                                 "master log %s, position %llu.",
5002                                 rli->get_for_channel_str(),
5003                                 rli->get_group_relay_log_name(),
5004                                 rli->get_group_relay_log_pos(),
5005                                 rli->get_group_master_log_name(),
5006                                 rli->get_group_master_log_pos());
5007           /*
5008              Few tests wait for UNTIL_SQL_AFTER_MTS_GAPS completion.
5009              Due to exisiting convention the status won't change
5010              prior to slave restarts.
5011              So making of UNTIL_SQL_AFTER_MTS_GAPS completion isdone here,
5012              and only in the debug build to make the test to catch the change
5013              despite a faulty design of UNTIL checking before execution.
5014           */
5015           if (rli->until_condition == Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS)
5016           {
5017             rli->until_condition= Relay_log_info::UNTIL_DONE;
5018           }
5019           // reset the Worker tables to remove last slave session time info
5020           if ((error= rli->mts_finalize_recovery()))
5021           {
5022             (void) Rpl_info_factory::reset_workers(rli);
5023           }
5024         }
5025         rli->mts_recovery_group_seen_begin= false;
5026         if (!error)
5027           error= rli->flush_info(true);
5028       }
5029     }
5030 
5031     if (error)
5032     {
5033       /*
5034         The update should not fail, so print an error message and
5035         return an error code.
5036 
5037         TODO: Replace this with a decent error message when merged
5038         with BUG#24954 (which adds several new error message).
5039       */
5040       char buf[22];
5041       rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
5042                   "It was not possible to update the positions"
5043                   " of the relay log information: the slave may"
5044                   " be in an inconsistent state."
5045                   " Stopped in %s position %s",
5046                   rli->get_group_relay_log_name(),
5047                   llstr(rli->get_group_relay_log_pos(), buf));
5048       DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR);
5049     }
5050   }
5051 
5052   DBUG_RETURN(exec_res ? SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR :
5053                          SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK);
5054 }
5055 
5056 /**
5057   Let the worker applying the current group to rollback and gracefully
5058   finish its work before.
5059 
5060   @param rli The slave's relay log info.
5061 
5062   @param ev a pointer to the event on hold before applying this rollback
5063   procedure.
5064 
5065   @retval false The rollback succeeded.
5066 
5067   @retval true  There was an error while injecting events.
5068 */
coord_handle_partial_binlogged_transaction(Relay_log_info * rli,const Log_event * ev)5069 static bool coord_handle_partial_binlogged_transaction(Relay_log_info *rli,
5070                                                        const Log_event *ev)
5071 {
5072   DBUG_ENTER("coord_handle_partial_binlogged_transaction");
5073   /*
5074     This function is called holding the rli->data_lock.
5075     We must return it still holding this lock, except in the case of returning
5076     error.
5077   */
5078   mysql_mutex_assert_owner(&rli->data_lock);
5079   THD *thd= rli->info_thd;
5080 
5081   if (!rli->curr_group_seen_begin)
5082   {
5083     DBUG_PRINT("info",("Injecting QUERY(BEGIN) to rollback worker"));
5084     Log_event *begin_event= new Query_log_event(thd,
5085                                                 STRING_WITH_LEN("BEGIN"),
5086                                                 true, /* using_trans */
5087                                                 false, /* immediate */
5088                                                 true, /* suppress_use */
5089                                                 0, /* error */
5090                                                 true /* ignore_command */);
5091     ((Query_log_event*) begin_event)->db= "";
5092     begin_event->common_header->data_written= 0;
5093     begin_event->server_id= ev->server_id;
5094     /*
5095       We must be careful to avoid SQL thread increasing its position
5096       farther than the event that triggered this QUERY(BEGIN).
5097     */
5098     begin_event->common_header->log_pos= ev->common_header->log_pos;
5099     begin_event->future_event_relay_log_pos= ev->future_event_relay_log_pos;
5100 
5101     if (apply_event_and_update_pos(&begin_event, thd, rli) !=
5102         SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK)
5103     {
5104       delete begin_event;
5105       DBUG_RETURN(true);
5106     }
5107     mysql_mutex_lock(&rli->data_lock);
5108   }
5109 
5110   DBUG_PRINT("info",("Injecting QUERY(ROLLBACK) to rollback worker"));
5111   Log_event *rollback_event= new Query_log_event(thd,
5112                                                  STRING_WITH_LEN("ROLLBACK"),
5113                                                  true, /* using_trans */
5114                                                  false, /* immediate */
5115                                                  true, /* suppress_use */
5116                                                  0, /* error */
5117                                                  true /* ignore_command */);
5118   ((Query_log_event*) rollback_event)->db= "";
5119   rollback_event->common_header->data_written= 0;
5120   rollback_event->server_id= ev->server_id;
5121   /*
5122     We must be careful to avoid SQL thread increasing its position
5123     farther than the event that triggered this QUERY(ROLLBACK).
5124   */
5125   rollback_event->common_header->log_pos= ev->common_header->log_pos;
5126   rollback_event->future_event_relay_log_pos= ev->future_event_relay_log_pos;
5127 
5128   if (apply_event_and_update_pos(&rollback_event, thd, rli) !=
5129       SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK)
5130   {
5131     delete rollback_event;
5132     DBUG_RETURN(true);
5133   }
5134   mysql_mutex_lock(&rli->data_lock);
5135 
5136   DBUG_RETURN(false);
5137 }
5138 
5139 /**
5140   Top-level function for executing the next event in the relay log.
5141   This is called from the SQL thread.
5142 
5143   This function reads the event from the relay log, executes it, and
5144   advances the relay log position.  It also handles errors, etc.
5145 
5146   This function may fail to apply the event for the following reasons:
5147 
5148    - The position specfied by the UNTIL condition of the START SLAVE
5149      command is reached.
5150 
5151    - It was not possible to read the event from the log.
5152 
5153    - The slave is killed.
5154 
5155    - An error occurred when applying the event, and the event has been
5156      tried slave_trans_retries times.  If the event has been retried
5157      fewer times, 0 is returned.
5158 
5159    - init_info or init_relay_log_pos failed. (These are called
5160      if a failure occurs when applying the event.)
5161 
5162    - An error occurred when updating the binlog position.
5163 
5164   @retval 0 The event was applied.
5165 
5166   @retval 1 The event was not applied.
5167 */
exec_relay_log_event(THD * thd,Relay_log_info * rli)5168 static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
5169 {
5170   DBUG_ENTER("exec_relay_log_event");
5171 
5172   /*
5173      We acquire this mutex since we need it for all operations except
5174      event execution. But we will release it in places where we will
5175      wait for something for example inside of next_event().
5176    */
5177   mysql_mutex_lock(&rli->data_lock);
5178 
5179   /*
5180     UNTIL_SQL_AFTER_GTIDS, UNTIL_MASTER_POS and UNTIL_RELAY_POS require
5181     special handling since we have to check whether the until_condition is
5182     satisfied *before* the SQL threads goes on a wait inside next_event()
5183     for the relay log to grow.
5184     This is required in the following case: We have already applied the last
5185     event in the waiting set, but the relay log ends after this event. Then it
5186     is not enough to check the condition in next_event; we also have to check
5187     it here, before going to sleep. Otherwise, if no updates were coming from
5188     the master, we would sleep forever despite having reached the required
5189     position.
5190   */
5191   if ((rli->until_condition == Relay_log_info::UNTIL_SQL_AFTER_GTIDS ||
5192        rli->until_condition == Relay_log_info::UNTIL_MASTER_POS ||
5193        rli->until_condition == Relay_log_info::UNTIL_RELAY_POS ||
5194        rli->until_condition == Relay_log_info::UNTIL_SQL_VIEW_ID) &&
5195        rli->is_until_satisfied(thd, NULL))
5196   {
5197     rli->abort_slave= 1;
5198     mysql_mutex_unlock(&rli->data_lock);
5199     DBUG_RETURN(1);
5200   }
5201 
5202   Log_event *ev = next_event(rli), **ptr_ev;
5203 
5204   DBUG_ASSERT(rli->info_thd==thd);
5205 
5206   if (sql_slave_killed(thd,rli))
5207   {
5208     mysql_mutex_unlock(&rli->data_lock);
5209     delete ev;
5210     DBUG_RETURN(1);
5211   }
5212   if (ev)
5213   {
5214     enum enum_slave_apply_event_and_update_pos_retval exec_res;
5215 
5216     ptr_ev= &ev;
5217     /*
5218       Even if we don't execute this event, we keep the master timestamp,
5219       so that seconds behind master shows correct delta (there are events
5220       that are not replayed, so we keep falling behind).
5221 
5222       If it is an artificial event, or a relay log event (IO thread generated
5223       event) or ev->when is set to 0, or a FD from master, or a heartbeat
5224       event with server_id '0' then  we don't update the last_master_timestamp.
5225 
5226       In case of parallel execution last_master_timestamp is only updated when
5227       a job is taken out of GAQ. Thus when last_master_timestamp is 0 (which
5228       indicates that GAQ is empty, all slave workers are waiting for events from
5229       the Coordinator), we need to initialize it with a timestamp from the first
5230       event to be executed in parallel.
5231     */
5232     if ((!rli->is_parallel_exec() || rli->last_master_timestamp == 0) &&
5233          !(ev->is_artificial_event() || ev->is_relay_log_event() ||
5234           (ev->common_header->when.tv_sec == 0) ||
5235           ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT ||
5236           ev->server_id == 0))
5237     {
5238       rli->last_master_timestamp= ev->common_header->when.tv_sec +
5239                                   (time_t) ev->exec_time;
5240       DBUG_ASSERT(rli->last_master_timestamp >= 0);
5241     }
5242 
5243     /*
5244       This tests if the position of the beginning of the current event
5245       hits the UNTIL barrier.
5246       MTS: since the master and the relay-group coordinates change
5247       asynchronously logics of rli->is_until_satisfied() can't apply.
5248       A special UNTIL_SQL_AFTER_MTS_GAPS is still deployed here
5249       temporarily (see is_until_satisfied todo).
5250     */
5251     if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
5252         rli->until_condition != Relay_log_info::UNTIL_SQL_AFTER_GTIDS &&
5253         rli->is_until_satisfied(thd, ev))
5254     {
5255       /*
5256         Setting abort_slave flag because we do not want additional message about
5257         error in query execution to be printed.
5258       */
5259       rli->abort_slave= 1;
5260       mysql_mutex_unlock(&rli->data_lock);
5261       delete ev;
5262       DBUG_RETURN(1);
5263     }
5264 
5265     { /**
5266          The following failure injecion works in cooperation with tests
5267          setting @@global.debug= 'd,incomplete_group_in_relay_log'.
5268          Xid or Commit events are not executed to force the slave sql
5269          read hanging if the realy log does not have any more events.
5270       */
5271       DBUG_EXECUTE_IF("incomplete_group_in_relay_log",
5272                       if ((ev->get_type_code() == binary_log::XID_EVENT) ||
5273                           ((ev->get_type_code() == binary_log::QUERY_EVENT) &&
5274                            strcmp("COMMIT", ((Query_log_event *) ev)->query) == 0))
5275                       {
5276                         DBUG_ASSERT(thd->get_transaction()->cannot_safely_rollback(
5277                             Transaction_ctx::SESSION));
5278                         rli->abort_slave= 1;
5279                         mysql_mutex_unlock(&rli->data_lock);
5280                         delete ev;
5281                         rli->inc_event_relay_log_pos();
5282                         DBUG_RETURN(0);
5283                       };);
5284     }
5285 
5286     /*
5287       GTID protocol will put a FORMAT_DESCRIPTION_EVENT from the master with
5288       log_pos != 0 after each (re)connection if auto positioning is enabled.
5289       This means that the SQL thread might have already started to apply the
5290       current group but, as the IO thread had to reconnect, it left this
5291       group incomplete and will start it again from the beginning.
5292       So, before applying this FORMAT_DESCRIPTION_EVENT, we must let the
5293       worker roll back the current group and gracefully finish its work,
5294       before starting to apply the new (complete) copy of the group.
5295     */
5296     if (ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT &&
5297         ev->server_id != ::server_id && ev->common_header->log_pos != 0 &&
5298         rli->is_parallel_exec() && rli->curr_group_seen_gtid)
5299     {
5300       if (coord_handle_partial_binlogged_transaction(rli, ev))
5301         /*
5302           In the case of an error, coord_handle_partial_binlogged_transaction
5303           will not try to get the rli->data_lock again.
5304         */
5305         DBUG_RETURN(1);
5306     }
5307 
5308     /* ptr_ev can change to NULL indicating MTS coorinator passed to a Worker */
5309     exec_res= apply_event_and_update_pos(ptr_ev, thd, rli);
5310     /*
5311       Note: the above call to apply_event_and_update_pos executes
5312       mysql_mutex_unlock(&rli->data_lock);
5313     */
5314 
5315     /* For deferred events, the ptr_ev is set to NULL
5316         in Deferred_log_events::add() function.
5317         Hence deferred events wont be deleted here.
5318         They will be deleted in Deferred_log_events::rewind() funciton.
5319     */
5320     if (*ptr_ev)
5321     {
5322       DBUG_ASSERT(*ptr_ev == ev); // event remains to belong to Coordinator
5323 
5324       DBUG_EXECUTE_IF("dbug.calculate_sbm_after_previous_gtid_log_event",
5325                     {
5326                       if (ev->get_type_code() == binary_log::PREVIOUS_GTIDS_LOG_EVENT)
5327                       {
5328                         const char act[]= "now signal signal.reached wait_for signal.done_sbm_calculation";
5329                         DBUG_ASSERT(opt_debug_sync_timeout > 0);
5330                         DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act)));
5331                       }
5332                     };);
5333       DBUG_EXECUTE_IF("dbug.calculate_sbm_after_fake_rotate_log_event",
5334                     {
5335                       if (ev->get_type_code() == binary_log::ROTATE_EVENT && ev->is_artificial_event())
5336                       {
5337                       const char act[]= "now signal signal.reached wait_for signal.done_sbm_calculation";
5338                       DBUG_ASSERT(opt_debug_sync_timeout > 0);
5339                       DBUG_ASSERT(!debug_sync_set_action(thd,
5340                                                          STRING_WITH_LEN(act)));
5341                       }
5342                     };);
5343       /*
5344         Format_description_log_event should not be deleted because it will be
5345         used to read info about the relay log's format; it will be deleted when
5346         the SQL thread does not need it, i.e. when this thread terminates.
5347         ROWS_QUERY_LOG_EVENT is destroyed at the end of the current statement
5348         clean-up routine.
5349       */
5350       if (ev->get_type_code() != binary_log::FORMAT_DESCRIPTION_EVENT &&
5351           ev->get_type_code() != binary_log::ROWS_QUERY_LOG_EVENT)
5352       {
5353         DBUG_PRINT("info", ("Deleting the event after it has been executed"));
5354         delete ev;
5355         ev= NULL;
5356       }
5357     }
5358 
5359     /*
5360       exec_res == SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR
5361                   update_log_pos failed: this should not happen, so we
5362                   don't retry.
5363       exec_res == SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR
5364                   append_item_to_jobs() failed, this happened because
5365                   thread was killed while waiting for enqueue on worker.
5366     */
5367     if (exec_res >= SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR)
5368     {
5369       delete ev;
5370       DBUG_RETURN(1);
5371     }
5372 
5373     if (slave_trans_retries)
5374     {
5375       int temp_err= 0;
5376       bool silent= false;
5377       if (exec_res && !is_mts_worker(thd) /* no reexecution in MTS mode */ &&
5378           (temp_err= rli->has_temporary_error(thd, 0, &silent)) &&
5379           !thd->get_transaction()->cannot_safely_rollback(
5380               Transaction_ctx::SESSION))
5381       {
5382         const char *errmsg;
5383         /*
5384           We were in a transaction which has been rolled back because of a
5385           temporary error;
5386           let's seek back to BEGIN log event and retry it all again.
5387 	  Note, if lock wait timeout (innodb_lock_wait_timeout exceeded)
5388 	  there is no rollback since 5.0.13 (ref: manual).
5389           We have to not only seek but also
5390           a) init_info(), to seek back to hot relay log's start for later
5391           (for when we will come back to this hot log after re-processing the
5392           possibly existing old logs where BEGIN is: check_binlog_magic() will
5393           then need the cache to be at position 0 (see comments at beginning of
5394           init_info()).
5395           b) init_relay_log_pos(), because the BEGIN may be an older relay log.
5396         */
5397         if (rli->trans_retries < slave_trans_retries)
5398         {
5399           /*
5400             The transactions has to be rolled back before
5401             load_mi_and_rli_from_repositories is called. Because
5402             load_mi_and_rli_from_repositories will starts a new
5403             transaction if master_info_repository is TABLE.
5404           */
5405           rli->cleanup_context(thd, 1);
5406           /*
5407              We need to figure out if there is a test case that covers
5408              this part. \Alfranio.
5409           */
5410           if (load_mi_and_rli_from_repositories(rli->mi, false, SLAVE_SQL))
5411             sql_print_error("Failed to initialize the master info structure%s",
5412                             rli->get_for_channel_str());
5413           else if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
5414                                            rli->get_group_relay_log_pos(),
5415                                            true/*need_data_lock=true*/,
5416                                            &errmsg, 1))
5417             sql_print_error("Error initializing relay log position%s: %s",
5418                             rli->get_for_channel_str(), errmsg);
5419           else
5420           {
5421             exec_res= SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK;
5422             /* chance for concurrent connection to get more locks */
5423             slave_sleep(thd, min<ulong>(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
5424                         sql_slave_killed, rli);
5425             mysql_mutex_lock(&rli->data_lock); // because of SHOW STATUS
5426             if (!silent)
5427               rli->trans_retries++;
5428 
5429             rli->retried_trans++;
5430             mysql_mutex_unlock(&rli->data_lock);
5431             DBUG_PRINT("info", ("Slave retries transaction "
5432                                 "rli->trans_retries: %lu", rli->trans_retries));
5433           }
5434         }
5435         else
5436         {
5437           thd->is_fatal_error= 1;
5438           rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
5439                       "Slave SQL thread retried transaction %lu time(s) "
5440                       "in vain, giving up. Consider raising the value of "
5441                       "the slave_transaction_retries variable.", rli->trans_retries);
5442         }
5443       }
5444       else if ((exec_res && !temp_err) ||
5445                (opt_using_transactions &&
5446                 rli->get_group_relay_log_pos() == rli->get_event_relay_log_pos()))
5447       {
5448         /*
5449           Only reset the retry counter if the entire group succeeded
5450           or failed with a non-transient error.  On a successful
5451           event, the execution will proceed as usual; in the case of a
5452           non-transient error, the slave will stop with an error.
5453          */
5454         rli->trans_retries= 0; // restart from fresh
5455         DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %lu",
5456                             rli->trans_retries));
5457       }
5458     }
5459     if (exec_res)
5460       delete ev;
5461     DBUG_RETURN(exec_res);
5462   }
5463   mysql_mutex_unlock(&rli->data_lock);
5464   rli->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_READ_FAILURE,
5465               ER(ER_SLAVE_RELAY_LOG_READ_FAILURE), "\
5466 Could not parse relay log event entry. The possible reasons are: the master's \
5467 binary log is corrupted (you can check this by running 'mysqlbinlog' on the \
5468 binary log), the slave's relay log is corrupted (you can check this by running \
5469 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's \
5470 or slave's MySQL code. If you want to check the master's binary log or slave's \
5471 relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' \
5472 on this slave.\
5473 ");
5474   DBUG_RETURN(1);
5475 }
5476 
check_io_slave_killed(THD * thd,Master_info * mi,const char * info)5477 static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info)
5478 {
5479   if (io_slave_killed(thd, mi))
5480   {
5481     if (info)
5482       sql_print_information("%s%s", info, mi->get_for_channel_str());
5483     return TRUE;
5484   }
5485   return FALSE;
5486 }
5487 
5488 /**
5489   @brief Try to reconnect slave IO thread.
5490 
5491   @details Terminates current connection to master, sleeps for
5492   @c mi->connect_retry msecs and initiates new connection with
5493   @c safe_reconnect(). Variable pointed by @c retry_count is increased -
5494   if it exceeds @c mi->retry_count then connection is not re-established
5495   and function signals error.
5496   Unless @c suppres_warnings is TRUE, a warning is put in the server error log
5497   when reconnecting. The warning message and messages used to report errors
5498   are taken from @c messages array. In case @c mi->retry_count is exceeded,
5499   no messages are added to the log.
5500 
5501   @param[in]     thd                 Thread context.
5502   @param[in]     mysql               MySQL connection.
5503   @param[in]     mi                  Master connection information.
5504   @param[in,out] retry_count         Number of attempts to reconnect.
5505   @param[in]     suppress_warnings   TRUE when a normal net read timeout
5506                                      has caused to reconnecting.
5507   @param[in]     messages            Messages to print/log, see
5508                                      reconnect_messages[] array.
5509 
5510   @retval        0                   OK.
5511   @retval        1                   There was an error.
5512 */
5513 
try_to_reconnect(THD * thd,MYSQL * mysql,Master_info * mi,uint * retry_count,bool suppress_warnings,const char * messages[SLAVE_RECON_MSG_MAX])5514 static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi,
5515                             uint *retry_count, bool suppress_warnings,
5516                             const char *messages[SLAVE_RECON_MSG_MAX])
5517 {
5518   mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
5519   thd->proc_info= messages[SLAVE_RECON_MSG_WAIT];
5520   thd->clear_active_vio();
5521   end_server(mysql);
5522   if ((*retry_count)++)
5523   {
5524     if (*retry_count > mi->retry_count)
5525       return 1;                             // Don't retry forever
5526     slave_sleep(thd, mi->connect_retry, io_slave_killed, mi);
5527   }
5528   if (check_io_slave_killed(thd, mi, messages[SLAVE_RECON_MSG_KILLED_WAITING]))
5529     return 1;
5530   thd->proc_info = messages[SLAVE_RECON_MSG_AFTER];
5531   if (!suppress_warnings)
5532   {
5533     char buf[256], llbuff[22];
5534     my_snprintf(buf, sizeof(buf), messages[SLAVE_RECON_MSG_FAILED],
5535                 mi->get_io_rpl_log_name(), llstr(mi->get_master_log_pos(),
5536                 llbuff));
5537     /*
5538       Raise a warining during registering on master/requesting dump.
5539       Log a message reading event.
5540     */
5541     if (messages[SLAVE_RECON_MSG_COMMAND][0])
5542     {
5543       mi->report(WARNING_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
5544                  ER(ER_SLAVE_MASTER_COM_FAILURE),
5545                  messages[SLAVE_RECON_MSG_COMMAND], buf);
5546     }
5547     else
5548     {
5549       sql_print_information("%s%s", buf, mi->get_for_channel_str());
5550     }
5551   }
5552   if (safe_reconnect(thd, mysql, mi, 1) || io_slave_killed(thd, mi))
5553   {
5554     sql_print_information("%s", messages[SLAVE_RECON_MSG_KILLED_AFTER]);
5555     return 1;
5556   }
5557   return 0;
5558 }
5559 
5560 
5561 /**
5562   Slave IO thread entry point.
5563 
5564   @param arg Pointer to Master_info struct that holds information for
5565   the IO thread.
5566 
5567   @return Always 0.
5568 */
handle_slave_io(void * arg)5569 extern "C" void *handle_slave_io(void *arg)
5570 {
5571   THD *thd= NULL; // needs to be first for thread_stack
5572   bool thd_added= false;
5573   MYSQL *mysql;
5574   Master_info *mi = (Master_info*)arg;
5575   Relay_log_info *rli= mi->rli;
5576   char llbuff[22];
5577   uint retry_count;
5578   bool suppress_warnings;
5579   int ret;
5580   int binlog_version;
5581 #ifndef DBUG_OFF
5582   uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0;
5583 #endif
5584   Global_THD_manager *thd_manager= Global_THD_manager::get_instance();
5585   // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
5586   my_thread_init();
5587   DBUG_ENTER("handle_slave_io");
5588 
5589   DBUG_ASSERT(mi->inited);
5590   mysql= NULL ;
5591   retry_count= 0;
5592 
5593   mysql_mutex_lock(&mi->run_lock);
5594   /* Inform waiting threads that slave has started */
5595   mi->slave_run_id++;
5596 
5597 #ifndef DBUG_OFF
5598   mi->events_until_exit = disconnect_slave_event_count;
5599 #endif
5600 
5601   thd= new THD; // note that contructor of THD uses DBUG_ !
5602   THD_CHECK_SENTRY(thd);
5603   mi->info_thd = thd;
5604 
5605   #ifdef HAVE_PSI_INTERFACE
5606   // save the instrumentation for IO thread in mi->info_thd
5607   struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)();
5608   thd_set_psi(mi->info_thd, psi);
5609   #endif
5610 
5611   thd->thread_stack= (char*) &thd; // remember where our stack is
5612   mi->clear_error();
5613   mi->slave_running = 1;
5614   if (init_slave_thread(thd, SLAVE_THD_IO))
5615   {
5616     mysql_cond_broadcast(&mi->start_cond);
5617     mysql_mutex_unlock(&mi->run_lock);
5618     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5619                ER_THD(thd, ER_SLAVE_FATAL_ERROR),
5620                "Failed during slave I/O thread initialization ");
5621     goto err;
5622   }
5623 
5624   thd_manager->add_thd(thd);
5625   thd_added= true;
5626 
5627   mi->abort_slave = 0;
5628   mysql_mutex_unlock(&mi->run_lock);
5629   mysql_cond_broadcast(&mi->start_cond);
5630 
5631   DBUG_PRINT("master_info",("log_file_name: '%s'  position: %s",
5632                             mi->get_master_log_name(),
5633                             llstr(mi->get_master_log_pos(), llbuff)));
5634 
5635   /* This must be called before run any binlog_relay_io hooks */
5636   my_set_thread_local(RPL_MASTER_INFO, mi);
5637 
5638   if (RUN_HOOK(binlog_relay_io, thread_start, (thd, mi)))
5639   {
5640     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5641                ER(ER_SLAVE_FATAL_ERROR), "Failed to run 'thread_start' hook");
5642     goto err;
5643   }
5644 
5645   if (!(mi->mysql = mysql = mysql_init(NULL)))
5646   {
5647     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5648                ER(ER_SLAVE_FATAL_ERROR), "error in mysql_init()");
5649     goto err;
5650   }
5651 
5652   THD_STAGE_INFO(thd, stage_connecting_to_master);
5653   // we can get killed during safe_connect
5654   if (!safe_connect(thd, mysql, mi))
5655   {
5656     sql_print_information("Slave I/O thread%s: connected to master '%s@%s:%d',"
5657                           "replication started in log '%s' at position %s",
5658                           mi->get_for_channel_str(),
5659                           mi->get_user(), mi->host, mi->port,
5660 			  mi->get_io_rpl_log_name(),
5661 			  llstr(mi->get_master_log_pos(), llbuff));
5662   }
5663   else
5664   {
5665     sql_print_information("Slave I/O thread%s killed while connecting to master",
5666                           mi->get_for_channel_str());
5667     goto err;
5668   }
5669 
5670 connected:
5671 
5672   /*
5673     When using auto positioning, the slave IO thread will always start reading
5674     a transaction from the beginning of the transaction (transaction's first
5675     event). So, we have to reset the transaction boundary parser after
5676     (re)connecting.
5677     If not using auto positioning, the Relay_log_info::rli_init_info() took
5678     care of putting the mi->transaction_parser in the correct state when
5679     initializing Received_gtid_set from relay log during slave server starts,
5680     as the IO thread might had stopped in the middle of a transaction.
5681   */
5682   if (mi->is_auto_position())
5683   {
5684     mi->transaction_parser.reset();
5685     mi->clear_last_gtid_queued();
5686   }
5687 
5688     DBUG_EXECUTE_IF("dbug.before_get_running_status_yes",
5689                     {
5690                       const char act[]=
5691                         "now "
5692                         "wait_for signal.io_thread_let_running";
5693                       DBUG_ASSERT(opt_debug_sync_timeout > 0);
5694                       DBUG_ASSERT(!debug_sync_set_action(thd,
5695                                                          STRING_WITH_LEN(act)));
5696                     };);
5697     DBUG_EXECUTE_IF("dbug.calculate_sbm_after_previous_gtid_log_event",
5698                     {
5699                       /* Fake that thread started 3 minutes ago */
5700                       thd->start_time.tv_sec-=180;
5701                     };);
5702   DBUG_EXECUTE_IF("dbug.calculate_sbm_after_fake_rotate_log_event",
5703                   {
5704                     /* Fake that thread started 3 minutes ago */
5705                     thd->start_time.tv_sec-=180;
5706                   };);
5707   mysql_mutex_lock(&mi->run_lock);
5708   mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
5709   mysql_mutex_unlock(&mi->run_lock);
5710 
5711   thd->slave_net = &mysql->net;
5712   THD_STAGE_INFO(thd, stage_checking_master_version);
5713   ret= get_master_version_and_clock(mysql, mi);
5714   if (!ret)
5715     ret= get_master_uuid(mysql, mi);
5716   if (!ret)
5717     ret= io_thread_init_commands(mysql, mi);
5718 
5719   if (ret == 1)
5720     /* Fatal error */
5721     goto err;
5722 
5723   if (ret == 2)
5724   {
5725     if (check_io_slave_killed(mi->info_thd, mi, "Slave I/O thread killed "
5726                               "while calling get_master_version_and_clock(...)"))
5727       goto err;
5728     suppress_warnings= FALSE;
5729     /* Try to reconnect because the error was caused by a transient network problem */
5730     if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
5731                              reconnect_messages[SLAVE_RECON_ACT_REG]))
5732       goto err;
5733     goto connected;
5734   }
5735 
5736   mysql_mutex_lock(&mi->data_lock);
5737   binlog_version= mi->get_mi_description_event()->binlog_version;
5738   mysql_mutex_unlock(&mi->data_lock);
5739 
5740   if (binlog_version > 1)
5741   {
5742     /*
5743       Register ourselves with the master.
5744     */
5745     THD_STAGE_INFO(thd, stage_registering_slave_on_master);
5746     if (register_slave_on_master(mysql, mi, &suppress_warnings))
5747     {
5748       if (!check_io_slave_killed(thd, mi, "Slave I/O thread killed "
5749                                 "while registering slave on master"))
5750       {
5751         sql_print_error("Slave I/O thread couldn't register on master");
5752         if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
5753                              reconnect_messages[SLAVE_RECON_ACT_REG]))
5754           goto err;
5755       }
5756       else
5757         goto err;
5758       goto connected;
5759     }
5760     DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_REG",
5761       if (!retry_count_reg)
5762       {
5763         retry_count_reg++;
5764         sql_print_information("Forcing to reconnect slave I/O thread%s",
5765                               mi->get_for_channel_str());
5766         if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
5767                              reconnect_messages[SLAVE_RECON_ACT_REG]))
5768           goto err;
5769         goto connected;
5770       });
5771   }
5772 
5773   DBUG_PRINT("info",("Starting reading binary log from master"));
5774   while (!io_slave_killed(thd,mi))
5775   {
5776     THD_STAGE_INFO(thd, stage_requesting_binlog_dump);
5777     if (request_dump(thd, mysql, mi, &suppress_warnings))
5778     {
5779       sql_print_error("Failed on request_dump()%s", mi->get_for_channel_str());
5780       if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
5781 requesting master dump") ||
5782           try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
5783                            reconnect_messages[SLAVE_RECON_ACT_DUMP]))
5784         goto err;
5785       goto connected;
5786     }
5787     DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_DUMP",
5788       if (!retry_count_dump)
5789       {
5790         retry_count_dump++;
5791         sql_print_information("Forcing to reconnect slave I/O thread%s",
5792                               mi->get_for_channel_str());
5793         if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
5794                              reconnect_messages[SLAVE_RECON_ACT_DUMP]))
5795           goto err;
5796         goto connected;
5797       });
5798     const char *event_buf;
5799 
5800     DBUG_ASSERT(mi->last_error().number == 0);
5801     while (!io_slave_killed(thd,mi))
5802     {
5803       ulong event_len;
5804       /*
5805          We say "waiting" because read_event() will wait if there's nothing to
5806          read. But if there's something to read, it will not wait. The
5807          important thing is to not confuse users by saying "reading" whereas
5808          we're in fact receiving nothing.
5809       */
5810       THD_STAGE_INFO(thd, stage_waiting_for_master_to_send_event);
5811       event_len= read_event(mysql, mi, &suppress_warnings);
5812       if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
5813 reading event"))
5814         goto err;
5815       DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT",
5816         if (!retry_count_event)
5817         {
5818           retry_count_event++;
5819           sql_print_information("Forcing to reconnect slave I/O thread%s",
5820                                 mi->get_for_channel_str());
5821           if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
5822                                reconnect_messages[SLAVE_RECON_ACT_EVENT]))
5823             goto err;
5824           goto connected;
5825         });
5826 
5827       if (event_len == packet_error)
5828       {
5829         uint mysql_error_number= mysql_errno(mysql);
5830         switch (mysql_error_number) {
5831         case CR_NET_PACKET_TOO_LARGE:
5832           sql_print_error("\
5833 Log entry on master is longer than slave_max_allowed_packet (%lu) on \
5834 slave. If the entry is correct, restart the server with a higher value of \
5835 slave_max_allowed_packet",
5836                          slave_max_allowed_packet);
5837           mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE,
5838                      "%s", "Got a packet bigger than 'slave_max_allowed_packet' bytes");
5839           goto err;
5840         case ER_MASTER_FATAL_ERROR_READING_BINLOG:
5841           mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG,
5842                      ER(ER_MASTER_FATAL_ERROR_READING_BINLOG),
5843                      mysql_error_number, mysql_error(mysql));
5844           goto err;
5845         case ER_OUT_OF_RESOURCES:
5846           sql_print_error("\
5847 Stopping slave I/O thread due to out-of-memory error from master");
5848           mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES,
5849                      "%s", ER(ER_OUT_OF_RESOURCES));
5850           goto err;
5851         }
5852         if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
5853                              reconnect_messages[SLAVE_RECON_ACT_EVENT]))
5854           goto err;
5855         goto connected;
5856       } // if (event_len == packet_error)
5857 
5858       retry_count=0;                    // ok event, reset retry counter
5859       THD_STAGE_INFO(thd, stage_queueing_master_event_to_the_relay_log);
5860       event_buf= (const char*)mysql->net.read_pos + 1;
5861       DBUG_PRINT("info", ("IO thread received event of type %s",
5862                  Log_event::get_type_str(
5863                             (Log_event_type)event_buf[EVENT_TYPE_OFFSET])));
5864       if (RUN_HOOK(binlog_relay_io, after_read_event,
5865                    (thd, mi,(const char*)mysql->net.read_pos + 1,
5866                     event_len, &event_buf, &event_len)))
5867       {
5868         mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5869                    ER(ER_SLAVE_FATAL_ERROR),
5870                    "Failed to run 'after_read_event' hook");
5871         goto err;
5872       }
5873 
5874       /* XXX: 'synced' should be updated by queue_event to indicate
5875          whether event has been synced to disk */
5876       bool synced= 0;
5877       if (queue_event(mi, event_buf, event_len))
5878       {
5879         mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
5880                    ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
5881                    "could not queue event from master");
5882         goto err;
5883       }
5884       if (RUN_HOOK(binlog_relay_io, after_queue_event,
5885                    (thd, mi, event_buf, event_len, synced)))
5886       {
5887         mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5888                    ER(ER_SLAVE_FATAL_ERROR),
5889                    "Failed to run 'after_queue_event' hook");
5890         goto err;
5891       }
5892 
5893       mysql_mutex_lock(&mi->data_lock);
5894       if (flush_master_info(mi, FALSE))
5895       {
5896         mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5897                    ER(ER_SLAVE_FATAL_ERROR),
5898                    "Failed to flush master info.");
5899         mysql_mutex_unlock(&mi->data_lock);
5900         goto err;
5901       }
5902       mysql_mutex_unlock(&mi->data_lock);
5903 
5904       /*
5905         Pause the IO thread execution and wait for
5906         'continue_after_queue_event' signal to continue IO thread
5907         execution.
5908       */
5909       DBUG_EXECUTE_IF("pause_after_queue_event",
5910                       {
5911                         const char act[]=
5912                           "now SIGNAL reached_after_queue_event "
5913                           "WAIT_FOR continue_after_queue_event";
5914                         DBUG_ASSERT(!debug_sync_set_action(current_thd,
5915                                                            STRING_WITH_LEN(act)));
5916                       };);
5917 
5918       /*
5919         See if the relay logs take too much space.
5920         We don't lock mi->rli->log_space_lock here; this dirty read saves time
5921         and does not introduce any problem:
5922         - if mi->rli->ignore_log_space_limit is 1 but becomes 0 just after (so
5923         the clean value is 0), then we are reading only one more event as we
5924         should, and we'll block only at the next event. No big deal.
5925         - if mi->rli->ignore_log_space_limit is 0 but becomes 1 just after (so
5926         the clean value is 1), then we are going into wait_for_relay_log_space()
5927         for no reason, but this function will do a clean read, notice the clean
5928         value and exit immediately.
5929       */
5930 #ifndef DBUG_OFF
5931       {
5932         char llbuf1[22], llbuf2[22];
5933         DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
5934 ignore_log_space_limit=%d",
5935                             llstr(rli->log_space_limit,llbuf1),
5936                             llstr(rli->log_space_total,llbuf2),
5937                             (int) rli->ignore_log_space_limit));
5938       }
5939 #endif
5940 
5941       if (rli->log_space_limit && rli->log_space_limit <
5942           rli->log_space_total &&
5943           !rli->ignore_log_space_limit)
5944         if (wait_for_relay_log_space(rli))
5945         {
5946           sql_print_error("Slave I/O thread aborted while waiting for relay"
5947                           " log space");
5948           goto err;
5949         }
5950       DBUG_EXECUTE_IF("flush_after_reading_user_var_event",
5951                       {
5952                       if (event_buf[EVENT_TYPE_OFFSET] == binary_log::USER_VAR_EVENT)
5953                       {
5954                       const char act[]= "now signal Reached wait_for signal.flush_complete_continue";
5955                       DBUG_ASSERT(opt_debug_sync_timeout > 0);
5956                       DBUG_ASSERT(!debug_sync_set_action(current_thd,
5957                                                          STRING_WITH_LEN(act)));
5958 
5959                       }
5960                       });
5961       DBUG_EXECUTE_IF("stop_io_after_reading_gtid_log_event",
5962         if (event_buf[EVENT_TYPE_OFFSET] == binary_log::GTID_LOG_EVENT)
5963           thd->killed= THD::KILLED_NO_VALUE;
5964       );
5965       DBUG_EXECUTE_IF("stop_io_after_reading_query_log_event",
5966         if (event_buf[EVENT_TYPE_OFFSET] == binary_log::QUERY_EVENT)
5967           thd->killed= THD::KILLED_NO_VALUE;
5968       );
5969       DBUG_EXECUTE_IF("stop_io_after_reading_user_var_log_event",
5970         if (event_buf[EVENT_TYPE_OFFSET] == binary_log::USER_VAR_EVENT)
5971           thd->killed= THD::KILLED_NO_VALUE;
5972       );
5973       DBUG_EXECUTE_IF("stop_io_after_reading_table_map_event",
5974         if (event_buf[EVENT_TYPE_OFFSET] == binary_log::TABLE_MAP_EVENT)
5975           thd->killed= THD::KILLED_NO_VALUE;
5976       );
5977       DBUG_EXECUTE_IF("stop_io_after_reading_xid_log_event",
5978         if (event_buf[EVENT_TYPE_OFFSET] == binary_log::XID_EVENT)
5979           thd->killed= THD::KILLED_NO_VALUE;
5980       );
5981       DBUG_EXECUTE_IF("stop_io_after_reading_write_rows_log_event",
5982         if (event_buf[EVENT_TYPE_OFFSET] == binary_log::WRITE_ROWS_EVENT)
5983           thd->killed= THD::KILLED_NO_VALUE;
5984       );
5985       DBUG_EXECUTE_IF("stop_io_after_reading_unknown_event",
5986         if (event_buf[EVENT_TYPE_OFFSET] >= binary_log::ENUM_END_EVENT)
5987           thd->killed= THD::KILLED_NO_VALUE;
5988       );
5989       DBUG_EXECUTE_IF("stop_io_after_queuing_event",
5990         thd->killed= THD::KILLED_NO_VALUE;
5991       );
5992       /*
5993         After event is flushed to relay log file, memory used
5994         by thread's mem_root is not required any more.
5995         Hence adding free_root(thd->mem_root,...) to do the
5996         cleanup, otherwise a long running IO thread can
5997         cause OOM error.
5998       */
5999       free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
6000     }
6001   }
6002 
6003   // error = 0;
6004 err:
6005   // print the current replication position
6006   sql_print_information("Slave I/O thread exiting%s, read up to log '%s', position %s",
6007                         mi->get_for_channel_str(), mi->get_io_rpl_log_name(),
6008                         llstr(mi->get_master_log_pos(), llbuff));
6009   /* At this point the I/O thread will not try to reconnect anymore. */
6010   mi->is_stopping.atomic_set(1);
6011   (void) RUN_HOOK(binlog_relay_io, thread_stop, (thd, mi));
6012   /*
6013     Pause the IO thread and wait for 'continue_to_stop_io_thread'
6014     signal to continue to shutdown the IO thread.
6015   */
6016   DBUG_EXECUTE_IF("pause_after_io_thread_stop_hook",
6017                   {
6018                     const char act[]= "now SIGNAL reached_stopping_io_thread "
6019                                       "WAIT_FOR continue_to_stop_io_thread";
6020                     DBUG_ASSERT(!debug_sync_set_action(thd,
6021                                                        STRING_WITH_LEN(act)));
6022                   };);
6023   thd->reset_query();
6024   thd->reset_db(NULL_CSTR);
6025   if (mysql)
6026   {
6027     /*
6028       Here we need to clear the active VIO before closing the
6029       connection with the master.  The reason is that THD::awake()
6030       might be called from terminate_slave_thread() because somebody
6031       issued a STOP SLAVE.  If that happends, the shutdown_active_vio()
6032       can be called in the middle of closing the VIO associated with
6033       the 'mysql' object, causing a crash.
6034     */
6035     thd->clear_active_vio();
6036     mysql_close(mysql);
6037     mi->mysql=0;
6038   }
6039   mysql_mutex_lock(&mi->data_lock);
6040   write_ignored_events_info_to_relay_log(thd, mi, false/* force_flush_mi_info */);
6041   mysql_mutex_unlock(&mi->data_lock);
6042   THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit);
6043   mysql_mutex_lock(&mi->run_lock);
6044   /*
6045     Clean information used to start slave in order to avoid
6046     security issues.
6047   */
6048   mi->reset_start_info();
6049   /* Forget the relay log's format */
6050   mysql_mutex_lock(&mi->data_lock);
6051   mi->set_mi_description_event(NULL);
6052   mysql_mutex_unlock(&mi->data_lock);
6053 
6054   // destructor will not free it, because net.vio is 0
6055   thd->get_protocol_classic()->end_net();
6056 
6057   thd->release_resources();
6058   THD_CHECK_SENTRY(thd);
6059   if (thd_added)
6060     thd_manager->remove_thd(thd);
6061 
6062   mi->abort_slave= 0;
6063   mi->slave_running= 0;
6064   mi->is_stopping.atomic_set(0);
6065   mysql_mutex_lock(&mi->info_thd_lock);
6066   mi->info_thd= NULL;
6067   mysql_mutex_unlock(&mi->info_thd_lock);
6068 
6069   /*
6070     The thd can only be destructed after indirect references
6071     through mi->info_thd are cleared: mi->info_thd= NULL.
6072 
6073     For instance, user thread might be issuing show_slave_status
6074     and attempting to read mi->info_thd->get_proc_info().
6075     Therefore thd must only be deleted after info_thd is set
6076     to NULL.
6077   */
6078   delete thd;
6079 
6080   /*
6081     Note: the order of the two following calls (first broadcast, then unlock)
6082     is important. Otherwise a killer_thread can execute between the calls and
6083     delete the mi structure leading to a crash! (see BUG#25306 for details)
6084    */
6085   mysql_cond_broadcast(&mi->stop_cond);       // tell the world we are done
6086   DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
6087   mysql_mutex_unlock(&mi->run_lock);
6088   DBUG_LEAVE;                                   // Must match DBUG_ENTER()
6089   my_thread_end();
6090 #if OPENSSL_VERSION_NUMBER < 0x10100000L
6091   ERR_remove_thread_state(0);
6092 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
6093   my_thread_exit(0);
6094   return(0);                                    // Avoid compiler warnings
6095 }
6096 
6097 /*
6098   Check the temporary directory used by commands like
6099   LOAD DATA INFILE.
6100  */
6101 static
check_temp_dir(char * tmp_file,const char * channel_name)6102 int check_temp_dir(char* tmp_file, const char *channel_name)
6103 {
6104   int fd;
6105   MY_DIR *dirp;
6106   char tmp_dir[FN_REFLEN];
6107   size_t tmp_dir_size;
6108 
6109   DBUG_ENTER("check_temp_dir");
6110 
6111   /*
6112     Get the directory from the temporary file.
6113   */
6114   dirname_part(tmp_dir, tmp_file, &tmp_dir_size);
6115 
6116   /*
6117     Check if the directory exists.
6118    */
6119   if (!(dirp=my_dir(tmp_dir,MYF(MY_WME))))
6120     DBUG_RETURN(1);
6121   my_dirend(dirp);
6122 
6123   /*
6124     Check permissions to create a file.
6125    */
6126   //append the server UUID to the temp file name.
6127   uint size_of_tmp_file_name= FN_REFLEN+TEMP_FILE_MAX_LEN * sizeof(char);
6128   char *unique_tmp_file_name= (char*)my_malloc(key_memory_rpl_slave_check_temp_dir,
6129                                                size_of_tmp_file_name, MYF(0));
6130   /*
6131     In the case of Multisource replication, the file create
6132     sometimes fail because of there is a race that a second SQL
6133     thread might create the same file and the creation fails.
6134     TO overcome this, we add a channel name to get a unique file name.
6135   */
6136 
6137   /* @TODO: dangerous. Prevent this buffer flow */
6138   my_snprintf(unique_tmp_file_name, size_of_tmp_file_name,
6139               "%s%s%s", tmp_file, channel_name, server_uuid);
6140   if ((fd= mysql_file_create(key_file_misc,
6141                              unique_tmp_file_name, CREATE_MODE,
6142                              O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
6143                              MYF(MY_WME))) < 0)
6144   DBUG_RETURN(1);
6145 
6146   /*
6147     Clean up.
6148    */
6149   mysql_file_close(fd, MYF(0));
6150 
6151   mysql_file_delete(key_file_misc, unique_tmp_file_name, MYF(0));
6152   my_free(unique_tmp_file_name);
6153   DBUG_RETURN(0);
6154 }
6155 
6156 /*
6157   Worker thread for the parallel execution of the replication events.
6158 */
handle_slave_worker(void * arg)6159 extern "C" void *handle_slave_worker(void *arg)
6160 {
6161   THD *thd;                     /* needs to be first for thread_stack */
6162   bool thd_added= false;
6163   int error= 0;
6164   Slave_worker *w= (Slave_worker *) arg;
6165   Relay_log_info* rli= w->c_rli;
6166   ulong purge_cnt= 0;
6167   ulonglong purge_size= 0;
6168   struct slave_job_item _item, *job_item= &_item;
6169   Global_THD_manager *thd_manager= Global_THD_manager::get_instance();
6170   #ifdef HAVE_PSI_INTERFACE
6171   struct PSI_thread *psi;
6172   #endif
6173 
6174   my_thread_init();
6175   DBUG_ENTER("handle_slave_worker");
6176 
6177   thd= new THD;
6178   if (!thd)
6179   {
6180     sql_print_error("Failed during slave worker initialization%s",
6181                     rli->get_for_channel_str());
6182     goto err;
6183   }
6184 
6185   if (channel_map.is_group_replication_channel_name(rli->get_channel())) {
6186     if (channel_map.is_group_replication_channel_name(rli->get_channel(),
6187                                                       true)) {
6188       thd->rpl_thd_ctx.set_rpl_channel_type(GR_APPLIER_CHANNEL);
6189     } else {
6190       thd->rpl_thd_ctx.set_rpl_channel_type(GR_RECOVERY_CHANNEL);
6191     }
6192   } else {
6193     thd->rpl_thd_ctx.set_rpl_channel_type(RPL_STANDARD_CHANNEL);
6194   }
6195 
6196   mysql_mutex_lock(&w->info_thd_lock);
6197   w->info_thd= thd;
6198   mysql_mutex_unlock(&w->info_thd_lock);
6199   thd->thread_stack = (char*)&thd;
6200 
6201   #ifdef HAVE_PSI_INTERFACE
6202   // save the instrumentation for worker thread in w->info_thd
6203   psi= PSI_THREAD_CALL(get_thread)();
6204   thd_set_psi(w->info_thd, psi);
6205   #endif
6206 
6207   if (init_slave_thread(thd, SLAVE_THD_WORKER))
6208   {
6209     // todo make SQL thread killed
6210     sql_print_error("Failed during slave worker initialization%s",
6211                     rli->get_for_channel_str());
6212     goto err;
6213   }
6214   thd->rli_slave= w;
6215   thd->init_for_queries(w);
6216   /* Set applier thread InnoDB priority */
6217   set_thd_tx_priority(thd, rli->get_thd_tx_priority());
6218 
6219   thd_manager->add_thd(thd);
6220   thd_added= true;
6221 
6222   if (w->update_is_transactional())
6223   {
6224     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
6225                 "Error checking if the worker repository is transactional.");
6226     goto err;
6227   }
6228 
6229   mysql_mutex_lock(&w->jobs_lock);
6230   w->running_status= Slave_worker::RUNNING;
6231   mysql_cond_signal(&w->jobs_cond);
6232 
6233   mysql_mutex_unlock(&w->jobs_lock);
6234 
6235   DBUG_ASSERT(thd->is_slave_error == 0);
6236 
6237   w->stats_exec_time= w->stats_read_time= 0;
6238   set_timespec_nsec(&w->ts_exec[0], 0);
6239   set_timespec_nsec(&w->ts_exec[1], 0);
6240   set_timespec_nsec(&w->stats_begin, 0);
6241 
6242   while (!error)
6243   {
6244     error= slave_worker_exec_job_group(w, rli);
6245   }
6246 
6247   /*
6248      Cleanup after an error requires clear_error() go first.
6249      Otherwise assert(!all) in binlog_rollback()
6250   */
6251   thd->clear_error();
6252   w->cleanup_context(thd, error);
6253 
6254   mysql_mutex_lock(&w->jobs_lock);
6255 
6256   while(de_queue(&w->jobs, job_item))
6257   {
6258     purge_cnt++;
6259     purge_size += job_item->data->common_header->data_written;
6260     DBUG_ASSERT(job_item->data);
6261     delete job_item->data;
6262   }
6263 
6264   DBUG_ASSERT(w->jobs.len == 0);
6265 
6266   mysql_mutex_unlock(&w->jobs_lock);
6267 
6268   mysql_mutex_lock(&rli->pending_jobs_lock);
6269   rli->pending_jobs -= purge_cnt;
6270   rli->mts_pending_jobs_size -= purge_size;
6271   DBUG_ASSERT(rli->mts_pending_jobs_size < rli->mts_pending_jobs_size_max);
6272 
6273   mysql_mutex_unlock(&rli->pending_jobs_lock);
6274 
6275   /*
6276      In MTS case cleanup_after_session() has be called explicitly.
6277      TODO: to make worker thd be deleted before Slave_worker instance.
6278   */
6279   if (thd->rli_slave)
6280   {
6281     w->cleanup_after_session();
6282     thd->rli_slave= NULL;
6283   }
6284   mysql_mutex_lock(&w->jobs_lock);
6285 
6286   struct timespec stats_end;
6287   set_timespec_nsec(&stats_end, 0);
6288   DBUG_PRINT("info", ("Worker %lu statistics: "
6289                       "events processed = %lu "
6290                       "online time = %llu "
6291                       "events exec time = %llu "
6292                       "events read time = %llu "
6293                       "hungry waits = %lu "
6294                       "priv queue overfills = %llu ",
6295                       w->id, w->events_done,
6296                       diff_timespec(&stats_end, &w->stats_begin),
6297                       w->stats_exec_time,
6298                       w->stats_read_time,
6299                       w->wq_empty_waits,
6300                       w->jobs.waited_overfill));
6301 
6302   w->running_status= Slave_worker::NOT_RUNNING;
6303   mysql_cond_signal(&w->jobs_cond);  // famous last goodbye
6304 
6305   mysql_mutex_unlock(&w->jobs_lock);
6306 
6307 err:
6308 
6309   if (thd)
6310   {
6311     /*
6312        The slave code is very bad. Notice that it is missing
6313        several clean up calls here. I've just added what was
6314        necessary to avoid valgrind errors.
6315 
6316        /Alfranio
6317     */
6318     thd->get_protocol_classic()->end_net();
6319 
6320     /*
6321       to avoid close_temporary_tables() closing temp tables as those
6322       are Coordinator's burden.
6323     */
6324     thd->system_thread= NON_SYSTEM_THREAD;
6325     thd->release_resources();
6326 
6327     THD_CHECK_SENTRY(thd);
6328     if (thd_added)
6329       thd_manager->remove_thd(thd);
6330     delete thd;
6331   }
6332 
6333   my_thread_end();
6334 #if OPENSSL_VERSION_NUMBER < 0x10100000L
6335   ERR_remove_thread_state(0);
6336 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
6337   my_thread_exit(0);
6338   DBUG_RETURN(0);
6339 }
6340 
6341 /**
6342    Orders jobs by comparing relay log information.
6343 */
6344 
mts_event_coord_cmp(LOG_POS_COORD * id1,LOG_POS_COORD * id2)6345 int mts_event_coord_cmp(LOG_POS_COORD *id1, LOG_POS_COORD *id2)
6346 {
6347   longlong filecmp= strcmp(id1->file_name, id2->file_name);
6348   longlong poscmp= id1->pos - id2->pos;
6349   return (filecmp < 0  ? -1 : (filecmp > 0  ?  1 :
6350          (poscmp  < 0  ? -1 : (poscmp  > 0  ?  1 : 0))));
6351 }
6352 
mts_recovery_groups(Relay_log_info * rli)6353 bool mts_recovery_groups(Relay_log_info *rli)
6354 {
6355   Log_event *ev= NULL;
6356   bool is_error= false;
6357   const char *errmsg= NULL;
6358   bool flag_group_seen_begin= FALSE;
6359   uint recovery_group_cnt= 0;
6360   bool not_reached_commit= true;
6361 
6362   // Value-initialization, to avoid compiler warnings on push_back.
6363   Slave_job_group job_worker= Slave_job_group();
6364 
6365   IO_CACHE log;
6366   File file;
6367   LOG_INFO linfo;
6368   my_off_t offset= 0;
6369   MY_BITMAP *groups= &rli->recovery_groups;
6370   THD *thd= current_thd;
6371 
6372   DBUG_ENTER("mts_recovery_groups");
6373 
6374   DBUG_ASSERT(rli->slave_parallel_workers == 0);
6375 
6376   /*
6377      Although mts_recovery_groups() is reentrant it returns
6378      early if the previous invocation raised any bit in
6379      recovery_groups bitmap.
6380   */
6381   if (rli->is_mts_recovery())
6382     DBUG_RETURN(0);
6383 
6384   /*
6385     Parallel applier recovery is based on master log name and
6386     position, on Group Replication we have several masters what
6387     makes impossible to recover parallel applier from that information.
6388     Since we always have GTID_MODE=ON on Group Replication, we can
6389     ignore the positions completely, seek the current relay log to the
6390     beginning and start from there. Already applied transactions will be
6391     skipped due to GTIDs auto skip feature and applier will resume from
6392     the last applied transaction.
6393   */
6394   if (channel_map.is_group_replication_channel_name(rli->get_channel(), true))
6395   {
6396     rli->recovery_parallel_workers= 0;
6397     rli->mts_recovery_group_cnt= 0;
6398     rli->set_group_relay_log_pos(BIN_LOG_HEADER_SIZE);
6399     rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
6400     DBUG_RETURN(0);
6401   }
6402 
6403   /*
6404     Save relay log position to compare with worker's position.
6405   */
6406   LOG_POS_COORD cp=
6407   {
6408     (char *) rli->get_group_master_log_name(),
6409     rli->get_group_master_log_pos()
6410   };
6411 
6412   Format_description_log_event fdle(BINLOG_VERSION), *p_fdle= &fdle;
6413   DBUG_ASSERT(p_fdle->is_valid());
6414 
6415   /*
6416     Gathers information on valuable workers and stores it in
6417     above_lwm_jobs in asc ordered by the master binlog coordinates.
6418   */
6419   Prealloced_array<Slave_job_group, 16, true>
6420     above_lwm_jobs(PSI_NOT_INSTRUMENTED);
6421   above_lwm_jobs.reserve(rli->recovery_parallel_workers);
6422 
6423   /*
6424     When info tables are used and autocommit= 0 we force a new
6425     transaction start to avoid table access deadlocks when START SLAVE
6426     is executed after STOP SLAVE with MTS enabled.
6427   */
6428   if (is_autocommit_off_and_infotables(thd))
6429     if (trans_begin(thd))
6430       goto err;
6431 
6432   for (uint id= 0; id < rli->recovery_parallel_workers; id++)
6433   {
6434     Slave_worker *worker=
6435       Rpl_info_factory::create_worker(opt_rli_repository_id, id, rli, true);
6436 
6437     if (!worker)
6438     {
6439       if (is_autocommit_off_and_infotables(thd))
6440         trans_rollback(thd);
6441       goto err;
6442     }
6443 
6444     LOG_POS_COORD w_last= { const_cast<char*>(worker->get_group_master_log_name()),
6445                             worker->get_group_master_log_pos() };
6446     if (mts_event_coord_cmp(&w_last, &cp) > 0)
6447     {
6448       /*
6449         Inserts information into a dynamic array for further processing.
6450         The jobs/workers are ordered by the last checkpoint positions
6451         workers have seen.
6452       */
6453       job_worker.worker= worker;
6454       job_worker.checkpoint_log_pos= worker->checkpoint_master_log_pos;
6455       job_worker.checkpoint_log_name= worker->checkpoint_master_log_name;
6456 
6457       above_lwm_jobs.push_back(job_worker);
6458     }
6459     else
6460     {
6461       /*
6462         Deletes the worker because its jobs are included in the latest
6463         checkpoint.
6464       */
6465       delete worker;
6466     }
6467   }
6468 
6469   /*
6470     When info tables are used and autocommit= 0 we force transaction
6471     commit to avoid table access deadlocks when START SLAVE is executed
6472     after STOP SLAVE with MTS enabled.
6473   */
6474   if (is_autocommit_off_and_infotables(thd))
6475     if (trans_commit(thd))
6476       goto err;
6477 
6478   /*
6479     In what follows, the group Recovery Bitmap is constructed.
6480 
6481      seek(lwm);
6482 
6483      while(w= next(above_lwm_w))
6484        do
6485          read G
6486          if G == w->last_comm
6487            w.B << group_cnt++;
6488            RB |= w.B;
6489             break;
6490          else
6491            group_cnt++;
6492         while(!eof);
6493         continue;
6494   */
6495   DBUG_ASSERT(!rli->recovery_groups_inited);
6496 
6497   if (!above_lwm_jobs.empty())
6498   {
6499     bitmap_init(groups, NULL, MTS_MAX_BITS_IN_GROUP, FALSE);
6500     rli->recovery_groups_inited= true;
6501     bitmap_clear_all(groups);
6502   }
6503   rli->mts_recovery_group_cnt= 0;
6504   for (Slave_job_group *jg= above_lwm_jobs.begin();
6505        jg != above_lwm_jobs.end(); ++jg)
6506   {
6507     Slave_worker *w= jg->worker;
6508     LOG_POS_COORD w_last= { const_cast<char*>(w->get_group_master_log_name()),
6509                             w->get_group_master_log_pos() };
6510     bool checksum_detected= FALSE;
6511 
6512     sql_print_information("Slave: MTS group recovery relay log info based on "
6513                           "Worker-Id %lu, "
6514                           "group_relay_log_name %s, group_relay_log_pos %llu "
6515                           "group_master_log_name %s, group_master_log_pos %llu",
6516                           w->id,
6517                           w->get_group_relay_log_name(),
6518                           w->get_group_relay_log_pos(),
6519                           w->get_group_master_log_name(),
6520                           w->get_group_master_log_pos());
6521 
6522     recovery_group_cnt= 0;
6523     not_reached_commit= true;
6524     if (rli->relay_log.find_log_pos(&linfo, rli->get_group_relay_log_name(), 1))
6525     {
6526       sql_print_error("Error looking for %s.", rli->get_group_relay_log_name());
6527       goto err;
6528     }
6529     offset= rli->get_group_relay_log_pos();
6530     for (int checking= 0 ; not_reached_commit; checking++)
6531     {
6532       if ((file= open_binlog_file(&log, linfo.log_file_name, &errmsg)) < 0)
6533       {
6534         sql_print_error("%s", errmsg);
6535         goto err;
6536       }
6537       /*
6538         Looking for the actual relay checksum algorithm that is present in
6539         a FD at head events of the relay log.
6540       */
6541       if (!checksum_detected)
6542       {
6543         int i= 0;
6544         while (i < 4 && (ev= Log_event::read_log_event(&log,
6545                (mysql_mutex_t*) 0, p_fdle, 0)))
6546         {
6547           if (ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT)
6548           {
6549             p_fdle->common_footer->checksum_alg=
6550                                    ev->common_footer->checksum_alg;
6551             checksum_detected= TRUE;
6552           }
6553           delete ev;
6554           i++;
6555         }
6556         if (!checksum_detected)
6557         {
6558           sql_print_error("%s", "malformed or very old relay log which "
6559                           "does not have FormatDescriptor");
6560           goto err;
6561         }
6562       }
6563 
6564       my_b_seek(&log, offset);
6565 
6566       while (not_reached_commit &&
6567              (ev= Log_event::read_log_event(&log, 0, p_fdle,
6568                                             opt_slave_sql_verify_checksum)))
6569       {
6570         DBUG_ASSERT(ev->is_valid());
6571 
6572         if (ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT)
6573           p_fdle->common_footer->checksum_alg= ev->common_footer->checksum_alg;
6574 
6575         if (ev->get_type_code() == binary_log::ROTATE_EVENT ||
6576             ev->get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT ||
6577             ev->get_type_code() == binary_log::PREVIOUS_GTIDS_LOG_EVENT)
6578         {
6579           delete ev;
6580           ev= NULL;
6581           continue;
6582         }
6583 
6584         DBUG_PRINT("mts", ("Event Recoverying relay log info "
6585                    "group_mster_log_name %s, event_master_log_pos %llu type code %u.",
6586                    linfo.log_file_name, ev->common_header->log_pos,
6587                    ev->get_type_code()));
6588 
6589         if (ev->starts_group())
6590         {
6591           flag_group_seen_begin= true;
6592         }
6593         else if ((ev->ends_group() || !flag_group_seen_begin) &&
6594                  !is_gtid_event(ev))
6595         {
6596           int ret= 0;
6597           LOG_POS_COORD ev_coord= { (char *) rli->get_group_master_log_name(),
6598                                       ev->common_header->log_pos };
6599           flag_group_seen_begin= false;
6600           recovery_group_cnt++;
6601 
6602           sql_print_information("Slave: MTS group recovery relay log info "
6603                                 "group_master_log_name %s, "
6604                                 "event_master_log_pos %llu.",
6605                                 rli->get_group_master_log_name(),
6606                                 ev->common_header->log_pos);
6607           if ((ret= mts_event_coord_cmp(&ev_coord, &w_last)) == 0)
6608           {
6609 #ifndef DBUG_OFF
6610             for (uint i= 0; i <= w->checkpoint_seqno; i++)
6611             {
6612               if (bitmap_is_set(&w->group_executed, i))
6613                 DBUG_PRINT("mts", ("Bit %u is set.", i));
6614               else
6615                 DBUG_PRINT("mts", ("Bit %u is not set.", i));
6616             }
6617 #endif
6618             DBUG_PRINT("mts",
6619                        ("Doing a shift ini(%lu) end(%lu).",
6620                        (w->checkpoint_seqno + 1) - recovery_group_cnt,
6621                         w->checkpoint_seqno));
6622 
6623             for (uint i= (w->checkpoint_seqno + 1) - recovery_group_cnt,
6624                  j= 0; i <= w->checkpoint_seqno; i++, j++)
6625             {
6626               if (bitmap_is_set(&w->group_executed, i))
6627               {
6628                 DBUG_PRINT("mts", ("Setting bit %u.", j));
6629                 bitmap_fast_test_and_set(groups, j);
6630               }
6631             }
6632             not_reached_commit= false;
6633           }
6634           else
6635             DBUG_ASSERT(ret < 0);
6636         }
6637         delete ev;
6638         ev= NULL;
6639       }
6640       end_io_cache(&log);
6641       mysql_file_close(file, MYF(MY_WME));
6642       offset= BIN_LOG_HEADER_SIZE;
6643       if (not_reached_commit && rli->relay_log.find_next_log(&linfo, 1))
6644       {
6645          sql_print_error("Error looking for file after %s.", linfo.log_file_name);
6646          goto err;
6647       }
6648     }
6649 
6650     rli->mts_recovery_group_cnt= (rli->mts_recovery_group_cnt < recovery_group_cnt ?
6651       recovery_group_cnt : rli->mts_recovery_group_cnt);
6652   }
6653 
6654   DBUG_ASSERT(!rli->recovery_groups_inited ||
6655               rli->mts_recovery_group_cnt <= groups->n_bits);
6656 
6657   goto end;
6658 err:
6659   is_error= true;
6660 end:
6661 
6662   for (Slave_job_group *jg= above_lwm_jobs.begin();
6663        jg != above_lwm_jobs.end(); ++jg)
6664   {
6665     delete jg->worker;
6666   }
6667 
6668   if (rli->mts_recovery_group_cnt == 0)
6669     rli->clear_mts_recovery_groups();
6670 
6671   DBUG_RETURN(is_error);
6672 }
6673 
6674 /**
6675    Processing rli->gaq to find out the low-water-mark (lwm) coordinates
6676    which is stored into the cental recovery table.
6677 
6678    @param rli            pointer to Relay-log-info of Coordinator
6679    @param period         period of processing GAQ, normally derived from
6680                          @c mts_checkpoint_period
6681    @param force          if TRUE then hang in a loop till some progress
6682    @param need_data_lock False if rli->data_lock mutex is aquired by
6683                          the caller.
6684 
6685    @return FALSE success, TRUE otherwise
6686 */
mts_checkpoint_routine(Relay_log_info * rli,ulonglong period,bool force,bool need_data_lock)6687 bool mts_checkpoint_routine(Relay_log_info *rli, ulonglong period,
6688                             bool force, bool need_data_lock)
6689 {
6690   ulong cnt;
6691   bool error= FALSE;
6692   struct timespec curr_clock;
6693   time_t ts=0;
6694 
6695   DBUG_ENTER("checkpoint_routine");
6696 
6697 #ifndef DBUG_OFF
6698   if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
6699   {
6700     if (!rli->gaq->count_done(rli))
6701       DBUG_RETURN(FALSE);
6702   }
6703   DBUG_EXECUTE_IF("mts_checkpoint",
6704                   {
6705                     const char act[]=
6706                       "now signal mts_checkpoint_start";
6707                     DBUG_ASSERT(!debug_sync_set_action(rli->info_thd,
6708                                                        STRING_WITH_LEN(act)));
6709                  };);
6710 #endif
6711 
6712   /*
6713     rli->checkpoint_group can have two possible values due to
6714     two possible status of the last (being scheduled) group.
6715   */
6716   DBUG_ASSERT(!rli->gaq->full() ||
6717               ((rli->checkpoint_seqno == rli->checkpoint_group -1 &&
6718                 rli->mts_group_status == Relay_log_info::MTS_IN_GROUP) ||
6719                rli->checkpoint_seqno == rli->checkpoint_group));
6720 
6721   /*
6722     Currently, the checkpoint routine is being called by the SQL Thread.
6723     For that reason, this function is called call from appropriate points
6724     in the SQL Thread's execution path and the elapsed time is calculated
6725     here to check if it is time to execute it.
6726   */
6727   set_timespec_nsec(&curr_clock, 0);
6728   ulonglong diff= diff_timespec(&curr_clock, &rli->last_clock);
6729   if (!force && diff < period)
6730   {
6731     /*
6732       We do not need to execute the checkpoint now because
6733       the time elapsed is not enough.
6734     */
6735     DBUG_RETURN(FALSE);
6736   }
6737 
6738  do
6739   {
6740     if (!is_mts_db_partitioned(rli))
6741       mysql_mutex_lock(&rli->mts_gaq_LOCK);
6742 
6743     cnt= rli->gaq->move_queue_head(&rli->workers);
6744 
6745     if (!is_mts_db_partitioned(rli))
6746       mysql_mutex_unlock(&rli->mts_gaq_LOCK);
6747 #ifndef DBUG_OFF
6748     if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0) &&
6749         cnt != opt_mts_checkpoint_period)
6750       sql_print_error("This an error cnt != mts_checkpoint_period");
6751 #endif
6752   } while (!sql_slave_killed(rli->info_thd, rli) &&
6753            cnt == 0 && force &&
6754            !DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0) &&
6755            (my_sleep(rli->mts_coordinator_basic_nap), 1));
6756   /*
6757     This checks how many consecutive jobs where processed.
6758     If this value is different than zero the checkpoint
6759     routine can proceed. Otherwise, there is nothing to be
6760     done.
6761   */
6762   if (cnt == 0)
6763     goto end;
6764 
6765  /*
6766     The workers have completed  cnt jobs from the gaq. This means that we
6767     should increment C->jobs_done by cnt.
6768   */
6769   if (!is_mts_worker(rli->info_thd) &&
6770       !is_mts_db_partitioned(rli))
6771   {
6772     DBUG_PRINT("info", ("jobs_done this itr=%ld", cnt));
6773     static_cast<Mts_submode_logical_clock*>
6774       (rli->current_mts_submode)->jobs_done+= cnt;
6775   }
6776 
6777   /* TODO:
6778      to turn the least occupied selection in terms of jobs pieces
6779   */
6780   for (Slave_worker **it= rli->workers.begin();
6781        it != rli->workers.begin(); ++it)
6782   {
6783     Slave_worker *w_i= *it;
6784     rli->least_occupied_workers[w_i->id]= w_i->jobs.len;
6785   };
6786   std::sort(rli->least_occupied_workers.begin(),
6787             rli->least_occupied_workers.end());
6788 
6789   if (need_data_lock)
6790     mysql_mutex_lock(&rli->data_lock);
6791   else
6792     mysql_mutex_assert_owner(&rli->data_lock);
6793 
6794   /*
6795     "Coordinator::commit_positions" {
6796 
6797     rli->gaq->lwm has been updated in move_queue_head() and
6798     to contain all but rli->group_master_log_name which
6799     is altered solely by Coordinator at special checkpoints.
6800   */
6801   rli->set_group_master_log_pos(rli->gaq->lwm.group_master_log_pos);
6802   rli->set_group_relay_log_pos(rli->gaq->lwm.group_relay_log_pos);
6803   DBUG_PRINT("mts", ("New checkpoint %llu %llu %s",
6804              rli->gaq->lwm.group_master_log_pos,
6805              rli->gaq->lwm.group_relay_log_pos,
6806              rli->gaq->lwm.group_relay_log_name));
6807 
6808   if (rli->gaq->lwm.group_relay_log_name[0] != 0)
6809     rli->set_group_relay_log_name(rli->gaq->lwm.group_relay_log_name);
6810 
6811   /*
6812      todo: uncomment notifies when UNTIL will be supported
6813 
6814      rli->notify_group_master_log_name_update();
6815      rli->notify_group_relay_log_name_update();
6816 
6817      Todo: optimize with if (wait_flag) broadcast
6818          waiter: set wait_flag; waits....; drops wait_flag;
6819   */
6820 
6821   error= rli->flush_info(TRUE);
6822 
6823   mysql_cond_broadcast(&rli->data_cond);
6824   if (need_data_lock)
6825     mysql_mutex_unlock(&rli->data_lock);
6826 
6827   /*
6828     We need to ensure that this is never called at this point when
6829     cnt is zero. This value means that the checkpoint information
6830     will be completely reset.
6831   */
6832 
6833   /*
6834     Update the rli->last_master_timestamp for reporting correct Seconds_behind_master.
6835 
6836     If GAQ is empty, set it to zero.
6837     Else, update it with the timestamp of the first job of the Slave_job_queue
6838     which was assigned in the Log_event::get_slave_worker() function.
6839   */
6840   ts= rli->gaq->empty()
6841     ? 0
6842     : reinterpret_cast<Slave_job_group*>(rli->gaq->head_queue())->ts;
6843   rli->reset_notified_checkpoint(cnt, ts, need_data_lock, true);
6844   /* end-of "Coordinator::"commit_positions" */
6845 
6846 end:
6847 #ifndef DBUG_OFF
6848   if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
6849     DBUG_SUICIDE();
6850   DBUG_EXECUTE_IF("mts_checkpoint",
6851                   {
6852                     const char act[]=
6853                       "now signal mts_checkpoint_end";
6854                     DBUG_ASSERT(!debug_sync_set_action(rli->info_thd,
6855                                                        STRING_WITH_LEN(act)));
6856                   };);
6857 #endif
6858   set_timespec_nsec(&rli->last_clock, 0);
6859 
6860   DBUG_RETURN(error);
6861 }
6862 
6863 /**
6864    Instantiation of a Slave_worker and forking out a single Worker thread.
6865 
6866    @param  rli  Coordinator's Relay_log_info pointer
6867    @param  i    identifier of the Worker
6868 
6869    @return 0 suppress or 1 if fails
6870 */
slave_start_single_worker(Relay_log_info * rli,ulong i)6871 int slave_start_single_worker(Relay_log_info *rli, ulong i)
6872 {
6873   int error= 0;
6874   my_thread_handle th;
6875   Slave_worker *w= NULL;
6876 
6877   mysql_mutex_assert_owner(&rli->run_lock);
6878 
6879   if (!(w=
6880         Rpl_info_factory::create_worker(opt_rli_repository_id, i, rli, false)))
6881   {
6882     sql_print_error("Failed during slave worker thread creation%s",
6883                     rli->get_for_channel_str());
6884     error= 1;
6885     goto err;
6886   }
6887 
6888   if (w->init_worker(rli, i))
6889   {
6890     sql_print_error("Failed during slave worker thread creation%s",
6891                     rli->get_for_channel_str());
6892     error= 1;
6893     goto err;
6894   }
6895 
6896   // We assume that workers are added in sequential order here.
6897   DBUG_ASSERT(i == rli->workers.size());
6898   if (i >= rli->workers.size())
6899     rli->workers.resize(i+1);
6900   rli->workers[i]= w;
6901 
6902   w->currently_executing_gtid.set_automatic();
6903 
6904   if (DBUG_EVALUATE_IF("mts_worker_thread_fails", i == 1, 0) ||
6905       (error= mysql_thread_create(key_thread_slave_worker, &th,
6906                                   &connection_attrib, handle_slave_worker,
6907                                   (void*) w)))
6908   {
6909     sql_print_error("Failed during slave worker thread creation%s (errno= %d)",
6910                     rli->get_for_channel_str(), error);
6911     error= 1;
6912     goto err;
6913   }
6914 
6915   mysql_mutex_lock(&w->jobs_lock);
6916   if (w->running_status == Slave_worker::NOT_RUNNING)
6917     mysql_cond_wait(&w->jobs_cond, &w->jobs_lock);
6918   mysql_mutex_unlock(&w->jobs_lock);
6919   // Least occupied inited with zero
6920   {
6921     ulong jobs_len= w->jobs.len;
6922     rli->least_occupied_workers.push_back(jobs_len);
6923   }
6924 err:
6925   if (error && w)
6926   {
6927     // Free the current submode object
6928     delete w->current_mts_submode;
6929     w->current_mts_submode= 0;
6930     delete w;
6931     /*
6932       Any failure after array inserted must follow with deletion
6933       of just created item.
6934     */
6935     if (rli->workers.size() == i + 1)
6936       rli->workers.erase(i);
6937   }
6938   return error;
6939 }
6940 
6941 /**
6942    Initialization of the central rli members for Coordinator's role,
6943    communication channels such as Assigned Partition Hash (APH),
6944    and starting the Worker pool.
6945 
6946    @param  n   Number of configured Workers in the upcoming session.
6947 
6948    @return 0         success
6949            non-zero  as failure
6950 */
slave_start_workers(Relay_log_info * rli,ulong n,bool * mts_inited)6951 int slave_start_workers(Relay_log_info *rli, ulong n, bool *mts_inited)
6952 {
6953   uint i;
6954   int error= 0;
6955 
6956   mysql_mutex_assert_owner(&rli->run_lock);
6957 
6958   if (n == 0 && rli->mts_recovery_group_cnt == 0)
6959   {
6960     rli->workers.clear();
6961     goto end;
6962   }
6963 
6964   *mts_inited= true;
6965 
6966   /*
6967     The requested through argument number of Workers can be different
6968      from the previous time which ended with an error. Thereby
6969      the effective number of configured Workers is max of the two.
6970   */
6971   rli->init_workers(max(n, rli->recovery_parallel_workers));
6972 
6973   rli->last_assigned_worker= NULL;     // associated with curr_group_assigned
6974   // Least_occupied_workers array to hold items size of Slave_jobs_queue::len
6975   rli->least_occupied_workers.resize(n);
6976 
6977   /*
6978      GAQ  queue holds seqno:s of scheduled groups. C polls workers in
6979      @c opt_mts_checkpoint_period to update GAQ (see @c next_event())
6980      The length of GAQ is set to be equal to checkpoint_group.
6981      Notice, the size matters for mts_checkpoint_routine's progress loop.
6982   */
6983 
6984   rli->gaq= new Slave_committed_queue(rli->get_group_master_log_name(),
6985                                       rli->checkpoint_group, n);
6986   if (!rli->gaq->inited)
6987     return 1;
6988 
6989   // length of WQ is actually constant though can be made configurable
6990   rli->mts_slave_worker_queue_len_max= mts_slave_worker_queue_len_max;
6991   rli->mts_pending_jobs_size= 0;
6992   rli->mts_pending_jobs_size_max= ::opt_mts_pending_jobs_size_max;
6993   rli->mts_wq_underrun_w_id= MTS_WORKER_UNDEF;
6994   rli->mts_wq_excess_cnt= 0;
6995   rli->mts_wq_overrun_cnt= 0;
6996   rli->mts_wq_oversize= FALSE;
6997   rli->mts_coordinator_basic_nap= mts_coordinator_basic_nap;
6998   rli->mts_worker_underrun_level= mts_worker_underrun_level;
6999   rli->curr_group_seen_begin= rli->curr_group_seen_gtid= false;
7000   rli->curr_group_isolated= FALSE;
7001   rli->checkpoint_seqno= 0;
7002   rli->mts_last_online_stat= my_time(0);
7003   rli->mts_group_status= Relay_log_info::MTS_NOT_IN_GROUP;
7004 
7005   if (init_hash_workers(rli))  // MTS: mapping_db_to_worker
7006   {
7007     sql_print_error("Failed to init partitions hash");
7008     error= 1;
7009     goto err;
7010   }
7011 
7012   for (i= 0; i < n; i++)
7013   {
7014     if ((error= slave_start_single_worker(rli, i)))
7015       goto err;
7016     rli->slave_parallel_workers++;
7017   }
7018 
7019 end:
7020   /*
7021     Free the buffer that was being used to report worker's status through
7022     the table performance_schema.table_replication_applier_status_by_worker
7023     between stop slave and next start slave.
7024   */
7025   for (int i= static_cast<int>(rli->workers_copy_pfs.size()) - 1; i >= 0; i--)
7026     delete rli->workers_copy_pfs[i];
7027   rli->workers_copy_pfs.clear();
7028 
7029   // Effective end of the recovery right now when there is no gaps
7030   if (!error && rli->mts_recovery_group_cnt == 0)
7031   {
7032     if ((error= rli->mts_finalize_recovery()))
7033       (void) Rpl_info_factory::reset_workers(rli);
7034     if (!error)
7035       error= rli->flush_info(TRUE);
7036   }
7037 
7038 err:
7039   return error;
7040 }
7041 
7042 /*
7043    Ending Worker threads.
7044 
7045    Not in case Coordinator is killed itself, it first waits for
7046    Workers have finished their assignements, and then updates checkpoint.
7047    Workers are notified with setting KILLED status
7048    and waited for their acknowledgment as specified by
7049    worker's running_status.
7050    Coordinator finalizes with its MTS running status to reset few objects.
7051 */
slave_stop_workers(Relay_log_info * rli,bool * mts_inited)7052 void slave_stop_workers(Relay_log_info *rli, bool *mts_inited)
7053 {
7054   THD *thd= rli->info_thd;
7055 
7056   if (!*mts_inited)
7057     return;
7058   else if (rli->slave_parallel_workers == 0)
7059     goto end;
7060 
7061   /*
7062     If request for stop slave is received notify worker
7063     to stop.
7064   */
7065   // Initialize worker exit count and max_updated_index to 0 during each stop.
7066   rli->exit_counter= 0;
7067   rli->max_updated_index= (rli->until_condition !=
7068                            Relay_log_info::UNTIL_NONE)?
7069                            rli->mts_groups_assigned:0;
7070   if (!rli->workers.empty())
7071   {
7072     for (int i= static_cast<int>(rli->workers.size()) - 1; i >= 0; i--)
7073     {
7074       Slave_worker *w= rli->workers[i];
7075       struct slave_job_item item= {NULL, 0, 0};
7076       struct slave_job_item *job_item= &item;
7077       mysql_mutex_lock(&w->jobs_lock);
7078 
7079       if (w->running_status != Slave_worker::RUNNING)
7080       {
7081         mysql_mutex_unlock(&w->jobs_lock);
7082         continue;
7083       }
7084 
7085       w->running_status= Slave_worker::STOP;
7086       (void) set_max_updated_index_on_stop(w, job_item);
7087       mysql_cond_signal(&w->jobs_cond);
7088 
7089       mysql_mutex_unlock(&w->jobs_lock);
7090 
7091       DBUG_PRINT("info",
7092                  ("Notifying worker %lu%s to exit, thd %p", w->id,
7093                   w->get_for_channel_str(), w->info_thd));
7094     }
7095   }
7096   thd_proc_info(thd, "Waiting for workers to exit");
7097 
7098   for (Slave_worker **it= rli->workers.begin(); it != rli->workers.end(); ++it)
7099   {
7100     Slave_worker *w= *it;
7101 
7102     /*
7103       Make copies for reporting through the performance schema tables.
7104       This is preserved until the next START SLAVE.
7105     */
7106     Slave_worker *worker_copy=new Slave_worker(NULL
7107     #ifdef HAVE_PSI_INTERFACE
7108                                                ,&key_relay_log_info_run_lock,
7109                                                &key_relay_log_info_data_lock,
7110                                                &key_relay_log_info_sleep_lock,
7111                                                &key_relay_log_info_thd_lock,
7112                                                &key_relay_log_info_data_cond,
7113                                                &key_relay_log_info_start_cond,
7114                                                &key_relay_log_info_stop_cond,
7115                                                &key_relay_log_info_sleep_cond
7116     #endif
7117                                                ,w->id, rli->get_channel());
7118     worker_copy->copy_values_for_PFS(w->id, w->running_status, w->info_thd,
7119                                      w->last_error(),
7120                                      w->currently_executing_gtid);
7121     rli->workers_copy_pfs.push_back(worker_copy);
7122   }
7123 
7124   for (Slave_worker **it= rli->workers.begin(); it != rli->workers.end(); ++it)
7125   {
7126     Slave_worker *w= *it;
7127     mysql_mutex_lock(&w->jobs_lock);
7128     while (w->running_status != Slave_worker::NOT_RUNNING)
7129     {
7130       PSI_stage_info old_stage;
7131       DBUG_ASSERT(w->running_status == Slave_worker::ERROR_LEAVING ||
7132                   w->running_status == Slave_worker::STOP ||
7133                   w->running_status == Slave_worker::STOP_ACCEPTED);
7134 
7135       thd->ENTER_COND(&w->jobs_cond, &w->jobs_lock,
7136                       &stage_slave_waiting_workers_to_exit, &old_stage);
7137       mysql_cond_wait(&w->jobs_cond, &w->jobs_lock);
7138       mysql_mutex_unlock(&w->jobs_lock);
7139       thd->EXIT_COND(&old_stage);
7140       mysql_mutex_lock(&w->jobs_lock);
7141     }
7142     mysql_mutex_unlock(&w->jobs_lock);
7143   }
7144 
7145   if (thd->killed == THD::NOT_KILLED)
7146     (void) mts_checkpoint_routine(rli, 0, false, true/*need_data_lock=true*/); // TODO:consider to propagate an error out of the function
7147 
7148   while (!rli->workers.empty())
7149   {
7150     Slave_worker *w= rli->workers.back();
7151     // Free the current submode object
7152     delete w->current_mts_submode;
7153     w->current_mts_submode= 0;
7154     rli->workers.pop_back();
7155     delete w;
7156   }
7157   struct timespec stats_end;
7158   set_timespec_nsec(&stats_end, 0);
7159 
7160   DBUG_PRINT("info", ("Total MTS session statistics: "
7161                       "events processed = %llu; "
7162                       "online time = %llu "
7163                       "worker queues filled over overrun level = %lu "
7164                       "waited due a Worker queue full = %lu "
7165                       "waited due the total size = %lu "
7166                       "total wait at clock conflicts = %llu "
7167                       "found (count) workers occupied = %lu "
7168                       "waited when workers occupied = %llu",
7169                       rli->mts_events_assigned,
7170                       diff_timespec(&stats_end, &rli->stats_begin),
7171                       rli->mts_wq_overrun_cnt,
7172                       rli->mts_wq_overfill_cnt, rli->wq_size_waits_cnt,
7173                       rli->mts_total_wait_overlap,
7174                       rli->mts_wq_no_underrun_cnt,
7175                       rli->mts_total_wait_worker_avail));
7176 
7177   DBUG_ASSERT(rli->pending_jobs == 0);
7178   DBUG_ASSERT(rli->mts_pending_jobs_size == 0);
7179 
7180 end:
7181   rli->mts_group_status= Relay_log_info::MTS_NOT_IN_GROUP;
7182   destroy_hash_workers(rli);
7183   delete rli->gaq;
7184   rli->least_occupied_workers.clear();
7185 
7186   // Destroy buffered events of the current group prior to exit.
7187   for (uint i= 0; i < rli->curr_group_da.size(); i++)
7188     delete rli->curr_group_da[i].data;
7189   rli->curr_group_da.clear();                      // GCDA
7190 
7191   rli->curr_group_assigned_parts.clear();          // GCAP
7192   rli->deinit_workers();
7193   rli->workers_array_initialized= false;
7194   rli->slave_parallel_workers= 0;
7195 
7196   *mts_inited= false;
7197 }
7198 
7199 
7200 /**
7201   Slave SQL thread entry point.
7202 
7203   @param arg Pointer to Relay_log_info object that holds information
7204   for the SQL thread.
7205 
7206   @return Always 0.
7207 */
handle_slave_sql(void * arg)7208 extern "C" void *handle_slave_sql(void *arg)
7209 {
7210   THD *thd;                     /* needs to be first for thread_stack */
7211   bool thd_added= false;
7212   char llbuff[22],llbuff1[22];
7213   char saved_log_name[FN_REFLEN];
7214   char saved_master_log_name[FN_REFLEN];
7215   my_off_t saved_log_pos= 0;
7216   my_off_t saved_master_log_pos= 0;
7217   my_off_t saved_skip= 0;
7218 
7219   Relay_log_info* rli = ((Master_info*)arg)->rli;
7220   const char *errmsg;
7221   const char *error_string;
7222   bool mts_inited= false;
7223   Global_THD_manager *thd_manager= Global_THD_manager::get_instance();
7224   Commit_order_manager *commit_order_mngr= NULL;
7225 
7226   // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
7227   my_thread_init();
7228   DBUG_ENTER("handle_slave_sql");
7229 
7230   DBUG_ASSERT(rli->inited);
7231   mysql_mutex_lock(&rli->run_lock);
7232   DBUG_ASSERT(!rli->slave_running);
7233   errmsg= 0;
7234   error_string= 0;
7235 #ifndef DBUG_OFF
7236   rli->events_until_exit = abort_slave_event_count;
7237 #endif
7238 
7239   thd = new THD; // note that contructor of THD uses DBUG_ !
7240   thd->thread_stack = (char*)&thd; // remember where our stack is
7241   mysql_mutex_lock(&rli->info_thd_lock);
7242   rli->info_thd= thd;
7243 
7244   #ifdef HAVE_PSI_INTERFACE
7245   // save the instrumentation for SQL thread in rli->info_thd
7246   struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)();
7247   thd_set_psi(rli->info_thd, psi);
7248   #endif
7249 
7250  if (rli->channel_mts_submode != MTS_PARALLEL_TYPE_DB_NAME)
7251    rli->current_mts_submode= new Mts_submode_logical_clock();
7252  else
7253    rli->current_mts_submode= new Mts_submode_database();
7254 
7255   if (opt_slave_preserve_commit_order && rli->opt_slave_parallel_workers > 0 &&
7256       opt_bin_log && opt_log_slave_updates)
7257     commit_order_mngr= new Commit_order_manager(rli->opt_slave_parallel_workers);
7258 
7259   rli->set_commit_order_manager(commit_order_mngr);
7260 
7261   if (channel_map.is_group_replication_channel_name(rli->get_channel())) {
7262     if (channel_map.is_group_replication_channel_name(rli->get_channel(),
7263                                                       true)) {
7264       thd->rpl_thd_ctx.set_rpl_channel_type(GR_APPLIER_CHANNEL);
7265     } else {
7266       thd->rpl_thd_ctx.set_rpl_channel_type(GR_RECOVERY_CHANNEL);
7267     }
7268   } else {
7269     thd->rpl_thd_ctx.set_rpl_channel_type(RPL_STANDARD_CHANNEL);
7270   }
7271 
7272   mysql_mutex_unlock(&rli->info_thd_lock);
7273 
7274   /* Inform waiting threads that slave has started */
7275   rli->slave_run_id++;
7276   rli->slave_running = 1;
7277   rli->reported_unsafe_warning= false;
7278   rli->sql_thread_kill_accepted= false;
7279 
7280   if (init_slave_thread(thd, SLAVE_THD_SQL))
7281   {
7282     /*
7283       TODO: this is currently broken - slave start and change master
7284       will be stuck if we fail here
7285     */
7286     mysql_cond_broadcast(&rli->start_cond);
7287     mysql_mutex_unlock(&rli->run_lock);
7288     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
7289                 "Failed during slave thread initialization");
7290     goto err;
7291   }
7292   thd->init_for_queries(rli);
7293   thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
7294   set_thd_in_use_temporary_tables(rli);   // (re)set sql_thd in use for saved temp tables
7295   /* Set applier thread InnoDB priority */
7296   set_thd_tx_priority(thd, rli->get_thd_tx_priority());
7297 
7298   thd_manager->add_thd(thd);
7299   thd_added= true;
7300 
7301   rli->stats_exec_time= rli->stats_read_time= 0;
7302   set_timespec_nsec(&rli->ts_exec[0], 0);
7303   set_timespec_nsec(&rli->ts_exec[1], 0);
7304   set_timespec_nsec(&rli->stats_begin, 0);
7305   rli->currently_executing_gtid.set_automatic();
7306 
7307   if (RUN_HOOK(binlog_relay_io, applier_start, (thd, rli->mi)))
7308   {
7309     mysql_cond_broadcast(&rli->start_cond);
7310     mysql_mutex_unlock(&rli->run_lock);
7311     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
7312                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
7313                 "Failed to run 'applier_start' hook");
7314     goto err;
7315   }
7316 
7317   /* MTS: starting the worker pool */
7318   if (slave_start_workers(rli, rli->opt_slave_parallel_workers, &mts_inited) != 0)
7319   {
7320     mysql_cond_broadcast(&rli->start_cond);
7321     mysql_mutex_unlock(&rli->run_lock);
7322     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
7323                 "Failed during slave workers initialization");
7324     goto err;
7325   }
7326   /*
7327     We are going to set slave_running to 1. Assuming slave I/O thread is
7328     alive and connected, this is going to make Seconds_Behind_Master be 0
7329     i.e. "caught up". Even if we're just at start of thread. Well it's ok, at
7330     the moment we start we can think we are caught up, and the next second we
7331     start receiving data so we realize we are not caught up and
7332     Seconds_Behind_Master grows. No big deal.
7333   */
7334   rli->abort_slave = 0;
7335 
7336   /*
7337     Reset errors for a clean start (otherwise, if the master is idle, the SQL
7338     thread may execute no Query_log_event, so the error will remain even
7339     though there's no problem anymore). Do not reset the master timestamp
7340     (imagine the slave has caught everything, the STOP SLAVE and START SLAVE:
7341     as we are not sure that we are going to receive a query, we want to
7342     remember the last master timestamp (to say how many seconds behind we are
7343     now.
7344     But the master timestamp is reset by RESET SLAVE & CHANGE MASTER.
7345   */
7346   rli->clear_error();
7347   if (rli->workers_array_initialized)
7348   {
7349     for(size_t i= 0; i<rli->get_worker_count(); i++)
7350     {
7351       rli->get_worker(i)->clear_error();
7352     }
7353   }
7354 
7355   if (rli->update_is_transactional())
7356   {
7357     mysql_cond_broadcast(&rli->start_cond);
7358     mysql_mutex_unlock(&rli->run_lock);
7359     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
7360                 "Error checking if the relay log repository is transactional.");
7361     goto err;
7362   }
7363 
7364   if (!rli->is_transactional())
7365     rli->report(WARNING_LEVEL, 0,
7366     "If a crash happens this configuration does not guarantee that the relay "
7367     "log info will be consistent");
7368 
7369   mysql_cond_broadcast(&rli->start_cond);
7370   mysql_mutex_unlock(&rli->run_lock);
7371 
7372   DEBUG_SYNC(thd, "after_start_slave");
7373 
7374   //tell the I/O thread to take relay_log_space_limit into account from now on
7375   mysql_mutex_lock(&rli->log_space_lock);
7376   rli->ignore_log_space_limit= 0;
7377   mysql_mutex_unlock(&rli->log_space_lock);
7378   rli->trans_retries= 0; // start from "no error"
7379   DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries));
7380 
7381   if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
7382                               rli->get_group_relay_log_pos(),
7383                               true/*need_data_lock=true*/, &errmsg,
7384                               1 /*look for a description_event*/))
7385   {
7386     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
7387                 "Error initializing relay log position: %s", errmsg);
7388     goto err;
7389   }
7390   THD_CHECK_SENTRY(thd);
7391 #ifndef DBUG_OFF
7392   {
7393     char llbuf1[22], llbuf2[22];
7394     DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
7395                         llstr(my_b_tell(rli->cur_log),llbuf1),
7396                         llstr(rli->get_event_relay_log_pos(),llbuf2)));
7397     DBUG_ASSERT(rli->get_event_relay_log_pos() >= BIN_LOG_HEADER_SIZE);
7398     /*
7399       Wonder if this is correct. I (Guilhem) wonder if my_b_tell() returns the
7400       correct position when it's called just after my_b_seek() (the questionable
7401       stuff is those "seek is done on next read" comments in the my_b_seek()
7402       source code).
7403       The crude reality is that this assertion randomly fails whereas
7404       replication seems to work fine. And there is no easy explanation why it
7405       fails (as we my_b_seek(rli->event_relay_log_pos) at the very end of
7406       init_relay_log_pos() called above). Maybe the assertion would be
7407       meaningful if we held rli->data_lock between the my_b_seek() and the
7408       DBUG_ASSERT().
7409 
7410       DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->get_event_relay_log_pos());
7411     */
7412   }
7413 #endif
7414   DBUG_ASSERT(rli->info_thd == thd);
7415 
7416 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
7417   /* engine specific hook, to be made generic */
7418   if (ndb_wait_setup_func && ndb_wait_setup_func(opt_ndb_wait_setup))
7419   {
7420     sql_print_warning("Slave SQL thread : NDB : Tables not available after %lu"
7421                       " seconds.  Consider increasing --ndb-wait-setup value",
7422                       opt_ndb_wait_setup);
7423   }
7424 #endif
7425 
7426   DBUG_PRINT("master_info",("log_file_name: %s  position: %s",
7427                             rli->get_group_master_log_name(),
7428                             llstr(rli->get_group_master_log_pos(),llbuff)));
7429   sql_print_information("Slave SQL thread%s initialized, starting replication in"
7430                         " log '%s' at position %s, relay log '%s' position: %s",
7431                         rli->get_for_channel_str(), rli->get_rpl_log_name(),
7432                         llstr(rli->get_group_master_log_pos(),llbuff),
7433                         rli->get_group_relay_log_name(),
7434                         llstr(rli->get_group_relay_log_pos(),llbuff1));
7435 
7436   if (check_temp_dir(rli->slave_patternload_file, rli->get_channel()))
7437   {
7438     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
7439                 "Unable to use slave's temporary directory %s - %s",
7440                 slave_load_tmpdir, thd->get_stmt_da()->message_text());
7441     goto err;
7442   }
7443 
7444   /* execute init_slave variable */
7445   if (opt_init_slave.length)
7446   {
7447     execute_init_command(thd, &opt_init_slave, &LOCK_sys_init_slave);
7448     if (thd->is_slave_error)
7449     {
7450       rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
7451                   "Slave SQL thread aborted. Can't execute init_slave query,"
7452                   "'%s'", thd->get_stmt_da()->message_text());
7453       goto err;
7454     }
7455   }
7456 
7457   /*
7458     First check until condition - probably there is nothing to execute. We
7459     do not want to wait for next event in this case.
7460   */
7461   mysql_mutex_lock(&rli->data_lock);
7462   if (rli->slave_skip_counter)
7463   {
7464     strmake(saved_log_name, rli->get_group_relay_log_name(), FN_REFLEN - 1);
7465     strmake(saved_master_log_name, rli->get_group_master_log_name(), FN_REFLEN - 1);
7466     saved_log_pos= rli->get_group_relay_log_pos();
7467     saved_master_log_pos= rli->get_group_master_log_pos();
7468     saved_skip= rli->slave_skip_counter;
7469   }
7470   if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
7471       rli->is_until_satisfied(thd, NULL))
7472   {
7473     mysql_mutex_unlock(&rli->data_lock);
7474     goto err;
7475   }
7476   mysql_mutex_unlock(&rli->data_lock);
7477 
7478   /* Read queries from the IO/THREAD until this thread is killed */
7479 
7480   while (!sql_slave_killed(thd,rli))
7481   {
7482     THD_STAGE_INFO(thd, stage_reading_event_from_the_relay_log);
7483     DBUG_ASSERT(rli->info_thd == thd);
7484     THD_CHECK_SENTRY(thd);
7485 
7486     if (saved_skip && rli->slave_skip_counter == 0)
7487     {
7488       sql_print_information("'SQL_SLAVE_SKIP_COUNTER=%ld' executed at "
7489         "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
7490         "master_log_pos='%ld' and new position at "
7491         "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
7492         "master_log_pos='%ld' ",
7493         (ulong) saved_skip, saved_log_name, (ulong) saved_log_pos,
7494         saved_master_log_name, (ulong) saved_master_log_pos,
7495         rli->get_group_relay_log_name(), (ulong) rli->get_group_relay_log_pos(),
7496         rli->get_group_master_log_name(), (ulong) rli->get_group_master_log_pos());
7497       saved_skip= 0;
7498     }
7499 
7500     if (exec_relay_log_event(thd,rli))
7501     {
7502       DBUG_PRINT("info", ("exec_relay_log_event() failed"));
7503       // do not scare the user if SQL thread was simply killed or stopped
7504       if (!sql_slave_killed(thd,rli))
7505       {
7506         /*
7507           retrieve as much info as possible from the thd and, error
7508           codes and warnings and print this to the error log as to
7509           allow the user to locate the error
7510         */
7511         uint32 const last_errno= rli->last_error().number;
7512 
7513         if (thd->is_error())
7514         {
7515           char const *const errmsg= thd->get_stmt_da()->message_text();
7516 
7517           DBUG_PRINT("info",
7518                      ("thd->get_stmt_da()->get_mysql_errno()=%d; "
7519                       "rli->last_error.number=%d",
7520                       thd->get_stmt_da()->mysql_errno(), last_errno));
7521           if (last_errno == 0)
7522           {
7523             /*
7524  	      This function is reporting an error which was not reported
7525  	      while executing exec_relay_log_event().
7526  	    */
7527             rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
7528                         "%s", errmsg);
7529           }
7530           else if (last_errno != thd->get_stmt_da()->mysql_errno())
7531           {
7532             /*
7533              * An error was reported while executing exec_relay_log_event()
7534              * however the error code differs from what is in the thread.
7535              * This function prints out more information to help finding
7536              * what caused the problem.
7537              */
7538             sql_print_error("Slave (additional info): %s Error_code: %d",
7539                             errmsg, thd->get_stmt_da()->mysql_errno());
7540           }
7541         }
7542 
7543         /* Print any warnings issued */
7544         Diagnostics_area::Sql_condition_iterator it=
7545           thd->get_stmt_da()->sql_conditions();
7546         const Sql_condition *err;
7547         /*
7548           Added controlled slave thread cancel for replication
7549           of user-defined variables.
7550         */
7551         bool udf_error = false;
7552         while ((err= it++))
7553         {
7554           if (err->mysql_errno() == ER_CANT_OPEN_LIBRARY)
7555             udf_error = true;
7556           sql_print_warning("Slave: %s Error_code: %d",
7557                             err->message_text(), err->mysql_errno());
7558         }
7559         if (udf_error)
7560           error_string= "Error loading user-defined library, slave SQL "
7561             "thread aborted. Install the missing library, and restart the"
7562             " slave SQL thread with \"SLAVE START\".";
7563         else
7564           error_string= "Error running query, slave SQL thread aborted."
7565             " Fix the problem, and restart the slave SQL thread with "
7566             "\"SLAVE START\".";
7567       }
7568       goto err;
7569     }
7570   }
7571 
7572  err:
7573   /* At this point the SQL thread will not try to work anymore. */
7574   rli->is_stopping.atomic_set(1);
7575   (void) RUN_HOOK(binlog_relay_io, applier_stop,
7576                   (thd, rli->mi,
7577                    rli->is_error() || !rli->sql_thread_kill_accepted));
7578 
7579   slave_stop_workers(rli, &mts_inited); // stopping worker pool
7580   /* Thread stopped. Print the current replication position to the log */
7581   if (error_string)
7582     sql_print_error("%s We stopped at log '%s' position %s.", error_string,
7583                     rli->get_rpl_log_name(),
7584                     llstr(rli->get_group_master_log_pos(), llbuff));
7585   else
7586     sql_print_information("Slave SQL thread%s exiting, replication stopped in log "
7587 			  "'%s' at position %s", rli->get_for_channel_str(),
7588 			  rli->get_rpl_log_name(),
7589 			  llstr(rli->get_group_master_log_pos(), llbuff));
7590 
7591   delete rli->current_mts_submode;
7592   rli->current_mts_submode= 0;
7593   rli->clear_mts_recovery_groups();
7594 
7595   /*
7596     Some events set some playgrounds, which won't be cleared because thread
7597     stops. Stopping of this thread may not be known to these events ("stop"
7598     request is detected only by the present function, not by events), so we
7599     must "proactively" clear playgrounds:
7600   */
7601   thd->clear_error();
7602   rli->cleanup_context(thd, 1);
7603   /*
7604     Some extra safety, which should not been needed (normally, event deletion
7605     should already have done these assignments (each event which sets these
7606     variables is supposed to set them to 0 before terminating)).
7607   */
7608   thd->set_catalog(NULL_CSTR);
7609   thd->reset_query();
7610   thd->reset_db(NULL_CSTR);
7611 
7612   /*
7613     Pause the SQL thread and wait for 'continue_to_stop_sql_thread'
7614     signal to continue to shutdown the SQL thread.
7615   */
7616   DBUG_EXECUTE_IF("pause_after_sql_thread_stop_hook",
7617                   {
7618                     const char act[]= "now SIGNAL reached_stopping_sql_thread "
7619                                       "WAIT_FOR continue_to_stop_sql_thread";
7620                     DBUG_ASSERT(!debug_sync_set_action(thd,
7621                                                        STRING_WITH_LEN(act)));
7622                   };);
7623 
7624   THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit);
7625   mysql_mutex_lock(&rli->run_lock);
7626   /* We need data_lock, at least to wake up any waiting master_pos_wait() */
7627   mysql_mutex_lock(&rli->data_lock);
7628   DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
7629   /* When master_pos_wait() wakes up it will check this and terminate */
7630   rli->slave_running= 0;
7631   rli->is_stopping.atomic_set(0);
7632   /* Forget the relay log's format */
7633   rli->set_rli_description_event(NULL);
7634   /* Wake up master_pos_wait() */
7635   DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions"));
7636   mysql_cond_broadcast(&rli->data_cond);
7637   mysql_mutex_unlock(&rli->data_lock);
7638   rli->ignore_log_space_limit= 0; /* don't need any lock */
7639   /* we die so won't remember charset - re-update them on next thread start */
7640   rli->cached_charset_invalidate();
7641   rli->save_temporary_tables = thd->temporary_tables;
7642 
7643   /*
7644     TODO: see if we can do this conditionally in next_event() instead
7645     to avoid unneeded position re-init
7646   */
7647   thd->temporary_tables = 0; // remove tempation from destructor to close them
7648   // destructor will not free it, because we are weird
7649   thd->get_protocol_classic()->end_net();
7650   DBUG_ASSERT(rli->info_thd == thd);
7651   THD_CHECK_SENTRY(thd);
7652   mysql_mutex_lock(&rli->info_thd_lock);
7653   rli->info_thd= NULL;
7654   if (commit_order_mngr)
7655   {
7656     delete commit_order_mngr;
7657     rli->set_commit_order_manager(NULL);
7658   }
7659 
7660   mysql_mutex_unlock(&rli->info_thd_lock);
7661   set_thd_in_use_temporary_tables(rli);  // (re)set info_thd in use for saved temp tables
7662 
7663  /*
7664   Note: the order of the broadcast and unlock calls below (first broadcast, then unlock)
7665   is important. Otherwise a killer_thread can execute between the calls and
7666   delete the mi structure leading to a crash! (see BUG#25306 for details)
7667  */
7668   mysql_cond_broadcast(&rli->stop_cond);
7669   DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
7670   mysql_mutex_unlock(&rli->run_lock);  // tell the world we are done
7671 
7672   thd->release_resources();
7673   THD_CHECK_SENTRY(thd);
7674   if (thd_added)
7675     thd_manager->remove_thd(thd);
7676 
7677   /*
7678     The thd can only be destructed after indirect references
7679     through mi->rli->info_thd are cleared: mi->rli->info_thd= NULL.
7680 
7681     For instance, user thread might be issuing show_slave_status
7682     and attempting to read mi->rli->info_thd->get_proc_info().
7683     Therefore thd must only be deleted after info_thd is set
7684     to NULL.
7685   */
7686   delete thd;
7687 
7688   DBUG_LEAVE;                            // Must match DBUG_ENTER()
7689   my_thread_end();
7690 #if OPENSSL_VERSION_NUMBER < 0x10100000L
7691   ERR_remove_thread_state(0);
7692 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
7693   my_thread_exit(0);
7694   return 0;                             // Avoid compiler warnings
7695 }
7696 
7697 
7698 /*
7699   process_io_create_file()
7700 */
7701 
process_io_create_file(Master_info * mi,Create_file_log_event * cev)7702 static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
7703 {
7704   int error = 1;
7705   ulong num_bytes;
7706   bool cev_not_written;
7707   THD *thd = mi->info_thd;
7708   NET *net = &mi->mysql->net;
7709   DBUG_ENTER("process_io_create_file");
7710 
7711   mysql_mutex_assert_owner(&mi->data_lock);
7712 
7713   if (unlikely(!cev->is_valid()))
7714     DBUG_RETURN(1);
7715 
7716   if (!rpl_filter->db_ok(cev->db))
7717   {
7718     skip_load_data_infile(net);
7719     DBUG_RETURN(0);
7720   }
7721   DBUG_ASSERT(cev->inited_from_old);
7722   thd->file_id = cev->file_id = mi->file_id++;
7723   thd->server_id = cev->server_id;
7724   cev_not_written = 1;
7725 
7726   if (unlikely(net_request_file(net,cev->fname)))
7727   {
7728     sql_print_error("Slave I/O: failed requesting download of '%s'",
7729                     cev->fname);
7730     goto err;
7731   }
7732 
7733   /*
7734     This dummy block is so we could instantiate Append_block_log_event
7735     once and then modify it slightly instead of doing it multiple times
7736     in the loop
7737   */
7738   {
7739     Append_block_log_event aev(thd,0,0,0,0);
7740 
7741     for (;;)
7742     {
7743       if (unlikely((num_bytes=my_net_read(net)) == packet_error))
7744       {
7745         sql_print_error("Network read error downloading '%s' from master",
7746                         cev->fname);
7747         goto err;
7748       }
7749       if (unlikely(!num_bytes)) /* eof */
7750       {
7751 	/* 3.23 master wants it */
7752         net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0);
7753         /*
7754           If we wrote Create_file_log_event, then we need to write
7755           Execute_load_log_event. If we did not write Create_file_log_event,
7756           then this is an empty file and we can just do as if the LOAD DATA
7757           INFILE had not existed, i.e. write nothing.
7758         */
7759         if (unlikely(cev_not_written))
7760           break;
7761         Execute_load_log_event xev(thd,0,0);
7762         xev.common_header->log_pos = cev->common_header->log_pos;
7763         if (unlikely(mi->rli->relay_log.append_event(&xev, mi) != 0))
7764         {
7765           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
7766                      ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
7767                      "error writing Exec_load event to relay log");
7768           goto err;
7769         }
7770         mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
7771         break;
7772       }
7773       if (unlikely(cev_not_written))
7774       {
7775         cev->block = net->read_pos;
7776         cev->block_len = num_bytes;
7777         if (unlikely(mi->rli->relay_log.append_event(cev, mi) != 0))
7778         {
7779           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
7780                      ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
7781                      "error writing Create_file event to relay log");
7782           goto err;
7783         }
7784         cev_not_written=0;
7785         mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
7786       }
7787       else
7788       {
7789         aev.block = net->read_pos;
7790         aev.block_len = num_bytes;
7791         aev.common_header->log_pos= cev->common_header->log_pos;
7792         if (unlikely(mi->rli->relay_log.append_event(&aev, mi) != 0))
7793         {
7794           mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
7795                      ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
7796                      "error writing Append_block event to relay log");
7797           goto err;
7798         }
7799         mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
7800       }
7801     }
7802   }
7803   error=0;
7804 err:
7805   DBUG_RETURN(error);
7806 }
7807 
7808 
7809 /**
7810   Used by the slave IO thread when it receives a rotate event from the
7811   master.
7812 
7813   Updates the master info with the place in the next binary log where
7814   we should start reading.  Rotate the relay log to avoid mixed-format
7815   relay logs.
7816 
7817   @param mi master_info for the slave
7818   @param rev The rotate log event read from the master
7819 
7820   @note The caller must hold mi->data_lock before invoking this function.
7821 
7822   @retval 0 ok
7823   @retval 1 error
7824 */
process_io_rotate(Master_info * mi,Rotate_log_event * rev)7825 static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
7826 {
7827   DBUG_ENTER("process_io_rotate");
7828   mysql_mutex_assert_owner(&mi->data_lock);
7829 
7830   if (unlikely(!rev->is_valid()))
7831     DBUG_RETURN(1);
7832 
7833   /* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
7834   memcpy(const_cast<char *>(mi->get_master_log_name()),
7835          rev->new_log_ident, rev->ident_len + 1);
7836   mi->set_master_log_pos(rev->pos);
7837   DBUG_PRINT("info", ("new (master_log_name, master_log_pos): ('%s', %lu)",
7838                       mi->get_master_log_name(), (ulong) mi->get_master_log_pos()));
7839 #ifndef DBUG_OFF
7840   /*
7841     If we do not do this, we will be getting the first
7842     rotate event forever, so we need to not disconnect after one.
7843   */
7844   if (disconnect_slave_event_count)
7845     mi->events_until_exit++;
7846 #endif
7847 
7848   /*
7849     If mi_description_event is format <4, there is conversion in the
7850     relay log to the slave's format (4). And Rotate can mean upgrade or
7851     nothing. If upgrade, it's to 5.0 or newer, so we will get a Format_desc, so
7852     no need to reset mi_description_event now. And if it's nothing (same
7853     master version as before), no need (still using the slave's format).
7854   */
7855   Format_description_log_event *old_fdle= mi->get_mi_description_event();
7856   if (old_fdle->binlog_version >= 4)
7857   {
7858     DBUG_ASSERT(old_fdle->common_footer->checksum_alg ==
7859                 mi->rli->relay_log.relay_log_checksum_alg);
7860     Format_description_log_event *new_fdle= new
7861       Format_description_log_event(3);
7862     new_fdle->common_footer->checksum_alg=
7863                              mi->rli->relay_log.relay_log_checksum_alg;
7864     mi->set_mi_description_event(new_fdle);
7865   }
7866   /*
7867     Rotate the relay log makes binlog format detection easier (at next slave
7868     start or mysqlbinlog)
7869   */
7870   int ret= rotate_relay_log(mi, true/*need_log_space_lock=true*/);
7871   DBUG_RETURN(ret);
7872 }
7873 
7874 /**
7875   Reads a 3.23 event and converts it to the slave's format. This code was
7876   copied from MySQL 4.0.
7877 
7878   @note The caller must hold mi->data_lock before invoking this function.
7879 */
queue_binlog_ver_1_event(Master_info * mi,const char * buf,ulong event_len)7880 static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
7881                                     ulong event_len)
7882 {
7883   const char *errmsg = 0;
7884   ulong inc_pos;
7885   bool ignore_event= 0;
7886   char *tmp_buf = 0;
7887   Relay_log_info *rli= mi->rli;
7888   DBUG_ENTER("queue_binlog_ver_1_event");
7889 
7890   mysql_mutex_assert_owner(&mi->data_lock);
7891 
7892   /*
7893     If we get Load event, we need to pass a non-reusable buffer
7894     to read_log_event, so we do a trick
7895   */
7896   if (buf[EVENT_TYPE_OFFSET] == binary_log::LOAD_EVENT)
7897   {
7898     if (unlikely(!(tmp_buf=(char*)my_malloc(key_memory_binlog_ver_1_event,
7899                                             event_len+1,MYF(MY_WME)))))
7900     {
7901       mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
7902                  ER(ER_SLAVE_FATAL_ERROR), "Memory allocation failed");
7903       DBUG_RETURN(1);
7904     }
7905     memcpy(tmp_buf,buf,event_len);
7906     /*
7907       Create_file constructor wants a 0 as last char of buffer, this 0 will
7908       serve as the string-termination char for the file's name (which is at the
7909       end of the buffer)
7910       We must increment event_len, otherwise the event constructor will not see
7911       this end 0, which leads to segfault.
7912     */
7913     tmp_buf[event_len++]=0;
7914     int4store(tmp_buf+EVENT_LEN_OFFSET, event_len);
7915     buf = (const char*)tmp_buf;
7916   }
7917   /*
7918     This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to
7919     send the loaded file, and write it to the relay log in the form of
7920     Append_block/Exec_load (the SQL thread needs the data, as that thread is not
7921     connected to the master).
7922   */
7923   Log_event *ev=
7924     Log_event::read_log_event(buf, event_len, &errmsg,
7925                               mi->get_mi_description_event(), 0);
7926   if (unlikely(!ev))
7927   {
7928     sql_print_error("Read invalid event from master: '%s',\
7929  master could be corrupt but a more likely cause of this is a bug",
7930                     errmsg);
7931     my_free(tmp_buf);
7932     DBUG_RETURN(1);
7933   }
7934   /* 3.23 events don't contain log_pos */
7935   mi->set_master_log_pos(ev->common_header->log_pos);
7936   switch (ev->get_type_code()) {
7937   case binary_log::STOP_EVENT:
7938     ignore_event= 1;
7939     inc_pos= event_len;
7940     break;
7941   case binary_log::ROTATE_EVENT:
7942     if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
7943     {
7944       delete ev;
7945       DBUG_RETURN(1);
7946     }
7947     inc_pos= 0;
7948     break;
7949   case binary_log::CREATE_FILE_EVENT:
7950     /*
7951       Yes it's possible to have CREATE_FILE_EVENT here, even if we're in
7952       queue_old_event() which is for 3.23 events which don't comprise
7953       CREATE_FILE_EVENT. This is because read_log_event() above has just
7954       transformed LOAD_EVENT into CREATE_FILE_EVENT.
7955     */
7956   {
7957     /* We come here when and only when tmp_buf != 0 */
7958     DBUG_ASSERT(tmp_buf != 0);
7959     inc_pos=event_len;
7960     ev->common_header->log_pos+= inc_pos;
7961     int error = process_io_create_file(mi,(Create_file_log_event*)ev);
7962     delete ev;
7963     mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
7964     DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
7965     my_free(tmp_buf);
7966     DBUG_RETURN(error);
7967   }
7968   default:
7969     inc_pos= event_len;
7970     break;
7971   }
7972   if (likely(!ignore_event))
7973   {
7974     if (ev->common_header->log_pos)
7975       /*
7976          Don't do it for fake Rotate events (see comment in
7977       Log_event::Log_event(const char* buf...) in log_event.cc).
7978       */
7979       /* make log_pos be the pos of the end of the event */
7980       ev->common_header->log_pos+= event_len;
7981     if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
7982     {
7983       delete ev;
7984       DBUG_RETURN(1);
7985     }
7986     rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
7987   }
7988   delete ev;
7989   mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
7990   DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
7991   DBUG_RETURN(0);
7992 }
7993 
7994 /**
7995   Reads a 4.0 event and converts it to the slave's format. This code was copied
7996   from queue_binlog_ver_1_event(), with some affordable simplifications.
7997 
7998   @note The caller must hold mi->data_lock before invoking this function.
7999 */
queue_binlog_ver_3_event(Master_info * mi,const char * buf,ulong event_len)8000 static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
8001                                     ulong event_len)
8002 {
8003   const char *errmsg = 0;
8004   ulong inc_pos;
8005   char *tmp_buf = 0;
8006   Relay_log_info *rli= mi->rli;
8007   DBUG_ENTER("queue_binlog_ver_3_event");
8008 
8009   mysql_mutex_assert_owner(&mi->data_lock);
8010 
8011   /* read_log_event() will adjust log_pos to be end_log_pos */
8012   Log_event *ev=
8013     Log_event::read_log_event(buf, event_len, &errmsg,
8014                               mi->get_mi_description_event(), 0);
8015   if (unlikely(!ev))
8016   {
8017     sql_print_error("Read invalid event from master: '%s',\
8018  master could be corrupt but a more likely cause of this is a bug",
8019                     errmsg);
8020     my_free(tmp_buf);
8021     DBUG_RETURN(1);
8022   }
8023   switch (ev->get_type_code()) {
8024   case binary_log::STOP_EVENT:
8025     goto err;
8026   case binary_log::ROTATE_EVENT:
8027     if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
8028     {
8029       delete ev;
8030       DBUG_RETURN(1);
8031     }
8032     inc_pos= 0;
8033     break;
8034   default:
8035     inc_pos= event_len;
8036     break;
8037   }
8038 
8039   if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
8040   {
8041     delete ev;
8042     DBUG_RETURN(1);
8043   }
8044   rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
8045   delete ev;
8046   mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
8047 err:
8048   DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
8049   DBUG_RETURN(0);
8050 }
8051 
8052 /*
8053   queue_old_event()
8054 
8055   Writes a 3.23 or 4.0 event to the relay log, after converting it to the 5.0
8056   (exactly, slave's) format. To do the conversion, we create a 5.0 event from
8057   the 3.23/4.0 bytes, then write this event to the relay log.
8058 
8059   TODO:
8060     Test this code before release - it has to be tested on a separate
8061     setup with 3.23 master or 4.0 master
8062 */
8063 
queue_old_event(Master_info * mi,const char * buf,ulong event_len)8064 static int queue_old_event(Master_info *mi, const char *buf,
8065                            ulong event_len)
8066 {
8067   DBUG_ENTER("queue_old_event");
8068 
8069   mysql_mutex_assert_owner(&mi->data_lock);
8070 
8071   switch (mi->get_mi_description_event()->binlog_version)
8072   {
8073   case 1:
8074       DBUG_RETURN(queue_binlog_ver_1_event(mi,buf,event_len));
8075   case 3:
8076       DBUG_RETURN(queue_binlog_ver_3_event(mi,buf,event_len));
8077   default: /* unsupported format; eg version 2 */
8078     DBUG_PRINT("info",("unsupported binlog format %d in queue_old_event()",
8079                        mi->get_mi_description_event()->binlog_version));
8080     DBUG_RETURN(1);
8081   }
8082 }
8083 
8084 /**
8085   Store an event received from the master connection into the relay
8086   log.
8087 
8088   @param mi The Master_info object representing this connection.
8089   @param buf Pointer to the event data.
8090   @param event_len Length of event data.
8091 
8092   @retval true Error.
8093   @retval false Success.
8094 
8095   @note
8096   If the event is 3.23/4.0, passes it to queue_old_event() which will convert
8097   it. Otherwise, writes a 5.0 (or newer) event to the relay log. Then there is
8098   no format conversion, it's pure read/write of bytes.
8099   So a 5.0.0 slave's relay log can contain events in the slave's format or in
8100   any >=5.0.0 format.
8101 
8102   @todo Make this a member of Master_info.
8103 */
queue_event(Master_info * mi,const char * buf,ulong event_len)8104 bool queue_event(Master_info* mi,const char* buf, ulong event_len)
8105 {
8106   bool error= false;
8107   ulong inc_pos= 0;
8108   Relay_log_info *rli= mi->rli;
8109   mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
8110   ulong s_id;
8111   int lock_count= 0;
8112   /*
8113     FD_q must have been prepared for the first R_a event
8114     inside get_master_version_and_clock()
8115     Show-up of FD:s affects checksum_alg at once because
8116     that changes FD_queue.
8117   */
8118   enum_binlog_checksum_alg checksum_alg= mi->checksum_alg_before_fd !=
8119                                          binary_log::BINLOG_CHECKSUM_ALG_UNDEF ?
8120     mi->checksum_alg_before_fd :
8121     mi->rli->relay_log.relay_log_checksum_alg;
8122 
8123   char *save_buf= NULL; // needed for checksumming the fake Rotate event
8124   char rot_buf[LOG_EVENT_HEADER_LEN + Binary_log_event::ROTATE_HEADER_LEN + FN_REFLEN];
8125   Gtid gtid= { 0, 0 };
8126   Log_event_type event_type= (Log_event_type)buf[EVENT_TYPE_OFFSET];
8127 
8128   DBUG_ASSERT(checksum_alg == binary_log::BINLOG_CHECKSUM_ALG_OFF ||
8129               checksum_alg == binary_log::BINLOG_CHECKSUM_ALG_UNDEF ||
8130               checksum_alg == binary_log::BINLOG_CHECKSUM_ALG_CRC32);
8131 
8132   DBUG_ENTER("queue_event");
8133 
8134   /*
8135     Pause the IO thread execution and wait for 'continue_queuing_event'
8136     signal to continue IO thread execution.
8137   */
8138   DBUG_EXECUTE_IF("pause_on_queuing_event",
8139                   {
8140                     const char act[]= "now SIGNAL reached_queuing_event "
8141                                       "WAIT_FOR continue_queuing_event";
8142                     DBUG_ASSERT(!debug_sync_set_action(current_thd,
8143                                                        STRING_WITH_LEN(act)));
8144                   };);
8145 
8146   /*
8147     FD_queue checksum alg description does not apply in a case of
8148     FD itself. The one carries both parts of the checksum data.
8149   */
8150   if (event_type == binary_log::FORMAT_DESCRIPTION_EVENT)
8151   {
8152     checksum_alg= Log_event_footer::get_checksum_alg(buf, event_len);
8153   }
8154   else if (event_type == binary_log::START_EVENT_V3)
8155   {
8156     // checksum behaviour is similar to the pre-checksum FD handling
8157     mi->checksum_alg_before_fd= binary_log::BINLOG_CHECKSUM_ALG_UNDEF;
8158     mysql_mutex_lock(&mi->data_lock);
8159     mi->get_mi_description_event()->common_footer->checksum_alg=
8160       mi->rli->relay_log.relay_log_checksum_alg= checksum_alg=
8161       binary_log::BINLOG_CHECKSUM_ALG_OFF;
8162     mysql_mutex_unlock(&mi->data_lock);
8163   }
8164 
8165   // does not hold always because of old binlog can work with NM
8166   // DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
8167 
8168   // should hold unless manipulations with RL. Tests that do that
8169   // will have to refine the clause.
8170   DBUG_ASSERT(mi->rli->relay_log.relay_log_checksum_alg !=
8171               binary_log::BINLOG_CHECKSUM_ALG_UNDEF);
8172 
8173   // Emulate the network corruption
8174   DBUG_EXECUTE_IF("corrupt_queue_event",
8175     if (event_type != binary_log::FORMAT_DESCRIPTION_EVENT)
8176     {
8177       char *debug_event_buf_c = (char*) buf;
8178       int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
8179       debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
8180       DBUG_PRINT("info", ("Corrupt the event at queue_event: byte on position %d", debug_cor_pos));
8181       DBUG_SET("");
8182     }
8183   );
8184   binary_log_debug::debug_checksum_test=
8185     DBUG_EVALUATE_IF("simulate_checksum_test_failure", true, false);
8186   binary_log_debug::debug_checksum_test=
8187     DBUG_EVALUATE_IF("gr_simulate_checksum_test_failure", true, binary_log_debug::debug_checksum_test);
8188   if (Log_event_footer::event_checksum_test((uchar *) buf,
8189                                             event_len, checksum_alg))
8190   {
8191     mi->report(ERROR_LEVEL, ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE,
8192                "%s", ER(ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE));
8193     goto err;
8194   }
8195 
8196   mysql_mutex_lock(&mi->data_lock);
8197   DBUG_ASSERT(lock_count == 0);
8198   lock_count= 1;
8199 
8200   if (mi->get_mi_description_event() == NULL)
8201   {
8202     sql_print_error("The queue event failed for channel '%s' as its "
8203                     "configuration is invalid.", mi->get_channel());
8204     goto err;
8205   }
8206 
8207   /*
8208     Simulate an unknown ignorable log event by rewriting a Xid
8209     log event before queuing it into relay log.
8210   */
8211   DBUG_EXECUTE_IF("simulate_unknown_ignorable_log_event_with_xid",
8212     if (event_type == binary_log::XID_EVENT)
8213     {
8214       uchar* ev_buf= (uchar*)buf;
8215       /* Overwrite the log event type with an unknown type. */
8216       ev_buf[EVENT_TYPE_OFFSET]= binary_log::ENUM_END_EVENT + 1;
8217       /* Set LOG_EVENT_IGNORABLE_F for the log event. */
8218       int2store(ev_buf + FLAGS_OFFSET,
8219                 uint2korr(ev_buf + FLAGS_OFFSET) | LOG_EVENT_IGNORABLE_F);
8220       /* Recalc event's CRC */
8221       ha_checksum ev_crc= checksum_crc32(0L, NULL, 0);
8222       ev_crc= checksum_crc32(ev_crc, (const uchar *) ev_buf,
8223                              event_len - BINLOG_CHECKSUM_LEN);
8224       int4store(&ev_buf[event_len - BINLOG_CHECKSUM_LEN], ev_crc);
8225       /*
8226         We will skip writing this event to the relay log in order to let
8227         the startup procedure to not finding it and assuming this transaction
8228         is incomplete.
8229         But we have to keep the unknown ignorable error to let the
8230         "stop_io_after_reading_unknown_event" debug point to work after
8231         "queuing" this event.
8232       */
8233       mi->set_master_log_pos(mi->get_master_log_pos() + event_len);
8234       goto end;
8235     }
8236   );
8237 
8238   /*
8239     This transaction parser is used to ensure that the GTID of the transaction
8240     (if it has one) will only be added to the Retrieved_Gtid_Set after the
8241     last event of the transaction be queued.
8242     It will also be used to avoid rotating the relay log in the middle of
8243     a transaction.
8244   */
8245   if (mi->transaction_parser.feed_event(buf, event_len,
8246                                         mi->get_mi_description_event(), true))
8247   {
8248     /*
8249       The transaction parser detected a problem while changing state and threw
8250       a warning message. We are taking care of avoiding transaction boundary
8251       issues, but it can happen.
8252 
8253       Transaction boundary errors might happen mostly because of bad master
8254       positioning in 'CHANGE MASTER TO' (or bad manipulation of master.info)
8255       when GTID auto positioning is off. Errors can also happen when using
8256       cross-version replication, replicating from a master that supports more
8257       event types than this slave.
8258 
8259       The IO thread will keep working and queuing events regardless of the
8260       transaction parser error, but we will throw another warning message to
8261       log the relay log file and position of the parser error to help
8262       forensics.
8263     */
8264     sql_print_warning(
8265       "An unexpected event sequence was detected by the IO thread while "
8266       "queuing the event received from master '%s' binary log file, at "
8267       "position %llu.", mi->get_master_log_name(), mi->get_master_log_pos());
8268   }
8269 
8270   if (mi->get_mi_description_event()->binlog_version < 4 &&
8271       event_type != binary_log::FORMAT_DESCRIPTION_EVENT /* a way to escape */)
8272   {
8273     if (queue_old_event(mi,buf,event_len))
8274       goto err;
8275     else
8276       goto end;
8277   }
8278   switch (event_type) {
8279   case binary_log::STOP_EVENT:
8280     /*
8281       We needn't write this event to the relay log. Indeed, it just indicates a
8282       master server shutdown. The only thing this does is cleaning. But
8283       cleaning is already done on a per-master-thread basis (as the master
8284       server is shutting down cleanly, it has written all DROP TEMPORARY TABLE
8285       prepared statements' deletion are TODO only when we binlog prep stmts).
8286 
8287       We don't even increment mi->get_master_log_pos(), because we may be just after
8288       a Rotate event. Btw, in a few milliseconds we are going to have a Start
8289       event from the next binlog (unless the master is presently running
8290       without --log-bin).
8291     */
8292     goto end;
8293   case binary_log::ROTATE_EVENT:
8294   {
8295     Rotate_log_event rev(buf, checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_OFF ?
8296                          event_len - BINLOG_CHECKSUM_LEN : event_len,
8297                          mi->get_mi_description_event());
8298 
8299     if (unlikely(process_io_rotate(mi, &rev)))
8300     {
8301       mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
8302                  ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
8303                  "could not queue event from master");
8304       goto err;
8305     }
8306     /*
8307        Checksum special cases for the fake Rotate (R_f) event caused by the protocol
8308        of events generation and serialization in RL where Rotate of master is
8309        queued right next to FD of slave.
8310        Since it's only FD that carries the alg desc of FD_s has to apply to R_m.
8311        Two special rules apply only to the first R_f which comes in before any FD_m.
8312        The 2nd R_f should be compatible with the FD_s that must have taken over
8313        the last seen FD_m's (A).
8314 
8315        RSC_1: If OM \and fake Rotate \and slave is configured to
8316               to compute checksum for its first FD event for RL
8317               the fake Rotate gets checksummed here.
8318     */
8319     if (uint4korr(&buf[0]) == 0 && checksum_alg ==
8320                   binary_log::BINLOG_CHECKSUM_ALG_OFF &&
8321                   mi->rli->relay_log.relay_log_checksum_alg !=
8322                   binary_log::BINLOG_CHECKSUM_ALG_OFF)
8323     {
8324       ha_checksum rot_crc= checksum_crc32(0L, NULL, 0);
8325       event_len += BINLOG_CHECKSUM_LEN;
8326       memcpy(rot_buf, buf, event_len - BINLOG_CHECKSUM_LEN);
8327       int4store(&rot_buf[EVENT_LEN_OFFSET],
8328                 uint4korr(rot_buf + EVENT_LEN_OFFSET) +
8329                 BINLOG_CHECKSUM_LEN);
8330       rot_crc= checksum_crc32(rot_crc, (const uchar *) rot_buf,
8331                            event_len - BINLOG_CHECKSUM_LEN);
8332       int4store(&rot_buf[event_len - BINLOG_CHECKSUM_LEN], rot_crc);
8333       DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
8334       DBUG_ASSERT(mi->get_mi_description_event()->common_footer->checksum_alg ==
8335                   mi->rli->relay_log.relay_log_checksum_alg);
8336       /* the first one */
8337       DBUG_ASSERT(mi->checksum_alg_before_fd !=
8338                   binary_log::BINLOG_CHECKSUM_ALG_UNDEF);
8339       save_buf= (char *) buf;
8340       buf= rot_buf;
8341     }
8342     else
8343       /*
8344         RSC_2: If NM \and fake Rotate \and slave does not compute checksum
8345         the fake Rotate's checksum is stripped off before relay-logging.
8346       */
8347       if (uint4korr(&buf[0]) == 0 && checksum_alg !=
8348                     binary_log::BINLOG_CHECKSUM_ALG_OFF &&
8349                     mi->rli->relay_log.relay_log_checksum_alg ==
8350                     binary_log::BINLOG_CHECKSUM_ALG_OFF)
8351       {
8352         event_len -= BINLOG_CHECKSUM_LEN;
8353         memcpy(rot_buf, buf, event_len);
8354         int4store(&rot_buf[EVENT_LEN_OFFSET],
8355                   uint4korr(rot_buf + EVENT_LEN_OFFSET) -
8356                   BINLOG_CHECKSUM_LEN);
8357         DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
8358         DBUG_ASSERT(mi->get_mi_description_event()->common_footer->checksum_alg ==
8359                     mi->rli->relay_log.relay_log_checksum_alg);
8360         /* the first one */
8361         DBUG_ASSERT(mi->checksum_alg_before_fd !=
8362                     binary_log::BINLOG_CHECKSUM_ALG_UNDEF);
8363         save_buf= (char *) buf;
8364         buf= rot_buf;
8365       }
8366     /*
8367       Now the I/O thread has just changed its mi->get_master_log_name(), so
8368       incrementing mi->get_master_log_pos() is nonsense.
8369     */
8370     inc_pos= 0;
8371     break;
8372   }
8373   case binary_log::FORMAT_DESCRIPTION_EVENT:
8374   {
8375     /*
8376       Create an event, and save it (when we rotate the relay log, we will have
8377       to write this event again).
8378     */
8379     /*
8380       We are the only thread which reads/writes mi_description_event.
8381       The relay_log struct does not move (though some members of it can
8382       change), so we needn't any lock (no rli->data_lock, no log lock).
8383     */
8384     const char* errmsg_unused;
8385     // mark it as undefined that is irrelevant anymore
8386     mi->checksum_alg_before_fd= binary_log::BINLOG_CHECKSUM_ALG_UNDEF;
8387     Format_description_log_event *new_fdle=
8388       (Format_description_log_event*)
8389       Log_event::read_log_event(buf, event_len, &errmsg_unused,
8390                                 mi->get_mi_description_event(), 1);
8391     /// @todo: don't ignore 'errmsg_unused'; instead report correct error here
8392     if (new_fdle == NULL)
8393     {
8394       mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
8395                  ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
8396                  "could not queue event from master");
8397       goto err;
8398     }
8399     if (new_fdle->common_footer->checksum_alg ==
8400                                  binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
8401       new_fdle->common_footer->checksum_alg= binary_log::BINLOG_CHECKSUM_ALG_OFF;
8402 
8403     mi->set_mi_description_event(new_fdle);
8404 
8405     /* installing new value of checksum Alg for relay log */
8406     mi->rli->relay_log.relay_log_checksum_alg= new_fdle->common_footer->checksum_alg;
8407 
8408     /*
8409        Though this does some conversion to the slave's format, this will
8410        preserve the master's binlog format version, and number of event types.
8411     */
8412     /*
8413        If the event was not requested by the slave (the slave did not ask for
8414        it), i.e. has end_log_pos=0, we do not increment mi->get_master_log_pos()
8415     */
8416     inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0;
8417     DBUG_PRINT("info",("binlog format is now %d",
8418                        mi->get_mi_description_event()->binlog_version));
8419 
8420   }
8421   break;
8422 
8423   case binary_log::HEARTBEAT_LOG_EVENT:
8424   {
8425     /*
8426       HB (heartbeat) cannot come before RL (Relay)
8427     */
8428     Heartbeat_log_event hb(buf,
8429                            mi->rli->relay_log.relay_log_checksum_alg
8430                            != binary_log::BINLOG_CHECKSUM_ALG_OFF ?
8431                            event_len - BINLOG_CHECKSUM_LEN : event_len,
8432                            mi->get_mi_description_event());
8433     if (!hb.is_valid())
8434     {
8435       char errbuf[1024];
8436       char llbuf[22];
8437       sprintf(errbuf, "inconsistent heartbeat event content; the event's data: "
8438               "log_file_name %-.512s log_pos %s",
8439               hb.get_log_ident(), llstr(hb.common_header->log_pos, llbuf));
8440       mi->report(ERROR_LEVEL, ER_SLAVE_HEARTBEAT_FAILURE,
8441                  ER(ER_SLAVE_HEARTBEAT_FAILURE), errbuf);
8442       goto err;
8443     }
8444     mi->received_heartbeats++;
8445     mi->last_heartbeat= my_time(0);
8446 
8447 
8448     /*
8449       During GTID protocol, if the master skips transactions,
8450       a heartbeat event is sent to the slave at the end of last
8451       skipped transaction to update coordinates.
8452 
8453       I/O thread receives the heartbeat event and updates mi
8454       only if the received heartbeat position is greater than
8455       mi->get_master_log_pos(). This event is written to the
8456       relay log as an ignored Rotate event. SQL thread reads
8457       the rotate event only to update the coordinates corresponding
8458       to the last skipped transaction. Note that,
8459       we update only the positions and not the file names, as a ROTATE
8460       EVENT from the master prior to this will update the file name.
8461     */
8462     if (mi->is_auto_position()  && mi->get_master_log_pos() <
8463        hb.common_header->log_pos &&  mi->get_master_log_name() != NULL)
8464     {
8465 
8466       DBUG_ASSERT(memcmp(const_cast<char*>(mi->get_master_log_name()),
8467                          hb.get_log_ident(), hb.get_ident_len()) == 0);
8468 
8469       DBUG_EXECUTE_IF("reached_heart_beat_queue_event", {
8470                       const char act[] = "now SIGNAL check_slave_master_info WAIT_FOR proceed_write_rotate";
8471                       DBUG_ASSERT(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act)));
8472                       };);
8473 
8474       mi->set_master_log_pos(hb.common_header->log_pos);
8475 
8476       /*
8477          Put this heartbeat event in the relay log as a Rotate Event.
8478       */
8479       inc_pos= 0;
8480       memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(),
8481              FN_REFLEN);
8482       rli->ign_master_log_pos_end = mi->get_master_log_pos();
8483 
8484       if (write_ignored_events_info_to_relay_log(mi->info_thd, mi,
8485                                                  false/* force_flush_mi_info */))
8486         goto end;
8487     }
8488 
8489     /*
8490        compare local and event's versions of log_file, log_pos.
8491 
8492        Heartbeat is sent only after an event corresponding to the corrdinates
8493        the heartbeat carries.
8494        Slave can not have a difference in coordinates except in the only
8495        special case when mi->get_master_log_name(), mi->get_master_log_pos() have never
8496        been updated by Rotate event i.e when slave does not have any history
8497        with the master (and thereafter mi->get_master_log_pos() is NULL).
8498 
8499        TODO: handling `when' for SHOW SLAVE STATUS' snds behind
8500     */
8501     if (memcmp(const_cast<char *>(mi->get_master_log_name()),
8502                hb.get_log_ident(), hb.get_ident_len())
8503         || (mi->get_master_log_pos() > hb.common_header->log_pos))
8504     {
8505       /* missed events of heartbeat from the past */
8506       char errbuf[1024];
8507       char llbuf[22];
8508       sprintf(errbuf, "heartbeat is not compatible with local info; "
8509               "the event's data: log_file_name %-.512s log_pos %s",
8510               hb.get_log_ident(), llstr(hb.common_header->log_pos, llbuf));
8511       mi->report(ERROR_LEVEL, ER_SLAVE_HEARTBEAT_FAILURE,
8512                  ER(ER_SLAVE_HEARTBEAT_FAILURE), errbuf);
8513       goto err;
8514     }
8515     goto end;
8516   }
8517   break;
8518 
8519   case binary_log::PREVIOUS_GTIDS_LOG_EVENT:
8520   {
8521     /*
8522       This event does not have any meaning for the slave and
8523       was just sent to show the slave the master is making
8524       progress and avoid possible deadlocks.
8525       So at this point, the event is replaced by a rotate
8526       event what will make the slave to update what it knows
8527       about the master's coordinates.
8528     */
8529     inc_pos= 0;
8530     mi->set_master_log_pos(mi->get_master_log_pos() + event_len);
8531     memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(), FN_REFLEN);
8532     rli->ign_master_log_pos_end= mi->get_master_log_pos();
8533 
8534     if (write_ignored_events_info_to_relay_log(mi->info_thd, mi,
8535                                                true/* force_flush_mi_info */))
8536       goto err;
8537 
8538     goto end;
8539   }
8540   break;
8541 
8542   case binary_log::GTID_LOG_EVENT:
8543   {
8544     global_sid_lock->rdlock();
8545     /*
8546       This can happen if the master uses GTID_MODE=OFF_PERMISSIVE, and
8547       sends GTID events to the slave. A possible scenario is that user
8548       does not follow the upgrade procedure for GTIDs, and creates a
8549       topology like A->B->C, where A uses GTID_MODE=ON_PERMISSIVE, B
8550       uses GTID_MODE=OFF_PERMISSIVE, and C uses GTID_MODE=OFF.  Each
8551       connection is allowed, but the master A will generate GTID
8552       transactions which will be sent through B to C.  Then C will hit
8553       this error.
8554     */
8555     if (get_gtid_mode(GTID_MODE_LOCK_SID) == GTID_MODE_OFF)
8556     {
8557       global_sid_lock->unlock();
8558       mi->report(ERROR_LEVEL, ER_CANT_REPLICATE_GTID_WITH_GTID_MODE_OFF,
8559                  ER(ER_CANT_REPLICATE_GTID_WITH_GTID_MODE_OFF),
8560                  mi->get_master_log_name(), mi->get_master_log_pos());
8561       goto err;
8562     }
8563     Gtid_log_event gtid_ev(buf,
8564                            checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_OFF ?
8565                            event_len - BINLOG_CHECKSUM_LEN : event_len,
8566                            mi->get_mi_description_event());
8567     gtid.sidno= gtid_ev.get_sidno(false);
8568     global_sid_lock->unlock();
8569     if (gtid.sidno < 0)
8570       goto err;
8571     gtid.gno= gtid_ev.get_gno();
8572     inc_pos= event_len;
8573   }
8574   break;
8575 
8576   case binary_log::ANONYMOUS_GTID_LOG_EVENT:
8577     /*
8578       This cannot normally happen, because the master has a check that
8579       prevents it from sending anonymous events when auto_position is
8580       enabled.  However, the master could be something else than
8581       mysqld, which could contain bugs that we have no control over.
8582       So we need this check on the slave to be sure that whoever is on
8583       the other side of the protocol does not break the protocol.
8584     */
8585     if (mi->is_auto_position())
8586     {
8587       mi->report(ERROR_LEVEL, ER_CANT_REPLICATE_ANONYMOUS_WITH_AUTO_POSITION,
8588                  ER(ER_CANT_REPLICATE_ANONYMOUS_WITH_AUTO_POSITION),
8589                  mi->get_master_log_name(), mi->get_master_log_pos());
8590       goto err;
8591     }
8592     /*
8593       This can happen if the master uses GTID_MODE=ON_PERMISSIVE, and
8594       sends an anonymous event to the slave. A possible scenario is
8595       that user does not follow the upgrade procedure for GTIDs, and
8596       creates a topology like A->B->C, where A uses
8597       GTID_MODE=OFF_PERMISSIVE, B uses GTID_MODE=ON_PERMISSIVE, and C
8598       uses GTID_MODE=ON.  Each connection is allowed, but the master A
8599       will generate anonymous transactions which will be sent through
8600       B to C.  Then C will hit this error.
8601     */
8602     else if (get_gtid_mode(GTID_MODE_LOCK_NONE) == GTID_MODE_ON)
8603     {
8604       mi->report(ERROR_LEVEL, ER_CANT_REPLICATE_ANONYMOUS_WITH_GTID_MODE_ON,
8605                  ER(ER_CANT_REPLICATE_ANONYMOUS_WITH_GTID_MODE_ON),
8606                  mi->get_master_log_name(), mi->get_master_log_pos());
8607       goto err;
8608     }
8609     /* fall through */
8610 
8611   default:
8612     inc_pos= event_len;
8613   break;
8614   }
8615 
8616   /*
8617     Simulate an unknown ignorable log event by rewriting the write_rows log
8618     event and previous_gtids log event before writing them in relay log.
8619   */
8620   DBUG_EXECUTE_IF("simulate_unknown_ignorable_log_event",
8621     if (event_type == binary_log::WRITE_ROWS_EVENT ||
8622         event_type == binary_log::PREVIOUS_GTIDS_LOG_EVENT)
8623     {
8624       char *event_buf= const_cast<char*>(buf);
8625       /* Overwrite the log event type with an unknown type. */
8626       event_buf[EVENT_TYPE_OFFSET]= binary_log::ENUM_END_EVENT + 1;
8627       /* Set LOG_EVENT_IGNORABLE_F for the log event. */
8628       int2store(event_buf + FLAGS_OFFSET,
8629                 uint2korr(event_buf + FLAGS_OFFSET) | LOG_EVENT_IGNORABLE_F);
8630     }
8631   );
8632 
8633   /*
8634      If this event is originating from this server, don't queue it.
8635      We don't check this for 3.23 events because it's simpler like this; 3.23
8636      will be filtered anyway by the SQL slave thread which also tests the
8637      server id (we must also keep this test in the SQL thread, in case somebody
8638      upgrades a 4.0 slave which has a not-filtered relay log).
8639 
8640      ANY event coming from ourselves can be ignored: it is obvious for queries;
8641      for STOP_EVENT/ROTATE_EVENT/START_EVENT: these cannot come from ourselves
8642      (--log-slave-updates would not log that) unless this slave is also its
8643      direct master (an unsupported, useless setup!).
8644   */
8645 
8646   mysql_mutex_lock(log_lock);
8647   DBUG_ASSERT(lock_count == 1);
8648   lock_count= 2;
8649 
8650   s_id= uint4korr(buf + SERVER_ID_OFFSET);
8651 
8652   /*
8653     If server_id_bits option is set we need to mask out irrelevant bits
8654     when checking server_id, but we still put the full unmasked server_id
8655     into the Relay log so that it can be accessed when applying the event
8656   */
8657   s_id&= opt_server_id_mask;
8658 
8659   if ((s_id == ::server_id && !mi->rli->replicate_same_server_id) ||
8660       /*
8661         the following conjunction deals with IGNORE_SERVER_IDS, if set
8662         If the master is on the ignore list, execution of
8663         format description log events and rotate events is necessary.
8664       */
8665       (mi->ignore_server_ids->dynamic_ids.size() > 0 &&
8666        mi->shall_ignore_server_id(s_id) &&
8667        /* everything is filtered out from non-master */
8668        (s_id != mi->master_id ||
8669         /* for the master meta information is necessary */
8670         (event_type != binary_log::FORMAT_DESCRIPTION_EVENT &&
8671          event_type != binary_log::ROTATE_EVENT))))
8672   {
8673     /*
8674       Do not write it to the relay log.
8675       a) We still want to increment mi->get_master_log_pos(), so that we won't
8676       re-read this event from the master if the slave IO thread is now
8677       stopped/restarted (more efficient if the events we are ignoring are big
8678       LOAD DATA INFILE).
8679       b) We want to record that we are skipping events, for the information of
8680       the slave SQL thread, otherwise that thread may let
8681       rli->group_relay_log_pos stay too small if the last binlog's event is
8682       ignored.
8683       But events which were generated by this slave and which do not exist in
8684       the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
8685       mi->get_master_log_pos().
8686       If the event is originated remotely and is being filtered out by
8687       IGNORE_SERVER_IDS it increments mi->get_master_log_pos()
8688       as well as rli->group_relay_log_pos.
8689     */
8690     if (!(s_id == ::server_id && !mi->rli->replicate_same_server_id) ||
8691         (event_type != binary_log::FORMAT_DESCRIPTION_EVENT &&
8692          event_type != binary_log::ROTATE_EVENT &&
8693          event_type != binary_log::STOP_EVENT))
8694     {
8695       mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
8696       memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(), FN_REFLEN);
8697       DBUG_ASSERT(rli->ign_master_log_name_end[0]);
8698       rli->ign_master_log_pos_end= mi->get_master_log_pos();
8699     }
8700     rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
8701     DBUG_PRINT("info", ("master_log_pos: %lu, event originating from %u server, ignored",
8702                         (ulong) mi->get_master_log_pos(), uint4korr(buf + SERVER_ID_OFFSET)));
8703   }
8704   else
8705   {
8706     bool is_error= false;
8707     /* write the event to the relay log */
8708     if (likely(rli->relay_log.append_buffer(buf, event_len, mi) == 0))
8709     {
8710       mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
8711       DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
8712       rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
8713 
8714       /*
8715         If this event is GTID_LOG_EVENT we store its GTID to add to the
8716         Retrieved_Gtid_Set later, when the last event of the transaction be
8717         queued.
8718       */
8719       if (event_type == binary_log::GTID_LOG_EVENT)
8720       {
8721         mi->set_last_gtid_queued(gtid);
8722       }
8723 
8724       /*
8725         If we are starting an anonymous transaction, we have to discard
8726         the GTID of the partial transaction that was not finished (if
8727         there is one).
8728         */
8729       if (event_type == binary_log::ANONYMOUS_GTID_LOG_EVENT)
8730       {
8731 #ifndef DBUG_OFF
8732         if (!mi->get_last_gtid_queued()->is_empty())
8733         {
8734           DBUG_PRINT("info", ("Discarding Gtid(%d, %lld) as the transaction "
8735                               "wasn't complete and we found an "
8736                               "ANONYMOUS_GTID_LOG_EVENT.",
8737                               mi->get_last_gtid_queued()->sidno,
8738                               mi->get_last_gtid_queued()->gno));
8739         }
8740 #endif
8741         mi->clear_last_gtid_queued();
8742       }
8743     }
8744     else
8745       is_error= true;
8746     rli->ign_master_log_name_end[0]= 0; // last event is not ignored
8747     if (save_buf != NULL)
8748       buf= save_buf;
8749     if (is_error)
8750     {
8751       mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
8752                  ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
8753                  "could not queue event from master");
8754       goto err;
8755     }
8756   }
8757   goto end;
8758 
8759 err:
8760   error= true;
8761 
8762 end:
8763   if (lock_count >= 1)
8764     mysql_mutex_unlock(&mi->data_lock);
8765   if (lock_count >= 2)
8766     mysql_mutex_unlock(log_lock);
8767   DBUG_PRINT("info", ("error: %d", error));
8768   DBUG_RETURN(error);
8769 }
8770 
8771 /**
8772   Hook to detach the active VIO before closing a connection handle.
8773 
8774   The client API might close the connection (and associated data)
8775   in case it encounters a unrecoverable (network) error. This hook
8776   is called from the client code before the VIO handle is deleted
8777   allows the thread to detach the active vio so it does not point
8778   to freed memory.
8779 
8780   Other calls to THD::clear_active_vio throughout this module are
8781   redundant due to the hook but are left in place for illustrative
8782   purposes.
8783 */
8784 
slave_io_thread_detach_vio()8785 extern "C" void slave_io_thread_detach_vio()
8786 {
8787   THD *thd= current_thd;
8788   if (thd && thd->slave_thread)
8789     thd->clear_active_vio();
8790 }
8791 
8792 
8793 /*
8794   Try to connect until successful or slave killed
8795 
8796   SYNPOSIS
8797     safe_connect()
8798     thd                 Thread handler for slave
8799     mysql               MySQL connection handle
8800     mi                  Replication handle
8801 
8802   RETURN
8803     0   ok
8804     #   Error
8805 */
8806 
safe_connect(THD * thd,MYSQL * mysql,Master_info * mi)8807 static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi)
8808 {
8809   DBUG_ENTER("safe_connect");
8810 
8811   DBUG_RETURN(connect_to_master(thd, mysql, mi, 0, 0));
8812 }
8813 
8814 
8815 /*
8816   SYNPOSIS
8817     connect_to_master()
8818 
8819   IMPLEMENTATION
8820     Try to connect until successful or slave killed or we have retried
8821     mi->retry_count times
8822 */
8823 
connect_to_master(THD * thd,MYSQL * mysql,Master_info * mi,bool reconnect,bool suppress_warnings)8824 static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
8825                              bool reconnect, bool suppress_warnings)
8826 {
8827   int slave_was_killed= 0;
8828   int last_errno= -2;                           // impossible error
8829   ulong err_count=0;
8830   char llbuff[22];
8831   char password[MAX_PASSWORD_LENGTH + 1];
8832   size_t password_size= sizeof(password);
8833   DBUG_ENTER("connect_to_master");
8834   set_slave_max_allowed_packet(thd, mysql);
8835 #ifndef DBUG_OFF
8836   mi->events_until_exit = disconnect_slave_event_count;
8837 #endif
8838   ulong client_flag= CLIENT_REMEMBER_OPTIONS;
8839   if (opt_slave_compressed_protocol)
8840     client_flag|= CLIENT_COMPRESS;              /* We will use compression */
8841 
8842   mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
8843   mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
8844 
8845   if (mi->bind_addr[0])
8846   {
8847     DBUG_PRINT("info",("bind_addr: %s", mi->bind_addr));
8848     mysql_options(mysql, MYSQL_OPT_BIND, mi->bind_addr);
8849   }
8850 
8851 #ifdef HAVE_OPENSSL
8852   /* By default the channel is not configured to use SSL */
8853   enum mysql_ssl_mode ssl_mode= SSL_MODE_DISABLED;
8854   if (mi->ssl)
8855   {
8856     /* The channel is configured to use SSL */
8857     mysql_ssl_set(mysql,
8858                   mi->ssl_key[0]?mi->ssl_key:0,
8859                   mi->ssl_cert[0]?mi->ssl_cert:0,
8860                   mi->ssl_ca[0]?mi->ssl_ca:0,
8861                   mi->ssl_capath[0]?mi->ssl_capath:0,
8862                   mi->ssl_cipher[0]?mi->ssl_cipher:0);
8863     mysql_options(mysql, MYSQL_OPT_SSL_CRL,
8864                   mi->ssl_crl[0] ? mi->ssl_crl : 0);
8865     mysql_options(mysql, MYSQL_OPT_TLS_VERSION,
8866                   mi->tls_version[0] ? mi->tls_version : 0);
8867     mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH,
8868                   mi->ssl_crlpath[0] ? mi->ssl_crlpath : 0);
8869     if (mi->ssl_verify_server_cert)
8870       ssl_mode= SSL_MODE_VERIFY_IDENTITY;
8871     else if (mi->ssl_ca[0] || mi->ssl_capath[0])
8872       ssl_mode= SSL_MODE_VERIFY_CA;
8873     else
8874       ssl_mode= SSL_MODE_REQUIRED;
8875   }
8876   mysql_options(mysql, MYSQL_OPT_SSL_MODE, &ssl_mode);
8877 #endif
8878 
8879   /*
8880     If server's default charset is not supported (like utf16, utf32) as client
8881     charset, then set client charset to 'latin1' (default client charset).
8882   */
8883   if (is_supported_parser_charset(default_charset_info))
8884     mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset_info->csname);
8885   else
8886   {
8887     sql_print_information("'%s' can not be used as client character set. "
8888                           "'%s' will be used as default client character set "
8889                           "while connecting to master.",
8890                           default_charset_info->csname,
8891                           default_client_charset_info->csname);
8892     mysql_options(mysql, MYSQL_SET_CHARSET_NAME,
8893                   default_client_charset_info->csname);
8894   }
8895 
8896 
8897   /* This one is not strictly needed but we have it here for completeness */
8898   mysql_options(mysql, MYSQL_SET_CHARSET_DIR, (char *) charsets_dir);
8899 
8900   if (mi->is_start_plugin_auth_configured())
8901   {
8902     DBUG_PRINT("info", ("Slaving is using MYSQL_DEFAULT_AUTH %s",
8903                         mi->get_start_plugin_auth()));
8904     mysql_options(mysql, MYSQL_DEFAULT_AUTH, mi->get_start_plugin_auth());
8905   }
8906 
8907   if (mi->is_start_plugin_dir_configured())
8908   {
8909     DBUG_PRINT("info", ("Slaving is using MYSQL_PLUGIN_DIR %s",
8910                         mi->get_start_plugin_dir()));
8911     mysql_options(mysql, MYSQL_PLUGIN_DIR, mi->get_start_plugin_dir());
8912   }
8913   /* Set MYSQL_PLUGIN_DIR in case master asks for an external authentication plugin */
8914   else if (opt_plugin_dir_ptr && *opt_plugin_dir_ptr)
8915     mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir_ptr);
8916 
8917   if (!mi->is_start_user_configured())
8918     sql_print_warning("%s", ER(ER_INSECURE_CHANGE_MASTER));
8919 
8920   if (mi->get_password(password, &password_size))
8921   {
8922     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8923                ER(ER_SLAVE_FATAL_ERROR),
8924                "Unable to configure password when attempting to "
8925                "connect to the master server. Connection attempt "
8926                "terminated.");
8927     DBUG_RETURN(1);
8928   }
8929 
8930   const char* user= mi->get_user();
8931   if (user == NULL || user[0] == 0)
8932   {
8933     mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8934                ER(ER_SLAVE_FATAL_ERROR),
8935                "Invalid (empty) username when attempting to "
8936                "connect to the master server. Connection attempt "
8937                "terminated.");
8938     DBUG_RETURN(1);
8939   }
8940 
8941   mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
8942                 "program_name", "mysqld");
8943   mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
8944                 "_client_role", "binary_log_listener");
8945   mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
8946                 "_client_replication_channel_name", mi->get_channel());
8947 
8948   while (!(slave_was_killed = io_slave_killed(thd,mi))
8949          && (reconnect ? mysql_reconnect(mysql) != 0 :
8950              mysql_real_connect(mysql, mi->host, user,
8951                                 password, 0, mi->port, 0, client_flag) == 0))
8952   {
8953     /*
8954        SHOW SLAVE STATUS will display the number of retries which
8955        would be real retry counts instead of mi->retry_count for
8956        each connection attempt by 'Last_IO_Error' entry.
8957     */
8958     last_errno=mysql_errno(mysql);
8959     suppress_warnings= 0;
8960     mi->report(ERROR_LEVEL, last_errno,
8961                "error %s to master '%s@%s:%d'"
8962                " - retry-time: %d  retries: %lu",
8963                (reconnect ? "reconnecting" : "connecting"),
8964                mi->get_user(), mi->host, mi->port,
8965                mi->connect_retry, err_count + 1);
8966     /*
8967       By default we try forever. The reason is that failure will trigger
8968       master election, so if the user did not set mi->retry_count we
8969       do not want to have election triggered on the first failure to
8970       connect
8971     */
8972     if (++err_count == mi->retry_count)
8973     {
8974       slave_was_killed=1;
8975       break;
8976     }
8977     slave_sleep(thd, mi->connect_retry, io_slave_killed, mi);
8978   }
8979 
8980   if (!slave_was_killed)
8981   {
8982     mi->clear_error(); // clear possible left over reconnect error
8983     if (reconnect)
8984     {
8985       if (!suppress_warnings)
8986         sql_print_information("Slave%s: connected to master '%s@%s:%d',"
8987                               "replication resumed in log '%s' at position %s",
8988                               mi->get_for_channel_str(), mi->get_user(),
8989                               mi->host, mi->port,
8990                               mi->get_io_rpl_log_name(),
8991                               llstr(mi->get_master_log_pos(),llbuff));
8992     }
8993     else
8994     {
8995       query_logger.general_log_print(thd, COM_CONNECT_OUT, "%s@%s:%d",
8996                                      mi->get_user(), mi->host, mi->port);
8997     }
8998 
8999     thd->set_active_vio(mysql->net.vio);
9000   }
9001   mysql->reconnect= 1;
9002   DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed));
9003   DBUG_RETURN(slave_was_killed);
9004 }
9005 
9006 
9007 /*
9008   safe_reconnect()
9009 
9010   IMPLEMENTATION
9011     Try to connect until successful or slave killed or we have retried
9012     mi->retry_count times
9013 */
9014 
safe_reconnect(THD * thd,MYSQL * mysql,Master_info * mi,bool suppress_warnings)9015 static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
9016                           bool suppress_warnings)
9017 {
9018   DBUG_ENTER("safe_reconnect");
9019   DBUG_RETURN(connect_to_master(thd, mysql, mi, 1, suppress_warnings));
9020 }
9021 
9022 
9023 /*
9024   Called when we notice that the current "hot" log got rotated under our feet.
9025 */
9026 
reopen_relay_log(Relay_log_info * rli,const char ** errmsg)9027 static IO_CACHE *reopen_relay_log(Relay_log_info *rli, const char **errmsg)
9028 {
9029   DBUG_ENTER("reopen_relay_log");
9030   DBUG_ASSERT(rli->cur_log != &rli->cache_buf);
9031   DBUG_ASSERT(rli->cur_log_fd == -1);
9032 
9033   IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
9034   if ((rli->cur_log_fd=open_binlog_file(cur_log,rli->get_event_relay_log_name(),
9035                                         errmsg)) <0)
9036     DBUG_RETURN(0);
9037   /*
9038     We want to start exactly where we was before:
9039     relay_log_pos       Current log pos
9040     pending             Number of bytes already processed from the event
9041   */
9042   rli->set_event_relay_log_pos(max<ulonglong>(rli->get_event_relay_log_pos(),
9043                                               BIN_LOG_HEADER_SIZE));
9044   my_b_seek(cur_log,rli->get_event_relay_log_pos());
9045   DBUG_RETURN(cur_log);
9046 }
9047 
9048 
9049 /**
9050   Reads next event from the relay log.  Should be called from the
9051   slave SQL thread.
9052 
9053   @param rli Relay_log_info structure for the slave SQL thread.
9054 
9055   @return The event read, or NULL on error.  If an error occurs, the
9056   error is reported through the sql_print_information() or
9057   sql_print_error() functions.
9058 */
next_event(Relay_log_info * rli)9059 static Log_event* next_event(Relay_log_info* rli)
9060 {
9061   Log_event* ev;
9062   IO_CACHE* cur_log = rli->cur_log;
9063   mysql_mutex_t *log_lock = rli->relay_log.get_log_lock();
9064   const char* errmsg=0;
9065   THD* thd = rli->info_thd;
9066   DBUG_ENTER("next_event");
9067 
9068   DBUG_ASSERT(thd != 0);
9069 
9070 #ifndef DBUG_OFF
9071   if (abort_slave_event_count && !rli->events_until_exit--)
9072     DBUG_RETURN(0);
9073 #endif
9074 
9075   /*
9076     For most operations we need to protect rli members with data_lock,
9077     so we assume calling function acquired this mutex for us and we will
9078     hold it for the most of the loop below However, we will release it
9079     whenever it is worth the hassle,  and in the cases when we go into a
9080     mysql_cond_wait() with the non-data_lock mutex
9081   */
9082   mysql_mutex_assert_owner(&rli->data_lock);
9083 
9084   while (!sql_slave_killed(thd,rli))
9085   {
9086     /*
9087       We can have two kinds of log reading:
9088       hot_log:
9089         rli->cur_log points at the IO_CACHE of relay_log, which
9090         is actively being updated by the I/O thread. We need to be careful
9091         in this case and make sure that we are not looking at a stale log that
9092         has already been rotated. If it has been, we reopen the log.
9093 
9094       The other case is much simpler:
9095         We just have a read only log that nobody else will be updating.
9096     */
9097     bool hot_log;
9098     if ((hot_log = (cur_log != &rli->cache_buf)) ||
9099         DBUG_EVALUATE_IF("force_sql_thread_error", 1, 0))
9100     {
9101       DBUG_ASSERT(rli->cur_log_fd == -1); // foreign descriptor
9102       mysql_mutex_lock(log_lock);
9103 
9104       /*
9105         Reading xxx_file_id is safe because the log will only
9106         be rotated when we hold relay_log.LOCK_log
9107       */
9108       if (rli->relay_log.get_open_count() != rli->cur_log_old_open_count &&
9109           DBUG_EVALUATE_IF("force_sql_thread_error", 0, 1))
9110       {
9111         // The master has switched to a new log file; Reopen the old log file
9112         cur_log=reopen_relay_log(rli, &errmsg);
9113         mysql_mutex_unlock(log_lock);
9114         if (!cur_log)                           // No more log files
9115           goto err;
9116         hot_log=0;                              // Using old binary log
9117       }
9118     }
9119     /*
9120       As there is no guarantee that the relay is open (for example, an I/O
9121       error during a write by the slave I/O thread may have closed it), we
9122       have to test it.
9123     */
9124     if (!my_b_inited(cur_log) ||
9125         DBUG_EVALUATE_IF("force_sql_thread_error", 1, 0))
9126     {
9127       if (hot_log)
9128         mysql_mutex_unlock(log_lock);
9129       goto err;
9130     }
9131 #ifndef DBUG_OFF
9132     {
9133       DBUG_PRINT("info", ("assertion skip %lu file pos %lu event relay log pos %lu file %s\n",
9134         (ulong) rli->slave_skip_counter, (ulong) my_b_tell(cur_log),
9135         (ulong) rli->get_event_relay_log_pos(),
9136         rli->get_event_relay_log_name()));
9137 
9138       /* This is an assertion which sometimes fails, let's try to track it */
9139       char llbuf1[22], llbuf2[22];
9140       DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
9141                           llstr(my_b_tell(cur_log),llbuf1),
9142                           llstr(rli->get_event_relay_log_pos(),llbuf2)));
9143 
9144       DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
9145       DBUG_ASSERT(my_b_tell(cur_log) == rli->get_event_relay_log_pos() || rli->is_parallel_exec());
9146 
9147       DBUG_PRINT("info", ("next_event group master %s %lu group relay %s %lu event %s %lu\n",
9148         rli->get_group_master_log_name(),
9149         (ulong) rli->get_group_master_log_pos(),
9150         rli->get_group_relay_log_name(),
9151         (ulong) rli->get_group_relay_log_pos(),
9152         rli->get_event_relay_log_name(),
9153         (ulong) rli->get_event_relay_log_pos()));
9154     }
9155 #endif
9156     rli->set_event_start_pos(my_b_tell(cur_log));
9157     /*
9158       Relay log is always in new format - if the master is 3.23, the
9159       I/O thread will convert the format for us.
9160       A problem: the description event may be in a previous relay log. So if
9161       the slave has been shutdown meanwhile, we would have to look in old relay
9162       logs, which may even have been deleted. So we need to write this
9163       description event at the beginning of the relay log.
9164       When the relay log is created when the I/O thread starts, easy: the
9165       master will send the description event and we will queue it.
9166       But if the relay log is created by new_file(): then the solution is:
9167       MYSQL_BIN_LOG::open() will write the buffered description event.
9168     */
9169     if ((ev= Log_event::read_log_event(cur_log, 0,
9170                                        rli->get_rli_description_event(),
9171                                        opt_slave_sql_verify_checksum)))
9172     {
9173       DBUG_ASSERT(thd==rli->info_thd);
9174       /*
9175         read it while we have a lock, to avoid a mutex lock in
9176         inc_event_relay_log_pos()
9177       */
9178       rli->set_future_event_relay_log_pos(my_b_tell(cur_log));
9179       ev->future_event_relay_log_pos= rli->get_future_event_relay_log_pos();
9180 
9181       if (hot_log)
9182         mysql_mutex_unlock(log_lock);
9183       /*
9184          MTS checkpoint in the successful read branch.
9185          The following block makes sure that
9186          a. GAQ the job assignment control resource is not run out of space, and
9187          b. Last executed transaction coordinates are advanced whenever
9188             there's been progress by Workers.
9189          Notice, MTS logical clock scheduler does not introduce any
9190          own specfics even though internally it may need to learn about
9191          the done status of a job.
9192       */
9193       bool force= (rli->checkpoint_seqno > (rli->checkpoint_group - 1));
9194       if (rli->is_parallel_exec() && (opt_mts_checkpoint_period != 0 || force))
9195       {
9196         ulonglong period= static_cast<ulonglong>(opt_mts_checkpoint_period * 1000000ULL);
9197         mysql_mutex_unlock(&rli->data_lock);
9198         /*
9199           At this point the coordinator has is delegating jobs to workers and
9200           the checkpoint routine must be periodically invoked.
9201         */
9202         (void) mts_checkpoint_routine(rli, period, force, true/*need_data_lock=true*/); // TODO: ALFRANIO ERROR
9203         DBUG_ASSERT(!force ||
9204                     (force && (rli->checkpoint_seqno <= (rli->checkpoint_group - 1))) ||
9205                     sql_slave_killed(thd, rli));
9206         mysql_mutex_lock(&rli->data_lock);
9207       }
9208       DBUG_RETURN(ev);
9209     }
9210     DBUG_ASSERT(thd==rli->info_thd);
9211     if (opt_reckless_slave)                     // For mysql-test
9212       cur_log->error = 0;
9213     if (cur_log->error < 0)
9214     {
9215       errmsg = "slave SQL thread aborted because of I/O error";
9216       if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
9217         /*
9218           MTS group status is set to MTS_KILLED_GROUP, whenever a read event
9219           error happens and there was already a non-terminal event scheduled.
9220         */
9221         rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
9222       if (hot_log)
9223         mysql_mutex_unlock(log_lock);
9224       goto err;
9225     }
9226     if (!cur_log->error) /* EOF */
9227     {
9228       /*
9229         On a hot log, EOF means that there are no more updates to
9230         process and we must block until I/O thread adds some and
9231         signals us to continue
9232       */
9233       if (hot_log)
9234       {
9235         /*
9236           We say in Seconds_Behind_Master that we have "caught up". Note that
9237           for example if network link is broken but I/O slave thread hasn't
9238           noticed it (slave_net_timeout not elapsed), then we'll say "caught
9239           up" whereas we're not really caught up. Fixing that would require
9240           internally cutting timeout in smaller pieces in network read, no
9241           thanks. Another example: SQL has caught up on I/O, now I/O has read
9242           a new event and is queuing it; the false "0" will exist until SQL
9243           finishes executing the new event; it will be look abnormal only if
9244           the events have old timestamps (then you get "many", 0, "many").
9245 
9246           Transient phases like this can be fixed with implemeting
9247           Heartbeat event which provides the slave the status of the
9248           master at time the master does not have any new update to send.
9249           Seconds_Behind_Master would be zero only when master has no
9250           more updates in binlog for slave. The heartbeat can be sent
9251           in a (small) fraction of slave_net_timeout. Until it's done
9252           rli->last_master_timestamp is temporarely (for time of
9253           waiting for the following event) reset whenever EOF is
9254           reached.
9255         */
9256 
9257         /* shows zero while it is sleeping (and until the next event
9258            is about to be executed).  Note, in MTS case
9259            Seconds_Behind_Master resetting follows slightly different
9260            schema where reaching EOF is not enough.  The status
9261            parameter is updated per some number of processed group of
9262            events. The number can't be greater than
9263            @@global.slave_checkpoint_group and anyway SBM updating
9264            rate does not exceed @@global.slave_checkpoint_period.
9265            Notice that SBM is set to a new value after processing the
9266            terminal event (e.g Commit) of a group.  Coordinator resets
9267            SBM when notices no more groups left neither to read from
9268            Relay-log nor to process by Workers.
9269         */
9270         if (!rli->is_parallel_exec())
9271           rli->last_master_timestamp= 0;
9272 
9273         DBUG_ASSERT(rli->relay_log.get_open_count() ==
9274                     rli->cur_log_old_open_count);
9275 
9276         if (rli->ign_master_log_name_end[0])
9277         {
9278           /* We generate and return a Rotate, to make our positions advance */
9279           DBUG_PRINT("info",("seeing an ignored end segment"));
9280           ev= new Rotate_log_event(rli->ign_master_log_name_end,
9281                                    0, rli->ign_master_log_pos_end,
9282                                    Rotate_log_event::DUP_NAME);
9283           rli->ign_master_log_name_end[0]= 0;
9284           mysql_mutex_unlock(log_lock);
9285           if (unlikely(!ev))
9286           {
9287             errmsg= "Slave SQL thread failed to create a Rotate event "
9288               "(out of memory?), SHOW SLAVE STATUS may be inaccurate";
9289             goto err;
9290           }
9291           ev->server_id= 0; // don't be ignored by slave SQL thread
9292           DBUG_RETURN(ev);
9293         }
9294 
9295         /*
9296           We can, and should release data_lock while we are waiting for
9297           update. If we do not, show slave status will block
9298         */
9299         mysql_mutex_unlock(&rli->data_lock);
9300 
9301         /*
9302           Possible deadlock :
9303           - the I/O thread has reached log_space_limit
9304           - the SQL thread has read all relay logs, but cannot purge for some
9305           reason:
9306             * it has already purged all logs except the current one
9307             * there are other logs than the current one but they're involved in
9308             a transaction that finishes in the current one (or is not finished)
9309           Solution :
9310           Wake up the possibly waiting I/O thread, and set a boolean asking
9311           the I/O thread to temporarily ignore the log_space_limit
9312           constraint, because we do not want the I/O thread to block because of
9313           space (it's ok if it blocks for any other reason (e.g. because the
9314           master does not send anything). Then the I/O thread stops waiting
9315           and reads one more event and starts honoring log_space_limit again.
9316 
9317           If the SQL thread needs more events to be able to rotate the log (it
9318           might need to finish the current group first), then it can ask for one
9319           more at a time. Thus we don't outgrow the relay log indefinitely,
9320           but rather in a controlled manner, until the next rotate.
9321 
9322           When the SQL thread starts it sets ignore_log_space_limit to false.
9323           We should also reset ignore_log_space_limit to 0 when the user does
9324           RESET SLAVE, but in fact, no need as RESET SLAVE requires that the slave
9325           be stopped, and the SQL thread sets ignore_log_space_limit to 0 when
9326           it stops.
9327         */
9328         mysql_mutex_lock(&rli->log_space_lock);
9329 
9330         /*
9331           If we have reached the limit of the relay space and we
9332           are going to sleep, waiting for more events:
9333 
9334           1. If outside a group, SQL thread asks the IO thread
9335              to force a rotation so that the SQL thread purges
9336              logs next time it processes an event (thus space is
9337              freed).
9338 
9339           2. If in a group, SQL thread asks the IO thread to
9340              ignore the limit and queues yet one more event
9341              so that the SQL thread finishes the group and
9342              is are able to rotate and purge sometime soon.
9343          */
9344         if (rli->log_space_limit &&
9345             rli->log_space_limit < rli->log_space_total)
9346         {
9347           /* force rotation if not in an unfinished group */
9348           if (!rli->is_parallel_exec())
9349           {
9350             rli->sql_force_rotate_relay= !rli->is_in_group();
9351           }
9352           else
9353           {
9354             rli->sql_force_rotate_relay=
9355               (rli->mts_group_status != Relay_log_info::MTS_IN_GROUP);
9356           }
9357           /* ask for one more event */
9358           rli->ignore_log_space_limit= true;
9359         }
9360 
9361         /*
9362           If the I/O thread is blocked, unblock it.  Ok to broadcast
9363           after unlock, because the mutex is only destroyed in
9364           ~Relay_log_info(), i.e. when rli is destroyed, and rli will
9365           not be destroyed before we exit the present function.
9366         */
9367         mysql_mutex_unlock(&rli->log_space_lock);
9368         mysql_cond_broadcast(&rli->log_space_cond);
9369         // Note that wait_for_update_relay_log unlocks lock_log !
9370 
9371         if (rli->is_parallel_exec() && (opt_mts_checkpoint_period != 0 ||
9372             DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0)))
9373         {
9374           int ret= 0;
9375           struct timespec waittime;
9376           ulonglong period= static_cast<ulonglong>(opt_mts_checkpoint_period * 1000000ULL);
9377           ulong signal_cnt= rli->relay_log.signal_cnt;
9378 
9379           mysql_mutex_unlock(log_lock);
9380           do
9381           {
9382             /*
9383               At this point the coordinator has no job to delegate to workers.
9384               However, workers are executing their assigned jobs and as such
9385               the checkpoint routine must be periodically invoked.
9386             */
9387             (void) mts_checkpoint_routine(rli, period, false, true/*need_data_lock=true*/); // TODO: ALFRANIO ERROR
9388             mysql_mutex_lock(log_lock);
9389 
9390             if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
9391               period= 10000000ULL;
9392 
9393             set_timespec_nsec(&waittime, period);
9394             ret= rli->relay_log.wait_for_update_relay_log(thd, &waittime);
9395           } while ((ret == ETIMEDOUT || ret == ETIME) /* todo:remove */ &&
9396                    signal_cnt == rli->relay_log.signal_cnt && !thd->killed);
9397         }
9398         else
9399         {
9400           rli->relay_log.wait_for_update_relay_log(thd, NULL);
9401         }
9402 
9403         // re-acquire data lock since we released it earlier
9404         mysql_mutex_lock(&rli->data_lock);
9405         continue;
9406       }
9407       /*
9408         If the log was not hot, we need to move to the next log in
9409         sequence. The next log could be hot or cold, we deal with both
9410         cases separately after doing some common initialization
9411       */
9412       end_io_cache(cur_log);
9413       DBUG_ASSERT(rli->cur_log_fd >= 0);
9414       mysql_file_close(rli->cur_log_fd, MYF(MY_WME));
9415       rli->cur_log_fd = -1;
9416 
9417       if (relay_log_purge)
9418       {
9419         /*
9420           purge_first_log will properly set up relay log coordinates in rli.
9421           If the group's coordinates are equal to the event's coordinates
9422           (i.e. the relay log was not rotated in the middle of a group),
9423           we can purge this relay log too.
9424           We do ulonglong and string comparisons, this may be slow but
9425           - purging the last relay log is nice (it can save 1GB of disk), so we
9426           like to detect the case where we can do it, and given this,
9427           - I see no better detection method
9428           - purge_first_log is not called that often
9429         */
9430         if (rli->relay_log.purge_first_log
9431             (rli,
9432              rli->get_group_relay_log_pos() == rli->get_event_relay_log_pos()
9433              && !strcmp(rli->get_group_relay_log_name(),rli->get_event_relay_log_name())))
9434         {
9435           errmsg = "Error purging processed logs";
9436           goto err;
9437         }
9438         DBUG_PRINT("info", ("next_event group master %s %lu  group relay %s %lu event %s %lu\n",
9439           rli->get_group_master_log_name(),
9440           (ulong) rli->get_group_master_log_pos(),
9441           rli->get_group_relay_log_name(),
9442           (ulong) rli->get_group_relay_log_pos(),
9443           rli->get_event_relay_log_name(),
9444           (ulong) rli->get_event_relay_log_pos()));
9445       }
9446       else
9447       {
9448         /*
9449           If hot_log is set, then we already have a lock on
9450           LOCK_log.  If not, we have to get the lock.
9451 
9452           According to Sasha, the only time this code will ever be executed
9453           is if we are recovering from a bug.
9454         */
9455         if (rli->relay_log.find_next_log(&rli->linfo, !hot_log))
9456         {
9457           errmsg = "error switching to the next log";
9458           goto err;
9459         }
9460         rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
9461         rli->set_event_relay_log_name(rli->linfo.log_file_name);
9462         /*
9463           We may update the worker here but this is not extremlly
9464           necessary. /Alfranio
9465         */
9466         rli->flush_info();
9467       }
9468 
9469       /* Reset the relay-log-change-notified status of  Slave Workers */
9470       if (rli->is_parallel_exec())
9471       {
9472         DBUG_PRINT("info", ("next_event: MTS group relay log changes to %s %lu\n",
9473                             rli->get_group_relay_log_name(),
9474                             (ulong) rli->get_group_relay_log_pos()));
9475         rli->reset_notified_relay_log_change();
9476       }
9477 
9478       /*
9479         Now we want to open this next log. To know if it's a hot log (the one
9480         being written by the I/O thread now) or a cold log, we can use
9481         is_active(); if it is hot, we use the I/O cache; if it's cold we open
9482         the file normally. But if is_active() reports that the log is hot, this
9483         may change between the test and the consequence of the test. So we may
9484         open the I/O cache whereas the log is now cold, which is nonsense.
9485         To guard against this, we need to have LOCK_log.
9486       */
9487 
9488       DBUG_PRINT("info",("hot_log: %d",hot_log));
9489       if (!hot_log) /* if hot_log, we already have this mutex */
9490         mysql_mutex_lock(log_lock);
9491       if (rli->relay_log.is_active(rli->linfo.log_file_name))
9492       {
9493 #ifdef EXTRA_DEBUG
9494         sql_print_information("next log '%s' is currently active",
9495                               rli->linfo.log_file_name);
9496 #endif
9497         rli->cur_log= cur_log= rli->relay_log.get_log_file();
9498         rli->cur_log_old_open_count= rli->relay_log.get_open_count();
9499         DBUG_ASSERT(rli->cur_log_fd == -1);
9500 
9501         /*
9502            When the SQL thread is [stopped and] (re)started the
9503            following may happen:
9504 
9505            1. Log was hot at stop time and remains hot at restart
9506 
9507               SQL thread reads again from hot_log (SQL thread was
9508               reading from the active log when it was stopped and the
9509               very same log is still active on SQL thread restart).
9510 
9511               In this case, my_b_seek is performed on cur_log, while
9512               cur_log points to relay_log.get_log_file();
9513 
9514            2. Log was hot at stop time but got cold before restart
9515 
9516               The log was hot when SQL thread stopped, but it is not
9517               anymore when the SQL thread restarts.
9518 
9519               In this case, the SQL thread reopens the log, using
9520               cache_buf, ie, cur_log points to &cache_buf, and thence
9521               its coordinates are reset.
9522 
9523            3. Log was already cold at stop time
9524 
9525               The log was not hot when the SQL thread stopped, and, of
9526               course, it will not be hot when it restarts.
9527 
9528               In this case, the SQL thread opens the cold log again,
9529               using cache_buf, ie, cur_log points to &cache_buf, and
9530               thence its coordinates are reset.
9531 
9532            4. Log was hot at stop time, DBA changes to previous cold
9533               log and restarts SQL thread
9534 
9535               The log was hot when the SQL thread was stopped, but the
9536               user changed the coordinates of the SQL thread to
9537               restart from a previous cold log.
9538 
9539               In this case, at start time, cur_log points to a cold
9540               log, opened using &cache_buf as cache, and coordinates
9541               are reset. However, as it moves on to the next logs, it
9542               will eventually reach the hot log. If the hot log is the
9543               same at the time the SQL thread was stopped, then
9544               coordinates were not reset - the cur_log will point to
9545               relay_log.get_log_file(), and not a freshly opened
9546               IO_CACHE through cache_buf. For this reason we need to
9547               deploy a my_b_seek before calling check_binlog_magic at
9548               this point of the code (see: BUG#55263 for more
9549               details).
9550 
9551           NOTES:
9552             - We must keep the LOCK_log to read the 4 first bytes, as
9553               this is a hot log (same as when we call read_log_event()
9554               above: for a hot log we take the mutex).
9555 
9556             - Because of scenario #4 above, we need to have a
9557               my_b_seek here. Otherwise, we might hit the assertion
9558               inside check_binlog_magic.
9559         */
9560 
9561         my_b_seek(cur_log, (my_off_t) 0);
9562         if (check_binlog_magic(cur_log,&errmsg))
9563         {
9564           if (!hot_log)
9565             mysql_mutex_unlock(log_lock);
9566           goto err;
9567         }
9568         if (!hot_log)
9569           mysql_mutex_unlock(log_lock);
9570         continue;
9571       }
9572       if (!hot_log)
9573         mysql_mutex_unlock(log_lock);
9574       /*
9575         if we get here, the log was not hot, so we will have to open it
9576         ourselves. We are sure that the log is still not hot now (a log can get
9577         from hot to cold, but not from cold to hot). No need for LOCK_log.
9578       */
9579 #ifdef EXTRA_DEBUG
9580       sql_print_information("next log '%s' is not active",
9581                             rli->linfo.log_file_name);
9582 #endif
9583       // open_binlog_file() will check the magic header
9584       if ((rli->cur_log_fd=open_binlog_file(cur_log,rli->linfo.log_file_name,
9585                                             &errmsg)) <0)
9586         goto err;
9587     }
9588     else
9589     {
9590       /*
9591         Read failed with a non-EOF error.
9592         TODO: come up with something better to handle this error
9593       */
9594       if (hot_log)
9595         mysql_mutex_unlock(log_lock);
9596       sql_print_error("Slave SQL thread%s: I/O error reading "
9597                       "event(errno: %d  cur_log->error: %d)",
9598                       rli->get_for_channel_str(), my_errno(),cur_log->error);
9599       // set read position to the beginning of the event
9600       my_b_seek(cur_log,rli->get_event_relay_log_pos());
9601       /* otherwise, we have had a partial read */
9602       errmsg = "Aborting slave SQL thread because of partial event read";
9603       break;                                    // To end of function
9604     }
9605   }
9606   if (!errmsg)
9607   {
9608     sql_print_information("Error reading relay log event%s: %s",
9609                           rli->get_for_channel_str(), "slave SQL thread was killed");
9610     DBUG_RETURN(0);
9611   }
9612 
9613 err:
9614   if (errmsg)
9615     sql_print_error("Error reading relay log event%s: %s", rli->get_for_channel_str(), errmsg);
9616   DBUG_RETURN(0);
9617 }
9618 
9619 /*
9620   Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation
9621   because of size is simpler because when we do it we already have all relevant
9622   locks; here we don't, so this function is mainly taking locks).
9623   Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file()
9624   is void).
9625 */
9626 
rotate_relay_log(Master_info * mi,bool need_log_space_lock)9627 int rotate_relay_log(Master_info* mi, bool need_log_space_lock)
9628 {
9629   DBUG_ENTER("rotate_relay_log");
9630 
9631   mysql_mutex_assert_owner(&mi->data_lock);
9632   DBUG_EXECUTE_IF("crash_before_rotate_relaylog", DBUG_SUICIDE(););
9633 
9634   Relay_log_info* rli= mi->rli;
9635   int error= 0;
9636 
9637   /*
9638      We need to test inited because otherwise, new_file() will attempt to lock
9639      LOCK_log, which may not be inited (if we're not a slave).
9640   */
9641   if (!rli->inited)
9642   {
9643     DBUG_PRINT("info", ("rli->inited == 0"));
9644     goto end;
9645   }
9646 
9647   /* If the relay log is closed, new_file() will do nothing. */
9648   error= rli->relay_log.new_file(mi->get_mi_description_event());
9649   if (error != 0)
9650     goto end;
9651 
9652   /*
9653     We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately
9654     be counted, so imagine a succession of FLUSH LOGS  and assume the slave
9655     threads are started:
9656     relay_log_space decreases by the size of the deleted relay log, but does
9657     not increase, so flush-after-flush we may become negative, which is wrong.
9658     Even if this will be corrected as soon as a query is replicated on the
9659     slave (because the I/O thread will then call harvest_bytes_written() which
9660     will harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange
9661     output in SHOW SLAVE STATUS meanwhile. So we harvest now.
9662     If the log is closed, then this will just harvest the last writes, probably
9663     0 as they probably have been harvested.
9664   */
9665   rli->relay_log.harvest_bytes_written(rli, need_log_space_lock);
9666 end:
9667   DBUG_RETURN(error);
9668 }
9669 
9670 
9671 /**
9672   flushes the relay logs of a replication channel.
9673 
9674   @param[in]         mi      Master_info corresponding to the
9675                              channel.
9676   @return
9677     @retval          true     fail
9678     @retval          false     ok.
9679 */
flush_relay_logs(Master_info * mi)9680 bool flush_relay_logs(Master_info *mi)
9681 {
9682   DBUG_ENTER("flush_relay_logs");
9683   bool error= false;
9684 
9685   if (mi)
9686   {
9687     mysql_mutex_lock(&mi->data_lock);
9688     if (rotate_relay_log(mi, true/*need_log_space_lock=true*/))
9689       error= true;
9690     mysql_mutex_unlock(&mi->data_lock);
9691   }
9692   DBUG_RETURN(error);
9693 }
9694 
9695 
9696 /**
9697    Entry point for FLUSH RELAYLOGS command or to flush relaylogs for
9698    the FLUSH LOGS command.
9699    FLUSH LOGS or FLUSH RELAYLOGS needs to flush the relaylogs of all
9700    the replciaiton channels in multisource replication.
9701    FLUSH RELAYLOGS FOR CHANNEL flushes only the relaylogs pertaining to
9702    a channel.
9703 
9704    @param[in]         thd              the client thread carrying the command.
9705 
9706    @return
9707      @retval           true                fail
9708      @retval           false              success
9709 */
flush_relay_logs_cmd(THD * thd)9710 bool flush_relay_logs_cmd(THD *thd)
9711 {
9712   DBUG_ENTER("flush_relay_logs_cmd");
9713   Master_info *mi= 0;
9714   LEX *lex= thd->lex;
9715   bool error =false;
9716 
9717   channel_map.wrlock();
9718 
9719   /*
9720      lex->mi.channel is NULL, for FLUSH LOGS or when the client thread
9721      is not present. (See tmp_thd in  the caller).
9722      When channel is not provided, lex->mi.for_channel is false.
9723   */
9724   if (!lex->mi.channel || !lex->mi.for_channel)
9725   {
9726     for (mi_map::iterator it= channel_map.begin(); it!= channel_map.end(); it++)
9727     {
9728       mi= it->second;
9729 
9730       if ((error = flush_relay_logs(mi)))
9731         break;
9732     }
9733   }
9734   else
9735   {
9736 
9737     mi= channel_map.get_mi(lex->mi.channel);
9738 
9739     if (mi)
9740     {
9741       /*
9742         Disallow flush on Group Replication applier channel to avoid
9743         split transactions among relay log files due to DBA action.
9744       */
9745       if (channel_map.is_group_replication_channel_name(lex->mi.channel, true))
9746       {
9747         if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL ||
9748             thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER)
9749         {
9750           /*
9751             Log warning on SQL or worker threads.
9752           */
9753           sql_print_warning(ER(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED),
9754                             "FLUSH RELAY LOGS", lex->mi.channel);
9755         }
9756         else
9757         {
9758           /*
9759             Return error on client sessions.
9760           */
9761           error= true;
9762           my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED,
9763                    MYF(0), "FLUSH RELAY LOGS", lex->mi.channel);
9764         }
9765       }
9766       else
9767         error= flush_relay_logs(mi);
9768     }
9769     else
9770     {
9771       if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL ||
9772           thd->system_thread == SYSTEM_THREAD_SLAVE_WORKER)
9773       {
9774         /*
9775           Log warning on SQL or worker threads.
9776         */
9777         sql_print_warning(ER(ER_SLAVE_CHANNEL_DOES_NOT_EXIST),
9778                           lex->mi.channel);
9779       }
9780       else
9781       {
9782         /*
9783           Return error on client sessions.
9784         */
9785         error= true;
9786         my_error(ER_SLAVE_CHANNEL_DOES_NOT_EXIST, MYF(0), lex->mi.channel);
9787       }
9788     }
9789   }
9790 
9791   channel_map.unlock();
9792 
9793   DBUG_RETURN(error);
9794 }
9795 
9796 
9797 /**
9798    Detects, based on master's version (as found in the relay log), if master
9799    has a certain bug.
9800    @param rli Relay_log_info which tells the master's version
9801    @param bug_id Number of the bug as found in bugs.mysql.com
9802    @param report bool report error message, default TRUE
9803 
9804    @param pred Predicate function that will be called with @c param to
9805    check for the bug. If the function return @c true, the bug is present,
9806    otherwise, it is not.
9807 
9808    @param param  State passed to @c pred function.
9809 
9810    @return TRUE if master has the bug, FALSE if it does not.
9811 */
rpl_master_has_bug(const Relay_log_info * rli,uint bug_id,bool report,bool (* pred)(const void *),const void * param)9812 bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report,
9813                         bool (*pred)(const void *), const void *param)
9814 {
9815   struct st_version_range_for_one_bug {
9816     uint        bug_id;
9817     const uchar introduced_in[3]; // first version with bug
9818     const uchar fixed_in[3];      // first version with fix
9819   };
9820   static struct st_version_range_for_one_bug versions_for_all_bugs[]=
9821   {
9822     {24432, { 5, 0, 24 }, { 5, 0, 38 } },
9823     {24432, { 5, 1, 12 }, { 5, 1, 17 } },
9824     {33029, { 5, 0,  0 }, { 5, 0, 58 } },
9825     {33029, { 5, 1,  0 }, { 5, 1, 12 } },
9826     {37426, { 5, 1,  0 }, { 5, 1, 26 } },
9827   };
9828   const uchar *master_ver=
9829     rli->get_rli_description_event()->server_version_split;
9830 
9831   DBUG_ASSERT(sizeof(rli->get_rli_description_event()->server_version_split) == 3);
9832 
9833   for (uint i= 0;
9834        i < sizeof(versions_for_all_bugs)/sizeof(*versions_for_all_bugs);i++)
9835   {
9836     const uchar *introduced_in= versions_for_all_bugs[i].introduced_in,
9837       *fixed_in= versions_for_all_bugs[i].fixed_in;
9838     if ((versions_for_all_bugs[i].bug_id == bug_id) &&
9839         (memcmp(introduced_in, master_ver, 3) <= 0) &&
9840         (memcmp(fixed_in,      master_ver, 3) >  0) &&
9841         (pred == NULL || (*pred)(param)))
9842     {
9843       if (!report)
9844 	return TRUE;
9845       // a short message for SHOW SLAVE STATUS (message length constraints)
9846       my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from"
9847                       " http://bugs.mysql.com/bug.php?id=%u"
9848                       " so slave stops; check error log on slave"
9849                       " for more info", MYF(0), bug_id);
9850       // a verbose message for the error log
9851       enum loglevel report_level= INFORMATION_LEVEL;
9852       if (!ignored_error_code(ER_UNKNOWN_ERROR))
9853       {
9854         report_level= ERROR_LEVEL;
9855         current_thd->is_slave_error= 1;
9856       }
9857       /* In case of ignored errors report warnings only if log_warnings > 1. */
9858       else if (log_warnings > 1)
9859         report_level= WARNING_LEVEL;
9860 
9861       if (report_level != INFORMATION_LEVEL)
9862         rli->report(report_level, ER_UNKNOWN_ERROR,
9863                     "According to the master's version ('%s'),"
9864                     " it is probable that master suffers from this bug:"
9865                     " http://bugs.mysql.com/bug.php?id=%u"
9866                     " and thus replicating the current binary log event"
9867                     " may make the slave's data become different from the"
9868                     " master's data."
9869                     " To take no risk, slave refuses to replicate"
9870                     " this event and stops."
9871                     " We recommend that all updates be stopped on the"
9872                     " master and slave, that the data of both be"
9873                     " manually synchronized,"
9874                     " that master's binary logs be deleted,"
9875                     " that master be upgraded to a version at least"
9876                     " equal to '%d.%d.%d'. Then replication can be"
9877                     " restarted.",
9878                     rli->get_rli_description_event()->server_version,
9879                     bug_id,
9880                     fixed_in[0], fixed_in[1], fixed_in[2]);
9881       return TRUE;
9882     }
9883   }
9884   return FALSE;
9885 }
9886 
9887 /**
9888    BUG#33029, For all 5.0 up to 5.0.58 exclusive, and 5.1 up to 5.1.12
9889    exclusive, if one statement in a SP generated AUTO_INCREMENT value
9890    by the top statement, all statements after it would be considered
9891    generated AUTO_INCREMENT value by the top statement, and a
9892    erroneous INSERT_ID value might be associated with these statement,
9893    which could cause duplicate entry error and stop the slave.
9894 
9895    Detect buggy master to work around.
9896  */
rpl_master_erroneous_autoinc(THD * thd)9897 bool rpl_master_erroneous_autoinc(THD *thd)
9898 {
9899   if (thd->rli_slave && thd->rli_slave->info_thd == thd)
9900   {
9901     Relay_log_info *c_rli= thd->rli_slave->get_c_rli();
9902 
9903     DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
9904     return rpl_master_has_bug(c_rli, 33029, FALSE, NULL, NULL);
9905   }
9906   return FALSE;
9907 }
9908 
9909 /**
9910   a copy of active_mi->rli->slave_skip_counter, for showing in SHOW GLOBAL VARIABLES,
9911   INFORMATION_SCHEMA.GLOBAL_VARIABLES and @@sql_slave_skip_counter without
9912   taking all the mutexes needed to access active_mi->rli->slave_skip_counter
9913   properly.
9914 */
9915 uint sql_slave_skip_counter;
9916 
9917 /**
9918    Executes a START SLAVE statement.
9919 
9920   @param thd                 Pointer to THD object for the client thread
9921                              executing the statement.
9922 
9923    @param connection_param   Connection parameters for starting threads
9924 
9925    @param master_param       Master parameters used for starting threads
9926 
9927    @param thread_mask_input  The thread mask that identifies which threads to
9928                              start. If 0 is passed (start no thread) then this
9929                              parameter is ignored and all stopped threads are
9930                              started
9931 
9932    @param mi                 Pointer to Master_info object for the slave's IO
9933                              thread.
9934 
9935    @param set_mts_settings   If true, the channel uses the server MTS
9936                              configured settings when starting the applier
9937                              thread.
9938 
9939    @retval false success
9940    @retval true error
9941 */
start_slave(THD * thd,LEX_SLAVE_CONNECTION * connection_param,LEX_MASTER_INFO * master_param,int thread_mask_input,Master_info * mi,bool set_mts_settings)9942 bool start_slave(THD* thd,
9943                  LEX_SLAVE_CONNECTION* connection_param,
9944                  LEX_MASTER_INFO* master_param,
9945                  int thread_mask_input,
9946                  Master_info* mi,
9947                  bool set_mts_settings)
9948 {
9949   bool is_error= false;
9950   int thread_mask;
9951 
9952   DBUG_ENTER("start_slave(THD, lex, lex, int, Master_info, bool");
9953 
9954   /*
9955     START SLAVE command should ignore 'read-only' and 'super_read_only'
9956     options so that it can update 'mysql.slave_master_info' and
9957     'mysql.slave_relay_log_info' replication repository tables.
9958   */
9959   thd->set_skip_readonly_check();
9960   if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0))
9961     DBUG_RETURN(1);
9962 
9963   mi->channel_wrlock();
9964 
9965 #if !defined(EMBEDDED_LIBRARY)
9966   if (connection_param->user ||
9967       connection_param->password)
9968   {
9969     if (!thd->get_ssl())
9970     {
9971       push_warning(thd, Sql_condition::SL_NOTE,
9972                    ER_INSECURE_PLAIN_TEXT,
9973                    ER(ER_INSECURE_PLAIN_TEXT));
9974     }
9975   }
9976 #endif
9977 
9978   lock_slave_threads(mi);  // this allows us to cleanly read slave_running
9979   // Get a mask of _stopped_ threads
9980   init_thread_mask(&thread_mask,mi,1 /* inverse */);
9981   /*
9982     Below we will start all stopped threads.  But if the user wants to
9983     start only one thread, do as if the other thread was running (as we
9984     don't wan't to touch the other thread), so set the bit to 0 for the
9985     other thread
9986   */
9987   if (thread_mask_input)
9988   {
9989     thread_mask&= thread_mask_input;
9990   }
9991   if (thread_mask) //some threads are stopped, start them
9992   {
9993     if (load_mi_and_rli_from_repositories(mi, false, thread_mask))
9994     {
9995       is_error= true;
9996       my_error(ER_MASTER_INFO, MYF(0));
9997     }
9998     else if (server_id_supplied && (*mi->host || !(thread_mask & SLAVE_IO)))
9999     {
10000       /*
10001         If we will start IO thread we need to take care of possible
10002         options provided through the START SLAVE if there is any.
10003       */
10004       if (thread_mask & SLAVE_IO)
10005       {
10006         if (connection_param->user)
10007         {
10008           mi->set_start_user_configured(true);
10009           mi->set_user(connection_param->user);
10010         }
10011         if (connection_param->password)
10012         {
10013           mi->set_start_user_configured(true);
10014           mi->set_password(connection_param->password);
10015         }
10016         if (connection_param->plugin_auth)
10017           mi->set_plugin_auth(connection_param->plugin_auth);
10018         if (connection_param->plugin_dir)
10019           mi->set_plugin_dir(connection_param->plugin_dir);
10020       }
10021 
10022       /*
10023         If we will start SQL thread we will care about UNTIL options If
10024         not and they are specified we will ignore them and warn user
10025         about this fact.
10026       */
10027       if (thread_mask & SLAVE_SQL)
10028       {
10029         /*
10030           sql_slave_skip_counter only effects the applier thread which is
10031           first started. So after sql_slave_skip_counter is copied to
10032           rli->slave_skip_counter, it is reset to 0.
10033         */
10034         mysql_mutex_lock(&LOCK_sql_slave_skip_counter);
10035         mi->rli->slave_skip_counter= sql_slave_skip_counter;
10036         sql_slave_skip_counter= 0;
10037         mysql_mutex_unlock(&LOCK_sql_slave_skip_counter);
10038         /*
10039           To cache the MTS system var values and used them in the following
10040           runtime. The system vars can change meanwhile but having no other
10041           effects.
10042           It also allows the per channel definition of this variables.
10043         */
10044         if (set_mts_settings)
10045         {
10046           mi->rli->opt_slave_parallel_workers= opt_mts_slave_parallel_workers;
10047           if (mts_parallel_option == MTS_PARALLEL_TYPE_DB_NAME)
10048             mi->rli->channel_mts_submode = MTS_PARALLEL_TYPE_DB_NAME;
10049           else
10050             mi->rli->channel_mts_submode = MTS_PARALLEL_TYPE_LOGICAL_CLOCK;
10051 
10052 #ifndef DBUG_OFF
10053         if (!DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
10054 #endif
10055           mi->rli->checkpoint_group= opt_mts_checkpoint_group;
10056         }
10057 
10058         mysql_mutex_lock(&mi->rli->data_lock);
10059 
10060         if (master_param->pos)
10061         {
10062           if (master_param->relay_log_pos)
10063           {
10064             is_error= true;
10065             my_error(ER_BAD_SLAVE_UNTIL_COND, MYF(0));
10066           }
10067           mi->rli->until_condition= Relay_log_info::UNTIL_MASTER_POS;
10068           mi->rli->until_log_pos= master_param->pos;
10069           /*
10070              We don't check thd->lex->mi.log_file_name for NULL here
10071              since it is checked in sql_yacc.yy
10072           */
10073           strmake(mi->rli->until_log_name, master_param->log_file_name,
10074                   sizeof(mi->rli->until_log_name)-1);
10075         }
10076         else if (master_param->relay_log_pos)
10077         {
10078           if (master_param->pos)
10079           {
10080             is_error= true;
10081             my_error(ER_BAD_SLAVE_UNTIL_COND, MYF(0));
10082           }
10083           mi->rli->until_condition= Relay_log_info::UNTIL_RELAY_POS;
10084           mi->rli->until_log_pos= master_param->relay_log_pos;
10085           strmake(mi->rli->until_log_name, master_param->relay_log_name,
10086                   sizeof(mi->rli->until_log_name)-1);
10087         }
10088         else if (master_param->gtid)
10089         {
10090           global_sid_lock->wrlock();
10091           mi->rli->clear_until_condition();
10092           if (mi->rli->until_sql_gtids.add_gtid_text(master_param->gtid)
10093               != RETURN_STATUS_OK)
10094           {
10095             is_error= true;
10096             my_error(ER_BAD_SLAVE_UNTIL_COND, MYF(0));
10097           }
10098           else
10099           {
10100             mi->rli->until_condition=
10101               LEX_MASTER_INFO::UNTIL_SQL_BEFORE_GTIDS == master_param->gtid_until_condition
10102               ? Relay_log_info::UNTIL_SQL_BEFORE_GTIDS
10103               : Relay_log_info::UNTIL_SQL_AFTER_GTIDS;
10104             if ((mi->rli->until_condition ==
10105                Relay_log_info::UNTIL_SQL_AFTER_GTIDS) &&
10106                mi->rli->opt_slave_parallel_workers != 0)
10107             {
10108               mi->rli->opt_slave_parallel_workers= 0;
10109               push_warning_printf(thd, Sql_condition::SL_NOTE,
10110                                   ER_MTS_FEATURE_IS_NOT_SUPPORTED,
10111                                   ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED),
10112                                   "UNTIL condtion",
10113                                   "Slave is started in the sequential execution mode.");
10114             }
10115           }
10116           global_sid_lock->unlock();
10117         }
10118         else if (master_param->until_after_gaps)
10119         {
10120             mi->rli->until_condition= Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS;
10121             mi->rli->opt_slave_parallel_workers=
10122               mi->rli->recovery_parallel_workers;
10123         }
10124         else if (master_param->view_id)
10125         {
10126           mi->rli->until_condition= Relay_log_info::UNTIL_SQL_VIEW_ID;
10127           mi->rli->until_view_id.clear();
10128           mi->rli->until_view_id.append(master_param->view_id);
10129           mi->rli->until_view_id_found= false;
10130           mi->rli->until_view_id_commit_found= false;
10131         }
10132         else
10133           mi->rli->clear_until_condition();
10134 
10135         if (mi->rli->until_condition == Relay_log_info::UNTIL_MASTER_POS ||
10136             mi->rli->until_condition == Relay_log_info::UNTIL_RELAY_POS)
10137         {
10138           /* Preparing members for effective until condition checking */
10139           const char *p= fn_ext(mi->rli->until_log_name);
10140           char *p_end;
10141           if (*p)
10142           {
10143             //p points to '.'
10144             mi->rli->until_log_name_extension= strtoul(++p,&p_end, 10);
10145             /*
10146               p_end points to the first invalid character. If it equals
10147               to p, no digits were found, error. If it contains '\0' it
10148               means  conversion went ok.
10149             */
10150             if (p_end==p || *p_end)
10151             {
10152               is_error= true;
10153               my_error(ER_BAD_SLAVE_UNTIL_COND, MYF(0));
10154             }
10155           }
10156           else
10157           {
10158             is_error= true;
10159             my_error(ER_BAD_SLAVE_UNTIL_COND, MYF(0));
10160           }
10161 
10162           /* mark the cached result of the UNTIL comparison as "undefined" */
10163           mi->rli->until_log_names_cmp_result=
10164             Relay_log_info::UNTIL_LOG_NAMES_CMP_UNKNOWN;
10165 
10166           /* Issuing warning then started without --skip-slave-start */
10167           if (!opt_skip_slave_start)
10168             push_warning(thd, Sql_condition::SL_NOTE,
10169                          ER_MISSING_SKIP_SLAVE,
10170                          ER(ER_MISSING_SKIP_SLAVE));
10171           if (mi->rli->opt_slave_parallel_workers != 0)
10172           {
10173             mi->rli->opt_slave_parallel_workers= 0;
10174             push_warning_printf(thd, Sql_condition::SL_NOTE,
10175                                 ER_MTS_FEATURE_IS_NOT_SUPPORTED,
10176                                 ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED),
10177                                 "UNTIL condtion",
10178                                 "Slave is started in the sequential execution mode.");
10179           }
10180         }
10181 
10182         mysql_mutex_unlock(&mi->rli->data_lock);
10183 
10184         if (!is_error)
10185           is_error= check_slave_sql_config_conflict(mi->rli);
10186       }
10187       else if (master_param->pos || master_param->relay_log_pos || master_param->gtid)
10188         push_warning(thd, Sql_condition::SL_NOTE, ER_UNTIL_COND_IGNORED,
10189                      ER(ER_UNTIL_COND_IGNORED));
10190 
10191       if (!is_error)
10192         is_error= start_slave_threads(false/*need_lock_slave=false*/,
10193                                       true/*wait_for_start=true*/,
10194                                       mi, thread_mask);
10195     }
10196     else
10197     {
10198       is_error= true;
10199       my_error(ER_BAD_SLAVE, MYF(0));
10200     }
10201   }
10202   else
10203   {
10204     /* no error if all threads are already started, only a warning */
10205     push_warning_printf(thd, Sql_condition::SL_NOTE,
10206                         ER_SLAVE_CHANNEL_WAS_RUNNING,
10207                         ER(ER_SLAVE_CHANNEL_WAS_RUNNING),
10208                         mi->get_channel());
10209   }
10210 
10211   /*
10212     Clean up start information if there was an attempt to start
10213     the IO thread to avoid any security issue.
10214   */
10215   if (is_error && (thread_mask & SLAVE_IO) == SLAVE_IO)
10216     mi->reset_start_info();
10217 
10218   unlock_slave_threads(mi);
10219 
10220   mi->channel_unlock();
10221 
10222   DBUG_RETURN(is_error);
10223 }
10224 
10225 
10226 /**
10227   Execute a STOP SLAVE statement.
10228 
10229   @param thd              Pointer to THD object for the client thread executing
10230                           the statement.
10231 
10232   @param mi               Pointer to Master_info object for the slave's IO
10233                           thread.
10234 
10235   @param net_report       If true, saves the exit status into Diagnostics_area.
10236 
10237   @param for_one_channel  If the method is being invoked only for one channel
10238 
10239   @param push_temp_tables_warning  If it should push a "have temp tables
10240                                    warning" once having open temp tables. This
10241                                    avoids multiple warnings when there is more
10242                                    than one channel with open temp tables.
10243                                    This parameter can be removed when the
10244                                    warning is issued with per-channel
10245                                    information.
10246 
10247   @retval 0 success
10248   @retval 1 error
10249 */
stop_slave(THD * thd,Master_info * mi,bool net_report,bool for_one_channel,bool * push_temp_tables_warning)10250 int stop_slave(THD* thd, Master_info* mi, bool net_report, bool for_one_channel,
10251                bool* push_temp_tables_warning)
10252 {
10253   DBUG_ENTER("stop_slave(THD, Master_info, bool, bool");
10254 
10255   int slave_errno;
10256   if (!thd)
10257     thd = current_thd;
10258 
10259   /*
10260     STOP SLAVE command should ignore 'read-only' and 'super_read_only'
10261     options so that it can update 'mysql.slave_master_info' and
10262     'mysql.slave_relay_log_info' replication repository tables.
10263   */
10264   thd->set_skip_readonly_check();
10265 
10266   if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0))
10267     DBUG_RETURN(1);
10268 
10269   mi->channel_wrlock();
10270 
10271   THD_STAGE_INFO(thd, stage_killing_slave);
10272   int thread_mask;
10273   lock_slave_threads(mi);
10274 
10275   DBUG_EXECUTE_IF("simulate_hold_run_locks_on_stop_slave",
10276                   my_sleep(10000000););
10277 
10278   // Get a mask of _running_ threads
10279   init_thread_mask(&thread_mask,mi,0 /* not inverse*/);
10280 
10281   /*
10282     Below we will stop all running threads.
10283     But if the user wants to stop only one thread, do as if the other thread
10284     was stopped (as we don't wan't to touch the other thread), so set the
10285     bit to 0 for the other thread
10286   */
10287   if (thd->lex->slave_thd_opt)
10288     thread_mask &= thd->lex->slave_thd_opt;
10289 
10290   if (thread_mask)
10291   {
10292     slave_errno= terminate_slave_threads(mi,thread_mask,
10293                                          rpl_stop_slave_timeout,
10294                                          false/*need_lock_term=false*/);
10295   }
10296   else
10297   {
10298     //no error if both threads are already stopped, only a warning
10299     slave_errno= 0;
10300     push_warning_printf(thd, Sql_condition::SL_NOTE,
10301                         ER_SLAVE_CHANNEL_WAS_NOT_RUNNING,
10302                         ER(ER_SLAVE_CHANNEL_WAS_NOT_RUNNING),
10303                         mi->get_channel());
10304   }
10305 
10306   /*
10307     If the slave has open temp tables and there is a following CHANGE MASTER
10308     there is a possibility that the temporary tables are left open forever.
10309     Though we dont restrict failover here, we do warn users. In future, we
10310     should have a command to delete open temp tables the slave has replicated.
10311     See WL#7441 regarding this command.
10312   */
10313 
10314   if (mi->rli->channel_open_temp_tables.atomic_get() &&
10315       *push_temp_tables_warning)
10316   {
10317     push_warning(thd, Sql_condition::SL_WARNING,
10318                  ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO,
10319                  ER(ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO));
10320     *push_temp_tables_warning= false;
10321   }
10322 
10323   unlock_slave_threads(mi);
10324 
10325   mi->channel_unlock();
10326 
10327   if (slave_errno)
10328   {
10329     if ((slave_errno == ER_STOP_SLAVE_SQL_THREAD_TIMEOUT) ||
10330         (slave_errno == ER_STOP_SLAVE_IO_THREAD_TIMEOUT))
10331     {
10332       push_warning(thd, Sql_condition::SL_NOTE, slave_errno,
10333                    ER(slave_errno));
10334       sql_print_warning("%s",ER(slave_errno));
10335     }
10336     if (net_report)
10337       my_message(slave_errno, ER(slave_errno), MYF(0));
10338     DBUG_RETURN(1);
10339   }
10340   else if (net_report && for_one_channel)
10341     my_ok(thd);
10342 
10343   DBUG_RETURN(0);
10344 }
10345 
10346 /**
10347   Execute a RESET SLAVE (for all channels), used in Multisource replication.
10348   If resetting of a particular channel fails, it exits out.
10349 
10350   @param[in]  THD  THD object of the client.
10351 
10352   @retval     0    success
10353   @retval     1    error
10354  */
10355 
reset_slave(THD * thd)10356 int reset_slave(THD *thd)
10357 {
10358   DBUG_ENTER("reset_slave(THD)");
10359 
10360   channel_map.assert_some_wrlock();
10361 
10362   Master_info *mi= 0;
10363   int result= 0;
10364   mi_map::iterator it, gr_channel_map_it;
10365 
10366   if (thd->lex->reset_slave_info.all)
10367   {
10368     /* First do reset_slave for default channel */
10369     mi= channel_map.get_default_channel_mi();
10370     if (mi && reset_slave(thd, mi, thd->lex->reset_slave_info.all))
10371       DBUG_RETURN(1);
10372     /* Do while iteration for rest of the channels */
10373     it= channel_map.begin();
10374     while (it != channel_map.end())
10375     {
10376       if (!it->first.compare(channel_map.get_default_channel()))
10377       {
10378         it++;
10379         continue;
10380       }
10381       mi= it->second;
10382       DBUG_ASSERT(mi);
10383       if ((result= reset_slave(thd, mi, thd->lex->reset_slave_info.all)))
10384         break;
10385       it= channel_map.begin();
10386     }
10387     /* RESET group replication specific channels */
10388     gr_channel_map_it= channel_map.begin(GROUP_REPLICATION_CHANNEL);
10389     while (gr_channel_map_it != channel_map.end(GROUP_REPLICATION_CHANNEL))
10390     {
10391       mi= gr_channel_map_it->second;
10392       DBUG_ASSERT(mi);
10393       /*
10394         We cannot RESET a group replication channel while the group
10395         replication is running.
10396       */
10397       if (is_group_replication_running())
10398       {
10399         my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
10400                  "RESET SLAVE ALL FOR CHANNEL", mi->get_channel());
10401         DBUG_RETURN(1);
10402       }
10403       if ((result= reset_slave(thd, mi, thd->lex->reset_slave_info.all)))
10404         break;
10405       gr_channel_map_it= channel_map.begin(GROUP_REPLICATION_CHANNEL);
10406     }
10407   }
10408   else
10409   {
10410     it= channel_map.begin();
10411     while (it != channel_map.end())
10412     {
10413       mi= it->second;
10414       DBUG_ASSERT(mi);
10415       if ((result= reset_slave(thd, mi, thd->lex->reset_slave_info.all)))
10416         break;
10417       it++;
10418     }
10419     /*
10420       RESET group replication specific channels.
10421 
10422       We cannot RESET a group replication channel while the group
10423       replication is running.
10424     */
10425     gr_channel_map_it= channel_map.begin(GROUP_REPLICATION_CHANNEL);
10426     while (gr_channel_map_it != channel_map.end(GROUP_REPLICATION_CHANNEL))
10427     {
10428       mi= gr_channel_map_it->second;
10429       DBUG_ASSERT(mi);
10430       if (is_group_replication_running())
10431       {
10432         my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
10433                  "RESET SLAVE FOR CHANNEL", mi->get_channel());
10434         DBUG_RETURN(1);
10435       }
10436       if ((result= reset_slave(thd, mi, thd->lex->reset_slave_info.all)))
10437         break;
10438       gr_channel_map_it++;
10439     }
10440   }
10441   DBUG_RETURN(result);
10442 
10443 }
10444 
10445 
10446 /**
10447   Execute a RESET SLAVE statement.
10448   Locks slave threads and unlocks the slave threads after executing
10449   reset slave.
10450 
10451   @param thd        Pointer to THD object of the client thread executing the
10452                     statement.
10453 
10454   @param mi         Pointer to Master_info object for the slave.
10455 
10456   @param reset_all  Do a full reset or only clean master info structures
10457 
10458   @retval 0   success
10459   @retval !=0 error
10460 */
reset_slave(THD * thd,Master_info * mi,bool reset_all)10461 int reset_slave(THD *thd, Master_info* mi, bool reset_all)
10462 {
10463   int thread_mask= 0, error= 0;
10464   const char* errmsg= "Unknown error occured while reseting slave";
10465   DBUG_ENTER("reset_slave");
10466 
10467   bool is_default_channel= strcmp(mi->get_channel(),
10468                                   channel_map.get_default_channel()) == 0;
10469 
10470   /*
10471     RESET SLAVE command should ignore 'read-only' and 'super_read_only'
10472     options so that it can update 'mysql.slave_master_info' and
10473     'mysql.slave_relay_log_info' replication repository tables.
10474   */
10475   thd->set_skip_readonly_check();
10476   mi->channel_wrlock();
10477 
10478   lock_slave_threads(mi);
10479   init_thread_mask(&thread_mask,mi,0 /* not inverse */);
10480   if (thread_mask) // We refuse if any slave thread is running
10481   {
10482     my_error(ER_SLAVE_CHANNEL_MUST_STOP, MYF(0), mi->get_channel());
10483     error=ER_SLAVE_CHANNEL_MUST_STOP;
10484     unlock_slave_threads(mi);
10485     mi->channel_unlock();
10486     goto err;
10487   }
10488 
10489   ha_reset_slave(thd);
10490 
10491 
10492   // delete relay logs, clear relay log coordinates
10493   if ((error= mi->rli->purge_relay_logs(thd,
10494                                         1 /* just reset */,
10495                                         &errmsg,
10496                                         reset_all && !is_default_channel)))
10497   {
10498     my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg);
10499     error= ER_RELAY_LOG_FAIL;
10500     unlock_slave_threads(mi);
10501     mi->channel_unlock();
10502     goto err;
10503   }
10504 
10505   /* Clear master's log coordinates and associated information */
10506   DBUG_ASSERT(!mi->rli || !mi->rli->slave_running); // none writes in rli table
10507   if (remove_info(mi))
10508   {
10509     error= ER_UNKNOWN_ERROR;
10510     my_error(ER_UNKNOWN_ERROR, MYF(0));
10511     unlock_slave_threads(mi);
10512     mi->channel_unlock();
10513     goto err;
10514   }
10515   if (!reset_all)
10516   {
10517     mi->init_master_log_pos();
10518     mi->master_uuid[0]= 0;
10519     /*
10520       This shall prevent the channel to vanish if server is restarted
10521       after this RESET SLAVE and before the channel be started.
10522     */
10523     if (mi->reset &&
10524         opt_mi_repository_id == INFO_REPOSITORY_TABLE &&
10525         opt_rli_repository_id == INFO_REPOSITORY_TABLE &&
10526         mi->flush_info(true))
10527     {
10528       error= ER_MASTER_INFO;
10529       my_error(ER_MASTER_INFO, MYF(0));
10530       unlock_slave_threads(mi);
10531       mi->channel_unlock();
10532       goto err;
10533     }
10534   }
10535 
10536   unlock_slave_threads(mi);
10537 
10538   (void) RUN_HOOK(binlog_relay_io, after_reset_slave, (thd, mi));
10539 
10540   /*
10541      RESET SLAVE ALL deletes the channels(except default channel), so their mi
10542      and rli objects are removed. For default channel, its mi and rli are
10543      deleted and recreated to keep in clear status.
10544   */
10545   if (reset_all)
10546   {
10547     bool is_default= !strcmp(mi->get_channel(), channel_map.get_default_channel());
10548 
10549     channel_map.delete_mi(mi->get_channel());
10550 
10551     if (is_default)
10552     {
10553       if (!Rpl_info_factory::create_mi_and_rli_objects(opt_mi_repository_id,
10554                                                        opt_rli_repository_id,
10555                                                        channel_map.get_default_channel(),
10556                                                        true,
10557                                                        &channel_map))
10558       {
10559         error= ER_MASTER_INFO;
10560         my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
10561       }
10562     }
10563   }
10564   else
10565   {
10566     mi->channel_unlock();
10567   }
10568 
10569 err:
10570   DBUG_RETURN(error);
10571 }
10572 
10573 
10574 /**
10575   Entry function for RESET SLAVE command. Function either resets
10576   the slave for all channels or for a single channel.
10577   When RESET SLAVE ALL is given, the slave_info_objects (mi, rli & workers)
10578   are destroyed.
10579 
10580   @param[in]           thd          the client thread with the command.
10581 
10582   @return
10583     @retval            false            OK
10584     @retval            true            not OK
10585 */
reset_slave_cmd(THD * thd)10586 bool reset_slave_cmd(THD *thd)
10587 {
10588   DBUG_ENTER("reset_slave_cmd");
10589 
10590   Master_info *mi;
10591   LEX *lex= thd->lex;
10592   bool res= true;  // default, an error
10593 
10594   channel_map.wrlock();
10595 
10596   if (!is_slave_configured())
10597   {
10598     my_message(ER_SLAVE_CONFIGURATION, ER(ER_SLAVE_CONFIGURATION), MYF(0));
10599     channel_map.unlock();
10600     DBUG_RETURN(res= true);
10601   }
10602 
10603   if (!lex->mi.for_channel)
10604     res= reset_slave(thd);
10605   else
10606   {
10607     mi= channel_map.get_mi(lex->mi.channel);
10608     /*
10609       If the channel being used is a group replication channel and
10610       group_replication is still running we need to disable RESET SLAVE [ALL]
10611       command.
10612     */
10613     if (mi && channel_map.is_group_replication_channel_name(mi->get_channel(), true)
10614         && is_group_replication_running())
10615     {
10616       my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
10617                "RESET SLAVE [ALL] FOR CHANNEL", mi->get_channel());
10618       channel_map.unlock();
10619       DBUG_RETURN(true);
10620     }
10621 
10622     if (mi)
10623       res= reset_slave(thd, mi, thd->lex->reset_slave_info.all);
10624     else if (strcmp(channel_map.get_default_channel(), lex->mi.channel))
10625       my_error(ER_SLAVE_CHANNEL_DOES_NOT_EXIST, MYF(0), lex->mi.channel);
10626   }
10627 
10628   channel_map.unlock();
10629 
10630   DBUG_RETURN(res);
10631 }
10632 
10633 
10634 /**
10635    This function checks if the given CHANGE MASTER command has any receive
10636    option being set or changed.
10637 
10638    - used in change_master().
10639 
10640   @param  lex_mi structure that holds all change master options given on the
10641           change master command.
10642 
10643   @retval false No change master receive option.
10644   @retval true  At least one receive option was there.
10645 */
10646 
have_change_master_receive_option(const LEX_MASTER_INFO * lex_mi)10647 static bool have_change_master_receive_option(const LEX_MASTER_INFO* lex_mi)
10648 {
10649   bool have_receive_option= false;
10650 
10651   DBUG_ENTER("have_change_master_receive_option");
10652 
10653   /* Check if *at least one* receive option is given on change master command*/
10654   if (lex_mi->host ||
10655       lex_mi->user ||
10656       lex_mi->password ||
10657       lex_mi->log_file_name ||
10658       lex_mi->pos ||
10659       lex_mi->bind_addr ||
10660       lex_mi->port ||
10661       lex_mi->connect_retry ||
10662       lex_mi->server_id ||
10663       lex_mi->ssl != LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
10664       lex_mi->ssl_verify_server_cert != LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
10665       lex_mi->heartbeat_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
10666       lex_mi->retry_count_opt !=  LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
10667       lex_mi->ssl_key ||
10668       lex_mi->ssl_cert ||
10669       lex_mi->ssl_ca ||
10670       lex_mi->ssl_capath ||
10671       lex_mi->tls_version ||
10672       lex_mi->ssl_cipher ||
10673       lex_mi->ssl_crl ||
10674       lex_mi->ssl_crlpath ||
10675       lex_mi->repl_ignore_server_ids_opt == LEX_MASTER_INFO::LEX_MI_ENABLE)
10676     have_receive_option= true;
10677 
10678   DBUG_RETURN(have_receive_option);
10679 }
10680 
10681 /**
10682    This function checks if the given CHANGE MASTER command has any execute
10683    option being set or changed.
10684 
10685    - used in change_master().
10686 
10687   @param  lex_mi structure that holds all change master options given on the
10688           change master command.
10689 
10690   @param[OUT] need_relay_log_purge
10691               - If relay_log_file/relay_log_pos options are used,
10692                 we wont delete relaylogs. We set this boolean flag to false.
10693               - If relay_log_file/relay_log_pos options are NOT used,
10694                 we return the boolean flag UNCHANGED.
10695               - Used in change_receive_options() and change_master().
10696 
10697   @retval false No change master execute option.
10698   @retval true  At least one execute option was there.
10699 */
10700 
have_change_master_execute_option(const LEX_MASTER_INFO * lex_mi,bool * need_relay_log_purge)10701 static bool have_change_master_execute_option(const LEX_MASTER_INFO* lex_mi,
10702                                               bool* need_relay_log_purge )
10703 {
10704   bool have_execute_option= false;
10705 
10706   DBUG_ENTER("have_change_master_execute_option");
10707 
10708   /* Check if *at least one* execute option is given on change master command*/
10709   if (lex_mi->relay_log_name ||
10710       lex_mi->relay_log_pos ||
10711       lex_mi->sql_delay != -1)
10712     have_execute_option= true;
10713 
10714   if (lex_mi->relay_log_name || lex_mi->relay_log_pos)
10715     *need_relay_log_purge= false;
10716 
10717   DBUG_RETURN(have_execute_option);
10718 }
10719 
10720 /**
10721    This function is called if the change master command had at least one
10722    receive option. This function then sets or alters the receive option(s)
10723    given in the command. The execute options are handled in the function
10724    change_execute_options()
10725 
10726    - used in change_master().
10727    - Receiver threads should be stopped when this function is called.
10728 
10729   @param thd    Pointer to THD object for the client thread executing the
10730                 statement.
10731 
10732   @param lex_mi structure that holds all change master options given on the
10733                 change master command.
10734                 Coming from the an executing statement or set directly this
10735                 shall contain connection settings like hostname, user, password
10736                 and other settings like the number of connection retries.
10737 
10738   @param mi     Pointer to Master_info object belonging to the slave's IO
10739                 thread.
10740 
10741   @retval 0    no error i.e., success.
10742   @retval !=0  error.
10743 */
10744 
change_receive_options(THD * thd,LEX_MASTER_INFO * lex_mi,Master_info * mi)10745 static int change_receive_options(THD* thd, LEX_MASTER_INFO* lex_mi,
10746                                   Master_info* mi)
10747 {
10748   int ret= 0; /* return value. Set if there is an error. */
10749 
10750   DBUG_ENTER("change_receive_options");
10751 
10752   /*
10753     If the user specified host or port without binlog or position,
10754     reset binlog's name to FIRST and position to 4.
10755   */
10756 
10757   if ((lex_mi->host && strcmp(lex_mi->host, mi->host)) ||
10758       (lex_mi->port && lex_mi->port != mi->port))
10759   {
10760     /*
10761       This is necessary because the primary key, i.e. host or port, has
10762       changed.
10763 
10764       The repository does not support direct changes on the primary key,
10765       so the row is dropped and re-inserted with a new primary key. If we
10766       don't do that, the master info repository we will end up with several
10767       rows.
10768     */
10769     if (mi->clean_info())
10770     {
10771       ret= 1;
10772       goto err;
10773     }
10774     mi->master_uuid[0]= 0;
10775     mi->master_id= 0;
10776   }
10777 
10778   if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
10779   {
10780     char *var_master_log_name= NULL;
10781     var_master_log_name= const_cast<char*>(mi->get_master_log_name());
10782     var_master_log_name[0]= '\0';
10783     mi->set_master_log_pos(BIN_LOG_HEADER_SIZE);
10784   }
10785 
10786   if (lex_mi->log_file_name)
10787     mi->set_master_log_name(lex_mi->log_file_name);
10788   if (lex_mi->pos)
10789   {
10790     mi->set_master_log_pos(lex_mi->pos);
10791   }
10792 
10793   if (lex_mi->log_file_name && !lex_mi->pos)
10794     push_warning(thd, Sql_condition::SL_WARNING,
10795                  ER_WARN_ONLY_MASTER_LOG_FILE_NO_POS,
10796                  ER(ER_WARN_ONLY_MASTER_LOG_FILE_NO_POS));
10797 
10798   DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
10799 
10800   if (lex_mi->user || lex_mi->password)
10801   {
10802 #if !defined(EMBEDDED_LIBRARY)
10803     if (!thd->get_ssl())
10804     {
10805       push_warning(thd, Sql_condition::SL_NOTE,
10806                    ER_INSECURE_PLAIN_TEXT,
10807                    ER(ER_INSECURE_PLAIN_TEXT));
10808     }
10809 #endif
10810     push_warning(thd, Sql_condition::SL_NOTE,
10811                  ER_INSECURE_CHANGE_MASTER,
10812                  ER(ER_INSECURE_CHANGE_MASTER));
10813   }
10814 
10815   if (lex_mi->user)
10816     mi->set_user(lex_mi->user);
10817   if (lex_mi->password)
10818     mi->set_password(lex_mi->password);
10819   if (lex_mi->host)
10820     strmake(mi->host, lex_mi->host, sizeof(mi->host)-1);
10821   if (lex_mi->bind_addr)
10822     strmake(mi->bind_addr, lex_mi->bind_addr, sizeof(mi->bind_addr)-1);
10823   /*
10824     Setting channel's port number explicitly to '0' should be allowed.
10825     Eg: 'group_replication_recovery' channel (*after recovery is done*)
10826     or 'group_replication_applier' channel wants to set the port number
10827     to '0' as there is no actual network usage on these channels.
10828   */
10829   if (lex_mi->port || lex_mi->port_opt == LEX_MASTER_INFO::LEX_MI_ENABLE)
10830     mi->port = lex_mi->port;
10831   if (lex_mi->connect_retry)
10832     mi->connect_retry = lex_mi->connect_retry;
10833   if (lex_mi->retry_count_opt !=  LEX_MASTER_INFO::LEX_MI_UNCHANGED)
10834     mi->retry_count = lex_mi->retry_count;
10835 
10836   if (lex_mi->heartbeat_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
10837     mi->heartbeat_period = lex_mi->heartbeat_period;
10838   else if (lex_mi->host || lex_mi->port)
10839   {
10840     /*
10841       If the user specified host or port or both without heartbeat_period,
10842       we use default value for heartbeat_period. By default, We want to always
10843       have heartbeat enabled when we switch master unless
10844       master_heartbeat_period is explicitly set to zero (heartbeat disabled).
10845 
10846       Here is the default value for heartbeat period if CHANGE MASTER did not
10847       specify it.  (no data loss in conversion as hb period has a max)
10848     */
10849     mi->heartbeat_period= min<float>(SLAVE_MAX_HEARTBEAT_PERIOD,
10850                                      (slave_net_timeout/2.0f));
10851     DBUG_ASSERT(mi->heartbeat_period > (float) 0.001
10852                 || mi->heartbeat_period == 0);
10853 
10854     // counter is cleared if master is CHANGED.
10855     mi->received_heartbeats= 0;
10856     // clear timestamp of last heartbeat as well.
10857     mi->last_heartbeat= 0;
10858   }
10859 
10860   /*
10861     reset the last time server_id list if the current CHANGE MASTER
10862     is mentioning IGNORE_SERVER_IDS= (...)
10863   */
10864   if (lex_mi->repl_ignore_server_ids_opt == LEX_MASTER_INFO::LEX_MI_ENABLE)
10865     mi->ignore_server_ids->dynamic_ids.clear();
10866   for (size_t i= 0; i < lex_mi->repl_ignore_server_ids.size(); i++)
10867   {
10868     ulong s_id= lex_mi->repl_ignore_server_ids[i];
10869     if (s_id == ::server_id && replicate_same_server_id)
10870     {
10871       ret= ER_SLAVE_IGNORE_SERVER_IDS;
10872       my_error(ER_SLAVE_IGNORE_SERVER_IDS, MYF(0), static_cast<int>(s_id));
10873       goto err;
10874     }
10875     else
10876     {
10877       // Keep the array sorted, ignore duplicates.
10878       mi->ignore_server_ids->dynamic_ids.insert_unique(s_id);
10879     }
10880   }
10881 
10882   if (lex_mi->ssl != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
10883     mi->ssl= (lex_mi->ssl == LEX_MASTER_INFO::LEX_MI_ENABLE);
10884 
10885   if (lex_mi->ssl_verify_server_cert != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
10886     mi->ssl_verify_server_cert=
10887       (lex_mi->ssl_verify_server_cert == LEX_MASTER_INFO::LEX_MI_ENABLE);
10888 
10889   if (lex_mi->ssl_ca)
10890     strmake(mi->ssl_ca, lex_mi->ssl_ca, sizeof(mi->ssl_ca)-1);
10891   if (lex_mi->ssl_capath)
10892     strmake(mi->ssl_capath, lex_mi->ssl_capath, sizeof(mi->ssl_capath)-1);
10893   if (lex_mi->tls_version)
10894     strmake(mi->tls_version, lex_mi->tls_version, sizeof(mi->tls_version)-1);
10895   if (lex_mi->ssl_cert)
10896     strmake(mi->ssl_cert, lex_mi->ssl_cert, sizeof(mi->ssl_cert)-1);
10897   if (lex_mi->ssl_cipher)
10898     strmake(mi->ssl_cipher, lex_mi->ssl_cipher, sizeof(mi->ssl_cipher)-1);
10899   if (lex_mi->ssl_key)
10900     strmake(mi->ssl_key, lex_mi->ssl_key, sizeof(mi->ssl_key)-1);
10901   if (lex_mi->ssl_crl)
10902     strmake(mi->ssl_crl, lex_mi->ssl_crl, sizeof(mi->ssl_crl)-1);
10903   if (lex_mi->ssl_crlpath)
10904     strmake(mi->ssl_crlpath, lex_mi->ssl_crlpath, sizeof(mi->ssl_crlpath)-1);
10905 #ifndef HAVE_OPENSSL
10906   if (lex_mi->ssl || lex_mi->ssl_ca || lex_mi->ssl_capath ||
10907       lex_mi->ssl_cert || lex_mi->ssl_cipher || lex_mi->ssl_key ||
10908       lex_mi->ssl_verify_server_cert || lex_mi->ssl_crl || lex_mi->ssl_crlpath || lex_mi->tls_version)
10909     push_warning(thd, Sql_condition::SL_NOTE,
10910                  ER_SLAVE_IGNORED_SSL_PARAMS, ER(ER_SLAVE_IGNORED_SSL_PARAMS));
10911 #endif
10912 
10913 err:
10914   DBUG_RETURN(ret);
10915 }
10916 
10917 /**
10918    This function is called if the change master command had at least one
10919    execute option. This function then sets or alters the execute option(s)
10920    given in the command. The receive options are handled in the function
10921    change_receive_options()
10922 
10923    - used in change_master().
10924    - Execute threads should be stopped before this function is called.
10925 
10926   @param lex_mi structure that holds all change master options given on the
10927                 change master command.
10928 
10929   @param mi     Pointer to Master_info object belonging to the slave's IO
10930                 thread.
10931 */
10932 
change_execute_options(LEX_MASTER_INFO * lex_mi,Master_info * mi)10933 static void change_execute_options(LEX_MASTER_INFO* lex_mi, Master_info* mi)
10934 {
10935   DBUG_ENTER("change_execute_options");
10936 
10937   if (lex_mi->relay_log_name)
10938   {
10939     char relay_log_name[FN_REFLEN];
10940     mi->rli->relay_log.make_log_name(relay_log_name, lex_mi->relay_log_name);
10941     mi->rli->set_group_relay_log_name(relay_log_name);
10942     mi->rli->set_event_relay_log_name(relay_log_name);
10943     mi->rli->is_group_master_log_pos_invalid= true;
10944   }
10945 
10946   if (lex_mi->relay_log_pos)
10947   {
10948     mi->rli->set_group_relay_log_pos(lex_mi->relay_log_pos);
10949     mi->rli->set_event_relay_log_pos(lex_mi->relay_log_pos);
10950     mi->rli->is_group_master_log_pos_invalid= true;
10951   }
10952 
10953   if (lex_mi->sql_delay != -1)
10954     mi->rli->set_sql_delay(lex_mi->sql_delay);
10955 
10956   DBUG_VOID_RETURN;
10957 }
10958 
10959 /**
10960   Execute a CHANGE MASTER statement.
10961 
10962   Apart from changing the receive/execute configurations/positions,
10963   this function also does the following:
10964   - May leave replicated open temporary table after warning.
10965   - Purges relay logs if no threads running and no relay log file/pos options.
10966   - Delete worker info in mysql.slave_worker_info table if applier not running.
10967 
10968   @param thd            Pointer to THD object for the client thread executing
10969                         the statement.
10970 
10971   @param mi             Pointer to Master_info object belonging to the slave's
10972                         IO thread.
10973 
10974   @param lex_mi         Lex information with master connection data.
10975                         Coming from the an executing statement or set directly
10976                         this shall contain connection settings like hostname,
10977                         user, password and other settings like the number of
10978                         connection retries.
10979 
10980   @param preserve_logs  If the decision of purging the logs should be always be
10981                         false even if no relay log name/position is given to
10982                         the method. The preserve_logs parameter will not be
10983                         respected when the relay log info repository is not
10984                         initialized.
10985 
10986   @retval 0   success
10987   @retval !=0 error
10988 */
change_master(THD * thd,Master_info * mi,LEX_MASTER_INFO * lex_mi,bool preserve_logs)10989 int change_master(THD* thd, Master_info* mi, LEX_MASTER_INFO* lex_mi,
10990                   bool preserve_logs)
10991 {
10992   int error= 0;
10993 
10994   /* Do we have at least one receive related (IO thread) option? */
10995   bool have_receive_option= false;
10996   /* Do we have at least one execute related (SQL/coord/worker) option? */
10997   bool have_execute_option= false;
10998   /* If there are no mts gaps, we delete the rows in this table. */
10999   bool mts_remove_worker_info= false;
11000   /* used as a bit mask to indicate running slave threads. */
11001   int thread_mask;
11002   /*
11003     Relay logs are purged only if both receive and execute threads are
11004     stopped before executing CHANGE MASTER and relay_log_file/relay_log_pos
11005     options are not used.
11006   */
11007   bool need_relay_log_purge= 1;
11008 
11009   /*
11010     We want to save the old receive configurations so that we can use them to
11011     print the changes in these configurations (from-to form). This is used in
11012     sql_print_information() later.
11013   */
11014   char saved_host[HOSTNAME_LENGTH + 1], saved_bind_addr[HOSTNAME_LENGTH + 1];
11015   uint saved_port= 0;
11016   char saved_log_name[FN_REFLEN];
11017   my_off_t saved_log_pos= 0;
11018 
11019   DBUG_ENTER("change_master");
11020 
11021   /*
11022     CHANGE MASTER command should ignore 'read-only' and 'super_read_only'
11023     options so that it can update 'mysql.slave_master_info' replication
11024     repository tables.
11025   */
11026   thd->set_skip_readonly_check();
11027   mi->channel_wrlock();
11028   /*
11029     When we change master, we first decide which thread is running and
11030     which is not. We dont want this assumption to break while we change master.
11031 
11032     Suppose we decide that receiver thread is running and thus it is
11033     safe to change receive related options in mi. By this time if
11034     the receive thread is started, we may have a race condition between
11035     the client thread and receiver thread.
11036   */
11037   lock_slave_threads(mi);
11038 
11039   /*
11040     Get a bit mask for the slave threads that are running.
11041     Since the third argument is 0, thread_mask after the function
11042     returns stands for running threads.
11043   */
11044   init_thread_mask(&thread_mask, mi, 0);
11045 
11046   /*
11047     change master with master_auto_position=1 requires stopping both
11048     receiver and applier threads. If any slave thread is running,
11049     we report an error.
11050   */
11051   if (thread_mask) /* If any thread is running */
11052   {
11053     if (lex_mi->auto_position != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
11054     {
11055       error= ER_SLAVE_CHANNEL_MUST_STOP;
11056       my_error(ER_SLAVE_CHANNEL_MUST_STOP, MYF(0), mi->get_channel());
11057       goto err;
11058     }
11059     /*
11060       Prior to WL#6120, we imposed the condition that STOP SLAVE is required
11061       before CHANGE MASTER. Since the slave threads die on STOP SLAVE, it was
11062       fine if we purged relay logs.
11063 
11064       Now that we do allow CHANGE MASTER with a running receiver/applier thread,
11065       we need to make sure that the relay logs are purged only if both
11066       receiver and applier threads are stopped otherwise we could lose events.
11067 
11068       The idea behind purging relay logs if both the threads are stopped is to
11069       keep consistency with the old behavior. If the user/application is doing
11070       a CHANGE MASTER without stopping any one thread, the relay log purge
11071       should be controlled via the 'relay_log_purge' option.
11072     */
11073     need_relay_log_purge= 0;
11074   }
11075 
11076   /*
11077     We cannot specify auto position and set either the coordinates
11078     on master or slave. If we try to do so, an error message is
11079     printed out.
11080   */
11081   if (lex_mi->log_file_name != NULL || lex_mi->pos != 0 ||
11082       lex_mi->relay_log_name != NULL || lex_mi->relay_log_pos != 0)
11083   {
11084     if (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE ||
11085         (lex_mi->auto_position != LEX_MASTER_INFO::LEX_MI_DISABLE &&
11086          mi->is_auto_position()))
11087     {
11088       error= ER_BAD_SLAVE_AUTO_POSITION;
11089       my_message(ER_BAD_SLAVE_AUTO_POSITION,
11090                  ER(ER_BAD_SLAVE_AUTO_POSITION), MYF(0));
11091       goto err;
11092     }
11093   }
11094 
11095   /* CHANGE MASTER TO MASTER_AUTO_POSITION = 1 requires GTID_MODE != OFF */
11096   if (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE &&
11097       /*
11098         We hold channel_map lock for the duration of the CHANGE MASTER.
11099         This is important since it prevents that a concurrent
11100         connection changes to GTID_MODE=OFF between this check and the
11101         point where AUTO_POSITION is stored in the table and in mi.
11102       */
11103       get_gtid_mode(GTID_MODE_LOCK_CHANNEL_MAP) == GTID_MODE_OFF)
11104   {
11105     error= ER_AUTO_POSITION_REQUIRES_GTID_MODE_NOT_OFF;
11106     my_message(ER_AUTO_POSITION_REQUIRES_GTID_MODE_NOT_OFF,
11107                ER(ER_AUTO_POSITION_REQUIRES_GTID_MODE_NOT_OFF), MYF(0));
11108     goto err;
11109   }
11110 
11111   /* Check if at least one receive option is given on change master */
11112   have_receive_option= have_change_master_receive_option(lex_mi);
11113 
11114   /* Check if at least one execute option is given on change master */
11115   have_execute_option= have_change_master_execute_option(lex_mi,
11116                                                          &need_relay_log_purge);
11117 
11118   if (need_relay_log_purge && /* If we should purge the logs for this channel */
11119       preserve_logs &&        /* And we were asked to keep them */
11120       mi->rli->inited)        /* And the channel was initialized properly */
11121   {
11122     need_relay_log_purge= false;
11123   }
11124 
11125   /* With receiver thread running, we dont allow changing receive options. */
11126   if (have_receive_option && (thread_mask & SLAVE_IO))
11127   {
11128     error= ER_SLAVE_CHANNEL_IO_THREAD_MUST_STOP;
11129     my_error(ER_SLAVE_CHANNEL_IO_THREAD_MUST_STOP, MYF(0), mi->get_channel());
11130     goto err;
11131   }
11132 
11133   /* With an execute thread running, we don't allow changing execute options. */
11134   if (have_execute_option && (thread_mask & SLAVE_SQL))
11135   {
11136     error= ER_SLAVE_CHANNEL_SQL_THREAD_MUST_STOP;
11137     my_error(ER_SLAVE_CHANNEL_SQL_THREAD_MUST_STOP, MYF(0), mi->get_channel());
11138     goto err;
11139   }
11140 
11141   /*
11142     We need to check if there is an empty master_host. Otherwise
11143     change master succeeds, a master.info file is created containing
11144     empty master_host string and when issuing: start slave; an error
11145     is thrown stating that the server is not configured as slave.
11146     (See BUG#28796).
11147   */
11148   if (lex_mi->host && !*lex_mi->host)
11149   {
11150     error= ER_WRONG_ARGUMENTS;
11151     my_error(ER_WRONG_ARGUMENTS, MYF(0), "MASTER_HOST");
11152     goto err;
11153   }
11154 
11155   THD_STAGE_INFO(thd, stage_changing_master);
11156 
11157   int thread_mask_stopped_threads;
11158 
11159   /*
11160     Before load_mi_and_rli_from_repositories() call, get a bit mask to indicate
11161     stopped threads in thread_mask_stopped_threads. Since the third argguement
11162     is 1, thread_mask when the function returns stands for stopped threads.
11163   */
11164 
11165   init_thread_mask(&thread_mask_stopped_threads, mi, 1);
11166 
11167   if (load_mi_and_rli_from_repositories(mi, false, thread_mask_stopped_threads))
11168   {
11169     error= ER_MASTER_INFO;
11170     my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
11171     goto err;
11172   }
11173 
11174   if ((thread_mask & SLAVE_SQL) == 0) // If execute threads are stopped
11175   {
11176     if (mi->rli->mts_recovery_group_cnt)
11177     {
11178       /*
11179         Change-Master can't be done if there is a mts group gap.
11180         That requires mts-recovery which START SLAVE provides.
11181       */
11182       DBUG_ASSERT(mi->rli->recovery_parallel_workers);
11183 
11184       error= ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS;
11185       my_message(ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS,
11186                  ER(ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS), MYF(0));
11187       goto err;
11188     }
11189     else
11190     {
11191       /*
11192         Lack of mts group gaps makes Workers info stale regardless of
11193         need_relay_log_purge computation. We set the mts_remove_worker_info
11194         flag here and call reset_workers() later to delete the worker info
11195         in mysql.slave_worker_info table.
11196       */
11197       if (mi->rli->recovery_parallel_workers)
11198         mts_remove_worker_info= true;
11199     }
11200   }
11201 
11202   /*
11203     When give a warning?
11204     CHANGE MASTER command is used in three ways:
11205     a) To change a connection configuration but remain connected to
11206        the same master.
11207     b) To change positions in binary or relay log(eg: master_log_pos).
11208     c) To change the master you are replicating from.
11209     We give a warning in cases b and c.
11210   */
11211   if ((lex_mi->host || lex_mi->port || lex_mi->log_file_name || lex_mi->pos ||
11212        lex_mi->relay_log_name || lex_mi->relay_log_pos) &&
11213       (mi->rli->channel_open_temp_tables.atomic_get() > 0))
11214     push_warning(thd, Sql_condition::SL_WARNING,
11215                  ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO,
11216                  ER(ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO));
11217 
11218   /*
11219     auto_position is the only option that affects both receive
11220     and execute sections of replication. So, this code is kept
11221     outside both if (have_receive_option) and if (have_execute_option)
11222 
11223     Here, we check if the auto_position option was used and set the flag
11224     if the slave should connect to the master and look for GTIDs.
11225   */
11226   if (lex_mi->auto_position != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
11227     mi->set_auto_position(
11228       (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE));
11229 
11230   if (have_receive_option)
11231   {
11232     strmake(saved_host, mi->host, HOSTNAME_LENGTH);
11233     strmake(saved_bind_addr, mi->bind_addr, HOSTNAME_LENGTH);
11234     saved_port= mi->port;
11235     strmake(saved_log_name, mi->get_master_log_name(), FN_REFLEN - 1);
11236     saved_log_pos= mi->get_master_log_pos();
11237 
11238     if ((error= change_receive_options(thd, lex_mi, mi)))
11239     {
11240       goto err;
11241     }
11242   }
11243 
11244   /*
11245     If user didn't specify neither host nor port nor any log name nor any log
11246     pos, i.e. he specified only user/password/master_connect_retry, master_delay,
11247     he probably  wants replication to resume from where it had left, i.e. from the
11248     coordinates of the **SQL** thread (imagine the case where the I/O is ahead
11249     of the SQL; restarting from the coordinates of the I/O would lose some
11250     events which is probably unwanted when you are just doing minor changes
11251     like changing master_connect_retry).
11252     Note: coordinates of the SQL thread must be read before the block which
11253     resets them.
11254   */
11255   if (need_relay_log_purge)
11256   {
11257     /*
11258       A side-effect is that if only the I/O thread was started, this thread may
11259       restart from ''/4 after the CHANGE MASTER. That's a minor problem (it is a
11260       much more unlikely situation than the one we are fixing here).
11261     */
11262     if (!lex_mi->host && !lex_mi->port &&
11263         !lex_mi->log_file_name && !lex_mi->pos)
11264     {
11265       /*
11266         Sometimes mi->rli->master_log_pos == 0 (it happens when the SQL thread is
11267         not initialized), so we use a max().
11268         What happens to mi->rli->master_log_pos during the initialization stages
11269         of replication is not 100% clear, so we guard against problems using
11270         max().
11271       */
11272       mi->set_master_log_pos(max<ulonglong>(BIN_LOG_HEADER_SIZE,
11273                                             mi->rli->get_group_master_log_pos()));
11274       mi->set_master_log_name(mi->rli->get_group_master_log_name());
11275     }
11276   }
11277 
11278   if (have_receive_option)
11279     sql_print_information("'CHANGE MASTER TO%s executed'. "
11280       "Previous state master_host='%s', master_port= %u, master_log_file='%s', "
11281       "master_log_pos= %ld, master_bind='%s'. "
11282       "New state master_host='%s', master_port= %u, master_log_file='%s', "
11283       "master_log_pos= %ld, master_bind='%s'.",
11284       mi->get_for_channel_str(true),
11285       saved_host, saved_port, saved_log_name, (ulong) saved_log_pos,
11286       saved_bind_addr, mi->host, mi->port, mi->get_master_log_name(),
11287       (ulong) mi->get_master_log_pos(), mi->bind_addr);
11288 
11289   if (have_execute_option)
11290     change_execute_options(lex_mi, mi);
11291 
11292   /* If the receiver is stopped, flush master_info to disk. */
11293   if ((thread_mask & SLAVE_IO) == 0 && flush_master_info(mi, true))
11294   {
11295     error= ER_RELAY_LOG_INIT;
11296     my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file");
11297     goto err;
11298   }
11299 
11300   if ((thread_mask & SLAVE_SQL) == 0) /* Applier module is not executing */
11301   {
11302 
11303     /*
11304       The following code for purging logs can be improved. We currently use
11305       3 flags-
11306       1) need_relay_log_purge,
11307       2) relay_log_purge(global) and
11308       3) save_relay_log_purge.
11309 
11310       The use of the global variable 'relay_log_purge' is bad. So, when
11311       refactoring the code for purge logs, please consider improving this code.
11312     */
11313 
11314     /*
11315       Used as a temporary variable while logs are being purged.
11316 
11317       We save the value of the global variable 'relay_log_purge' here and then
11318       set/unset it as required in if (need_relay_log_purge){}else{} block
11319       following which we restore relay_log_purge value from its saved value.
11320     */
11321     bool save_relay_log_purge= relay_log_purge;
11322 
11323     if (need_relay_log_purge)
11324     {
11325       /*
11326         'if (need_relay_log_purge)' implicitly means that all slave threads are
11327         stopped and there is no use of relay_log_file/relay_log_pos options.
11328         We need not check these here again.
11329       */
11330 
11331       /* purge_relay_log() returns pointer to an error message here. */
11332       const char* errmsg= 0;
11333       /*
11334         purge_relay_log() assumes that we have run_lock and no slave threads
11335         are running.
11336       */
11337       relay_log_purge= 1;
11338       THD_STAGE_INFO(thd, stage_purging_old_relay_logs);
11339       if (mi->rli->purge_relay_logs(thd,
11340                                     0 /* not only reset, but also reinit */,
11341                                     &errmsg))
11342       {
11343         error= ER_RELAY_LOG_FAIL;
11344         my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg);
11345         goto err;
11346       }
11347     }
11348     else
11349     {
11350       /*
11351         If our applier module is executing and we want to switch to another
11352         master without disturbing it, relay log position need not be disturbed.
11353         The SQL/coordinator thread will continue reasding whereever it is
11354         placed at the moement, finish events from the old master and
11355         then start with the new relay log containing events from new master
11356         on its own. So we only  do this when the relay logs are not purged.
11357 
11358         execute this when the applier is NOT executing.
11359       */
11360       const char* msg;
11361       relay_log_purge= 0;
11362 
11363       /* Relay log must be already initialized */
11364       DBUG_ASSERT(mi->rli->inited);
11365       if (mi->rli->init_relay_log_pos(mi->rli->get_group_relay_log_name(),
11366                                       mi->rli->get_group_relay_log_pos(),
11367                                       true/*we do need mi->rli->data_lock*/,
11368                                       &msg, 0))
11369       {
11370         error= ER_RELAY_LOG_INIT;
11371         my_error(ER_RELAY_LOG_INIT, MYF(0), msg);
11372         goto err;
11373       }
11374     }
11375 
11376     relay_log_purge= save_relay_log_purge;
11377 
11378     /*
11379       Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block,
11380       so restore them to good values. If we left them to ''/0, that would work;
11381       but that would fail in the case of 2 successive CHANGE MASTER (without a
11382       START SLAVE in between): because first one would set the coords in mi to
11383       the good values of those in rli, then set those i>n rli to ''/0, then
11384       second CHANGE MASTER would set the coords in mi to those of rli, i.e. to
11385       ''/0: we have lost all copies of the original good coordinates.
11386       That's why we always save good coords in rli.
11387     */
11388     if (need_relay_log_purge)
11389     {
11390       mi->rli->set_group_master_log_pos(mi->get_master_log_pos());
11391       DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
11392       mi->rli->set_group_master_log_name(mi->get_master_log_name());
11393     }
11394 
11395     char *var_group_master_log_name=
11396       const_cast<char *>(mi->rli->get_group_master_log_name());
11397 
11398     if (!var_group_master_log_name[0]) // uninitialized case
11399       mi->rli->set_group_master_log_pos(0);
11400 
11401     mi->rli->abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */
11402 
11403     /* Clear the errors, for a clean start */
11404     mi->rli->clear_error();
11405     if (mi->rli->workers_array_initialized)
11406     {
11407       for(size_t i= 0; i < mi->rli->get_worker_count(); i++)
11408       {
11409         mi->rli->get_worker(i)->clear_error();
11410       }
11411     }
11412 
11413     mi->rli->clear_until_condition();
11414 
11415     /*
11416       If we don't write new coordinates to disk now, then old will remain in
11417       relay-log.info until START SLAVE is issued; but if mysqld is shutdown
11418       before START SLAVE, then old will remain in relay-log.info, and will be the
11419       in-memory value at restart (thus causing errors, as the old relay log does
11420       not exist anymore).
11421 
11422       Notice that the rli table is available exclusively as slave is not
11423       running.
11424     */
11425     if (mi->rli->flush_info(true))
11426     {
11427       error= ER_RELAY_LOG_INIT;
11428       my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush relay info file.");
11429       goto err;
11430     }
11431 
11432   } /* end 'if (thread_mask & SLAVE_SQL == 0)' */
11433 
11434   if (mts_remove_worker_info)
11435     if (Rpl_info_factory::reset_workers(mi->rli))
11436     {
11437       error= ER_MTS_RESET_WORKERS;
11438       my_error(ER_MTS_RESET_WORKERS, MYF(0));
11439       goto err;
11440     }
11441 
11442 err:
11443 
11444   unlock_slave_threads(mi);
11445   mi->channel_unlock();
11446   DBUG_RETURN(error);
11447 }
11448 
11449 
11450 /**
11451    This function is first called when the Master_info object
11452    corresponding to a channel in a multisourced slave does not
11453    exist. But before a new channel is created, certain
11454    conditions have to be met. The below function apriorily
11455    checks if all such conditions are met. If all the
11456    conditions are met then it creates a channel i.e
11457    mi<->rli
11458 
11459    @param[in,out]  mi                When new {mi,rli} are created,
11460                                      the reference is stored in *mi
11461    @param[in]      channel           The channel on which the change
11462                                      master was introduced.
11463 */
add_new_channel(Master_info ** mi,const char * channel)11464 int add_new_channel(Master_info** mi, const char* channel)
11465 {
11466   DBUG_ENTER("add_new_channel");
11467 
11468   int error= 0;
11469   enum_ident_name_check ident_check_status;
11470 
11471   /*
11472     Refuse to create a new channel if the repositories does not support this.
11473   */
11474 
11475   if (opt_mi_repository_id == INFO_REPOSITORY_FILE ||
11476       opt_rli_repository_id == INFO_REPOSITORY_FILE)
11477   {
11478     sql_print_error("Slave: Cannot create new master info structure when"
11479                     " repositories are of type FILE. Convert slave"
11480                     " repositories  to TABLE to replicate from multiple"
11481                     " sources.");
11482     error= ER_SLAVE_NEW_CHANNEL_WRONG_REPOSITORY;
11483     my_error(ER_SLAVE_NEW_CHANNEL_WRONG_REPOSITORY, MYF(0));
11484     goto err;
11485   }
11486 
11487   /*
11488     Return if max num of replication channels exceeded already.
11489   */
11490 
11491   if (!channel_map.is_valid_channel_count())
11492   {
11493     error= ER_SLAVE_MAX_CHANNELS_EXCEEDED;
11494     my_error(ER_SLAVE_MAX_CHANNELS_EXCEEDED, MYF(0));
11495     goto err;
11496   }
11497 
11498  /*
11499    Now check the sanity of the channel name. It's length etc. The channel
11500    identifier is similar to table names. So, use  check_table_function.
11501  */
11502   if (channel)
11503   {
11504     ident_check_status= check_table_name(channel, strlen(channel), false);
11505   }
11506   else
11507     ident_check_status= IDENT_NAME_WRONG;
11508 
11509   if (ident_check_status != IDENT_NAME_OK)
11510   {
11511     error= ER_SLAVE_CHANNEL_NAME_INVALID_OR_TOO_LONG;
11512     my_error(ER_SLAVE_CHANNEL_NAME_INVALID_OR_TOO_LONG, MYF(0));
11513     goto err;
11514   }
11515 
11516   if (!((*mi)=Rpl_info_factory::create_mi_and_rli_objects(opt_mi_repository_id,
11517                                                           opt_rli_repository_id,
11518                                                           channel,
11519                                                           false,
11520                                                           &channel_map)))
11521   {
11522     error= ER_MASTER_INFO;
11523     my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
11524     goto err;
11525   }
11526 
11527 err:
11528 
11529   DBUG_RETURN(error);
11530 
11531 }
11532 
11533 /**
11534    Method used to check if the user is trying to update any other option for
11535    the change master apart from the MASTER_USER and MASTER_PASSWORD.
11536    In case user tries to update any other parameter apart from these two,
11537    this method will return error.
11538 
11539    @param  lex_mi structure that holds all change master options given on
11540            the change master command.
11541 
11542    @retval TRUE - The CHANGE MASTER is updating a unsupported parameter for the
11543                   recovery channel.
11544 
11545    @retval FALSE - Everything is fine. The CHANGE MASTER can execute with the
11546                    given option(s) for the recovery channel.
11547 */
is_invalid_change_master_for_group_replication_recovery(const LEX_MASTER_INFO * lex_mi)11548 static bool is_invalid_change_master_for_group_replication_recovery(const
11549                                                                     LEX_MASTER_INFO*
11550                                                                     lex_mi)
11551 {
11552   DBUG_ENTER("is_invalid_change_master_for_group_replication_recovery");
11553   bool have_extra_option_received= false;
11554 
11555   /* Check if *at least one* receive/execute option is given on change master command*/
11556   if (lex_mi->host ||
11557       lex_mi->log_file_name ||
11558       lex_mi->pos ||
11559       lex_mi->bind_addr ||
11560       lex_mi->port ||
11561       lex_mi->connect_retry ||
11562       lex_mi->server_id ||
11563       lex_mi->auto_position != LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
11564       lex_mi->ssl != LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
11565       lex_mi->ssl_verify_server_cert != LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
11566       lex_mi->heartbeat_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
11567       lex_mi->retry_count_opt !=  LEX_MASTER_INFO::LEX_MI_UNCHANGED ||
11568       lex_mi->ssl_key ||
11569       lex_mi->ssl_cert ||
11570       lex_mi->ssl_ca ||
11571       lex_mi->ssl_capath ||
11572       lex_mi->tls_version ||
11573       lex_mi->ssl_cipher ||
11574       lex_mi->ssl_crl ||
11575       lex_mi->ssl_crlpath ||
11576       lex_mi->repl_ignore_server_ids_opt == LEX_MASTER_INFO::LEX_MI_ENABLE ||
11577       lex_mi->relay_log_name ||
11578       lex_mi->relay_log_pos ||
11579       lex_mi->sql_delay != -1)
11580     have_extra_option_received= true;
11581 
11582   DBUG_RETURN(have_extra_option_received);
11583 }
11584 
11585 /**
11586   Entry point for the CHANGE MASTER command. Function
11587   decides to create a new channel or create an existing one.
11588 
11589   @param[in]        thd        the client thread that issued the command.
11590 
11591   @return
11592     @retval         true        fail
11593     @retval         false       success.
11594 */
change_master_cmd(THD * thd)11595 bool change_master_cmd(THD *thd)
11596 {
11597   DBUG_ENTER("change_master_cmd");
11598 
11599   Master_info *mi= 0;
11600   LEX *lex= thd->lex;
11601   bool res=false;
11602 
11603   channel_map.wrlock();
11604 
11605   /* The slave must have been initialized to allow CHANGE MASTER statements */
11606   if (!is_slave_configured())
11607   {
11608     my_message(ER_SLAVE_CONFIGURATION, ER(ER_SLAVE_CONFIGURATION), MYF(0));
11609     res= true;
11610     goto err;
11611   }
11612 
11613   //If the chosen name is for group_replication_applier channel we abort
11614   if (channel_map.is_group_replication_channel_name(lex->mi.channel, true))
11615   {
11616     my_error(ER_SLAVE_CHANNEL_NAME_INVALID_OR_TOO_LONG, MYF(0));
11617     res= true;
11618     goto err;
11619   }
11620 
11621   // If the channel being used is group_replication_recovery we allow the
11622   // channel creation based on the check as to which field is being updated.
11623   if (channel_map.is_group_replication_channel_name(lex->mi.channel) &&
11624       !channel_map.is_group_replication_channel_name(lex->mi.channel, true))
11625   {
11626     LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
11627     if (is_invalid_change_master_for_group_replication_recovery(lex_mi))
11628     {
11629       my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
11630                "CHANGE MASTER with the given parameters", lex->mi.channel);
11631       res= true;
11632       goto err;
11633     }
11634   }
11635 
11636   /*
11637     Error out if number of replication channels are > 1 if FOR CHANNEL
11638     clause is not provided in the CHANGE MASTER command.
11639   */
11640   if (!lex->mi.for_channel && channel_map.get_num_instances() > 1)
11641   {
11642     my_error(ER_SLAVE_MULTIPLE_CHANNELS_CMD, MYF(0));
11643     res= true;
11644     goto err;
11645   }
11646 
11647   /* Get the Master_info of the channel */
11648   mi= channel_map.get_mi(lex->mi.channel);
11649 
11650   /* create a new channel if doesn't exist */
11651   if (!mi && strcmp(lex->mi.channel, channel_map.get_default_channel()))
11652   {
11653     /* The mi will be returned holding mi->channel_lock for writing */
11654     if (add_new_channel(&mi, lex->mi.channel))
11655       goto err;
11656   }
11657 
11658   if (mi)
11659   {
11660     if (!(res= change_master(thd, mi, &thd->lex->mi)))
11661     {
11662       my_ok(thd);
11663     }
11664   }
11665   else
11666   {
11667     /*
11668        Even default channel does not exist. So issue a previous
11669        backward compatible  error message (till 5.6).
11670        @TODO: This error message shall be improved.
11671     */
11672     my_message(ER_SLAVE_CONFIGURATION, ER(ER_SLAVE_CONFIGURATION), MYF(0));
11673   }
11674 
11675 err:
11676   channel_map.unlock();
11677 
11678   DBUG_RETURN(res);
11679 }
11680 
11681 
11682 /**
11683   Check if there is any slave SQL config conflict.
11684 
11685   @param[in] rli The slave's rli object.
11686 
11687   @return 0 is returned if there is no conflict, otherwise 1 is returned.
11688  */
check_slave_sql_config_conflict(const Relay_log_info * rli)11689 static int check_slave_sql_config_conflict(const Relay_log_info *rli)
11690 {
11691   int channel_mts_submode, slave_parallel_workers;
11692 
11693   if (rli)
11694   {
11695     channel_mts_submode= rli->channel_mts_submode;
11696     slave_parallel_workers= rli->opt_slave_parallel_workers;
11697   }
11698   else
11699   {
11700     /*
11701       When the slave is first initialized, we collect the values from the
11702       command line options
11703     */
11704     channel_mts_submode= mts_parallel_option;
11705     slave_parallel_workers= opt_mts_slave_parallel_workers;
11706   }
11707 
11708   if (opt_slave_preserve_commit_order && slave_parallel_workers > 0)
11709   {
11710     if (channel_mts_submode == MTS_PARALLEL_TYPE_DB_NAME)
11711     {
11712       my_error(ER_DONT_SUPPORT_SLAVE_PRESERVE_COMMIT_ORDER, MYF(0),
11713                "when slave_parallel_type is DATABASE");
11714       return ER_DONT_SUPPORT_SLAVE_PRESERVE_COMMIT_ORDER;
11715     }
11716 
11717     if ((!opt_bin_log || !opt_log_slave_updates) &&
11718         channel_mts_submode == MTS_PARALLEL_TYPE_LOGICAL_CLOCK)
11719     {
11720       my_error(ER_DONT_SUPPORT_SLAVE_PRESERVE_COMMIT_ORDER, MYF(0),
11721                "unless both log_bin and log_slave_updates are enabled");
11722       return ER_DONT_SUPPORT_SLAVE_PRESERVE_COMMIT_ORDER;
11723     }
11724   }
11725 
11726   if (rli)
11727   {
11728     const char* channel= const_cast<Relay_log_info*>(rli)->get_channel();
11729     if (slave_parallel_workers > 0 &&
11730         (channel_mts_submode != MTS_PARALLEL_TYPE_LOGICAL_CLOCK ||
11731          (channel_mts_submode == MTS_PARALLEL_TYPE_LOGICAL_CLOCK &&
11732           !opt_slave_preserve_commit_order)) &&
11733         channel_map.is_group_replication_channel_name(channel, true))
11734     {
11735         my_error(ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED, MYF(0),
11736                  "START SLAVE SQL_THREAD when SLAVE_PARALLEL_WORKERS > 0 "
11737                  "and SLAVE_PARALLEL_TYPE != LOGICAL_CLOCK "
11738                  "or SLAVE_PRESERVE_COMMIT_ORDER != ON", channel);
11739         return ER_SLAVE_CHANNEL_OPERATION_NOT_ALLOWED;
11740     }
11741   }
11742 
11743   return 0;
11744 }
11745 
11746 
11747 /**
11748   Checks if any slave threads of any channel is running in Multisource
11749   replication.
11750   @note: The caller shall possess channel_map lock before calling this function.
11751 
11752   @param[in]        thread_mask       type of slave thread- IO/SQL or any
11753   @param[in]        already_locked_mi the mi that has its run_lock already
11754                                       taken.
11755 
11756   @return
11757     @retval          true               atleast one channel threads are running.
11758     @retval          false              none of the the channels are running.
11759 */
is_any_slave_channel_running(int thread_mask,Master_info * already_locked_mi)11760 bool is_any_slave_channel_running(int thread_mask,
11761                                   Master_info* already_locked_mi)
11762 {
11763   DBUG_ENTER("is_any_slave_channel_running");
11764   Master_info *mi= 0;
11765   bool is_running;
11766 
11767   channel_map.assert_some_lock();
11768 
11769   for (mi_map::iterator it= channel_map.begin(); it != channel_map.end(); it++)
11770   {
11771     mi= it->second;
11772 
11773     if (mi)
11774     {
11775       if ((thread_mask & SLAVE_IO) != 0)
11776       {
11777         /*
11778           start_slave() might call this function after already locking the
11779           rli->run_lock for a slave channel that is going to be started.
11780           In this case, we just assert that the lock is taken.
11781         */
11782         if (mi != already_locked_mi)
11783           mysql_mutex_lock(&mi->run_lock);
11784         else
11785         {
11786           mysql_mutex_assert_owner(&mi->run_lock);
11787         }
11788         is_running= mi->slave_running;
11789         if (mi != already_locked_mi)
11790           mysql_mutex_unlock(&mi->run_lock);
11791         if (is_running)
11792           DBUG_RETURN(true);
11793       }
11794 
11795       if ((thread_mask & SLAVE_SQL) != 0)
11796       {
11797         /*
11798           start_slave() might call this function after already locking the
11799           rli->run_lock for a slave channel that is going to be started.
11800           In this case, we just assert that the lock is taken.
11801         */
11802         if (mi != already_locked_mi)
11803           mysql_mutex_lock(&mi->rli->run_lock);
11804         else
11805         {
11806           mysql_mutex_assert_owner(&mi->rli->run_lock);
11807         }
11808         is_running= mi->rli->slave_running;
11809         if (mi != already_locked_mi)
11810           mysql_mutex_unlock(&mi->rli->run_lock);
11811         if (is_running)
11812           DBUG_RETURN(true);
11813       }
11814     }
11815 
11816   }
11817 
11818   DBUG_RETURN(false);
11819 }
11820 
11821 
11822 /**
11823   @} (end of group Replication)
11824 */
11825 #endif /* HAVE_REPLICATION */
11826