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