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