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