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