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