1 /* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22
23
24 /**
25 @addtogroup Replication
26 @{
27
28 @file
29
30 @brief Code to run the io thread and the sql thread on the
31 replication slave.
32 */
33
34 #include "sql_priv.h"
35 #include "my_global.h"
36 #include "rpl_slave.h"
37 #include "sql_parse.h" // execute_init_command
38 #include "sql_table.h" // mysql_rm_table
39 #include "rpl_mi.h"
40 #include "rpl_rli.h"
41 #include "rpl_filter.h"
42 #include "rpl_info_factory.h"
43 #include "transaction.h"
44 #include <thr_alarm.h>
45 #include <my_dir.h>
46 #include <sql_common.h>
47 #include <errmsg.h>
48 #include <mysqld_error.h>
49 #include <mysys_err.h>
50 #include "rpl_handler.h"
51 #include "rpl_info_dummy.h"
52 #include <signal.h>
53 #include <mysql.h>
54 #include <myisam.h>
55
56 #include "sql_base.h" // close_thread_tables
57 #include "tztime.h" // struct Time_zone
58 #include "log_event.h" // Rotate_log_event,
59 // Create_file_log_event,
60 // Format_description_log_event
61 #include "dynamic_ids.h"
62 #include "rpl_rli_pdb.h"
63 #include "global_threads.h"
64
65 #ifdef HAVE_REPLICATION
66
67 #include "rpl_tblmap.h"
68 #include "debug_sync.h"
69
70 using std::min;
71 using std::max;
72
73 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
74
75 #define MAX_SLAVE_RETRY_PAUSE 5
76 /*
77 a parameter of sql_slave_killed() to defer the killed status
78 */
79 #define SLAVE_WAIT_GROUP_DONE 60
80 bool use_slave_mask = 0;
81 MY_BITMAP slave_error_mask;
82 char slave_skip_error_names[SHOW_VAR_FUNC_BUFF_SIZE];
83
84 static unsigned long stop_wait_timeout;
85 char* slave_load_tmpdir = 0;
86 Master_info *active_mi= 0;
87 my_bool replicate_same_server_id;
88 ulonglong relay_log_space_limit = 0;
89
90 const char *relay_log_index= 0;
91 const char *relay_log_basename= 0;
92
93 /*
94 MTS load-ballancing parameter.
95 Max length of one MTS Worker queue. The value also determines the size
96 of Relay_log_info::gaq (see @c slave_start_workers()).
97 It can be set to any value in [1, ULONG_MAX - 1] range.
98 */
99 const ulong mts_slave_worker_queue_len_max= 16384;
100
101 /*
102 Statistics go to the error log every # of seconds when --log-warnings > 1
103 */
104 const long mts_online_stat_period= 60 * 2;
105
106
107 /*
108 MTS load-ballancing parameter.
109 Time unit in microsecs to sleep by MTS Coordinator to avoid extra thread
110 signalling in the case of Worker queues are close to be filled up.
111 */
112 const ulong mts_coordinator_basic_nap= 5;
113
114 /*
115 MTS load-ballancing parameter.
116 Percent of Worker queue size at which Worker is considered to become
117 hungry.
118
119 C enqueues --+ . underrun level
120 V "
121 +----------+-+------------------+--------------+
122 | empty |.|::::::::::::::::::|xxxxxxxxxxxxxx| ---> Worker dequeues
123 +----------+-+------------------+--------------+
124
125 Like in the above diagram enqueuing to the x-d area would indicate
126 actual underrruning by Worker.
127 */
128 const ulong mts_worker_underrun_level= 10;
129
130 Slave_job_item * de_queue(Slave_jobs_queue *jobs, Slave_job_item *ret);
131 bool append_item_to_jobs(slave_job_item *job_item,
132 Slave_worker *w, Relay_log_info *rli);
133
134 /*
135 When slave thread exits, we need to remember the temporary tables so we
136 can re-use them on slave start.
137
138 TODO: move the vars below under Master_info
139 */
140
141 int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
142
143 static pthread_key(Master_info*, RPL_MASTER_INFO);
144
145 enum enum_slave_reconnect_actions
146 {
147 SLAVE_RECON_ACT_REG= 0,
148 SLAVE_RECON_ACT_DUMP= 1,
149 SLAVE_RECON_ACT_EVENT= 2,
150 SLAVE_RECON_ACT_MAX
151 };
152
153 enum enum_slave_reconnect_messages
154 {
155 SLAVE_RECON_MSG_WAIT= 0,
156 SLAVE_RECON_MSG_KILLED_WAITING= 1,
157 SLAVE_RECON_MSG_AFTER= 2,
158 SLAVE_RECON_MSG_FAILED= 3,
159 SLAVE_RECON_MSG_COMMAND= 4,
160 SLAVE_RECON_MSG_KILLED_AFTER= 5,
161 SLAVE_RECON_MSG_MAX
162 };
163
164 static const char *reconnect_messages[SLAVE_RECON_ACT_MAX][SLAVE_RECON_MSG_MAX]=
165 {
166 {
167 "Waiting to reconnect after a failed registration on master",
168 "Slave I/O thread killed while waitnig to reconnect after a failed \
169 registration on master",
170 "Reconnecting after a failed registration on master",
171 "failed registering on master, reconnecting to try again, \
172 log '%s' at position %s",
173 "COM_REGISTER_SLAVE",
174 "Slave I/O thread killed during or after reconnect"
175 },
176 {
177 "Waiting to reconnect after a failed binlog dump request",
178 "Slave I/O thread killed while retrying master dump",
179 "Reconnecting after a failed binlog dump request",
180 "failed dump request, reconnecting to try again, log '%s' at position %s",
181 "COM_BINLOG_DUMP",
182 "Slave I/O thread killed during or after reconnect"
183 },
184 {
185 "Waiting to reconnect after a failed master event read",
186 "Slave I/O thread killed while waiting to reconnect after a failed read",
187 "Reconnecting after a failed master event read",
188 "Slave I/O thread: Failed reading log event, reconnecting to retry, \
189 log '%s' at position %s",
190 "",
191 "Slave I/O thread killed during or after a reconnect done to recover from \
192 failed read"
193 }
194 };
195
196 enum enum_slave_apply_event_and_update_pos_retval
197 {
198 SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK= 0,
199 SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR= 1,
200 SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR= 2,
201 SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR= 3,
202 SLAVE_APPLY_EVENT_AND_UPDATE_POS_MAX
203 };
204
205
206 static int process_io_rotate(Master_info* mi, Rotate_log_event* rev);
207 static int process_io_create_file(Master_info* mi, Create_file_log_event* cev);
208 static bool wait_for_relay_log_space(Relay_log_info* rli);
209 static inline bool io_slave_killed(THD* thd,Master_info* mi);
210 static inline bool sql_slave_killed(THD* thd,Relay_log_info* rli);
211 static inline bool is_autocommit_off_and_infotables(THD* thd);
212 static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type);
213 static void print_slave_skip_errors(void);
214 static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi);
215 static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
216 bool suppress_warnings);
217 static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
218 bool reconnect, bool suppress_warnings);
219 static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi);
220 static int get_master_uuid(MYSQL *mysql, Master_info *mi);
221 int io_thread_init_commands(MYSQL *mysql, Master_info *mi);
222 static Log_event* next_event(Relay_log_info* rli);
223 static int queue_event(Master_info* mi,const char* buf,ulong event_len);
224 static void set_stop_slave_wait_timeout(unsigned long wait_timeout);
225 static int terminate_slave_thread(THD *thd,
226 mysql_mutex_t *term_lock,
227 mysql_cond_t *term_cond,
228 volatile uint *slave_running,
229 bool need_lock_term);
230 static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info);
231 int slave_worker_exec_job(Slave_worker * w, Relay_log_info *rli);
232 static int mts_event_coord_cmp(LOG_POS_COORD *id1, LOG_POS_COORD *id2);
233 /*
234 Function to set the slave's max_allowed_packet based on the value
235 of slave_max_allowed_packet.
236
237 @in_param thd Thread handler for slave
238 @in_param mysql MySQL connection handle
239 */
240
set_slave_max_allowed_packet(THD * thd,MYSQL * mysql)241 static void set_slave_max_allowed_packet(THD *thd, MYSQL *mysql)
242 {
243 DBUG_ENTER("set_slave_max_allowed_packet");
244 // thd and mysql must be valid
245 DBUG_ASSERT(thd && mysql);
246
247 thd->variables.max_allowed_packet= slave_max_allowed_packet;
248 thd->net.max_packet_size= slave_max_allowed_packet;
249 /*
250 Adding MAX_LOG_EVENT_HEADER_LEN to the max_packet_size on the I/O
251 thread and the mysql->option max_allowed_packet, since a
252 replication event can become this much larger than
253 the corresponding packet (query) sent from client to master.
254 */
255 thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER;
256 /*
257 Skipping the setting of mysql->net.max_packet size to slave
258 max_allowed_packet since this is done during mysql_real_connect.
259 */
260 mysql->options.max_allowed_packet=
261 slave_max_allowed_packet+MAX_LOG_EVENT_HEADER;
262 DBUG_VOID_RETURN;
263 }
264
265 /*
266 Find out which replications threads are running
267
268 SYNOPSIS
269 init_thread_mask()
270 mask Return value here
271 mi master_info for slave
272 inverse If set, returns which threads are not running
273
274 IMPLEMENTATION
275 Get a bit mask for which threads are running so that we can later restart
276 these threads.
277
278 RETURN
279 mask If inverse == 0, running threads
280 If inverse == 1, stopped threads
281 */
282
init_thread_mask(int * mask,Master_info * mi,bool inverse)283 void init_thread_mask(int* mask, Master_info* mi, bool inverse)
284 {
285 bool set_io = mi->slave_running, set_sql = mi->rli->slave_running;
286 register int tmp_mask=0;
287 DBUG_ENTER("init_thread_mask");
288
289 if (set_io)
290 tmp_mask |= SLAVE_IO;
291 if (set_sql)
292 tmp_mask |= SLAVE_SQL;
293 if (inverse)
294 tmp_mask^= (SLAVE_IO | SLAVE_SQL);
295 *mask = tmp_mask;
296 DBUG_VOID_RETURN;
297 }
298
299
300 /*
301 lock_slave_threads()
302 */
303
lock_slave_threads(Master_info * mi)304 void lock_slave_threads(Master_info* mi)
305 {
306 DBUG_ENTER("lock_slave_threads");
307
308 //TODO: see if we can do this without dual mutex
309 mysql_mutex_lock(&mi->run_lock);
310 mysql_mutex_lock(&mi->rli->run_lock);
311 DBUG_VOID_RETURN;
312 }
313
314
315 /*
316 unlock_slave_threads()
317 */
318
unlock_slave_threads(Master_info * mi)319 void unlock_slave_threads(Master_info* mi)
320 {
321 DBUG_ENTER("unlock_slave_threads");
322
323 //TODO: see if we can do this without dual mutex
324 mysql_mutex_unlock(&mi->rli->run_lock);
325 mysql_mutex_unlock(&mi->run_lock);
326 DBUG_VOID_RETURN;
327 }
328
329 #ifdef HAVE_PSI_INTERFACE
330 static PSI_thread_key key_thread_slave_io, key_thread_slave_sql, key_thread_slave_worker;
331
332 static PSI_thread_info all_slave_threads[]=
333 {
334 { &key_thread_slave_io, "slave_io", PSI_FLAG_GLOBAL},
335 { &key_thread_slave_sql, "slave_sql", PSI_FLAG_GLOBAL},
336 { &key_thread_slave_worker, "slave_worker", PSI_FLAG_GLOBAL}
337 };
338
init_slave_psi_keys(void)339 static void init_slave_psi_keys(void)
340 {
341 const char* category= "sql";
342 int count;
343
344 count= array_elements(all_slave_threads);
345 mysql_thread_register(category, all_slave_threads, count);
346 }
347 #endif /* HAVE_PSI_INTERFACE */
348
349 /* Initialize slave structures */
350
init_slave()351 int init_slave()
352 {
353 DBUG_ENTER("init_slave");
354 int error= 0;
355 int thread_mask= SLAVE_SQL | SLAVE_IO;
356 Relay_log_info* rli= NULL;
357
358 #ifdef HAVE_PSI_INTERFACE
359 init_slave_psi_keys();
360 #endif
361
362 /*
363 This is called when mysqld starts. Before client connections are
364 accepted. However bootstrap may conflict with us if it does START SLAVE.
365 So it's safer to take the lock.
366 */
367 mysql_mutex_lock(&LOCK_active_mi);
368
369 if (pthread_key_create(&RPL_MASTER_INFO, NULL))
370 DBUG_RETURN(1);
371
372 if ((error= Rpl_info_factory::create_coordinators(opt_mi_repository_id, &active_mi,
373 opt_rli_repository_id, &rli)))
374 {
375 sql_print_error("Failed to create or recover replication info repository.");
376 error= 1;
377 goto err;
378 }
379
380 /*
381 This is the startup routine and as such we try to
382 configure both the SLAVE_SQL and SLAVE_IO.
383 */
384 if (global_init_info(active_mi, true, thread_mask))
385 {
386 sql_print_error("Failed to initialize the master info structure");
387 error= 1;
388 goto err;
389 }
390
391 DBUG_PRINT("info", ("init group master %s %lu group relay %s %lu event %s %lu\n",
392 rli->get_group_master_log_name(),
393 (ulong) rli->get_group_master_log_pos(),
394 rli->get_group_relay_log_name(),
395 (ulong) rli->get_group_relay_log_pos(),
396 rli->get_event_relay_log_name(),
397 (ulong) rli->get_event_relay_log_pos()));
398
399 /* If server id is not set, start_slave_thread() will say it */
400 if (active_mi->host[0] && !opt_skip_slave_start)
401 {
402 /* same as in start_slave() cache the global var values into rli's members */
403 active_mi->rli->opt_slave_parallel_workers= opt_mts_slave_parallel_workers;
404 active_mi->rli->checkpoint_group= opt_mts_checkpoint_group;
405 if (start_slave_threads(true/*need_lock_slave=true*/,
406 false/*wait_for_start=false*/,
407 active_mi,
408 thread_mask))
409 {
410 sql_print_error("Failed to create slave threads");
411 error= 1;
412 goto err;
413 }
414 }
415
416 err:
417 mysql_mutex_unlock(&LOCK_active_mi);
418 if (error)
419 sql_print_information("Check error log for additional messages. "
420 "You will not be able to start replication until "
421 "the issue is resolved and the server restarted.");
422 DBUG_RETURN(error);
423 }
424
425 /**
426 Parse the given relay log and identify the rotate event from the master.
427 Ignore the Format description event, Previous_gtid log event and ignorable
428 events within the relay log. When a rotate event is found check if it is a
429 rotate that is originated from the master or not based on the server_id. If
430 the rotate is from slave or if it is a fake rotate event ignore the event.
431 If any other events are encountered apart from the above events generate an
432 error. From the rotate event extract the master's binary log name and
433 position.
434
435 @param filename
436 Relay log name which needs to be parsed.
437
438 @param[OUT] master_log_file
439 Set the master_log_file to the log file name that is extracted from
440 rotate event. The master_log_file should contain string of len
441 FN_REFLEN.
442
443 @param[OUT] master_log_pos
444 Set the master_log_pos to the log position extracted from rotate
445 event.
446
447 @retval FOUND_ROTATE: When rotate event is found in the relay log
448 @retval NOT_FOUND_ROTATE: When rotate event is not found in the relay log
449 @retval ERROR: On error
450 */
451 enum enum_read_rotate_from_relay_log_status
452 { FOUND_ROTATE, NOT_FOUND_ROTATE, ERROR };
453
454 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)455 read_rotate_from_relay_log(char *filename, char *master_log_file,
456 my_off_t *master_log_pos)
457 {
458 DBUG_ENTER("read_rotate_from_relay_log");
459 /*
460 Create a Format_description_log_event that is used to read the
461 first event of the log.
462 */
463 Format_description_log_event fd_ev(BINLOG_VERSION), *fd_ev_p= &fd_ev;
464 DBUG_ASSERT(fd_ev.is_valid());
465 IO_CACHE log;
466 const char *errmsg= NULL;
467 File file= open_binlog_file(&log, filename, &errmsg);
468 if (file < 0)
469 {
470 sql_print_error("Error during --relay-log-recovery: %s", errmsg);
471 DBUG_RETURN(ERROR);
472 }
473 my_b_seek(&log, BIN_LOG_HEADER_SIZE);
474 Log_event *ev= NULL;
475 bool done= false;
476 enum_read_rotate_from_relay_log_status ret= NOT_FOUND_ROTATE;
477 while (!done &&
478 (ev= Log_event::read_log_event(&log, 0, fd_ev_p, opt_slave_sql_verify_checksum)) !=
479 NULL)
480 {
481 DBUG_PRINT("info", ("Read event of type %s", ev->get_type_str()));
482 switch (ev->get_type_code())
483 {
484 case FORMAT_DESCRIPTION_EVENT:
485 if (fd_ev_p != &fd_ev)
486 delete fd_ev_p;
487 fd_ev_p= (Format_description_log_event *)ev;
488 break;
489 case ROTATE_EVENT:
490 /*
491 Check for rotate event from the master. Ignore the ROTATE event if it
492 is a fake rotate event with server_id=0.
493 */
494 if (ev->server_id && ev->server_id != ::server_id)
495 {
496 Rotate_log_event *rotate_ev= (Rotate_log_event *)ev;
497 DBUG_ASSERT(FN_REFLEN >= rotate_ev->ident_len + 1);
498 memcpy(master_log_file, rotate_ev->new_log_ident, rotate_ev->ident_len + 1);
499 *master_log_pos= rotate_ev->pos;
500 ret= FOUND_ROTATE;
501 done= true;
502 }
503 break;
504 case PREVIOUS_GTIDS_LOG_EVENT:
505 break;
506 case IGNORABLE_LOG_EVENT:
507 break;
508 default:
509 sql_print_error("Error during --relay-log-recovery: Could not locate "
510 "rotate event from the master.");
511 ret= ERROR;
512 done= true;
513 break;
514 }
515 if (ev != fd_ev_p)
516 delete ev;
517 }
518 if (log.error < 0)
519 {
520 sql_print_error("Error during --relay-log-recovery: Error reading events from relay log: %d",
521 log.error);
522 DBUG_RETURN(ERROR);
523 }
524
525 if (fd_ev_p != &fd_ev)
526 {
527 delete fd_ev_p;
528 fd_ev_p= &fd_ev;
529 }
530
531 if (mysql_file_close(file, MYF(MY_WME)))
532 DBUG_RETURN(ERROR);
533 if (end_io_cache(&log))
534 {
535 sql_print_error("Error during --relay-log-recovery: Error while freeing "
536 "IO_CACHE object");
537 DBUG_RETURN(ERROR);
538 }
539 DBUG_RETURN(ret);
540 }
541
542 /**
543 Reads relay logs one by one starting from the first relay log. Looks for
544 the first rotate event from the master. If rotate is not found in the relay
545 log search continues to next relay log. If rotate event from master is
546 found then the extracted master_log_file and master_log_pos are used to set
547 rli->group_master_log_name and rli->group_master_log_pos. If an error has
548 occurred the error code is retuned back.
549
550 @param rli
551 Relay_log_info object to read relay log files and to set
552 group_master_log_name and group_master_log_pos.
553
554 @retval 0 On success
555 @retval 1 On failure
556 */
557 static int
find_first_relay_log_with_rotate_from_master(Relay_log_info * rli)558 find_first_relay_log_with_rotate_from_master(Relay_log_info* rli)
559 {
560 DBUG_ENTER("find_first_relay_log_with_rotate_from_master");
561 int error= 0;
562 LOG_INFO linfo;
563 bool got_rotate_from_master= false;
564 int pos;
565 char master_log_file[FN_REFLEN];
566 my_off_t master_log_pos= 0;
567
568 for (pos= rli->relay_log.find_log_pos(&linfo, NULL, true);
569 !pos;
570 pos= rli->relay_log.find_next_log(&linfo, true))
571 {
572 switch (read_rotate_from_relay_log(linfo.log_file_name, master_log_file,
573 &master_log_pos))
574 {
575 case ERROR:
576 error= 1;
577 break;
578 case FOUND_ROTATE:
579 got_rotate_from_master= true;
580 break;
581 case NOT_FOUND_ROTATE:
582 break;
583 }
584 if (error || got_rotate_from_master)
585 break;
586 }
587 if (pos== LOG_INFO_IO)
588 {
589 error= 1;
590 sql_print_error("Error during --relay-log-recovery: Could not read "
591 "relay log index file due to an IO error.");
592 goto err;
593 }
594 if (pos== LOG_INFO_EOF)
595 {
596 error= 1;
597 sql_print_error("Error during --relay-log-recovery: Could not locate "
598 "rotate event from master in relay log file.");
599 goto err;
600 }
601 if (!error && got_rotate_from_master)
602 {
603 rli->set_group_master_log_name(master_log_file);
604 rli->set_group_master_log_pos(master_log_pos);
605 }
606 err:
607 DBUG_RETURN(error);
608 }
609
610 /*
611 Updates the master info based on the information stored in the
612 relay info and ignores relay logs previously retrieved by the IO
613 thread, which thus starts fetching again based on to the
614 master_log_pos and master_log_name. Eventually, the old
615 relay logs will be purged by the normal purge mechanism.
616
617 When GTID's are enabled the "Retrieved GTID" set should be cleared
618 so that partial read events are discarded and they are
619 fetched once again
620
621 @param mi pointer to Master_info instance
622 */
recover_relay_log(Master_info * mi)623 static void recover_relay_log(Master_info *mi)
624 {
625 Relay_log_info *rli=mi->rli;
626 // Set Receiver Thread's positions as per the recovered Applier Thread.
627 mi->set_master_log_pos(max<ulonglong>(BIN_LOG_HEADER_SIZE,
628 rli->get_group_master_log_pos()));
629 mi->set_master_log_name(rli->get_group_master_log_name());
630
631 sql_print_warning("Recovery from master pos %ld and file %s. "
632 "Previous relay log pos and relay log file had "
633 "been set to %lld, %s respectively.",
634 (ulong) mi->get_master_log_pos(), mi->get_master_log_name(),
635 rli->get_group_relay_log_pos(), rli->get_group_relay_log_name());
636
637 // Start with a fresh relay log.
638 rli->set_group_relay_log_name(rli->relay_log.get_log_fname());
639 rli->set_event_relay_log_name(rli->relay_log.get_log_fname());
640 rli->set_group_relay_log_pos(BIN_LOG_HEADER_SIZE);
641 rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
642 /*
643 Clear the retrieved GTID set so that events that are written partially
644 will be fetched again.
645 */
646 if (gtid_mode == GTID_MODE_ON)
647 {
648 global_sid_lock->wrlock();
649 (const_cast<Gtid_set *>(rli->get_gtid_set()))->clear();
650 global_sid_lock->unlock();
651 }
652 }
653
654
655 /*
656 Updates the master info based on the information stored in the
657 relay info and ignores relay logs previously retrieved by the IO
658 thread, which thus starts fetching again based on to the
659 master_log_pos and master_log_name. Eventually, the old
660 relay logs will be purged by the normal purge mechanism.
661
662 There can be a special case where rli->group_master_log_name and
663 rli->group_master_log_pos are not intialized, as the sql thread was never
664 started at all. In those cases all the existing relay logs are parsed
665 starting from the first one and the initial rotate event that was received
666 from the master is identified. From the rotate event master_log_name and
667 master_log_pos are extracted and they are set to rli->group_master_log_name
668 and rli->group_master_log_pos.
669
670 In the feature, we should improve this routine in order to avoid throwing
671 away logs that are safely stored in the disk. Note also that this recovery
672 routine relies on the correctness of the relay-log.info and only tolerates
673 coordinate problems in master.info.
674
675 In this function, there is no need for a mutex as the caller
676 (i.e. init_slave) already has one acquired.
677
678 Specifically, the following structures are updated:
679
680 1 - mi->master_log_pos <-- rli->group_master_log_pos
681 2 - mi->master_log_name <-- rli->group_master_log_name
682 3 - It moves the relay log to the new relay log file, by
683 rli->group_relay_log_pos <-- BIN_LOG_HEADER_SIZE;
684 rli->event_relay_log_pos <-- BIN_LOG_HEADER_SIZE;
685 rli->group_relay_log_name <-- rli->relay_log.get_log_fname();
686 rli->event_relay_log_name <-- rli->relay_log.get_log_fname();
687
688 If there is an error, it returns (1), otherwise returns (0).
689 */
init_recovery(Master_info * mi,const char ** errmsg)690 int init_recovery(Master_info* mi, const char** errmsg)
691 {
692 DBUG_ENTER("init_recovery");
693
694 int error= 0;
695 Relay_log_info *rli= mi->rli;
696 char *group_master_log_name= NULL;
697
698 if (rli->recovery_parallel_workers)
699 {
700 /*
701 This is not idempotent and a crash after this function and before
702 the recovery is actually done may lead the system to an inconsistent
703 state.
704
705 This may happen because the gap is not persitent stored anywhere
706 and eventually old relay log files will be removed and further
707 calculations on the gaps will be impossible.
708
709 We need to improve this. /Alfranio.
710 */
711 error= mts_recovery_groups(rli);
712 if (rli->mts_recovery_group_cnt)
713 {
714 if (gtid_mode == GTID_MODE_ON)
715 {
716 rli->recovery_parallel_workers= 0;
717 rli->clear_mts_recovery_groups();
718 }
719 else
720 DBUG_RETURN(error);
721 }
722 }
723
724 group_master_log_name= const_cast<char *>(rli->get_group_master_log_name());
725 if (!error)
726 {
727 if (!group_master_log_name[0])
728 {
729 if (rli->replicate_same_server_id)
730 {
731 error= 1;
732 sql_print_error("Error during --relay-log-recovery: "
733 "replicate_same_server_id is in use and sql thread's "
734 "positions are not initialized, hence relay log "
735 "recovery cannot happen.");
736 DBUG_RETURN(error);
737 }
738 error= find_first_relay_log_with_rotate_from_master(rli);
739 if (error)
740 DBUG_RETURN(error);
741 }
742 recover_relay_log(mi);
743 }
744 DBUG_RETURN(error);
745 }
746
747 /*
748 Relay log recovery in the case of MTS, is handled by the following function.
749 Gaps in MTS execution are filled using implicit execution of
750 START SLAVE UNTIL SQL_AFTER_MTS_GAPS call. Once slave reaches a consistent
751 gapless state receiver thread's positions are initialized to applier thread's
752 positions and the old relay logs are discarded. This completes the recovery
753 process.
754
755 @param mi pointer to Master_info instance.
756
757 @retval 0 success
758 @retval 1 error
759 */
fill_mts_gaps_and_recover(Master_info * mi)760 static inline int fill_mts_gaps_and_recover(Master_info* mi)
761 {
762 DBUG_ENTER("fill_mts_gaps_and_recover");
763 Relay_log_info *rli= mi->rli;
764 int recovery_error= 0;
765 rli->is_relay_log_recovery= FALSE;
766 rli->until_condition= Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS;
767 rli->opt_slave_parallel_workers= rli->recovery_parallel_workers;
768 sql_print_information("MTS recovery: starting coordinator thread to fill MTS "
769 "gaps.");
770 recovery_error= start_slave_thread(
771 #ifdef HAVE_PSI_INTERFACE
772 key_thread_slave_sql,
773 #endif
774 handle_slave_sql, &rli->run_lock,
775 &rli->run_lock,
776 &rli->start_cond,
777 &rli->slave_running,
778 &rli->slave_run_id,
779 mi);
780
781 if (recovery_error)
782 {
783 sql_print_warning("MTS recovery: failed to start the coordinator "
784 "thread. Check the error log for additional"
785 " details.");
786 goto err;
787 }
788 mysql_mutex_lock(&rli->run_lock);
789 mysql_cond_wait(&rli->stop_cond, &rli->run_lock);
790 mysql_mutex_unlock(&rli->run_lock);
791 if (rli->until_condition != Relay_log_info::UNTIL_DONE)
792 {
793 sql_print_warning("MTS recovery: automatic recovery failed. Either the "
794 "slave server had stopped due to an error during an "
795 "earlier session or relay logs are corrupted."
796 "Fix the cause of the slave side error and restart the "
797 "slave server or consider using RESET SLAVE.");
798 goto err;
799 }
800
801 /*
802 We need a mutex while we are changing master info parameters to
803 keep other threads from reading bogus info
804 */
805 mysql_mutex_lock(&mi->data_lock);
806 mysql_mutex_lock(&rli->data_lock);
807 recover_relay_log(mi);
808
809 const char* msg;
810 if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
811 rli->get_group_relay_log_pos(),
812 false/*need_data_lock=false*/,
813 &msg, 0))
814 {
815 char llbuf[22];
816 sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s).",
817 rli->get_group_relay_log_name(),
818 llstr(rli->get_group_relay_log_pos(), llbuf));
819
820 recovery_error=1;
821 mysql_mutex_unlock(&mi->data_lock);
822 mysql_mutex_unlock(&rli->data_lock);
823 goto err;
824 }
825 if (mi->flush_info(true) || rli->flush_info(true))
826 {
827 recovery_error= 1;
828 mysql_mutex_unlock(&mi->data_lock);
829 mysql_mutex_unlock(&rli->data_lock);
830 goto err;
831 }
832 rli->inited=1;
833 rli->error_on_rli_init_info= false;
834 mysql_mutex_unlock(&mi->data_lock);
835 mysql_mutex_unlock(&rli->data_lock);
836 sql_print_information("MTS recovery: completed successfully.\n");
837 DBUG_RETURN(recovery_error);
838 err:
839 /*
840 If recovery failed means we failed to initialize rli object in the case
841 of MTS. We should not allow the START SLAVE command to work as we do in
842 the case of STS. i.e if init_recovery call fails then we set inited=0.
843 */
844 rli->end_info();
845 rli->inited=0;
846 rli->error_on_rli_init_info= true;
847 DBUG_RETURN(recovery_error);
848 }
849
global_init_info(Master_info * mi,bool ignore_if_no_info,int thread_mask)850 int global_init_info(Master_info* mi, bool ignore_if_no_info, int thread_mask)
851 {
852 DBUG_ENTER("init_info");
853 DBUG_ASSERT(mi != NULL && mi->rli != NULL);
854 int init_error= 0;
855 enum_return_check check_return= ERROR_CHECKING_REPOSITORY;
856 THD *thd= current_thd;
857
858 /*
859 We need a mutex while we are changing master info parameters to
860 keep other threads from reading bogus info
861 */
862 mysql_mutex_lock(&mi->data_lock);
863 mysql_mutex_lock(&mi->rli->data_lock);
864
865 /*
866 When info tables are used and autocommit= 0 we force a new
867 transaction start to avoid table access deadlocks when START SLAVE
868 is executed after RESET SLAVE.
869 */
870 if (is_autocommit_off_and_infotables(thd))
871 {
872 if (trans_begin(thd))
873 {
874 init_error= 1;
875 goto end;
876 }
877 }
878
879 /*
880 This takes care of the startup dependency between the master_info
881 and relay_info. It initializes the master info if the SLAVE_IO
882 thread is being started and the relay log info if either the
883 SLAVE_SQL thread is being started or was not initialized as it is
884 required by the SLAVE_IO thread.
885 */
886 check_return= mi->check_info();
887 if (check_return == ERROR_CHECKING_REPOSITORY)
888 {
889 init_error= 1;
890 goto end;
891 }
892
893 if (!(ignore_if_no_info && check_return == REPOSITORY_DOES_NOT_EXIST))
894 {
895 if ((thread_mask & SLAVE_IO) != 0 && mi->mi_init_info())
896 init_error= 1;
897 }
898
899 check_return= mi->rli->check_info();
900 if (check_return == ERROR_CHECKING_REPOSITORY)
901 {
902 init_error= 1;
903 goto end;
904 }
905 if (!(ignore_if_no_info && check_return == REPOSITORY_DOES_NOT_EXIST))
906 {
907 if (((thread_mask & SLAVE_SQL) != 0 || !(mi->rli->inited))
908 && mi->rli->rli_init_info())
909 init_error= 1;
910 }
911
912 DBUG_EXECUTE_IF("enable_mts_worker_failure_init",
913 {DBUG_SET("+d,mts_worker_thread_init_fails");});
914 end:
915 /*
916 When info tables are used and autocommit= 0 we force transaction
917 commit to avoid table access deadlocks when START SLAVE is executed
918 after RESET SLAVE.
919 */
920 if (is_autocommit_off_and_infotables(thd))
921 if (trans_commit(thd))
922 init_error= 1;
923
924 mysql_mutex_unlock(&mi->rli->data_lock);
925 mysql_mutex_unlock(&mi->data_lock);
926
927 /*
928 Handling MTS Relay-log recovery after successful initialization of mi and
929 rli objects.
930
931 MTS Relay-log recovery is handled by SSUG command. In order to start the
932 slave applier thread rli needs to be inited and mi->rli->data_lock should
933 be in released state. Hence we do the MTS recovery at this point of time
934 where both conditions are satisfied.
935 */
936 if (!init_error && mi->rli->is_relay_log_recovery
937 && mi->rli->mts_recovery_group_cnt)
938 init_error= fill_mts_gaps_and_recover(mi);
939 DBUG_RETURN(init_error);
940 }
941
end_info(Master_info * mi)942 void end_info(Master_info* mi)
943 {
944 DBUG_ENTER("end_info");
945 DBUG_ASSERT(mi != NULL && mi->rli != NULL);
946
947 /*
948 The previous implementation was not acquiring locks. We do the same here.
949 However, this is quite strange.
950 */
951 mi->end_info();
952 mi->rli->end_info();
953
954 DBUG_VOID_RETURN;
955 }
956
remove_info(Master_info * mi)957 int remove_info(Master_info* mi)
958 {
959 int error= 1;
960 DBUG_ENTER("remove_info");
961 DBUG_ASSERT(mi != NULL && mi->rli != NULL);
962
963 /*
964 The previous implementation was not acquiring locks.
965 We do the same here. However, this is quite strange.
966 */
967 /*
968 Reset errors (the idea is that we forget about the
969 old master).
970 */
971 mi->clear_error();
972 mi->rli->clear_error();
973 mi->rli->clear_until_condition();
974 mi->rli->clear_sql_delay();
975
976 mi->end_info();
977 mi->rli->end_info();
978
979 if (mi->remove_info() || Rpl_info_factory::reset_workers(mi->rli) ||
980 mi->rli->remove_info())
981 goto err;
982
983 error= 0;
984
985 err:
986 DBUG_RETURN(error);
987 }
988
flush_master_info(Master_info * mi,bool force)989 int flush_master_info(Master_info* mi, bool force)
990 {
991 DBUG_ENTER("flush_master_info");
992 DBUG_ASSERT(mi != NULL && mi->rli != NULL);
993 /*
994 The previous implementation was not acquiring locks.
995 We do the same here. However, this is quite strange.
996 */
997 /*
998 With the appropriate recovery process, we will not need to flush
999 the content of the current log.
1000
1001 For now, we flush the relay log BEFORE the master.info file, because
1002 if we crash, we will get a duplicate event in the relay log at restart.
1003 If we change the order, there might be missing events.
1004
1005 If we don't do this and the slave server dies when the relay log has
1006 some parts (its last kilobytes) in memory only, with, say, from master's
1007 position 100 to 150 in memory only (not on disk), and with position 150
1008 in master.info, there will be missing information. When the slave restarts,
1009 the I/O thread will fetch binlogs from 150, so in the relay log we will
1010 have "[0, 100] U [150, infinity[" and nobody will notice it, so the SQL
1011 thread will jump from 100 to 150, and replication will silently break.
1012 */
1013 mysql_mutex_t *log_lock= mi->rli->relay_log.get_log_lock();
1014
1015 mysql_mutex_lock(log_lock);
1016
1017 int err= (mi->rli->flush_current_log() ||
1018 mi->flush_info(force));
1019
1020 mysql_mutex_unlock(log_lock);
1021
1022 DBUG_RETURN (err);
1023 }
1024
1025 /**
1026 Convert slave skip errors bitmap into a printable string.
1027 */
1028
print_slave_skip_errors(void)1029 static void print_slave_skip_errors(void)
1030 {
1031 /*
1032 To be safe, we want 10 characters of room in the buffer for a number
1033 plus terminators. Also, we need some space for constant strings.
1034 10 characters must be sufficient for a number plus {',' | '...'}
1035 plus a NUL terminator. That is a max 6 digit number.
1036 */
1037 const size_t MIN_ROOM= 10;
1038 DBUG_ENTER("print_slave_skip_errors");
1039 DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
1040 DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
1041
1042 if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
1043 {
1044 /* purecov: begin tested */
1045 memcpy(slave_skip_error_names, STRING_WITH_LEN("OFF"));
1046 /* purecov: end */
1047 }
1048 else if (bitmap_is_set_all(&slave_error_mask))
1049 {
1050 /* purecov: begin tested */
1051 memcpy(slave_skip_error_names, STRING_WITH_LEN("ALL"));
1052 /* purecov: end */
1053 }
1054 else
1055 {
1056 char *buff= slave_skip_error_names;
1057 char *bend= buff + sizeof(slave_skip_error_names);
1058 int errnum;
1059
1060 for (errnum= 0; errnum < MAX_SLAVE_ERROR; errnum++)
1061 {
1062 if (bitmap_is_set(&slave_error_mask, errnum))
1063 {
1064 if (buff + MIN_ROOM >= bend)
1065 break; /* purecov: tested */
1066 buff= int10_to_str(errnum, buff, 10);
1067 *buff++= ',';
1068 }
1069 }
1070 if (buff != slave_skip_error_names)
1071 buff--; // Remove last ','
1072 if (errnum < MAX_SLAVE_ERROR)
1073 {
1074 /* Couldn't show all errors */
1075 buff= strmov(buff, "..."); /* purecov: tested */
1076 }
1077 *buff=0;
1078 }
1079 DBUG_PRINT("init", ("error_names: '%s'", slave_skip_error_names));
1080 DBUG_VOID_RETURN;
1081 }
1082
set_stop_slave_wait_timeout(unsigned long wait_timeout)1083 static void set_stop_slave_wait_timeout(unsigned long wait_timeout) {
1084 stop_wait_timeout = wait_timeout;
1085 }
1086
1087 /**
1088 Change arg to the string with the nice, human-readable skip error values.
1089 @param slave_skip_errors_ptr
1090 The pointer to be changed
1091 */
set_slave_skip_errors(char ** slave_skip_errors_ptr)1092 void set_slave_skip_errors(char** slave_skip_errors_ptr)
1093 {
1094 DBUG_ENTER("set_slave_skip_errors");
1095 print_slave_skip_errors();
1096 *slave_skip_errors_ptr= slave_skip_error_names;
1097 DBUG_VOID_RETURN;
1098 }
1099
1100 /**
1101 Init function to set up array for errors that should be skipped for slave
1102 */
init_slave_skip_errors()1103 static void init_slave_skip_errors()
1104 {
1105 DBUG_ENTER("init_slave_skip_errors");
1106 DBUG_ASSERT(!use_slave_mask); // not already initialized
1107
1108 if (bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0))
1109 {
1110 fprintf(stderr, "Badly out of memory, please check your system status\n");
1111 exit(1);
1112 }
1113 use_slave_mask = 1;
1114 DBUG_VOID_RETURN;
1115 }
1116
add_slave_skip_errors(const uint * errors,uint n_errors)1117 static void add_slave_skip_errors(const uint* errors, uint n_errors)
1118 {
1119 DBUG_ENTER("add_slave_skip_errors");
1120 DBUG_ASSERT(errors);
1121 DBUG_ASSERT(use_slave_mask);
1122
1123 for (uint i = 0; i < n_errors; i++)
1124 {
1125 const uint err_code = errors[i];
1126 if (err_code < MAX_SLAVE_ERROR)
1127 bitmap_set_bit(&slave_error_mask, err_code);
1128 }
1129 DBUG_VOID_RETURN;
1130 }
1131
1132 /*
1133 Add errors that should be skipped for slave
1134
1135 SYNOPSIS
1136 add_slave_skip_errors()
1137 arg List of errors numbers to be added to skip, separated with ','
1138
1139 NOTES
1140 Called from get_options() in mysqld.cc on start-up
1141 */
1142
add_slave_skip_errors(const char * arg)1143 void add_slave_skip_errors(const char* arg)
1144 {
1145 const char *p= NULL;
1146 /*
1147 ALL is only valid when nothing else is provided.
1148 */
1149 const uchar SKIP_ALL[]= "all";
1150 size_t SIZE_SKIP_ALL= strlen((const char *) SKIP_ALL) + 1;
1151 /*
1152 IGNORE_DDL_ERRORS can be combined with other parameters
1153 but must be the first one provided.
1154 */
1155 const uchar SKIP_DDL_ERRORS[]= "ddl_exist_errors";
1156 size_t SIZE_SKIP_DDL_ERRORS= strlen((const char *) SKIP_DDL_ERRORS);
1157 DBUG_ENTER("add_slave_skip_errors");
1158
1159 // initialize mask if not done yet
1160 if (!use_slave_mask)
1161 init_slave_skip_errors();
1162
1163 for (; my_isspace(system_charset_info,*arg); ++arg)
1164 /* empty */;
1165 if (!my_strnncoll(system_charset_info, (uchar*)arg, SIZE_SKIP_ALL,
1166 SKIP_ALL, SIZE_SKIP_ALL))
1167 {
1168 bitmap_set_all(&slave_error_mask);
1169 DBUG_VOID_RETURN;
1170 }
1171 if (!my_strnncoll(system_charset_info, (uchar*)arg, SIZE_SKIP_DDL_ERRORS,
1172 SKIP_DDL_ERRORS, SIZE_SKIP_DDL_ERRORS))
1173 {
1174 // DDL errors to be skipped for relaxed 'exist' handling
1175 const uint ddl_errors[] = {
1176 // error codes with create/add <schema object>
1177 ER_DB_CREATE_EXISTS, ER_TABLE_EXISTS_ERROR, ER_DUP_KEYNAME,
1178 ER_MULTIPLE_PRI_KEY,
1179 // error codes with change/rename <schema object>
1180 ER_BAD_FIELD_ERROR, ER_NO_SUCH_TABLE, ER_DUP_FIELDNAME,
1181 // error codes with drop <schema object>
1182 ER_DB_DROP_EXISTS, ER_BAD_TABLE_ERROR, ER_CANT_DROP_FIELD_OR_KEY
1183 };
1184
1185 add_slave_skip_errors(ddl_errors,
1186 sizeof(ddl_errors)/sizeof(ddl_errors[0]));
1187 /*
1188 After processing the SKIP_DDL_ERRORS, the pointer is
1189 increased to the position after the comma.
1190 */
1191 if (strlen(arg) > SIZE_SKIP_DDL_ERRORS + 1)
1192 arg+= SIZE_SKIP_DDL_ERRORS + 1;
1193 }
1194 for (p= arg ; *p; )
1195 {
1196 long err_code;
1197 if (!(p= str2int(p, 10, 0, LONG_MAX, &err_code)))
1198 break;
1199 if (err_code < MAX_SLAVE_ERROR)
1200 bitmap_set_bit(&slave_error_mask,(uint)err_code);
1201 while (!my_isdigit(system_charset_info,*p) && *p)
1202 p++;
1203 }
1204 DBUG_VOID_RETURN;
1205 }
1206
set_thd_in_use_temporary_tables(Relay_log_info * rli)1207 static void set_thd_in_use_temporary_tables(Relay_log_info *rli)
1208 {
1209 TABLE *table;
1210
1211 for (table= rli->save_temporary_tables ; table ; table= table->next)
1212 {
1213 table->in_use= rli->info_thd;
1214 if (table->file != NULL)
1215 {
1216 /*
1217 Since we are stealing opened temporary tables from one thread to another,
1218 we need to let the performance schema know that,
1219 for aggregates per thread to work properly.
1220 */
1221 table->file->unbind_psi();
1222 table->file->rebind_psi();
1223 }
1224 }
1225 }
1226
terminate_slave_threads(Master_info * mi,int thread_mask,bool need_lock_term)1227 int terminate_slave_threads(Master_info* mi,int thread_mask,bool need_lock_term)
1228 {
1229 DBUG_ENTER("terminate_slave_threads");
1230
1231 if (!mi->inited)
1232 DBUG_RETURN(0); /* successfully do nothing */
1233 int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
1234 mysql_mutex_t *sql_lock = &mi->rli->run_lock, *io_lock = &mi->run_lock;
1235 mysql_mutex_t *log_lock= mi->rli->relay_log.get_log_lock();
1236 set_stop_slave_wait_timeout(rpl_stop_slave_timeout);
1237
1238 if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
1239 {
1240 DBUG_PRINT("info",("Terminating SQL thread"));
1241 mi->rli->abort_slave= 1;
1242 if ((error=terminate_slave_thread(mi->rli->info_thd, sql_lock,
1243 &mi->rli->stop_cond,
1244 &mi->rli->slave_running,
1245 need_lock_term)) &&
1246 !force_all)
1247 {
1248 if (error == 1)
1249 {
1250 DBUG_RETURN(ER_STOP_SLAVE_SQL_THREAD_TIMEOUT);
1251 }
1252 DBUG_RETURN(error);
1253 }
1254 mysql_mutex_lock(log_lock);
1255
1256 DBUG_PRINT("info",("Flushing relay-log info file."));
1257 if (current_thd)
1258 THD_STAGE_INFO(current_thd, stage_flushing_relay_log_info_file);
1259
1260 /*
1261 Flushes the relay log info regardles of the sync_relay_log_info option.
1262 */
1263 if (mi->rli->flush_info(TRUE))
1264 {
1265 mysql_mutex_unlock(log_lock);
1266 DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1267 }
1268
1269 mysql_mutex_unlock(log_lock);
1270 }
1271 if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
1272 {
1273 DBUG_PRINT("info",("Terminating IO thread"));
1274 mi->abort_slave=1;
1275 if ((error=terminate_slave_thread(mi->info_thd,io_lock,
1276 &mi->stop_cond,
1277 &mi->slave_running,
1278 need_lock_term)) &&
1279 !force_all)
1280 {
1281 if (error == 1)
1282 {
1283 DBUG_RETURN(ER_STOP_SLAVE_IO_THREAD_TIMEOUT);
1284 }
1285 DBUG_RETURN(error);
1286 }
1287 mysql_mutex_lock(log_lock);
1288
1289 DBUG_PRINT("info",("Flushing relay log and master info repository."));
1290 if (current_thd)
1291 THD_STAGE_INFO(current_thd, stage_flushing_relay_log_and_master_info_repository);
1292
1293 /*
1294 Flushes the master info regardles of the sync_master_info option.
1295 */
1296 if (mi->flush_info(TRUE))
1297 {
1298 mysql_mutex_unlock(log_lock);
1299 DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1300 }
1301
1302 /*
1303 Flushes the relay log regardles of the sync_relay_log option.
1304 */
1305 if (mi->rli->relay_log.is_open() &&
1306 mi->rli->relay_log.flush_and_sync(true))
1307 {
1308 mysql_mutex_unlock(log_lock);
1309 DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
1310 }
1311
1312 mysql_mutex_unlock(log_lock);
1313 }
1314 DBUG_RETURN(0);
1315 }
1316
1317
1318 /**
1319 Wait for a slave thread to terminate.
1320
1321 This function is called after requesting the thread to terminate
1322 (by setting @c abort_slave member of @c Relay_log_info or @c
1323 Master_info structure to 1). Termination of the thread is
1324 controlled with the the predicate <code>*slave_running</code>.
1325
1326 Function will acquire @c term_lock before waiting on the condition
1327 unless @c need_lock_term is false in which case the mutex should be
1328 owned by the caller of this function and will remain acquired after
1329 return from the function.
1330
1331 @param term_lock
1332 Associated lock to use when waiting for @c term_cond
1333
1334 @param term_cond
1335 Condition that is signalled when the thread has terminated
1336
1337 @param slave_running
1338 Pointer to predicate to check for slave thread termination
1339
1340 @param need_lock_term
1341 If @c false the lock will not be acquired before waiting on
1342 the condition. In this case, it is assumed that the calling
1343 function acquires the lock before calling this function.
1344
1345 @retval 0 All OK, 1 on "STOP SLAVE" command timeout, ER_SLAVE_NOT_RUNNING otherwise.
1346
1347 @note If the executing thread has to acquire term_lock
1348 (need_lock_term is true, the negative running status does not
1349 represent any issue therefore no error is reported.
1350
1351 */
1352 static int
terminate_slave_thread(THD * thd,mysql_mutex_t * term_lock,mysql_cond_t * term_cond,volatile uint * slave_running,bool need_lock_term)1353 terminate_slave_thread(THD *thd,
1354 mysql_mutex_t *term_lock,
1355 mysql_cond_t *term_cond,
1356 volatile uint *slave_running,
1357 bool need_lock_term)
1358 {
1359 DBUG_ENTER("terminate_slave_thread");
1360 if (need_lock_term)
1361 {
1362 mysql_mutex_lock(term_lock);
1363 }
1364 else
1365 {
1366 mysql_mutex_assert_owner(term_lock);
1367 }
1368 if (!*slave_running)
1369 {
1370 if (need_lock_term)
1371 {
1372 /*
1373 if run_lock (term_lock) is acquired locally then either
1374 slave_running status is fine
1375 */
1376 mysql_mutex_unlock(term_lock);
1377 DBUG_RETURN(0);
1378 }
1379 else
1380 {
1381 DBUG_RETURN(ER_SLAVE_NOT_RUNNING);
1382 }
1383 }
1384 DBUG_ASSERT(thd != 0);
1385 THD_CHECK_SENTRY(thd);
1386
1387 /*
1388 Is is critical to test if the slave is running. Otherwise, we might
1389 be referening freed memory trying to kick it
1390 */
1391
1392 while (*slave_running) // Should always be true
1393 {
1394 int error MY_ATTRIBUTE((unused));
1395 DBUG_PRINT("loop", ("killing slave thread"));
1396
1397 mysql_mutex_lock(&thd->LOCK_thd_data);
1398 #ifndef DONT_USE_THR_ALARM
1399 /*
1400 Error codes from pthread_kill are:
1401 EINVAL: invalid signal number (can't happen)
1402 ESRCH: thread already killed (can happen, should be ignored)
1403 */
1404 int err MY_ATTRIBUTE((unused))= pthread_kill(thd->real_id, thr_client_alarm);
1405 DBUG_ASSERT(err != EINVAL);
1406 #endif
1407 thd->awake(THD::NOT_KILLED);
1408 mysql_mutex_unlock(&thd->LOCK_thd_data);
1409
1410 /*
1411 There is a small chance that slave thread might miss the first
1412 alarm. To protect againts it, resend the signal until it reacts
1413 */
1414 struct timespec abstime;
1415 set_timespec(abstime,2);
1416 error= mysql_cond_timedwait(term_cond, term_lock, &abstime);
1417 if (stop_wait_timeout >= 2)
1418 stop_wait_timeout= stop_wait_timeout - 2;
1419 else if (*slave_running)
1420 {
1421 if (need_lock_term)
1422 mysql_mutex_unlock(term_lock);
1423 DBUG_RETURN (1);
1424 }
1425 DBUG_ASSERT(error == ETIMEDOUT || error == 0);
1426 }
1427
1428 DBUG_ASSERT(*slave_running == 0);
1429
1430 if (need_lock_term)
1431 mysql_mutex_unlock(term_lock);
1432 DBUG_RETURN(0);
1433 }
1434
1435
start_slave_thread(PSI_thread_key thread_key,pthread_handler 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)1436 int start_slave_thread(
1437 #ifdef HAVE_PSI_INTERFACE
1438 PSI_thread_key thread_key,
1439 #endif
1440 pthread_handler h_func, mysql_mutex_t *start_lock,
1441 mysql_mutex_t *cond_lock,
1442 mysql_cond_t *start_cond,
1443 volatile uint *slave_running,
1444 volatile ulong *slave_run_id,
1445 Master_info* mi)
1446 {
1447 pthread_t th;
1448 ulong start_id;
1449 int error;
1450 DBUG_ENTER("start_slave_thread");
1451
1452 if (start_lock)
1453 mysql_mutex_lock(start_lock);
1454 if (!server_id)
1455 {
1456 if (start_cond)
1457 mysql_cond_broadcast(start_cond);
1458 if (start_lock)
1459 mysql_mutex_unlock(start_lock);
1460 sql_print_error("Server id not set, will not start slave");
1461 DBUG_RETURN(ER_BAD_SLAVE);
1462 }
1463
1464 if (*slave_running)
1465 {
1466 if (start_cond)
1467 mysql_cond_broadcast(start_cond);
1468 if (start_lock)
1469 mysql_mutex_unlock(start_lock);
1470 DBUG_RETURN(ER_SLAVE_MUST_STOP);
1471 }
1472 start_id= *slave_run_id;
1473 DBUG_PRINT("info",("Creating new slave thread"));
1474 if ((error= mysql_thread_create(thread_key,
1475 &th, &connection_attrib, h_func, (void*)mi)))
1476 {
1477 sql_print_error("Can't create slave thread (errno= %d).", error);
1478 if (start_lock)
1479 mysql_mutex_unlock(start_lock);
1480 DBUG_RETURN(ER_SLAVE_THREAD);
1481 }
1482 if (start_cond && cond_lock) // caller has cond_lock
1483 {
1484 THD* thd = current_thd;
1485 while (start_id == *slave_run_id && thd != NULL)
1486 {
1487 DBUG_PRINT("sleep",("Waiting for slave thread to start"));
1488 PSI_stage_info saved_stage= {0, "", 0};
1489 thd->ENTER_COND(start_cond, cond_lock,
1490 & stage_waiting_for_slave_thread_to_start,
1491 & saved_stage);
1492 /*
1493 It is not sufficient to test this at loop bottom. We must test
1494 it after registering the mutex in enter_cond(). If the kill
1495 happens after testing of thd->killed and before the mutex is
1496 registered, we could otherwise go waiting though thd->killed is
1497 set.
1498 */
1499 if (!thd->killed)
1500 mysql_cond_wait(start_cond, cond_lock);
1501 thd->EXIT_COND(& saved_stage);
1502 mysql_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
1503 if (thd->killed)
1504 {
1505 if (start_lock)
1506 mysql_mutex_unlock(start_lock);
1507 DBUG_RETURN(thd->killed_errno());
1508 }
1509 }
1510 }
1511 if (start_lock)
1512 mysql_mutex_unlock(start_lock);
1513 DBUG_RETURN(0);
1514 }
1515
1516
1517 /*
1518 start_slave_threads()
1519
1520 NOTES
1521 SLAVE_FORCE_ALL is not implemented here on purpose since it does not make
1522 sense to do that for starting a slave--we always care if it actually
1523 started the threads that were not previously running
1524 */
1525
start_slave_threads(bool need_lock_slave,bool wait_for_start,Master_info * mi,int thread_mask)1526 int start_slave_threads(bool need_lock_slave, bool wait_for_start,
1527 Master_info* mi, int thread_mask)
1528 {
1529 mysql_mutex_t *lock_io=0, *lock_sql=0, *lock_cond_io=0, *lock_cond_sql=0;
1530 mysql_cond_t* cond_io=0, *cond_sql=0;
1531 int error=0;
1532 DBUG_ENTER("start_slave_threads");
1533 DBUG_EXECUTE_IF("uninitialized_master-info_structure",
1534 mi->inited= FALSE;);
1535
1536 if (!mi->inited || !mi->rli->inited)
1537 {
1538 error= !mi->inited ? ER_SLAVE_MI_INIT_REPOSITORY :
1539 ER_SLAVE_RLI_INIT_REPOSITORY;
1540 Rpl_info *info= (!mi->inited ? mi : static_cast<Rpl_info *>(mi->rli));
1541 const char* prefix= current_thd ? ER(error) : ER_DEFAULT(error);
1542 info->report(ERROR_LEVEL, error, prefix, NULL);
1543
1544 DBUG_RETURN(error);
1545 }
1546
1547 if (need_lock_slave)
1548 {
1549 lock_io = &mi->run_lock;
1550 lock_sql = &mi->rli->run_lock;
1551 }
1552 if (wait_for_start)
1553 {
1554 cond_io = &mi->start_cond;
1555 cond_sql = &mi->rli->start_cond;
1556 lock_cond_io = &mi->run_lock;
1557 lock_cond_sql = &mi->rli->run_lock;
1558 }
1559
1560 if (thread_mask & SLAVE_IO)
1561 error= start_slave_thread(
1562 #ifdef HAVE_PSI_INTERFACE
1563 key_thread_slave_io,
1564 #endif
1565 handle_slave_io, lock_io, lock_cond_io,
1566 cond_io,
1567 &mi->slave_running, &mi->slave_run_id,
1568 mi);
1569 if (!error && (thread_mask & SLAVE_SQL))
1570 {
1571 /*
1572 MTS-recovery gaps gathering is placed onto common execution path
1573 for either START-SLAVE and --skip-start-slave= 0
1574 */
1575 if (mi->rli->recovery_parallel_workers != 0)
1576 error= mts_recovery_groups(mi->rli);
1577 if (!error)
1578 error= start_slave_thread(
1579 #ifdef HAVE_PSI_INTERFACE
1580 key_thread_slave_sql,
1581 #endif
1582 handle_slave_sql, lock_sql, lock_cond_sql,
1583 cond_sql,
1584 &mi->rli->slave_running, &mi->rli->slave_run_id,
1585 mi);
1586 if (error)
1587 terminate_slave_threads(mi, thread_mask & SLAVE_IO, need_lock_slave);
1588 }
1589 DBUG_RETURN(error);
1590 }
1591
1592 /*
1593 Release slave threads at time of executing shutdown.
1594
1595 SYNOPSIS
1596 end_slave()
1597 */
1598
end_slave()1599 void end_slave()
1600 {
1601 DBUG_ENTER("end_slave");
1602
1603 /*
1604 This is called when the server terminates, in close_connections().
1605 It terminates slave threads. However, some CHANGE MASTER etc may still be
1606 running presently. If a START SLAVE was in progress, the mutex lock below
1607 will make us wait until slave threads have started, and START SLAVE
1608 returns, then we terminate them here.
1609 */
1610 mysql_mutex_lock(&LOCK_active_mi);
1611 if (active_mi)
1612 {
1613 /*
1614 TODO: replace the line below with
1615 list_walk(&master_list, (list_walk_action)end_slave_on_walk,0);
1616 once multi-master code is ready.
1617 */
1618 terminate_slave_threads(active_mi,SLAVE_FORCE_ALL);
1619 }
1620 mysql_mutex_unlock(&LOCK_active_mi);
1621 DBUG_VOID_RETURN;
1622 }
1623
1624 /**
1625 Free all resources used by slave threads at time of executing shutdown.
1626 The routine must be called after all possible users of @c active_mi
1627 have left.
1628
1629 SYNOPSIS
1630 close_active_mi()
1631
1632 */
close_active_mi()1633 void close_active_mi()
1634 {
1635 mysql_mutex_lock(&LOCK_active_mi);
1636 if (active_mi)
1637 {
1638 end_info(active_mi);
1639 if (active_mi->rli)
1640 delete active_mi->rli;
1641 delete active_mi;
1642 active_mi= 0;
1643 }
1644 mysql_mutex_unlock(&LOCK_active_mi);
1645 }
1646
1647 /**
1648 Check if multi-statement transaction mode and master and slave info
1649 repositories are set to table.
1650
1651 @param THD THD object
1652
1653 @retval true Success
1654 @retval false Failure
1655 */
is_autocommit_off_and_infotables(THD * thd)1656 static bool is_autocommit_off_and_infotables(THD* thd)
1657 {
1658 DBUG_ENTER("is_autocommit_off_and_infotables");
1659 DBUG_RETURN((thd && thd->in_multi_stmt_transaction_mode() &&
1660 (opt_mi_repository_id == INFO_REPOSITORY_TABLE ||
1661 opt_rli_repository_id == INFO_REPOSITORY_TABLE))?
1662 true : false);
1663 }
1664
io_slave_killed(THD * thd,Master_info * mi)1665 static bool io_slave_killed(THD* thd, Master_info* mi)
1666 {
1667 DBUG_ENTER("io_slave_killed");
1668
1669 DBUG_ASSERT(mi->info_thd == thd);
1670 DBUG_ASSERT(mi->slave_running); // tracking buffer overrun
1671 DBUG_RETURN(mi->abort_slave || abort_loop || thd->killed);
1672 }
1673
1674 /**
1675 The function analyzes a possible killed status and makes
1676 a decision whether to accept it or not.
1677 Normally upon accepting the sql thread goes to shutdown.
1678 In the event of deferring decision @rli->last_event_start_time waiting
1679 timer is set to force the killed status be accepted upon its expiration.
1680
1681 Notice Multi-Threaded-Slave behaves similarly in that when it's being
1682 stopped and the current group of assigned events has not yet scheduled
1683 completely, Coordinator defers to accept to leave its read-distribute
1684 state. The above timeout ensures waiting won't last endlessly, and in
1685 such case an error is reported.
1686
1687 @param thd pointer to a THD instance
1688 @param rli pointer to Relay_log_info instance
1689
1690 @return TRUE the killed status is recognized, FALSE a possible killed
1691 status is deferred.
1692 */
sql_slave_killed(THD * thd,Relay_log_info * rli)1693 static bool sql_slave_killed(THD* thd, Relay_log_info* rli)
1694 {
1695 bool is_parallel_warn= FALSE;
1696
1697 DBUG_ENTER("sql_slave_killed");
1698
1699 DBUG_ASSERT(rli->info_thd == thd);
1700 DBUG_ASSERT(rli->slave_running == 1);
1701 if (rli->sql_thread_kill_accepted)
1702 DBUG_RETURN(true);
1703 DBUG_EXECUTE_IF("stop_when_mts_in_group", rli->abort_slave = 1;
1704 DBUG_SET("-d,stop_when_mts_in_group");
1705 DBUG_SET("-d,simulate_stop_when_mts_in_group");
1706 DBUG_RETURN(false););
1707 if (abort_loop || thd->killed || rli->abort_slave)
1708 {
1709 rli->sql_thread_kill_accepted= true;
1710 is_parallel_warn= (rli->is_parallel_exec() &&
1711 (rli->is_mts_in_group() || thd->killed));
1712 /*
1713 Slave can execute stop being in one of two MTS or Single-Threaded mode.
1714 The modes define different criteria to accept the stop.
1715 In particular that relates to the concept of groupping.
1716 Killed Coordinator thread expects the worst so it warns on
1717 possible consistency issue.
1718 */
1719 if (is_parallel_warn ||
1720 (!rli->is_parallel_exec() &&
1721 thd->transaction.all.cannot_safely_rollback() && rli->is_in_group()))
1722 {
1723 char msg_stopped[]=
1724 "... Slave SQL Thread stopped with incomplete event group "
1725 "having non-transactional changes. "
1726 "If the group consists solely of row-based events, you can try "
1727 "to restart the slave with --slave-exec-mode=IDEMPOTENT, which "
1728 "ignores duplicate key, key not found, and similar errors (see "
1729 "documentation for details).";
1730 char msg_stopped_mts[]=
1731 "... The slave coordinator and worker threads are stopped, possibly "
1732 "leaving data in inconsistent state. A restart should "
1733 "restore consistency automatically, although using non-transactional "
1734 "storage for data or info tables or DDL queries could lead to problems. "
1735 "In such cases you have to examine your data (see documentation for "
1736 "details).";
1737
1738 if (rli->abort_slave)
1739 {
1740 DBUG_PRINT("info", ("Request to stop slave SQL Thread received while "
1741 "applying an MTS group or a group that "
1742 "has non-transactional "
1743 "changes; waiting for completion of the group ... "));
1744
1745 /*
1746 Slave sql thread shutdown in face of unfinished group modified
1747 Non-trans table is handled via a timer. The slave may eventually
1748 give out to complete the current group and in that case there
1749 might be issues at consequent slave restart, see the error message.
1750 WL#2975 offers a robust solution requiring to store the last exectuted
1751 event's coordinates along with the group's coordianates
1752 instead of waiting with @c last_event_start_time the timer.
1753 */
1754
1755 if (rli->last_event_start_time == 0)
1756 rli->last_event_start_time= my_time(0);
1757 rli->sql_thread_kill_accepted= difftime(my_time(0),
1758 rli->last_event_start_time) <=
1759 SLAVE_WAIT_GROUP_DONE ?
1760 FALSE : TRUE;
1761
1762 DBUG_EXECUTE_IF("stop_slave_middle_group",
1763 DBUG_EXECUTE_IF("incomplete_group_in_relay_log",
1764 rli->sql_thread_kill_accepted= TRUE;);); // time is over
1765
1766 if (!rli->sql_thread_kill_accepted && !rli->reported_unsafe_warning)
1767 {
1768 rli->report(WARNING_LEVEL, 0,
1769 !is_parallel_warn ?
1770 "Request to stop slave SQL Thread received while "
1771 "applying a group that has non-transactional "
1772 "changes; waiting for completion of the group ... "
1773 :
1774 "Coordinator thread of multi-threaded slave is being "
1775 "stopped in the middle of assigning a group of events; "
1776 "deferring to exit until the group completion ... ");
1777 rli->reported_unsafe_warning= true;
1778 }
1779 }
1780 if (rli->sql_thread_kill_accepted)
1781 {
1782 rli->last_event_start_time= 0;
1783 if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
1784 {
1785 rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
1786 }
1787 if (is_parallel_warn)
1788 rli->report(!rli->is_error() ? ERROR_LEVEL :
1789 WARNING_LEVEL, // an error was reported by Worker
1790 ER_MTS_INCONSISTENT_DATA,
1791 ER(ER_MTS_INCONSISTENT_DATA),
1792 msg_stopped_mts);
1793 else
1794 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
1795 ER(ER_SLAVE_FATAL_ERROR), msg_stopped);
1796 }
1797 }
1798 }
1799 DBUG_RETURN(rli->sql_thread_kill_accepted);
1800 }
1801
1802
1803 /*
1804 skip_load_data_infile()
1805
1806 NOTES
1807 This is used to tell a 3.23 master to break send_file()
1808 */
1809
skip_load_data_infile(NET * net)1810 void skip_load_data_infile(NET *net)
1811 {
1812 DBUG_ENTER("skip_load_data_infile");
1813
1814 (void)net_request_file(net, "/dev/null");
1815 (void)my_net_read(net); // discard response
1816 (void)net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0); // ok
1817 DBUG_VOID_RETURN;
1818 }
1819
1820
net_request_file(NET * net,const char * fname)1821 bool net_request_file(NET* net, const char* fname)
1822 {
1823 DBUG_ENTER("net_request_file");
1824 DBUG_RETURN(net_write_command(net, 251, (uchar*) fname, strlen(fname),
1825 (uchar*) "", 0));
1826 }
1827
1828 /*
1829 From other comments and tests in code, it looks like
1830 sometimes Query_log_event and Load_log_event can have db == 0
1831 (see rewrite_db() above for example)
1832 (cases where this happens are unclear; it may be when the master is 3.23).
1833 */
1834
print_slave_db_safe(const char * db)1835 const char *print_slave_db_safe(const char* db)
1836 {
1837 DBUG_ENTER("*print_slave_db_safe");
1838
1839 DBUG_RETURN((db ? db : ""));
1840 }
1841
1842 /*
1843 Check if the error is caused by network.
1844 @param[in] errorno Number of the error.
1845 RETURNS:
1846 TRUE network error
1847 FALSE not network error
1848 */
1849
is_network_error(uint errorno)1850 bool is_network_error(uint errorno)
1851 {
1852 if (errorno == CR_CONNECTION_ERROR ||
1853 errorno == CR_CONN_HOST_ERROR ||
1854 errorno == CR_SERVER_GONE_ERROR ||
1855 errorno == CR_SERVER_LOST ||
1856 errorno == ER_CON_COUNT_ERROR ||
1857 errorno == ER_SERVER_SHUTDOWN)
1858 return TRUE;
1859
1860 return FALSE;
1861 }
1862
1863
1864 /**
1865 Execute an initialization query for the IO thread.
1866
1867 If there is an error, then this function calls mysql_free_result;
1868 otherwise the MYSQL object holds the result after this call. If
1869 there is an error other than allowed_error, then this function
1870 prints a message and returns -1.
1871
1872 @param mysql MYSQL object.
1873 @param query Query string.
1874 @param allowed_error Allowed error code, or 0 if no errors are allowed.
1875 @param[out] master_res If this is not NULL and there is no error, then
1876 mysql_store_result() will be called and the result stored in this pointer.
1877 @param[out] master_row If this is not NULL and there is no error, then
1878 mysql_fetch_row() will be called and the result stored in this pointer.
1879
1880 @retval COMMAND_STATUS_OK No error.
1881 @retval COMMAND_STATUS_ALLOWED_ERROR There was an error and the
1882 error code was 'allowed_error'.
1883 @retval COMMAND_STATUS_ERROR There was an error and the error code
1884 was not 'allowed_error'.
1885 */
1886 enum enum_command_status
1887 { COMMAND_STATUS_OK, COMMAND_STATUS_ERROR, COMMAND_STATUS_ALLOWED_ERROR };
1888 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)1889 io_thread_init_command(Master_info *mi, const char *query, int allowed_error,
1890 MYSQL_RES **master_res= NULL,
1891 MYSQL_ROW *master_row= NULL)
1892 {
1893 DBUG_ENTER("io_thread_init_command");
1894 DBUG_PRINT("info", ("IO thread initialization command: '%s'", query));
1895 MYSQL *mysql= mi->mysql;
1896 int ret= mysql_real_query(mysql, query, strlen(query));
1897 if (io_slave_killed(mi->info_thd, mi))
1898 {
1899 sql_print_information("The slave IO thread was killed while executing "
1900 "initialization query '%s'", query);
1901 mysql_free_result(mysql_store_result(mysql));
1902 DBUG_RETURN(COMMAND_STATUS_ERROR);
1903 }
1904 if (ret != 0)
1905 {
1906 int err= mysql_errno(mysql);
1907 mysql_free_result(mysql_store_result(mysql));
1908 if (!err || err != allowed_error)
1909 {
1910 mi->report(is_network_error(err) ? WARNING_LEVEL : ERROR_LEVEL, err,
1911 "The slave IO thread stops because the initialization query "
1912 "'%s' failed with error '%s'.",
1913 query, mysql_error(mysql));
1914 DBUG_RETURN(COMMAND_STATUS_ERROR);
1915 }
1916 DBUG_RETURN(COMMAND_STATUS_ALLOWED_ERROR);
1917 }
1918 if (master_res != NULL)
1919 {
1920 if ((*master_res= mysql_store_result(mysql)) == NULL)
1921 {
1922 mi->report(WARNING_LEVEL, mysql_errno(mysql),
1923 "The slave IO thread stops because the initialization query "
1924 "'%s' did not return any result.",
1925 query);
1926 DBUG_RETURN(COMMAND_STATUS_ERROR);
1927 }
1928 if (master_row != NULL)
1929 {
1930 if ((*master_row= mysql_fetch_row(*master_res)) == NULL)
1931 {
1932 mysql_free_result(*master_res);
1933 mi->report(WARNING_LEVEL, mysql_errno(mysql),
1934 "The slave IO thread stops because the initialization query "
1935 "'%s' did not return any row.",
1936 query);
1937 DBUG_RETURN(COMMAND_STATUS_ERROR);
1938 }
1939 }
1940 }
1941 else
1942 DBUG_ASSERT(master_row == NULL);
1943 DBUG_RETURN(COMMAND_STATUS_OK);
1944 }
1945
1946
1947 /**
1948 Set user variables after connecting to the master.
1949
1950 @param mysql MYSQL to request uuid from master.
1951 @param mi Master_info to set master_uuid
1952
1953 @return 0: Success, 1: Fatal error, 2: Network error.
1954 */
io_thread_init_commands(MYSQL * mysql,Master_info * mi)1955 int io_thread_init_commands(MYSQL *mysql, Master_info *mi)
1956 {
1957 char query[256];
1958 int ret= 0;
1959 DBUG_EXECUTE_IF("fake_5_5_version_slave", return ret;);
1960
1961 sprintf(query, "SET @slave_uuid= '%s'", server_uuid);
1962 if (mysql_real_query(mysql, query, strlen(query))
1963 && !check_io_slave_killed(mi->info_thd, mi, NULL))
1964 goto err;
1965
1966 mysql_free_result(mysql_store_result(mysql));
1967 return ret;
1968
1969 err:
1970 if (mysql_errno(mysql) && is_network_error(mysql_errno(mysql)))
1971 {
1972 mi->report(WARNING_LEVEL, mysql_errno(mysql),
1973 "The initialization command '%s' failed with the following"
1974 " error: '%s'.", query, mysql_error(mysql));
1975 ret= 2;
1976 }
1977 else
1978 {
1979 char errmsg[512];
1980 const char *errmsg_fmt=
1981 "The slave I/O thread stops because a fatal error is encountered "
1982 "when it tries to send query to master(query: %s).";
1983
1984 sprintf(errmsg, errmsg_fmt, query);
1985 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
1986 errmsg);
1987 ret= 1;
1988 }
1989 mysql_free_result(mysql_store_result(mysql));
1990 return ret;
1991 }
1992
1993 /**
1994 Get master's uuid on connecting.
1995
1996 @param mysql MYSQL to request uuid from master.
1997 @param mi Master_info to set master_uuid
1998
1999 @return 0: Success, 1: Fatal error, 2: Network error.
2000 */
get_master_uuid(MYSQL * mysql,Master_info * mi)2001 static int get_master_uuid(MYSQL *mysql, Master_info *mi)
2002 {
2003 const char *errmsg;
2004 MYSQL_RES *master_res= NULL;
2005 MYSQL_ROW master_row= NULL;
2006 int ret= 0;
2007
2008 DBUG_EXECUTE_IF("dbug.before_get_MASTER_UUID",
2009 {
2010 const char act[]= "now wait_for signal.get_master_uuid";
2011 DBUG_ASSERT(opt_debug_sync_timeout > 0);
2012 DBUG_ASSERT(!debug_sync_set_action(current_thd,
2013 STRING_WITH_LEN(act)));
2014 };);
2015
2016 DBUG_EXECUTE_IF("dbug.simulate_busy_io",
2017 {
2018 const char act[]= "now signal Reached wait_for signal.got_stop_slave";
2019 DBUG_ASSERT(opt_debug_sync_timeout > 0);
2020 DBUG_ASSERT(!debug_sync_set_action(current_thd,
2021 STRING_WITH_LEN(act)));
2022 };);
2023 if (!mysql_real_query(mysql,
2024 STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_UUID'")) &&
2025 (master_res= mysql_store_result(mysql)) &&
2026 (master_row= mysql_fetch_row(master_res)))
2027 {
2028 if (!strcmp(::server_uuid, master_row[1]) &&
2029 !mi->rli->replicate_same_server_id)
2030 {
2031 errmsg= "The slave I/O thread stops because master and slave have equal "
2032 "MySQL server UUIDs; these UUIDs must be different for "
2033 "replication to work.";
2034 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
2035 errmsg);
2036 // Fatal error
2037 ret= 1;
2038 }
2039 else
2040 {
2041 if (mi->master_uuid[0] != 0 && strcmp(mi->master_uuid, master_row[1]))
2042 sql_print_warning("The master's UUID has changed, although this should"
2043 " not happen unless you have changed it manually."
2044 " The old UUID was %s.",
2045 mi->master_uuid);
2046 strncpy(mi->master_uuid, master_row[1], UUID_LENGTH);
2047 mi->master_uuid[UUID_LENGTH]= 0;
2048 }
2049 }
2050 else if (mysql_errno(mysql))
2051 {
2052 if (is_network_error(mysql_errno(mysql)))
2053 {
2054 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2055 "Get master SERVER_UUID failed with error: %s",
2056 mysql_error(mysql));
2057 ret= 2;
2058 }
2059 else
2060 {
2061 /* Fatal error */
2062 errmsg= "The slave I/O thread stops because a fatal error is encountered "
2063 "when it tries to get the value of SERVER_UUID variable from master.";
2064 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
2065 errmsg);
2066 ret= 1;
2067 }
2068 }
2069 else if (!master_row && master_res)
2070 {
2071 mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2072 "Unknown system variable 'SERVER_UUID' on master. "
2073 "A probable cause is that the variable is not supported on the "
2074 "master (version: %s), even though it is on the slave (version: %s)",
2075 mysql->server_version, server_version);
2076 }
2077
2078 if (master_res)
2079 mysql_free_result(master_res);
2080 return ret;
2081 }
2082
2083
2084 /**
2085 Determine, case-sensitively, if short_string is equal to
2086 long_string, or a true prefix of long_string, or not a prefix.
2087
2088 @retval 0 short_string is not a prefix of long_string.
2089 @retval 1 short_string is a true prefix of long_string (not equal).
2090 @retval 2 short_string is equal to long_string.
2091 */
is_str_prefix_case(const char * short_string,const char * long_string)2092 static int is_str_prefix_case(const char *short_string, const char *long_string)
2093 {
2094 int i;
2095 for (i= 0; short_string[i]; i++)
2096 if (my_toupper(system_charset_info, short_string[i]) !=
2097 my_toupper(system_charset_info, long_string[i]))
2098 return 0;
2099 return long_string[i] ? 1 : 2;
2100 }
2101
2102 /*
2103 Note that we rely on the master's version (3.23, 4.0.14 etc) instead of
2104 relying on the binlog's version. This is not perfect: imagine an upgrade
2105 of the master without waiting that all slaves are in sync with the master;
2106 then a slave could be fooled about the binlog's format. This is what happens
2107 when people upgrade a 3.23 master to 4.0 without doing RESET MASTER: 4.0
2108 slaves are fooled. So we do this only to distinguish between 3.23 and more
2109 recent masters (it's too late to change things for 3.23).
2110
2111 RETURNS
2112 0 ok
2113 1 error
2114 2 transient network problem, the caller should try to reconnect
2115 */
2116
get_master_version_and_clock(MYSQL * mysql,Master_info * mi)2117 static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
2118 {
2119 char err_buff[MAX_SLAVE_ERRMSG];
2120 const char* errmsg= 0;
2121 int err_code= 0;
2122 int version_number=0;
2123 version_number= atoi(mysql->server_version);
2124
2125 MYSQL_RES *master_res= 0;
2126 MYSQL_ROW master_row;
2127 DBUG_ENTER("get_master_version_and_clock");
2128
2129 /*
2130 Free old mi_description_event (that is needed if we are in
2131 a reconnection).
2132 */
2133 DBUG_EXECUTE_IF("unrecognized_master_version",
2134 {
2135 version_number= 1;
2136 };);
2137 mysql_mutex_lock(&mi->data_lock);
2138 mi->set_mi_description_event(NULL);
2139
2140 if (!my_isdigit(&my_charset_bin,*mysql->server_version))
2141 {
2142 errmsg = "Master reported unrecognized MySQL version";
2143 err_code= ER_SLAVE_FATAL_ERROR;
2144 sprintf(err_buff, ER(err_code), errmsg);
2145 }
2146 else
2147 {
2148 /*
2149 Note the following switch will bug when we have MySQL branch 30 ;)
2150 */
2151 switch (version_number)
2152 {
2153 case 0:
2154 case 1:
2155 case 2:
2156 errmsg = "Master reported unrecognized MySQL version";
2157 err_code= ER_SLAVE_FATAL_ERROR;
2158 sprintf(err_buff, ER(err_code), errmsg);
2159 break;
2160 case 3:
2161 mi->set_mi_description_event(new
2162 Format_description_log_event(1, mysql->server_version));
2163 break;
2164 case 4:
2165 mi->set_mi_description_event(new
2166 Format_description_log_event(3, mysql->server_version));
2167 break;
2168 default:
2169 /*
2170 Master is MySQL >=5.0. Give a default Format_desc event, so that we can
2171 take the early steps (like tests for "is this a 3.23 master") which we
2172 have to take before we receive the real master's Format_desc which will
2173 override this one. Note that the Format_desc we create below is garbage
2174 (it has the format of the *slave*); it's only good to help know if the
2175 master is 3.23, 4.0, etc.
2176 */
2177 mi->set_mi_description_event(new
2178 Format_description_log_event(4, mysql->server_version));
2179 break;
2180 }
2181 }
2182
2183 /*
2184 This does not mean that a 5.0 slave will be able to read a 5.5 master; but
2185 as we don't know yet, we don't want to forbid this for now. If a 5.0 slave
2186 can't read a 5.5 master, this will show up when the slave can't read some
2187 events sent by the master, and there will be error messages.
2188 */
2189
2190 if (errmsg)
2191 {
2192 /* unlock the mutex on master info structure */
2193 mysql_mutex_unlock(&mi->data_lock);
2194 goto err;
2195 }
2196
2197 /* as we are here, we tried to allocate the event */
2198 if (mi->get_mi_description_event() == NULL)
2199 {
2200 mysql_mutex_unlock(&mi->data_lock);
2201 errmsg= "default Format_description_log_event";
2202 err_code= ER_SLAVE_CREATE_EVENT_FAILURE;
2203 sprintf(err_buff, ER(err_code), errmsg);
2204 goto err;
2205 }
2206
2207 if (mi->get_mi_description_event()->binlog_version < 4 &&
2208 opt_slave_sql_verify_checksum)
2209 {
2210 sql_print_warning("Found a master with MySQL server version older than "
2211 "5.0. With checksums enabled on the slave, replication "
2212 "might not work correctly. To ensure correct "
2213 "replication, restart the slave server with "
2214 "--slave_sql_verify_checksum=0.");
2215 }
2216 /*
2217 FD_q's (A) is set initially from RL's (A): FD_q.(A) := RL.(A).
2218 It's necessary to adjust FD_q.(A) at this point because in the following
2219 course FD_q is going to be dumped to RL.
2220 Generally FD_q is derived from a received FD_m (roughly FD_q := FD_m)
2221 in queue_event and the master's (A) is installed.
2222 At one step with the assignment the Relay-Log's checksum alg is set to
2223 a new value: RL.(A) := FD_q.(A). If the slave service is stopped
2224 the last time assigned RL.(A) will be passed over to the restarting
2225 service (to the current execution point).
2226 RL.A is a "codec" to verify checksum in queue_event() almost all the time
2227 the first fake Rotate event.
2228 Starting from this point IO thread will executes the following checksum
2229 warmup sequence of actions:
2230
2231 FD_q.A := RL.A,
2232 A_m^0 := master.@@global.binlog_checksum,
2233 {queue_event(R_f): verifies(R_f, A_m^0)},
2234 {queue_event(FD_m): verifies(FD_m, FD_m.A), dump(FD_q), rotate(RL),
2235 FD_q := FD_m, RL.A := FD_q.A)}
2236
2237 See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg
2238 docs lines (binlog.h).
2239 In above A_m^0 - the value of master's
2240 @@binlog_checksum determined in the upcoming handshake (stored in
2241 mi->checksum_alg_before_fd).
2242
2243
2244 After the warm-up sequence IO gets to "normal" checksum verification mode
2245 to use RL.A in
2246
2247 {queue_event(E_m): verifies(E_m, RL.A)}
2248
2249 until it has received a new FD_m.
2250 */
2251 mi->get_mi_description_event()->checksum_alg=
2252 mi->rli->relay_log.relay_log_checksum_alg;
2253
2254 DBUG_ASSERT(mi->get_mi_description_event()->checksum_alg !=
2255 BINLOG_CHECKSUM_ALG_UNDEF);
2256 DBUG_ASSERT(mi->rli->relay_log.relay_log_checksum_alg !=
2257 BINLOG_CHECKSUM_ALG_UNDEF);
2258
2259 mysql_mutex_unlock(&mi->data_lock);
2260
2261 /*
2262 Compare the master and slave's clock. Do not die if master's clock is
2263 unavailable (very old master not supporting UNIX_TIMESTAMP()?).
2264 */
2265
2266 DBUG_EXECUTE_IF("dbug.before_get_UNIX_TIMESTAMP",
2267 {
2268 const char act[]=
2269 "now "
2270 "wait_for signal.get_unix_timestamp";
2271 DBUG_ASSERT(opt_debug_sync_timeout > 0);
2272 DBUG_ASSERT(!debug_sync_set_action(current_thd,
2273 STRING_WITH_LEN(act)));
2274 };);
2275
2276 master_res= NULL;
2277 if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
2278 (master_res= mysql_store_result(mysql)) &&
2279 (master_row= mysql_fetch_row(master_res)))
2280 {
2281 mysql_mutex_lock(&mi->data_lock);
2282 mi->clock_diff_with_master=
2283 (long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
2284 mysql_mutex_unlock(&mi->data_lock);
2285 }
2286 else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2287 goto slave_killed_err;
2288 else if (is_network_error(mysql_errno(mysql)))
2289 {
2290 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2291 "Get master clock failed with error: %s", mysql_error(mysql));
2292 goto network_err;
2293 }
2294 else
2295 {
2296 mysql_mutex_lock(&mi->data_lock);
2297 mi->clock_diff_with_master= 0; /* The "most sensible" value */
2298 mysql_mutex_unlock(&mi->data_lock);
2299 sql_print_warning("\"SELECT UNIX_TIMESTAMP()\" failed on master, "
2300 "do not trust column Seconds_Behind_Master of SHOW "
2301 "SLAVE STATUS. Error: %s (%d)",
2302 mysql_error(mysql), mysql_errno(mysql));
2303 }
2304 if (master_res)
2305 {
2306 mysql_free_result(master_res);
2307 master_res= NULL;
2308 }
2309
2310 /*
2311 Check that the master's server id and ours are different. Because if they
2312 are equal (which can result from a simple copy of master's datadir to slave,
2313 thus copying some my.cnf), replication will work but all events will be
2314 skipped.
2315 Do not die if SHOW VARIABLES LIKE 'SERVER_ID' fails on master (very old
2316 master?).
2317 Note: we could have put a @@SERVER_ID in the previous SELECT
2318 UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters.
2319 */
2320 DBUG_EXECUTE_IF("dbug.before_get_SERVER_ID",
2321 {
2322 const char act[]=
2323 "now "
2324 "wait_for signal.get_server_id";
2325 DBUG_ASSERT(opt_debug_sync_timeout > 0);
2326 DBUG_ASSERT(!debug_sync_set_action(current_thd,
2327 STRING_WITH_LEN(act)));
2328 };);
2329 master_res= NULL;
2330 master_row= NULL;
2331 if (!mysql_real_query(mysql,
2332 STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_ID'")) &&
2333 (master_res= mysql_store_result(mysql)) &&
2334 (master_row= mysql_fetch_row(master_res)))
2335 {
2336 if ((::server_id == (mi->master_id= strtoul(master_row[1], 0, 10))) &&
2337 !mi->rli->replicate_same_server_id)
2338 {
2339 errmsg= "The slave I/O thread stops because master and slave have equal \
2340 MySQL server ids; these ids must be different for replication to work (or \
2341 the --replicate-same-server-id option must be used on slave but this does \
2342 not always make sense; please check the manual before using it).";
2343 err_code= ER_SLAVE_FATAL_ERROR;
2344 sprintf(err_buff, ER(err_code), errmsg);
2345 goto err;
2346 }
2347 }
2348 else if (mysql_errno(mysql))
2349 {
2350 if (check_io_slave_killed(mi->info_thd, mi, NULL))
2351 goto slave_killed_err;
2352 else if (is_network_error(mysql_errno(mysql)))
2353 {
2354 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2355 "Get master SERVER_ID failed with error: %s", mysql_error(mysql));
2356 goto network_err;
2357 }
2358 /* Fatal error */
2359 errmsg= "The slave I/O thread stops because a fatal error is encountered \
2360 when it try to get the value of SERVER_ID variable from master.";
2361 err_code= mysql_errno(mysql);
2362 sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2363 goto err;
2364 }
2365 else if (!master_row && master_res)
2366 {
2367 mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2368 "Unknown system variable 'SERVER_ID' on master, \
2369 maybe it is a *VERY OLD MASTER*.");
2370 }
2371 if (master_res)
2372 {
2373 mysql_free_result(master_res);
2374 master_res= NULL;
2375 }
2376 if (mi->master_id == 0 && mi->ignore_server_ids->dynamic_ids.elements > 0)
2377 {
2378 errmsg= "Slave configured with server id filtering could not detect the master server id.";
2379 err_code= ER_SLAVE_FATAL_ERROR;
2380 sprintf(err_buff, ER(err_code), errmsg);
2381 goto err;
2382 }
2383
2384 /*
2385 Check that the master's global character_set_server and ours are the same.
2386 Not fatal if query fails (old master?).
2387 Note that we don't check for equality of global character_set_client and
2388 collation_connection (neither do we prevent their setting in
2389 set_var.cc). That's because from what I (Guilhem) have tested, the global
2390 values of these 2 are never used (new connections don't use them).
2391 We don't test equality of global collation_database either as it's is
2392 going to be deprecated (made read-only) in 4.1 very soon.
2393 The test is only relevant if master < 5.0.3 (we'll test only if it's older
2394 than the 5 branch; < 5.0.3 was alpha...), as >= 5.0.3 master stores
2395 charset info in each binlog event.
2396 We don't do it for 3.23 because masters <3.23.50 hang on
2397 SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). So finally we
2398 test only if master is 4.x.
2399 */
2400
2401 /* redundant with rest of code but safer against later additions */
2402 if (*mysql->server_version == '3')
2403 goto err;
2404
2405 if (*mysql->server_version == '4')
2406 {
2407 master_res= NULL;
2408 if (!mysql_real_query(mysql,
2409 STRING_WITH_LEN("SELECT @@GLOBAL.COLLATION_SERVER")) &&
2410 (master_res= mysql_store_result(mysql)) &&
2411 (master_row= mysql_fetch_row(master_res)))
2412 {
2413 if (strcmp(master_row[0], global_system_variables.collation_server->name))
2414 {
2415 errmsg= "The slave I/O thread stops because master and slave have \
2416 different values for the COLLATION_SERVER global variable. The values must \
2417 be equal for the Statement-format replication to work";
2418 err_code= ER_SLAVE_FATAL_ERROR;
2419 sprintf(err_buff, ER(err_code), errmsg);
2420 goto err;
2421 }
2422 }
2423 else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2424 goto slave_killed_err;
2425 else if (is_network_error(mysql_errno(mysql)))
2426 {
2427 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2428 "Get master COLLATION_SERVER failed with error: %s", mysql_error(mysql));
2429 goto network_err;
2430 }
2431 else if (mysql_errno(mysql) != ER_UNKNOWN_SYSTEM_VARIABLE)
2432 {
2433 /* Fatal error */
2434 errmsg= "The slave I/O thread stops because a fatal error is encountered \
2435 when it try to get the value of COLLATION_SERVER global variable from master.";
2436 err_code= mysql_errno(mysql);
2437 sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2438 goto err;
2439 }
2440 else
2441 mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
2442 "Unknown system variable 'COLLATION_SERVER' on master, \
2443 maybe it is a *VERY OLD MASTER*. *NOTE*: slave may experience \
2444 inconsistency if replicated data deals with collation.");
2445
2446 if (master_res)
2447 {
2448 mysql_free_result(master_res);
2449 master_res= NULL;
2450 }
2451 }
2452
2453 /*
2454 Perform analogous check for time zone. Theoretically we also should
2455 perform check here to verify that SYSTEM time zones are the same on
2456 slave and master, but we can't rely on value of @@system_time_zone
2457 variable (it is time zone abbreviation) since it determined at start
2458 time and so could differ for slave and master even if they are really
2459 in the same system time zone. So we are omiting this check and just
2460 relying on documentation. Also according to Monty there are many users
2461 who are using replication between servers in various time zones. Hence
2462 such check will broke everything for them. (And now everything will
2463 work for them because by default both their master and slave will have
2464 'SYSTEM' time zone).
2465 This check is only necessary for 4.x masters (and < 5.0.4 masters but
2466 those were alpha).
2467 */
2468 if (*mysql->server_version == '4')
2469 {
2470 master_res= NULL;
2471 if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) &&
2472 (master_res= mysql_store_result(mysql)) &&
2473 (master_row= mysql_fetch_row(master_res)))
2474 {
2475 if (strcmp(master_row[0],
2476 global_system_variables.time_zone->get_name()->ptr()))
2477 {
2478 errmsg= "The slave I/O thread stops because master and slave have \
2479 different values for the TIME_ZONE global variable. The values must \
2480 be equal for the Statement-format replication to work";
2481 err_code= ER_SLAVE_FATAL_ERROR;
2482 sprintf(err_buff, ER(err_code), errmsg);
2483 goto err;
2484 }
2485 }
2486 else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2487 goto slave_killed_err;
2488 else if (is_network_error(mysql_errno(mysql)))
2489 {
2490 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2491 "Get master TIME_ZONE failed with error: %s", mysql_error(mysql));
2492 goto network_err;
2493 }
2494 else
2495 {
2496 /* Fatal error */
2497 errmsg= "The slave I/O thread stops because a fatal error is encountered \
2498 when it try to get the value of TIME_ZONE global variable from master.";
2499 err_code= mysql_errno(mysql);
2500 sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2501 goto err;
2502 }
2503 if (master_res)
2504 {
2505 mysql_free_result(master_res);
2506 master_res= NULL;
2507 }
2508 }
2509
2510 if (mi->heartbeat_period != 0.0)
2511 {
2512 char llbuf[22];
2513 const char query_format[]= "SET @master_heartbeat_period= %s";
2514 char query[sizeof(query_format) - 2 + sizeof(llbuf)];
2515 /*
2516 the period is an ulonglong of nano-secs.
2517 */
2518 llstr((ulonglong) (mi->heartbeat_period*1000000000UL), llbuf);
2519 sprintf(query, query_format, llbuf);
2520
2521 if (mysql_real_query(mysql, query, strlen(query)))
2522 {
2523 if (check_io_slave_killed(mi->info_thd, mi, NULL))
2524 goto slave_killed_err;
2525
2526 if (is_network_error(mysql_errno(mysql)))
2527 {
2528 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2529 "SET @master_heartbeat_period to master failed with error: %s",
2530 mysql_error(mysql));
2531 mysql_free_result(mysql_store_result(mysql));
2532 goto network_err;
2533 }
2534 else
2535 {
2536 /* Fatal error */
2537 errmsg= "The slave I/O thread stops because a fatal error is encountered "
2538 " when it tries to SET @master_heartbeat_period on master.";
2539 err_code= ER_SLAVE_FATAL_ERROR;
2540 sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2541 mysql_free_result(mysql_store_result(mysql));
2542 goto err;
2543 }
2544 }
2545 mysql_free_result(mysql_store_result(mysql));
2546 }
2547
2548 /*
2549 Querying if master is capable to checksum and notifying it about own
2550 CRC-awareness. The master's side instant value of @@global.binlog_checksum
2551 is stored in the dump thread's uservar area as well as cached locally
2552 to become known in consensus by master and slave.
2553 */
2554 if (DBUG_EVALUATE_IF("simulate_slave_unaware_checksum", 0, 1))
2555 {
2556 int rc;
2557 const char query[]= "SET @master_binlog_checksum= @@global.binlog_checksum";
2558 master_res= NULL;
2559 mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF; //initially undefined
2560 /*
2561 @c checksum_alg_before_fd is queried from master in this block.
2562 If master is old checksum-unaware the value stays undefined.
2563 Once the first FD will be received its alg descriptor will replace
2564 the being queried one.
2565 */
2566 rc= mysql_real_query(mysql, query, strlen(query));
2567 if (rc != 0)
2568 {
2569 mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_OFF;
2570 if (check_io_slave_killed(mi->info_thd, mi, NULL))
2571 goto slave_killed_err;
2572
2573 if (mysql_errno(mysql) == ER_UNKNOWN_SYSTEM_VARIABLE)
2574 {
2575 // this is tolerable as OM -> NS is supported
2576 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2577 "Notifying master by %s failed with "
2578 "error: %s", query, mysql_error(mysql));
2579 }
2580 else
2581 {
2582 if (is_network_error(mysql_errno(mysql)))
2583 {
2584 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2585 "Notifying master by %s failed with "
2586 "error: %s", query, mysql_error(mysql));
2587 mysql_free_result(mysql_store_result(mysql));
2588 goto network_err;
2589 }
2590 else
2591 {
2592 errmsg= "The slave I/O thread stops because a fatal error is encountered "
2593 "when it tried to SET @master_binlog_checksum on master.";
2594 err_code= ER_SLAVE_FATAL_ERROR;
2595 sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2596 mysql_free_result(mysql_store_result(mysql));
2597 goto err;
2598 }
2599 }
2600 }
2601 else
2602 {
2603 mysql_free_result(mysql_store_result(mysql));
2604 if (!mysql_real_query(mysql,
2605 STRING_WITH_LEN("SELECT @master_binlog_checksum")) &&
2606 (master_res= mysql_store_result(mysql)) &&
2607 (master_row= mysql_fetch_row(master_res)) &&
2608 (master_row[0] != NULL))
2609 {
2610 mi->checksum_alg_before_fd= (uint8)
2611 find_type(master_row[0], &binlog_checksum_typelib, 1) - 1;
2612
2613 DBUG_EXECUTE_IF("undefined_algorithm_on_slave",
2614 mi->checksum_alg_before_fd = BINLOG_CHECKSUM_ALG_UNDEF;);
2615 if(mi->checksum_alg_before_fd == BINLOG_CHECKSUM_ALG_UNDEF)
2616 {
2617 errmsg= "The slave I/O thread was stopped because a fatal error is encountered "
2618 "The checksum algorithm used by master is unknown to slave.";
2619 err_code= ER_SLAVE_FATAL_ERROR;
2620 sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2621 mysql_free_result(mysql_store_result(mysql));
2622 goto err;
2623 }
2624
2625 // valid outcome is either of
2626 DBUG_ASSERT(mi->checksum_alg_before_fd == BINLOG_CHECKSUM_ALG_OFF ||
2627 mi->checksum_alg_before_fd == BINLOG_CHECKSUM_ALG_CRC32);
2628 }
2629 else if (check_io_slave_killed(mi->info_thd, mi, NULL))
2630 goto slave_killed_err;
2631 else if (is_network_error(mysql_errno(mysql)))
2632 {
2633 mi->report(WARNING_LEVEL, mysql_errno(mysql),
2634 "Get master BINLOG_CHECKSUM failed with error: %s", mysql_error(mysql));
2635 goto network_err;
2636 }
2637 else
2638 {
2639 errmsg= "The slave I/O thread stops because a fatal error is encountered "
2640 "when it tried to SELECT @master_binlog_checksum.";
2641 err_code= ER_SLAVE_FATAL_ERROR;
2642 sprintf(err_buff, "%s Error: %s", errmsg, mysql_error(mysql));
2643 mysql_free_result(mysql_store_result(mysql));
2644 goto err;
2645 }
2646 }
2647 if (master_res)
2648 {
2649 mysql_free_result(master_res);
2650 master_res= NULL;
2651 }
2652 }
2653 else
2654 mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_OFF;
2655
2656 if (DBUG_EVALUATE_IF("simulate_slave_unaware_gtid", 0, 1))
2657 {
2658 switch (io_thread_init_command(mi, "SELECT @@GLOBAL.GTID_MODE",
2659 ER_UNKNOWN_SYSTEM_VARIABLE,
2660 &master_res, &master_row))
2661 {
2662 case COMMAND_STATUS_ERROR:
2663 DBUG_RETURN(2);
2664 case COMMAND_STATUS_ALLOWED_ERROR:
2665 // master is old and does not have @@GLOBAL.GTID_MODE
2666 mi->master_gtid_mode= 0;
2667 break;
2668 case COMMAND_STATUS_OK:
2669 const char *master_gtid_mode_string= master_row[0];
2670 bool found_valid_mode= false;
2671 DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_on_permissive",
2672 { master_gtid_mode_string= "on_permissive"; });
2673 DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_off_permissive",
2674 { master_gtid_mode_string= "off_permissive"; });
2675 DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_on_something",
2676 { master_gtid_mode_string= "on_something"; });
2677 DBUG_EXECUTE_IF("simulate_master_has_gtid_mode_off_something",
2678 { master_gtid_mode_string= "off_something"; });
2679 DBUG_EXECUTE_IF("simulate_master_has_unknown_gtid_mode",
2680 { master_gtid_mode_string= "Krakel Spektakel"; });
2681 for (int mode= 0; mode <= 3 && !found_valid_mode; mode+= 3)
2682 {
2683 switch (is_str_prefix_case(gtid_mode_typelib.type_names[mode],
2684 master_gtid_mode_string))
2685 {
2686 case 0: // is not a prefix
2687 break;
2688 case 1: // is a true prefix, i.e. not equal
2689 mi->report(WARNING_LEVEL, ER_UNKNOWN_ERROR,
2690 "The master uses an unknown GTID_MODE '%s'. "
2691 "Treating it as '%s'.",
2692 master_gtid_mode_string,
2693 gtid_mode_typelib.type_names[mode]);
2694 // fall through
2695 case 2: // is equal
2696 found_valid_mode= true;
2697 mi->master_gtid_mode= mode;
2698 break;
2699 }
2700 }
2701 if (!found_valid_mode)
2702 {
2703 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
2704 "The slave IO thread stops because the master has "
2705 "an unknown @@GLOBAL.GTID_MODE '%s'.",
2706 master_gtid_mode_string);
2707 mysql_free_result(master_res);
2708 DBUG_RETURN(1);
2709 }
2710 mysql_free_result(master_res);
2711 break;
2712 }
2713 if (mi->master_gtid_mode > gtid_mode + 1 ||
2714 gtid_mode > mi->master_gtid_mode + 1)
2715 {
2716 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
2717 "The slave IO thread stops because the master has "
2718 "@@GLOBAL.GTID_MODE %s and this server has "
2719 "@@GLOBAL.GTID_MODE %s",
2720 gtid_mode_names[mi->master_gtid_mode],
2721 gtid_mode_names[gtid_mode]);
2722 DBUG_RETURN(1);
2723 }
2724 if (mi->is_auto_position() && mi->master_gtid_mode != 3)
2725 {
2726 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
2727 "The slave IO thread stops because the master has "
2728 "@@GLOBAL.GTID_MODE %s and we are trying to connect "
2729 "using MASTER_AUTO_POSITION.",
2730 gtid_mode_names[mi->master_gtid_mode]);
2731 DBUG_RETURN(1);
2732 }
2733 }
2734
2735 err:
2736 if (errmsg)
2737 {
2738 if (master_res)
2739 mysql_free_result(master_res);
2740 DBUG_ASSERT(err_code != 0);
2741 mi->report(ERROR_LEVEL, err_code, "%s", err_buff);
2742 DBUG_RETURN(1);
2743 }
2744
2745 DBUG_RETURN(0);
2746
2747 network_err:
2748 if (master_res)
2749 mysql_free_result(master_res);
2750 DBUG_RETURN(2);
2751
2752 slave_killed_err:
2753 if (master_res)
2754 mysql_free_result(master_res);
2755 DBUG_RETURN(2);
2756 }
2757
wait_for_relay_log_space(Relay_log_info * rli)2758 static bool wait_for_relay_log_space(Relay_log_info* rli)
2759 {
2760 bool slave_killed=0;
2761 Master_info* mi = rli->mi;
2762 PSI_stage_info old_stage;
2763 THD* thd = mi->info_thd;
2764 DBUG_ENTER("wait_for_relay_log_space");
2765
2766 mysql_mutex_lock(&rli->log_space_lock);
2767 thd->ENTER_COND(&rli->log_space_cond,
2768 &rli->log_space_lock,
2769 &stage_waiting_for_relay_log_space,
2770 &old_stage);
2771 while (rli->log_space_limit < rli->log_space_total &&
2772 !(slave_killed=io_slave_killed(thd,mi)) &&
2773 !rli->ignore_log_space_limit)
2774 mysql_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
2775
2776 /*
2777 Makes the IO thread read only one event at a time
2778 until the SQL thread is able to purge the relay
2779 logs, freeing some space.
2780
2781 Therefore, once the SQL thread processes this next
2782 event, it goes to sleep (no more events in the queue),
2783 sets ignore_log_space_limit=true and wakes the IO thread.
2784 However, this event may have been enough already for
2785 the SQL thread to purge some log files, freeing
2786 rli->log_space_total .
2787
2788 This guarantees that the SQL and IO thread move
2789 forward only one event at a time (to avoid deadlocks),
2790 when the relay space limit is reached. It also
2791 guarantees that when the SQL thread is prepared to
2792 rotate (to be able to purge some logs), the IO thread
2793 will know about it and will rotate.
2794
2795 NOTE: The ignore_log_space_limit is only set when the SQL
2796 thread sleeps waiting for events.
2797
2798 */
2799 if (rli->ignore_log_space_limit)
2800 {
2801 #ifndef DBUG_OFF
2802 {
2803 char llbuf1[22], llbuf2[22];
2804 DBUG_PRINT("info", ("log_space_limit=%s "
2805 "log_space_total=%s "
2806 "ignore_log_space_limit=%d "
2807 "sql_force_rotate_relay=%d",
2808 llstr(rli->log_space_limit,llbuf1),
2809 llstr(rli->log_space_total,llbuf2),
2810 (int) rli->ignore_log_space_limit,
2811 (int) rli->sql_force_rotate_relay));
2812 }
2813 #endif
2814 if (rli->sql_force_rotate_relay)
2815 {
2816 mysql_mutex_lock(&mi->data_lock);
2817 rotate_relay_log(mi, false/*need_log_space_lock=false*/);
2818 mysql_mutex_unlock(&mi->data_lock);
2819 rli->sql_force_rotate_relay= false;
2820 }
2821
2822 rli->ignore_log_space_limit= false;
2823 }
2824
2825 thd->EXIT_COND(&old_stage);
2826 DBUG_RETURN(slave_killed);
2827 }
2828
2829
2830 /*
2831 Builds a Rotate from the ignored events' info and writes it to relay log.
2832
2833 The caller must hold mi->data_lock before invoking this function.
2834
2835 @param thd pointer to I/O Thread's Thd.
2836 @param mi point to I/O Thread metadata class.
2837
2838 @return 0 if everything went fine, 1 otherwise.
2839 */
write_ignored_events_info_to_relay_log(THD * thd,Master_info * mi)2840 static int write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi)
2841 {
2842 Relay_log_info *rli= mi->rli;
2843 mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
2844 int error= 0;
2845 DBUG_ENTER("write_ignored_events_info_to_relay_log");
2846
2847 DBUG_ASSERT(thd == mi->info_thd);
2848 mysql_mutex_assert_owner(&mi->data_lock);
2849 mysql_mutex_lock(log_lock);
2850 if (rli->ign_master_log_name_end[0])
2851 {
2852 DBUG_PRINT("info",("writing a Rotate event to track down ignored events"));
2853 Rotate_log_event *ev= new Rotate_log_event(rli->ign_master_log_name_end,
2854 0, rli->ign_master_log_pos_end,
2855 Rotate_log_event::DUP_NAME);
2856 if (mi->get_mi_description_event() != NULL)
2857 ev->checksum_alg= mi->get_mi_description_event()->checksum_alg;
2858
2859 rli->ign_master_log_name_end[0]= 0;
2860 /* can unlock before writing as slave SQL thd will soon see our Rotate */
2861 mysql_mutex_unlock(log_lock);
2862 if (likely((bool)ev))
2863 {
2864 ev->server_id= 0; // don't be ignored by slave SQL thread
2865 if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
2866 mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
2867 ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
2868 "failed to write a Rotate event"
2869 " to the relay log, SHOW SLAVE STATUS may be"
2870 " inaccurate");
2871 rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
2872 if (flush_master_info(mi, TRUE))
2873 {
2874 error= 1;
2875 sql_print_error("Failed to flush master info file.");
2876 }
2877 delete ev;
2878 }
2879 else
2880 {
2881 error= 1;
2882 mi->report(ERROR_LEVEL, ER_SLAVE_CREATE_EVENT_FAILURE,
2883 ER(ER_SLAVE_CREATE_EVENT_FAILURE),
2884 "Rotate_event (out of memory?),"
2885 " SHOW SLAVE STATUS may be inaccurate");
2886 }
2887 }
2888 else
2889 mysql_mutex_unlock(log_lock);
2890
2891 DBUG_RETURN(error);
2892 }
2893
2894
register_slave_on_master(MYSQL * mysql,Master_info * mi,bool * suppress_warnings)2895 int register_slave_on_master(MYSQL* mysql, Master_info *mi,
2896 bool *suppress_warnings)
2897 {
2898 uchar buf[1024], *pos= buf;
2899 uint report_host_len=0, report_user_len=0, report_password_len=0;
2900 DBUG_ENTER("register_slave_on_master");
2901
2902 *suppress_warnings= FALSE;
2903 if (report_host)
2904 report_host_len= strlen(report_host);
2905 if (report_host_len > HOSTNAME_LENGTH)
2906 {
2907 sql_print_warning("The length of report_host is %d. "
2908 "It is larger than the max length(%d), so this "
2909 "slave cannot be registered to the master.",
2910 report_host_len, HOSTNAME_LENGTH);
2911 DBUG_RETURN(0);
2912 }
2913
2914 if (report_user)
2915 report_user_len= strlen(report_user);
2916 if (report_user_len > USERNAME_LENGTH)
2917 {
2918 sql_print_warning("The length of report_user is %d. "
2919 "It is larger than the max length(%d), so this "
2920 "slave cannot be registered to the master.",
2921 report_user_len, USERNAME_LENGTH);
2922 DBUG_RETURN(0);
2923 }
2924
2925 if (report_password)
2926 report_password_len= strlen(report_password);
2927 if (report_password_len > MAX_PASSWORD_LENGTH)
2928 {
2929 sql_print_warning("The length of report_password is %d. "
2930 "It is larger than the max length(%d), so this "
2931 "slave cannot be registered to the master.",
2932 report_password_len, MAX_PASSWORD_LENGTH);
2933 DBUG_RETURN(0);
2934 }
2935
2936 int4store(pos, server_id); pos+= 4;
2937 pos= net_store_data(pos, (uchar*) report_host, report_host_len);
2938 pos= net_store_data(pos, (uchar*) report_user, report_user_len);
2939 pos= net_store_data(pos, (uchar*) report_password, report_password_len);
2940 int2store(pos, (uint16) report_port); pos+= 2;
2941 /*
2942 Fake rpl_recovery_rank, which was removed in BUG#13963,
2943 so that this server can register itself on old servers,
2944 see BUG#49259.
2945 */
2946 int4store(pos, /* rpl_recovery_rank */ 0); pos+= 4;
2947 /* The master will fill in master_id */
2948 int4store(pos, 0); pos+= 4;
2949
2950 if (simple_command(mysql, COM_REGISTER_SLAVE, buf, (size_t) (pos- buf), 0))
2951 {
2952 if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
2953 {
2954 *suppress_warnings= TRUE; // Suppress reconnect warning
2955 }
2956 else if (!check_io_slave_killed(mi->info_thd, mi, NULL))
2957 {
2958 char buf[256];
2959 my_snprintf(buf, sizeof(buf), "%s (Errno: %d)", mysql_error(mysql),
2960 mysql_errno(mysql));
2961 mi->report(ERROR_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
2962 ER(ER_SLAVE_MASTER_COM_FAILURE), "COM_REGISTER_SLAVE", buf);
2963 }
2964 DBUG_RETURN(1);
2965 }
2966
2967 DBUG_EXECUTE_IF("simulate_register_slave_killed", {
2968 mi->abort_slave = 1;
2969 DBUG_RETURN(1);
2970 };);
2971
2972 DBUG_RETURN(0);
2973 }
2974
2975
2976 /**
2977 Execute a SHOW SLAVE STATUS statement.
2978
2979 @param thd Pointer to THD object for the client thread executing the
2980 statement.
2981
2982 @param mi Pointer to Master_info object for the IO thread.
2983
2984 @retval FALSE success
2985 @retval TRUE failure
2986 */
show_slave_status(THD * thd,Master_info * mi)2987 bool show_slave_status(THD* thd, Master_info* mi)
2988 {
2989 // TODO: fix this for multi-master
2990 List<Item> field_list;
2991 Protocol *protocol= thd->protocol;
2992 char *slave_sql_running_state= NULL;
2993 char *sql_gtid_set_buffer= NULL, *io_gtid_set_buffer= NULL;
2994 int sql_gtid_set_size= 0, io_gtid_set_size= 0;
2995 DBUG_ENTER("show_slave_status");
2996
2997 if (mi != NULL)
2998 {
2999 global_sid_lock->wrlock();
3000 const Gtid_set* sql_gtid_set= gtid_state->get_logged_gtids();
3001 const Gtid_set* io_gtid_set= mi->rli->get_gtid_set();
3002 if ((sql_gtid_set_size= sql_gtid_set->to_string(&sql_gtid_set_buffer)) < 0 ||
3003 (io_gtid_set_size= io_gtid_set->to_string(&io_gtid_set_buffer)) < 0)
3004 {
3005 my_eof(thd);
3006 my_free(sql_gtid_set_buffer);
3007 my_free(io_gtid_set_buffer);
3008 global_sid_lock->unlock();
3009 DBUG_RETURN(true);
3010 }
3011 global_sid_lock->unlock();
3012 }
3013
3014 field_list.push_back(new Item_empty_string("Slave_IO_State",
3015 14));
3016 field_list.push_back(new Item_empty_string("Master_Host", mi != NULL ?
3017 sizeof(mi->host) : 0));
3018 field_list.push_back(new Item_empty_string("Master_User", mi != NULL ?
3019 mi->get_user_size() : 0));
3020 field_list.push_back(new Item_return_int("Master_Port", 7,
3021 MYSQL_TYPE_LONG));
3022 field_list.push_back(new Item_return_int("Connect_Retry", 10,
3023 MYSQL_TYPE_LONG));
3024 field_list.push_back(new Item_empty_string("Master_Log_File",
3025 FN_REFLEN));
3026 field_list.push_back(new Item_return_int("Read_Master_Log_Pos", 10,
3027 MYSQL_TYPE_LONGLONG));
3028 field_list.push_back(new Item_empty_string("Relay_Log_File",
3029 FN_REFLEN));
3030 field_list.push_back(new Item_return_int("Relay_Log_Pos", 10,
3031 MYSQL_TYPE_LONGLONG));
3032 field_list.push_back(new Item_empty_string("Relay_Master_Log_File",
3033 FN_REFLEN));
3034 field_list.push_back(new Item_empty_string("Slave_IO_Running", 3));
3035 field_list.push_back(new Item_empty_string("Slave_SQL_Running", 3));
3036 field_list.push_back(new Item_empty_string("Replicate_Do_DB", 20));
3037 field_list.push_back(new Item_empty_string("Replicate_Ignore_DB", 20));
3038 field_list.push_back(new Item_empty_string("Replicate_Do_Table", 20));
3039 field_list.push_back(new Item_empty_string("Replicate_Ignore_Table", 23));
3040 field_list.push_back(new Item_empty_string("Replicate_Wild_Do_Table", 24));
3041 field_list.push_back(new Item_empty_string("Replicate_Wild_Ignore_Table",
3042 28));
3043 field_list.push_back(new Item_return_int("Last_Errno", 4, MYSQL_TYPE_LONG));
3044 field_list.push_back(new Item_empty_string("Last_Error", 20));
3045 field_list.push_back(new Item_return_int("Skip_Counter", 10,
3046 MYSQL_TYPE_LONG));
3047 field_list.push_back(new Item_return_int("Exec_Master_Log_Pos", 10,
3048 MYSQL_TYPE_LONGLONG));
3049 field_list.push_back(new Item_return_int("Relay_Log_Space", 10,
3050 MYSQL_TYPE_LONGLONG));
3051 field_list.push_back(new Item_empty_string("Until_Condition", 6));
3052 field_list.push_back(new Item_empty_string("Until_Log_File", FN_REFLEN));
3053 field_list.push_back(new Item_return_int("Until_Log_Pos", 10,
3054 MYSQL_TYPE_LONGLONG));
3055 field_list.push_back(new Item_empty_string("Master_SSL_Allowed", 7));
3056 field_list.push_back(new Item_empty_string("Master_SSL_CA_File", mi != NULL ?
3057 sizeof(mi->ssl_ca) : 0));
3058 field_list.push_back(new Item_empty_string("Master_SSL_CA_Path", mi != NULL ?
3059 sizeof(mi->ssl_capath) : 0));
3060 field_list.push_back(new Item_empty_string("Master_SSL_Cert", mi != NULL ?
3061 sizeof(mi->ssl_cert) : 0));
3062 field_list.push_back(new Item_empty_string("Master_SSL_Cipher", mi != NULL ?
3063 sizeof(mi->ssl_cipher) : 0));
3064 field_list.push_back(new Item_empty_string("Master_SSL_Key", mi != NULL ?
3065 sizeof(mi->ssl_key) : 0));
3066 field_list.push_back(new Item_return_int("Seconds_Behind_Master", 10,
3067 MYSQL_TYPE_LONGLONG));
3068 field_list.push_back(new Item_empty_string("Master_SSL_Verify_Server_Cert",
3069 3));
3070 field_list.push_back(new Item_return_int("Last_IO_Errno", 4, MYSQL_TYPE_LONG));
3071 field_list.push_back(new Item_empty_string("Last_IO_Error", 20));
3072 field_list.push_back(new Item_return_int("Last_SQL_Errno", 4, MYSQL_TYPE_LONG));
3073 field_list.push_back(new Item_empty_string("Last_SQL_Error", 20));
3074 field_list.push_back(new Item_empty_string("Replicate_Ignore_Server_Ids",
3075 FN_REFLEN));
3076 field_list.push_back(new Item_return_int("Master_Server_Id", sizeof(ulong),
3077 MYSQL_TYPE_LONG));
3078 field_list.push_back(new Item_empty_string("Master_UUID", UUID_LENGTH));
3079 field_list.push_back(new Item_empty_string("Master_Info_File",
3080 2 * FN_REFLEN));
3081 field_list.push_back(new Item_return_int("SQL_Delay", 10, MYSQL_TYPE_LONG));
3082 field_list.push_back(new Item_return_int("SQL_Remaining_Delay", 8, MYSQL_TYPE_LONG));
3083 field_list.push_back(new Item_empty_string("Slave_SQL_Running_State", 20));
3084 field_list.push_back(new Item_return_int("Master_Retry_Count", 10,
3085 MYSQL_TYPE_LONGLONG));
3086 field_list.push_back(new Item_empty_string("Master_Bind", mi != NULL ?
3087 sizeof(mi->bind_addr) : 0));
3088 field_list.push_back(new Item_empty_string("Last_IO_Error_Timestamp", 20));
3089 field_list.push_back(new Item_empty_string("Last_SQL_Error_Timestamp", 20));
3090 field_list.push_back(new Item_empty_string("Master_SSL_Crl", mi != NULL ?
3091 sizeof(mi->ssl_crl) : 0));
3092 field_list.push_back(new Item_empty_string("Master_SSL_Crlpath", mi != NULL ?
3093 sizeof(mi->ssl_crlpath) : 0));
3094 field_list.push_back(new Item_empty_string("Retrieved_Gtid_Set",
3095 io_gtid_set_size));
3096 field_list.push_back(new Item_empty_string("Executed_Gtid_Set",
3097 sql_gtid_set_size));
3098 field_list.push_back(new Item_return_int("Auto_Position", sizeof(ulong),
3099 MYSQL_TYPE_LONG));
3100
3101 if (protocol->send_result_set_metadata(&field_list,
3102 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
3103 {
3104 my_free(sql_gtid_set_buffer);
3105 my_free(io_gtid_set_buffer);
3106 DBUG_RETURN(true);
3107 }
3108
3109 if (mi != NULL && mi->host[0])
3110 {
3111 DBUG_PRINT("info",("host is set: '%s'", mi->host));
3112 String *packet= &thd->packet;
3113 protocol->prepare_for_resend();
3114
3115 /*
3116 slave_running can be accessed without run_lock but not other
3117 non-volotile members like mi->info_thd, which is guarded by the mutex.
3118 */
3119 mysql_mutex_lock(&mi->run_lock);
3120 protocol->store(mi->info_thd ? mi->info_thd->get_proc_info() : "", &my_charset_bin);
3121 mysql_mutex_unlock(&mi->run_lock);
3122
3123 mysql_mutex_lock(&mi->rli->run_lock);
3124 slave_sql_running_state= const_cast<char *>(mi->rli->info_thd ? mi->rli->info_thd->get_proc_info() : "");
3125 mysql_mutex_unlock(&mi->rli->run_lock);
3126
3127 mysql_mutex_lock(&mi->data_lock);
3128 mysql_mutex_lock(&mi->rli->data_lock);
3129 mysql_mutex_lock(&mi->err_lock);
3130 mysql_mutex_lock(&mi->rli->err_lock);
3131
3132 DEBUG_SYNC(thd, "wait_after_lock_active_mi_and_rli_data_lock_is_acquired");
3133 protocol->store(mi->host, &my_charset_bin);
3134 protocol->store(mi->get_user(), &my_charset_bin);
3135 protocol->store((uint32) mi->port);
3136 protocol->store((uint32) mi->connect_retry);
3137 protocol->store(mi->get_master_log_name(), &my_charset_bin);
3138 protocol->store((ulonglong) mi->get_master_log_pos());
3139 protocol->store(mi->rli->get_group_relay_log_name() +
3140 dirname_length(mi->rli->get_group_relay_log_name()),
3141 &my_charset_bin);
3142 protocol->store((ulonglong) mi->rli->get_group_relay_log_pos());
3143 protocol->store(mi->rli->get_group_master_log_name(), &my_charset_bin);
3144 protocol->store(mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
3145 "Yes" : (mi->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT ?
3146 "Connecting" : "No"), &my_charset_bin);
3147 protocol->store(mi->rli->slave_running ? "Yes":"No", &my_charset_bin);
3148 protocol->store(rpl_filter->get_do_db());
3149 protocol->store(rpl_filter->get_ignore_db());
3150
3151 char buf[256];
3152 String tmp(buf, sizeof(buf), &my_charset_bin);
3153 rpl_filter->get_do_table(&tmp);
3154 protocol->store(&tmp);
3155 rpl_filter->get_ignore_table(&tmp);
3156 protocol->store(&tmp);
3157 rpl_filter->get_wild_do_table(&tmp);
3158 protocol->store(&tmp);
3159 rpl_filter->get_wild_ignore_table(&tmp);
3160 protocol->store(&tmp);
3161
3162 protocol->store(mi->rli->last_error().number);
3163 protocol->store(mi->rli->last_error().message, &my_charset_bin);
3164 protocol->store((uint32) mi->rli->slave_skip_counter);
3165 protocol->store((ulonglong) mi->rli->get_group_master_log_pos());
3166 protocol->store((ulonglong) mi->rli->log_space_total);
3167
3168 const char *until_type= "";
3169
3170 switch (mi->rli->until_condition)
3171 {
3172 case Relay_log_info::UNTIL_NONE:
3173 until_type= "None";
3174 break;
3175 case Relay_log_info::UNTIL_MASTER_POS:
3176 until_type= "Master";
3177 break;
3178 case Relay_log_info::UNTIL_RELAY_POS:
3179 until_type= "Relay";
3180 break;
3181 case Relay_log_info::UNTIL_SQL_BEFORE_GTIDS:
3182 until_type= "SQL_BEFORE_GTIDS";
3183 break;
3184 case Relay_log_info::UNTIL_SQL_AFTER_GTIDS:
3185 until_type= "SQL_AFTER_GTIDS";
3186 break;
3187 case Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS:
3188 until_type= "SQL_AFTER_MTS_GAPS";
3189 case Relay_log_info::UNTIL_DONE:
3190 until_type= "DONE";
3191 break;
3192 default:
3193 DBUG_ASSERT(0);
3194 }
3195 protocol->store(until_type, &my_charset_bin);
3196 protocol->store(mi->rli->until_log_name, &my_charset_bin);
3197 protocol->store((ulonglong) mi->rli->until_log_pos);
3198
3199 #ifdef HAVE_OPENSSL
3200 protocol->store(mi->ssl? "Yes":"No", &my_charset_bin);
3201 #else
3202 protocol->store(mi->ssl? "Ignored":"No", &my_charset_bin);
3203 #endif
3204 protocol->store(mi->ssl_ca, &my_charset_bin);
3205 protocol->store(mi->ssl_capath, &my_charset_bin);
3206 protocol->store(mi->ssl_cert, &my_charset_bin);
3207 protocol->store(mi->ssl_cipher, &my_charset_bin);
3208 protocol->store(mi->ssl_key, &my_charset_bin);
3209
3210 /*
3211 The pseudo code to compute Seconds_Behind_Master:
3212 if (SQL thread is running)
3213 {
3214 if (SQL thread processed all the available relay log)
3215 {
3216 if (IO thread is running)
3217 print 0;
3218 else
3219 print NULL;
3220 }
3221 else
3222 compute Seconds_Behind_Master;
3223 }
3224 else
3225 print NULL;
3226 */
3227 if (mi->rli->slave_running)
3228 {
3229 /* Check if SQL thread is at the end of relay log
3230 Checking should be done using two conditions
3231 condition1: compare the log positions and
3232 condition2: compare the file names (to handle rotation case)
3233 */
3234 if ((mi->get_master_log_pos() == mi->rli->get_group_master_log_pos()) &&
3235 (!strcmp(mi->get_master_log_name(), mi->rli->get_group_master_log_name())))
3236 {
3237 if (mi->slave_running == MYSQL_SLAVE_RUN_CONNECT)
3238 protocol->store(0LL);
3239 else
3240 protocol->store_null();
3241 }
3242 else
3243 {
3244 long time_diff= ((long)(time(0) - mi->rli->last_master_timestamp)
3245 - mi->clock_diff_with_master);
3246 /*
3247 Apparently on some systems time_diff can be <0. Here are possible
3248 reasons related to MySQL:
3249 - the master is itself a slave of another master whose time is ahead.
3250 - somebody used an explicit SET TIMESTAMP on the master.
3251 Possible reason related to granularity-to-second of time functions
3252 (nothing to do with MySQL), which can explain a value of -1:
3253 assume the master's and slave's time are perfectly synchronized, and
3254 that at slave's connection time, when the master's timestamp is read,
3255 it is at the very end of second 1, and (a very short time later) when
3256 the slave's timestamp is read it is at the very beginning of second
3257 2. Then the recorded value for master is 1 and the recorded value for
3258 slave is 2. At SHOW SLAVE STATUS time, assume that the difference
3259 between timestamp of slave and rli->last_master_timestamp is 0
3260 (i.e. they are in the same second), then we get 0-(2-1)=-1 as a result.
3261 This confuses users, so we don't go below 0: hence the max().
3262
3263 last_master_timestamp == 0 (an "impossible" timestamp 1970) is a
3264 special marker to say "consider we have caught up".
3265 */
3266 protocol->store((longlong)(mi->rli->last_master_timestamp ?
3267 max(0L, time_diff) : 0));
3268 }
3269 }
3270 else
3271 {
3272 protocol->store_null();
3273 }
3274 protocol->store(mi->ssl_verify_server_cert? "Yes":"No", &my_charset_bin);
3275
3276 // Last_IO_Errno
3277 protocol->store(mi->last_error().number);
3278 // Last_IO_Error
3279 protocol->store(mi->last_error().message, &my_charset_bin);
3280 // Last_SQL_Errno
3281 protocol->store(mi->rli->last_error().number);
3282 // Last_SQL_Error
3283 protocol->store(mi->rli->last_error().message, &my_charset_bin);
3284 // Replicate_Ignore_Server_Ids
3285 {
3286 char buff[FN_REFLEN];
3287 ulong i, cur_len;
3288 for (i= 0, buff[0]= 0, cur_len= 0;
3289 i < mi->ignore_server_ids->dynamic_ids.elements; i++)
3290 {
3291 ulong s_id, slen;
3292 char sbuff[FN_REFLEN];
3293 get_dynamic(&(mi->ignore_server_ids->dynamic_ids), (uchar*) &s_id, i);
3294 slen= sprintf(sbuff, (i == 0 ? "%lu" : ", %lu"), s_id);
3295 if (cur_len + slen + 4 > FN_REFLEN)
3296 {
3297 /*
3298 break the loop whenever remained space could not fit
3299 ellipses on the next cycle
3300 */
3301 sprintf(buff + cur_len, "...");
3302 break;
3303 }
3304 cur_len += sprintf(buff + cur_len, "%s", sbuff);
3305 }
3306 protocol->store(buff, &my_charset_bin);
3307 }
3308 // Master_Server_id
3309 protocol->store((uint32) mi->master_id);
3310 protocol->store(mi->master_uuid, &my_charset_bin);
3311 // Master_Info_File
3312 protocol->store(mi->get_description_info(), &my_charset_bin);
3313 // SQL_Delay
3314 protocol->store((uint32) mi->rli->get_sql_delay());
3315 // SQL_Remaining_Delay
3316 if (slave_sql_running_state == stage_sql_thd_waiting_until_delay.m_name)
3317 {
3318 time_t t= my_time(0), sql_delay_end= mi->rli->get_sql_delay_end();
3319 protocol->store((uint32)(t < sql_delay_end ? sql_delay_end - t : 0));
3320 }
3321 else
3322 protocol->store_null();
3323 // Slave_SQL_Running_State
3324 protocol->store(slave_sql_running_state, &my_charset_bin);
3325 // Master_Retry_Count
3326 protocol->store((ulonglong) mi->retry_count);
3327 // Master_Bind
3328 protocol->store(mi->bind_addr, &my_charset_bin);
3329 // Last_IO_Error_Timestamp
3330 protocol->store(mi->last_error().timestamp, &my_charset_bin);
3331 // Last_SQL_Error_Timestamp
3332 protocol->store(mi->rli->last_error().timestamp, &my_charset_bin);
3333 // Master_Ssl_Crl
3334 protocol->store(mi->ssl_crl, &my_charset_bin);
3335 // Master_Ssl_Crlpath
3336 protocol->store(mi->ssl_crlpath, &my_charset_bin);
3337 // Retrieved_Gtid_Set
3338 protocol->store(io_gtid_set_buffer, &my_charset_bin);
3339 // Executed_Gtid_Set
3340 protocol->store(sql_gtid_set_buffer, &my_charset_bin);
3341 // Auto_Position
3342 protocol->store(mi->is_auto_position() ? 1 : 0);
3343
3344 mysql_mutex_unlock(&mi->rli->err_lock);
3345 mysql_mutex_unlock(&mi->err_lock);
3346 mysql_mutex_unlock(&mi->rli->data_lock);
3347 mysql_mutex_unlock(&mi->data_lock);
3348
3349 if (my_net_write(&thd->net, (uchar*) thd->packet.ptr(), packet->length()))
3350 {
3351 my_free(sql_gtid_set_buffer);
3352 my_free(io_gtid_set_buffer);
3353 DBUG_RETURN(true);
3354 }
3355 }
3356 my_eof(thd);
3357 my_free(sql_gtid_set_buffer);
3358 my_free(io_gtid_set_buffer);
3359 DBUG_RETURN(false);
3360 }
3361
3362
set_slave_thread_options(THD * thd)3363 void set_slave_thread_options(THD* thd)
3364 {
3365 DBUG_ENTER("set_slave_thread_options");
3366 /*
3367 It's nonsense to constrain the slave threads with max_join_size; if a
3368 query succeeded on master, we HAVE to execute it. So set
3369 OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
3370 (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
3371 SELECT examining more than 4 billion rows would still fail (yes, because
3372 when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
3373 only for client threads.
3374 */
3375 ulonglong options= thd->variables.option_bits | OPTION_BIG_SELECTS;
3376 if (opt_log_slave_updates)
3377 options|= OPTION_BIN_LOG;
3378 else
3379 options&= ~OPTION_BIN_LOG;
3380 thd->variables.option_bits= options;
3381 thd->variables.completion_type= 0;
3382
3383 /*
3384 Set autocommit= 1 when info tables are used and autocommit == 0 to
3385 avoid trigger asserts on mysql_execute_command(THD *thd) caused by
3386 info tables updates which do not commit, like Rotate, Stop and
3387 skipped events handling.
3388 */
3389 if (is_autocommit_off_and_infotables(thd))
3390 {
3391 thd->variables.option_bits|= OPTION_AUTOCOMMIT;
3392 thd->variables.option_bits&= ~OPTION_NOT_AUTOCOMMIT;
3393 thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
3394 }
3395
3396 DBUG_VOID_RETURN;
3397 }
3398
set_slave_thread_default_charset(THD * thd,Relay_log_info const * rli)3399 void set_slave_thread_default_charset(THD* thd, Relay_log_info const *rli)
3400 {
3401 DBUG_ENTER("set_slave_thread_default_charset");
3402
3403 thd->variables.character_set_client=
3404 global_system_variables.character_set_client;
3405 thd->variables.collation_connection=
3406 global_system_variables.collation_connection;
3407 thd->variables.collation_server=
3408 global_system_variables.collation_server;
3409 thd->update_charset();
3410
3411 /*
3412 We use a const cast here since the conceptual (and externally
3413 visible) behavior of the function is to set the default charset of
3414 the thread. That the cache has to be invalidated is a secondary
3415 effect.
3416 */
3417 const_cast<Relay_log_info*>(rli)->cached_charset_invalidate();
3418 DBUG_VOID_RETURN;
3419 }
3420
3421 /*
3422 init_slave_thread()
3423 */
3424
init_slave_thread(THD * thd,SLAVE_THD_TYPE thd_type)3425 static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
3426 {
3427 DBUG_ENTER("init_slave_thread");
3428 #if !defined(DBUG_OFF)
3429 int simulate_error= 0;
3430 #endif
3431 thd->system_thread= (thd_type == SLAVE_THD_WORKER) ?
3432 SYSTEM_THREAD_SLAVE_WORKER : (thd_type == SLAVE_THD_SQL) ?
3433 SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
3434 thd->security_ctx->skip_grants();
3435 my_net_init(&thd->net, 0);
3436 thd->slave_thread = 1;
3437 thd->enable_slow_log= opt_log_slow_slave_statements;
3438 set_slave_thread_options(thd);
3439 mysql_mutex_lock(&LOCK_thread_count);
3440 thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
3441 mysql_mutex_unlock(&LOCK_thread_count);
3442
3443 DBUG_EXECUTE_IF("simulate_io_slave_error_on_init",
3444 simulate_error|= (1 << SLAVE_THD_IO););
3445 DBUG_EXECUTE_IF("simulate_sql_slave_error_on_init",
3446 simulate_error|= (1 << SLAVE_THD_SQL););
3447 #if !defined(DBUG_OFF)
3448 if (init_thr_lock() || thd->store_globals() || simulate_error & (1<< thd_type))
3449 #else
3450 if (init_thr_lock() || thd->store_globals())
3451 #endif
3452 {
3453 DBUG_RETURN(-1);
3454 }
3455
3456 if (thd_type == SLAVE_THD_SQL)
3457 {
3458 THD_STAGE_INFO(thd, stage_waiting_for_the_next_event_in_relay_log);
3459 }
3460 else
3461 {
3462 THD_STAGE_INFO(thd, stage_waiting_for_master_update);
3463 }
3464 thd->set_time();
3465 /* Do not use user-supplied timeout value for system threads. */
3466 thd->variables.lock_wait_timeout= LONG_TIMEOUT;
3467 DBUG_RETURN(0);
3468 }
3469
3470
3471 /**
3472 Sleep for a given amount of time or until killed.
3473
3474 @param thd Thread context of the current thread.
3475 @param seconds The number of seconds to sleep.
3476 @param func Function object to check if the thread has been killed.
3477 @param info The Rpl_info object associated with this sleep.
3478
3479 @retval True if the thread has been killed, false otherwise.
3480 */
3481 template <typename killed_func, typename rpl_info>
slave_sleep(THD * thd,time_t seconds,killed_func func,rpl_info info)3482 static inline bool slave_sleep(THD *thd, time_t seconds,
3483 killed_func func, rpl_info info)
3484 {
3485 bool ret;
3486 struct timespec abstime;
3487 mysql_mutex_t *lock= &info->sleep_lock;
3488 mysql_cond_t *cond= &info->sleep_cond;
3489
3490 /* Absolute system time at which the sleep time expires. */
3491 set_timespec(abstime, seconds);
3492
3493 mysql_mutex_lock(lock);
3494 thd->ENTER_COND(cond, lock, NULL, NULL);
3495
3496 while (! (ret= func(thd, info)))
3497 {
3498 int error= mysql_cond_timedwait(cond, lock, &abstime);
3499 if (error == ETIMEDOUT || error == ETIME)
3500 break;
3501 }
3502
3503 /* Implicitly unlocks the mutex. */
3504 thd->EXIT_COND(NULL);
3505
3506 return ret;
3507 }
3508
request_dump(THD * thd,MYSQL * mysql,Master_info * mi,bool * suppress_warnings)3509 static int request_dump(THD *thd, MYSQL* mysql, Master_info* mi,
3510 bool *suppress_warnings)
3511 {
3512 DBUG_ENTER("request_dump");
3513
3514 const int BINLOG_NAME_INFO_SIZE= strlen(mi->get_master_log_name());
3515 int error= 1;
3516 size_t command_size= 0;
3517 enum_server_command command= mi->is_auto_position() ?
3518 COM_BINLOG_DUMP_GTID : COM_BINLOG_DUMP;
3519 uchar* command_buffer= NULL;
3520 ushort binlog_flags= 0;
3521
3522 if (RUN_HOOK(binlog_relay_io,
3523 before_request_transmit,
3524 (thd, mi, binlog_flags)))
3525 goto err;
3526
3527 *suppress_warnings= false;
3528 if (command == COM_BINLOG_DUMP_GTID)
3529 {
3530 // get set of GTIDs
3531 Sid_map sid_map(NULL/*no lock needed*/);
3532 Gtid_set gtid_executed(&sid_map);
3533 global_sid_lock->wrlock();
3534 gtid_state->dbug_print();
3535
3536 /*
3537 We are unsure whether I/O thread retrieved the last gtid transaction
3538 completely or not (before it is going down because of a crash/normal
3539 shutdown/normal stop slave io_thread). It is possible that I/O thread
3540 would have retrieved and written only partial transaction events. So We
3541 request Master to send the last gtid event once again. We do this by
3542 removing the last I/O thread retrieved gtid event from
3543 "Retrieved_gtid_set". Possible cases: 1) I/O thread would have
3544 retrieved full transaction already in the first time itself, but
3545 retrieving them again will not cause problem because GTID number is
3546 same, Hence SQL thread will not commit it again. 2) I/O thread would
3547 have retrieved full transaction already and SQL thread would have
3548 already executed it. In that case, We are not going remove last
3549 retrieved gtid from "Retrieved_gtid_set" otherwise we will see gaps in
3550 "Retrieved set". The same case is handled in the below code. Please
3551 note there will be paritial transactions written in relay log but they
3552 will not cause any problem incase of transactional tables. But incase
3553 of non-transaction tables, partial trx will create inconsistency
3554 between master and slave. In that case, users need to check manually.
3555 */
3556
3557 Gtid_set * retrieved_set= (const_cast<Gtid_set *>(mi->rli->get_gtid_set()));
3558 Gtid *last_retrieved_gtid= mi->rli->get_last_retrieved_gtid();
3559
3560 /*
3561 Remove last_retrieved_gtid only if it is not part of
3562 executed_gtid_set
3563 */
3564 if (!last_retrieved_gtid->empty() &&
3565 !gtid_state->get_logged_gtids()->contains_gtid(*last_retrieved_gtid))
3566 {
3567 if (retrieved_set->_remove_gtid(*last_retrieved_gtid) != RETURN_STATUS_OK)
3568 {
3569 global_sid_lock->unlock();
3570 goto err;
3571 }
3572 }
3573
3574 if (gtid_executed.add_gtid_set(mi->rli->get_gtid_set()) != RETURN_STATUS_OK ||
3575 gtid_executed.add_gtid_set(gtid_state->get_logged_gtids()) !=
3576 RETURN_STATUS_OK)
3577 {
3578 global_sid_lock->unlock();
3579 goto err;
3580 }
3581 global_sid_lock->unlock();
3582
3583 // allocate buffer
3584 size_t encoded_data_size= gtid_executed.get_encoded_length();
3585 size_t allocation_size=
3586 ::BINLOG_FLAGS_INFO_SIZE + ::BINLOG_SERVER_ID_INFO_SIZE +
3587 ::BINLOG_NAME_SIZE_INFO_SIZE + BINLOG_NAME_INFO_SIZE +
3588 ::BINLOG_POS_INFO_SIZE + ::BINLOG_DATA_SIZE_INFO_SIZE +
3589 encoded_data_size + 1;
3590 if (!(command_buffer= (uchar *) my_malloc(allocation_size, MYF(MY_WME))))
3591 goto err;
3592 uchar* ptr_buffer= command_buffer;
3593
3594 DBUG_PRINT("info", ("Do I know something about the master? (binary log's name %s - auto position %d).",
3595 mi->get_master_log_name(), mi->is_auto_position()));
3596 /*
3597 Note: binlog_flags is always 0. However, in versions up to 5.6
3598 RC, the master would check the lowest bit and do something
3599 unexpected if it was set; in early versions of 5.6 it would also
3600 use the two next bits. Therefore, for backward compatibility,
3601 if we ever start to use the flags, we should leave the three
3602 lowest bits unused.
3603 */
3604 int2store(ptr_buffer, binlog_flags);
3605 ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE;
3606 int4store(ptr_buffer, server_id);
3607 ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE;
3608 int4store(ptr_buffer, BINLOG_NAME_INFO_SIZE);
3609 ptr_buffer+= ::BINLOG_NAME_SIZE_INFO_SIZE;
3610 memset(ptr_buffer, 0, BINLOG_NAME_INFO_SIZE);
3611 ptr_buffer+= BINLOG_NAME_INFO_SIZE;
3612 int8store(ptr_buffer, 4LL);
3613 ptr_buffer+= ::BINLOG_POS_INFO_SIZE;
3614
3615 int4store(ptr_buffer, encoded_data_size);
3616 ptr_buffer+= ::BINLOG_DATA_SIZE_INFO_SIZE;
3617 gtid_executed.encode(ptr_buffer);
3618 ptr_buffer+= encoded_data_size;
3619
3620 command_size= ptr_buffer - command_buffer;
3621 DBUG_ASSERT(command_size == (allocation_size - 1));
3622 }
3623 else
3624 {
3625 size_t allocation_size= ::BINLOG_POS_OLD_INFO_SIZE +
3626 BINLOG_NAME_INFO_SIZE + ::BINLOG_FLAGS_INFO_SIZE +
3627 ::BINLOG_SERVER_ID_INFO_SIZE + 1;
3628 if (!(command_buffer= (uchar *) my_malloc(allocation_size, MYF(MY_WME))))
3629 goto err;
3630 uchar* ptr_buffer= command_buffer;
3631
3632 int4store(ptr_buffer, mi->get_master_log_pos());
3633 ptr_buffer+= ::BINLOG_POS_OLD_INFO_SIZE;
3634 // See comment regarding binlog_flags above.
3635 int2store(ptr_buffer, binlog_flags);
3636 ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE;
3637 int4store(ptr_buffer, server_id);
3638 ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE;
3639 memcpy(ptr_buffer, mi->get_master_log_name(), BINLOG_NAME_INFO_SIZE);
3640 ptr_buffer+= BINLOG_NAME_INFO_SIZE;
3641
3642 command_size= ptr_buffer - command_buffer;
3643 DBUG_ASSERT(command_size == (allocation_size - 1));
3644 }
3645
3646 if (simple_command(mysql, command, command_buffer, command_size, 1))
3647 {
3648 /*
3649 Something went wrong, so we will just reconnect and retry later
3650 in the future, we should do a better error analysis, but for
3651 now we just fill up the error log :-)
3652 */
3653 if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
3654 *suppress_warnings= true; // Suppress reconnect warning
3655 else
3656 sql_print_error("Error on %s: %d %s, will retry in %d secs",
3657 command_name[command].str,
3658 mysql_errno(mysql), mysql_error(mysql),
3659 mi->connect_retry);
3660 goto err;
3661 }
3662 error= 0;
3663
3664 err:
3665 my_free(command_buffer);
3666 DBUG_RETURN(error);
3667 }
3668
3669
3670 /*
3671 Read one event from the master
3672
3673 SYNOPSIS
3674 read_event()
3675 mysql MySQL connection
3676 mi Master connection information
3677 suppress_warnings TRUE when a normal net read timeout has caused us to
3678 try a reconnect. We do not want to print anything to
3679 the error log in this case because this a anormal
3680 event in an idle server.
3681
3682 RETURN VALUES
3683 'packet_error' Error
3684 number Length of packet
3685 */
3686
read_event(MYSQL * mysql,Master_info * mi,bool * suppress_warnings)3687 static ulong read_event(MYSQL* mysql, Master_info *mi, bool* suppress_warnings)
3688 {
3689 ulong len;
3690 DBUG_ENTER("read_event");
3691
3692 *suppress_warnings= FALSE;
3693 /*
3694 my_real_read() will time us out
3695 We check if we were told to die, and if not, try reading again
3696 */
3697 #ifndef DBUG_OFF
3698 if (disconnect_slave_event_count && !(mi->events_until_exit--))
3699 DBUG_RETURN(packet_error);
3700 #endif
3701
3702 len = cli_safe_read(mysql);
3703 if (len == packet_error || (long) len < 1)
3704 {
3705 if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED)
3706 {
3707 /*
3708 We are trying a normal reconnect after a read timeout;
3709 we suppress prints to .err file as long as the reconnect
3710 happens without problems
3711 */
3712 *suppress_warnings= TRUE;
3713 }
3714 else
3715 {
3716 if (!mi->abort_slave)
3717 {
3718 sql_print_error("Error reading packet from server: %s (server_errno=%d)",
3719 mysql_error(mysql), mysql_errno(mysql));
3720 }
3721 }
3722 DBUG_RETURN(packet_error);
3723 }
3724
3725 /* Check if eof packet */
3726 if (len < 8 && mysql->net.read_pos[0] == 254)
3727 {
3728 sql_print_information("Slave: received end packet from server due to dump "
3729 "thread being killed on master. Dump threads are "
3730 "killed for example during master shutdown, "
3731 "explicitly by a user, or when the master receives "
3732 "a binlog send request from a duplicate server "
3733 "UUID <%s> : Error %s", ::server_uuid,
3734 mysql_error(mysql));
3735 DBUG_RETURN(packet_error);
3736 }
3737
3738 DBUG_PRINT("exit", ("len: %lu net->read_pos[4]: %d",
3739 len, mysql->net.read_pos[4]));
3740 DBUG_RETURN(len - 1);
3741 }
3742
3743
3744 /**
3745 If this is a lagging slave (specified with CHANGE MASTER TO MASTER_DELAY = X), delays accordingly. Also unlocks rli->data_lock.
3746
3747 Design note: this is the place to unlock rli->data_lock. The lock
3748 must be held when reading delay info from rli, but it should not be
3749 held while sleeping.
3750
3751 @param ev Event that is about to be executed.
3752
3753 @param thd The sql thread's THD object.
3754
3755 @param rli The sql thread's Relay_log_info structure.
3756
3757 @retval 0 If the delay timed out and the event shall be executed.
3758
3759 @retval nonzero If the delay was interrupted and the event shall be skipped.
3760 */
sql_delay_event(Log_event * ev,THD * thd,Relay_log_info * rli)3761 static int sql_delay_event(Log_event *ev, THD *thd, Relay_log_info *rli)
3762 {
3763 long sql_delay= rli->get_sql_delay();
3764
3765 DBUG_ENTER("sql_delay_event");
3766 mysql_mutex_assert_owner(&rli->data_lock);
3767 DBUG_ASSERT(!rli->belongs_to_client());
3768
3769 int type= ev->get_type_code();
3770 if (sql_delay && type != ROTATE_EVENT &&
3771 type != FORMAT_DESCRIPTION_EVENT && type != START_EVENT_V3)
3772 {
3773 // The time when we should execute the event.
3774 time_t sql_delay_end=
3775 ev->when.tv_sec + rli->mi->clock_diff_with_master + sql_delay;
3776 // The current time.
3777 time_t now= my_time(0);
3778 // The time we will have to sleep before executing the event.
3779 unsigned long nap_time= 0;
3780 if (sql_delay_end > now)
3781 nap_time= sql_delay_end - now;
3782
3783 DBUG_PRINT("info", ("sql_delay= %lu "
3784 "ev->when= %lu "
3785 "rli->mi->clock_diff_with_master= %lu "
3786 "now= %ld "
3787 "sql_delay_end= %ld "
3788 "nap_time= %ld",
3789 sql_delay, (long) ev->when.tv_sec,
3790 rli->mi->clock_diff_with_master,
3791 (long)now, (long)sql_delay_end, (long)nap_time));
3792
3793 if (sql_delay_end > now)
3794 {
3795 DBUG_PRINT("info", ("delaying replication event %lu secs",
3796 nap_time));
3797 rli->start_sql_delay(sql_delay_end);
3798 mysql_mutex_unlock(&rli->data_lock);
3799 DBUG_RETURN(slave_sleep(thd, nap_time, sql_slave_killed, rli));
3800 }
3801 }
3802
3803 mysql_mutex_unlock(&rli->data_lock);
3804
3805 DBUG_RETURN(0);
3806 }
3807
3808 /**
3809 a sort_dynamic function on ulong type
3810 returns as specified by @c qsort_cmp
3811 */
ulong_cmp(ulong * id1,ulong * id2)3812 int ulong_cmp(ulong *id1, ulong *id2)
3813 {
3814 return *id1 < *id2? -1 : (*id1 > *id2? 1 : 0);
3815 }
3816
3817 /**
3818 Applies the given event and advances the relay log position.
3819
3820 This is needed by the sql thread to execute events from the binlog,
3821 and by clients executing BINLOG statements. Conceptually, this
3822 function does:
3823
3824 @code
3825 ev->apply_event(rli);
3826 ev->update_pos(rli);
3827 @endcode
3828
3829 It also does the following maintainance:
3830
3831 - Initializes the thread's server_id and time; and the event's
3832 thread.
3833
3834 - If !rli->belongs_to_client() (i.e., if it belongs to the slave
3835 sql thread instead of being used for executing BINLOG
3836 statements), it does the following things: (1) skips events if it
3837 is needed according to the server id or slave_skip_counter; (2)
3838 unlocks rli->data_lock; (3) sleeps if required by 'CHANGE MASTER
3839 TO MASTER_DELAY=X'; (4) maintains the running state of the sql
3840 thread (rli->thread_state).
3841
3842 - Reports errors as needed.
3843
3844 @param ptr_ev a pointer to a reference to the event to apply.
3845
3846 @param thd The client thread that executes the event (i.e., the
3847 slave sql thread if called from a replication slave, or the client
3848 thread if called to execute a BINLOG statement).
3849
3850 @param rli The relay log info (i.e., the slave's rli if called from
3851 a replication slave, or the client's thd->rli_fake if called to
3852 execute a BINLOG statement).
3853
3854 @note MTS can store NULL to @c ptr_ev location to indicate
3855 the event is taken over by a Worker.
3856
3857 @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK
3858 OK.
3859
3860 @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR
3861 Error calling ev->apply_event().
3862
3863 @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR
3864 No error calling ev->apply_event(), but error calling
3865 ev->update_pos().
3866
3867 @retval SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR
3868 append_item_to_jobs() failed, thread was killed while waiting
3869 for successful enqueue on worker.
3870 */
3871 enum enum_slave_apply_event_and_update_pos_retval
apply_event_and_update_pos(Log_event ** ptr_ev,THD * thd,Relay_log_info * rli)3872 apply_event_and_update_pos(Log_event** ptr_ev, THD* thd, Relay_log_info* rli)
3873 {
3874 int exec_res= 0;
3875 bool skip_event= FALSE;
3876 Log_event *ev= *ptr_ev;
3877 Log_event::enum_skip_reason reason= Log_event::EVENT_SKIP_NOT;
3878
3879 DBUG_ENTER("apply_event_and_update_pos");
3880
3881 DBUG_PRINT("exec_event",("%s(type_code: %d; server_id: %d)",
3882 ev->get_type_str(), ev->get_type_code(),
3883 ev->server_id));
3884 DBUG_PRINT("info", ("thd->options: %s%s; rli->last_event_start_time: %lu",
3885 FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT),
3886 FLAGSTR(thd->variables.option_bits, OPTION_BEGIN),
3887 (ulong) rli->last_event_start_time));
3888
3889 /*
3890 Execute the event to change the database and update the binary
3891 log coordinates, but first we set some data that is needed for
3892 the thread.
3893
3894 The event will be executed unless it is supposed to be skipped.
3895
3896 Queries originating from this server must be skipped. Low-level
3897 events (Format_description_log_event, Rotate_log_event,
3898 Stop_log_event) from this server must also be skipped. But for
3899 those we don't want to modify 'group_master_log_pos', because
3900 these events did not exist on the master.
3901 Format_description_log_event is not completely skipped.
3902
3903 Skip queries specified by the user in 'slave_skip_counter'. We
3904 can't however skip events that has something to do with the log
3905 files themselves.
3906
3907 Filtering on own server id is extremely important, to ignore
3908 execution of events created by the creation/rotation of the relay
3909 log (remember that now the relay log starts with its Format_desc,
3910 has a Rotate etc).
3911 */
3912 /*
3913 Set the unmasked and actual server ids from the event
3914 */
3915 thd->server_id = ev->server_id; // use the original server id for logging
3916 thd->unmasked_server_id = ev->unmasked_server_id;
3917 thd->set_time(); // time the query
3918 thd->lex->current_select= 0;
3919 if (!ev->when.tv_sec)
3920 my_micro_time_to_timeval(my_micro_time(), &ev->when);
3921 ev->thd = thd; // because up to this point, ev->thd == 0
3922
3923 if (!(rli->is_mts_recovery() && bitmap_is_set(&rli->recovery_groups,
3924 rli->mts_recovery_index)))
3925 {
3926 reason= ev->shall_skip(rli);
3927 }
3928 #ifndef DBUG_OFF
3929 if (rli->is_mts_recovery())
3930 {
3931 DBUG_PRINT("mts", ("Mts is recovering %d, number of bits set %d, "
3932 "bitmap is set %d, index %lu.\n",
3933 rli->is_mts_recovery(),
3934 bitmap_bits_set(&rli->recovery_groups),
3935 bitmap_is_set(&rli->recovery_groups,
3936 rli->mts_recovery_index),
3937 rli->mts_recovery_index));
3938 }
3939 #endif
3940 if (reason == Log_event::EVENT_SKIP_COUNT)
3941 {
3942 sql_slave_skip_counter= --rli->slave_skip_counter;
3943 skip_event= TRUE;
3944 }
3945 if (reason == Log_event::EVENT_SKIP_NOT)
3946 {
3947 // Sleeps if needed, and unlocks rli->data_lock.
3948 if (sql_delay_event(ev, thd, rli))
3949 DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK);
3950
3951 exec_res= ev->apply_event(rli);
3952 DBUG_EXECUTE_IF("simulate_stop_when_mts_in_group",
3953 if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP
3954 && rli->curr_group_seen_begin)
3955 DBUG_SET("+d,stop_when_mts_in_group"););
3956
3957 if (!exec_res && (ev->worker != rli))
3958 {
3959 if (ev->worker)
3960 {
3961 Slave_job_item item= {ev}, *job_item= &item;
3962 Slave_worker *w= (Slave_worker *) ev->worker;
3963 // specially marked group typically with OVER_MAX_DBS_IN_EVENT_MTS db:s
3964 bool need_sync= ev->is_mts_group_isolated();
3965
3966 // all events except BEGIN-query must be marked with a non-NULL Worker
3967 DBUG_ASSERT(((Slave_worker*) ev->worker) == rli->last_assigned_worker);
3968
3969 DBUG_PRINT("Log_event::apply_event:",
3970 ("-> job item data %p to W_%lu", job_item->data, w->id));
3971
3972 // Reset mts in-group state
3973 if (rli->mts_group_status == Relay_log_info::MTS_END_GROUP)
3974 {
3975 // CGAP cleanup
3976 for (uint i= rli->curr_group_assigned_parts.elements; i > 0; i--)
3977 delete_dynamic_element(&rli->
3978 curr_group_assigned_parts, i - 1);
3979 // reset the B-group and Gtid-group marker
3980 rli->curr_group_seen_begin= rli->curr_group_seen_gtid= false;
3981 rli->last_assigned_worker= NULL;
3982 }
3983 /*
3984 Stroring GAQ index of the group that the event belongs to
3985 in the event. Deferred events are handled similarly below.
3986 */
3987 ev->mts_group_idx= rli->gaq->assigned_group_index;
3988
3989 bool append_item_to_jobs_error= false;
3990 if (rli->curr_group_da.elements > 0)
3991 {
3992 /*
3993 the current event sorted out which partion the current group
3994 belongs to. It's time now to processed deferred array events.
3995 */
3996 for (uint i= 0; i < rli->curr_group_da.elements; i++)
3997 {
3998 Slave_job_item da_item;
3999 get_dynamic(&rli->curr_group_da, (uchar*) &da_item.data, i);
4000 DBUG_PRINT("mts", ("Assigning job %llu to worker %lu",
4001 ((Log_event* )da_item.data)->log_pos, w->id));
4002 static_cast<Log_event*>(da_item.data)->mts_group_idx=
4003 rli->gaq->assigned_group_index; // similarly to above
4004 if (!append_item_to_jobs_error)
4005 append_item_to_jobs_error= append_item_to_jobs(&da_item, w, rli);
4006 if (append_item_to_jobs_error)
4007 delete static_cast<Log_event*>(da_item.data);
4008 }
4009 if (rli->curr_group_da.elements > rli->curr_group_da.max_element)
4010 {
4011 // reallocate to less mem
4012 rli->curr_group_da.elements= rli->curr_group_da.max_element;
4013 rli->curr_group_da.max_element= 0;
4014 freeze_size(&rli->curr_group_da); // restores max_element
4015 }
4016 rli->curr_group_da.elements= 0;
4017 }
4018 if (append_item_to_jobs_error)
4019 DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR);
4020
4021 DBUG_PRINT("mts", ("Assigning job %llu to worker %lu\n",
4022 ((Log_event* )job_item->data)->log_pos, w->id));
4023
4024 /* Notice `ev' instance can be destoyed after `append()' */
4025 if (append_item_to_jobs(job_item, w, rli))
4026 DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR);
4027 if (need_sync)
4028 {
4029 /*
4030 combination of over-max db:s and end of the current group
4031 forces to wait for the assigned groups completion by assigned
4032 to the event worker.
4033 Indeed MTS group status could be safely set to MTS_NOT_IN_GROUP
4034 after wait_() returns.
4035 No need to know a possible error out of synchronization call.
4036 */
4037 (void) wait_for_workers_to_finish(rli);
4038 }
4039
4040 }
4041 *ptr_ev= NULL; // announcing the event is passed to w-worker
4042
4043 if (log_warnings > 1 &&
4044 rli->is_parallel_exec() && rli->mts_events_assigned % 1024 == 1)
4045 {
4046 time_t my_now= my_time(0);
4047
4048 if ((my_now - rli->mts_last_online_stat) >=
4049 mts_online_stat_period)
4050 {
4051 sql_print_information("Multi-threaded slave statistics: "
4052 "seconds elapsed = %lu; "
4053 "events assigned = %llu; "
4054 "worker queues filled over overrun level = %lu; "
4055 "waited due a Worker queue full = %lu; "
4056 "waited due the total size = %lu; "
4057 "slept when Workers occupied = %lu ",
4058 static_cast<unsigned long>
4059 (my_now - rli->mts_last_online_stat),
4060 rli->mts_events_assigned,
4061 rli->mts_wq_overrun_cnt,
4062 rli->mts_wq_overfill_cnt,
4063 rli->wq_size_waits_cnt,
4064 rli->mts_wq_no_underrun_cnt);
4065 rli->mts_last_online_stat= my_now;
4066 }
4067 }
4068 }
4069 }
4070 else
4071 mysql_mutex_unlock(&rli->data_lock);
4072
4073 DBUG_PRINT("info", ("apply_event error = %d", exec_res));
4074 if (exec_res == 0)
4075 {
4076 /*
4077 Positions are not updated here when an XID is processed. To make
4078 a slave crash-safe, positions must be updated while processing a
4079 XID event and as such do not need to be updated here again.
4080
4081 However, if the event needs to be skipped, this means that it
4082 will not be processed and then positions need to be updated here.
4083
4084 See sql/rpl_rli.h for further details.
4085 */
4086 int error= 0;
4087 if (*ptr_ev &&
4088 (ev->get_type_code() != XID_EVENT ||
4089 skip_event || (rli->is_mts_recovery() && !is_gtid_event(ev) &&
4090 (ev->ends_group() || !rli->mts_recovery_group_seen_begin) &&
4091 bitmap_is_set(&rli->recovery_groups, rli->mts_recovery_index))))
4092 {
4093 #ifndef DBUG_OFF
4094 /*
4095 This only prints information to the debug trace.
4096
4097 TODO: Print an informational message to the error log?
4098 */
4099 static const char *const explain[] = {
4100 // EVENT_SKIP_NOT,
4101 "not skipped",
4102 // EVENT_SKIP_IGNORE,
4103 "skipped because event should be ignored",
4104 // EVENT_SKIP_COUNT
4105 "skipped because event skip counter was non-zero"
4106 };
4107 DBUG_PRINT("info", ("OPTION_BEGIN: %d; IN_STMT: %d",
4108 MY_TEST(thd->variables.option_bits & OPTION_BEGIN),
4109 rli->get_flag(Relay_log_info::IN_STMT)));
4110 DBUG_PRINT("skip_event", ("%s event was %s",
4111 ev->get_type_str(), explain[reason]));
4112 #endif
4113
4114 error= ev->update_pos(rli);
4115
4116 #ifndef DBUG_OFF
4117 DBUG_PRINT("info", ("update_pos error = %d", error));
4118 if (!rli->belongs_to_client())
4119 {
4120 char buf[22];
4121 DBUG_PRINT("info", ("group %s %s",
4122 llstr(rli->get_group_relay_log_pos(), buf),
4123 rli->get_group_relay_log_name()));
4124 DBUG_PRINT("info", ("event %s %s",
4125 llstr(rli->get_event_relay_log_pos(), buf),
4126 rli->get_event_relay_log_name()));
4127 }
4128 #endif
4129 }
4130 else
4131 {
4132 DBUG_ASSERT(*ptr_ev == ev || rli->is_parallel_exec() ||
4133 (!ev->worker &&
4134 (ev->get_type_code() == INTVAR_EVENT ||
4135 ev->get_type_code() == RAND_EVENT ||
4136 ev->get_type_code() == USER_VAR_EVENT)));
4137
4138 rli->inc_event_relay_log_pos();
4139 }
4140
4141 if (!error && rli->is_mts_recovery() &&
4142 ev->get_type_code() != ROTATE_EVENT &&
4143 ev->get_type_code() != FORMAT_DESCRIPTION_EVENT &&
4144 ev->get_type_code() != PREVIOUS_GTIDS_LOG_EVENT)
4145 {
4146 if (ev->starts_group())
4147 {
4148 rli->mts_recovery_group_seen_begin= true;
4149 }
4150 else if ((ev->ends_group() || !rli->mts_recovery_group_seen_begin) &&
4151 !is_gtid_event(ev))
4152 {
4153 rli->mts_recovery_index++;
4154 if (--rli->mts_recovery_group_cnt == 0)
4155 {
4156 rli->mts_recovery_index= 0;
4157 sql_print_information("Slave: MTS Recovery has completed at "
4158 "relay log %s, position %llu "
4159 "master log %s, position %llu.",
4160 rli->get_group_relay_log_name(),
4161 rli->get_group_relay_log_pos(),
4162 rli->get_group_master_log_name(),
4163 rli->get_group_master_log_pos());
4164 /*
4165 Few tests wait for UNTIL_SQL_AFTER_MTS_GAPS completion.
4166 Due to exisiting convention the status won't change
4167 prior to slave restarts.
4168 So making of UNTIL_SQL_AFTER_MTS_GAPS completion isdone here,
4169 and only in the debug build to make the test to catch the change
4170 despite a faulty design of UNTIL checking before execution.
4171 */
4172 if (rli->until_condition == Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS)
4173 {
4174 rli->until_condition= Relay_log_info::UNTIL_DONE;
4175 }
4176 // reset the Worker tables to remove last slave session time info
4177 if ((error= rli->mts_finalize_recovery()))
4178 {
4179 (void) Rpl_info_factory::reset_workers(rli);
4180 }
4181 }
4182 rli->mts_recovery_group_seen_begin= false;
4183 if (!error)
4184 error= rli->flush_info(true);
4185 }
4186 }
4187
4188 if (error)
4189 {
4190 /*
4191 The update should not fail, so print an error message and
4192 return an error code.
4193
4194 TODO: Replace this with a decent error message when merged
4195 with BUG#24954 (which adds several new error message).
4196 */
4197 char buf[22];
4198 rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
4199 "It was not possible to update the positions"
4200 " of the relay log information: the slave may"
4201 " be in an inconsistent state."
4202 " Stopped in %s position %s",
4203 rli->get_group_relay_log_name(),
4204 llstr(rli->get_group_relay_log_pos(), buf));
4205 DBUG_RETURN(SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR);
4206 }
4207 }
4208
4209 DBUG_RETURN(exec_res ? SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPLY_ERROR
4210 : SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK);
4211 }
4212
4213 /**
4214 Let the worker applying the current group to rollback and gracefully
4215 finish its work before.
4216
4217 @param rli The slave's relay log info.
4218
4219 @param ev a pointer to the event on hold before applying this rollback
4220 procedure.
4221
4222 @retval false The rollback succeeded.
4223
4224 @retval true There was an error while injecting events.
4225 */
coord_handle_partial_binlogged_transaction(Relay_log_info * rli,const Log_event * ev)4226 static bool coord_handle_partial_binlogged_transaction(Relay_log_info *rli,
4227 const Log_event *ev)
4228 {
4229 DBUG_ENTER("coord_handle_partial_binlogged_transaction");
4230 /*
4231 This function is called holding the rli->data_lock.
4232 We must return it still holding this lock, except in the case of returning
4233 error.
4234 */
4235 mysql_mutex_assert_owner(&rli->data_lock);
4236 THD *thd= rli->info_thd;
4237
4238 if (!rli->curr_group_seen_begin)
4239 {
4240 DBUG_PRINT("info",("Injecting QUERY(BEGIN) to rollback worker"));
4241 Log_event *begin_event= new Query_log_event(thd,
4242 STRING_WITH_LEN("BEGIN"),
4243 true, /* using_trans */
4244 false, /* immediate */
4245 true, /* suppress_use */
4246 0, /* error */
4247 true /* ignore_command */);
4248 ((Query_log_event*) begin_event)->db= "";
4249 begin_event->data_written= 0;
4250 begin_event->server_id= ev->server_id;
4251 /*
4252 We must be careful to avoid SQL thread increasing its position
4253 farther than the event that triggered this QUERY(BEGIN).
4254 */
4255 begin_event->log_pos= ev->log_pos;
4256 begin_event->future_event_relay_log_pos= ev->future_event_relay_log_pos;
4257
4258 if (apply_event_and_update_pos(&begin_event, thd, rli) !=
4259 SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK)
4260 {
4261 delete begin_event;
4262 DBUG_RETURN(true);
4263 }
4264 mysql_mutex_lock(&rli->data_lock);
4265 }
4266
4267 DBUG_PRINT("info",("Injecting QUERY(ROLLBACK) to rollback worker"));
4268 Log_event *rollback_event= new Query_log_event(thd,
4269 STRING_WITH_LEN("ROLLBACK"),
4270 true, /* using_trans */
4271 false, /* immediate */
4272 true, /* suppress_use */
4273 0, /* error */
4274 true /* ignore_command */);
4275 ((Query_log_event*) rollback_event)->db= "";
4276 rollback_event->data_written= 0;
4277 rollback_event->server_id= ev->server_id;
4278 /*
4279 We must be careful to avoid SQL thread increasing its position
4280 farther than the event that triggered this QUERY(ROLLBACK).
4281 */
4282 rollback_event->log_pos= ev->log_pos;
4283 rollback_event->future_event_relay_log_pos= ev->future_event_relay_log_pos;
4284
4285 if (apply_event_and_update_pos(&rollback_event, thd, rli) !=
4286 SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK)
4287 {
4288 delete rollback_event;
4289 DBUG_RETURN(true);
4290 }
4291 mysql_mutex_lock(&rli->data_lock);
4292
4293 DBUG_RETURN(false);
4294 }
4295
4296 /**
4297 Top-level function for executing the next event in the relay log.
4298 This is called from the SQL thread.
4299
4300 This function reads the event from the relay log, executes it, and
4301 advances the relay log position. It also handles errors, etc.
4302
4303 This function may fail to apply the event for the following reasons:
4304
4305 - The position specfied by the UNTIL condition of the START SLAVE
4306 command is reached.
4307
4308 - It was not possible to read the event from the log.
4309
4310 - The slave is killed.
4311
4312 - An error occurred when applying the event, and the event has been
4313 tried slave_trans_retries times. If the event has been retried
4314 fewer times, 0 is returned.
4315
4316 - init_info or init_relay_log_pos failed. (These are called
4317 if a failure occurs when applying the event.)
4318
4319 - An error occurred when updating the binlog position.
4320
4321 @retval 0 The event was applied.
4322
4323 @retval 1 The event was not applied.
4324 */
exec_relay_log_event(THD * thd,Relay_log_info * rli)4325 static int exec_relay_log_event(THD* thd, Relay_log_info* rli)
4326 {
4327 DBUG_ENTER("exec_relay_log_event");
4328
4329 /*
4330 We acquire this mutex since we need it for all operations except
4331 event execution. But we will release it in places where we will
4332 wait for something for example inside of next_event().
4333 */
4334 mysql_mutex_lock(&rli->data_lock);
4335
4336 /*
4337 UNTIL_SQL_AFTER_GTIDS requires special handling since we have to check
4338 whether the until_condition is satisfied *before* the SQL threads goes on
4339 a wait inside next_event() for the relay log to grow. This is reuired since
4340 if we have already applied the last event in the waiting set but since he
4341 check happens only at the start of the next event we may end up waiting
4342 forever the next event is not available or is delayed.
4343 */
4344 if (rli->until_condition == Relay_log_info::UNTIL_SQL_AFTER_GTIDS &&
4345 rli->is_until_satisfied(thd, NULL))
4346 {
4347 rli->abort_slave= 1;
4348 mysql_mutex_unlock(&rli->data_lock);
4349 DBUG_RETURN(1);
4350 }
4351
4352 Log_event *ev = next_event(rli), **ptr_ev;
4353
4354 DBUG_ASSERT(rli->info_thd==thd);
4355
4356 if (sql_slave_killed(thd,rli))
4357 {
4358 mysql_mutex_unlock(&rli->data_lock);
4359 delete ev;
4360 DBUG_RETURN(1);
4361 }
4362 if (ev)
4363 {
4364 enum enum_slave_apply_event_and_update_pos_retval exec_res;
4365
4366 ptr_ev= &ev;
4367 /*
4368 Even if we don't execute this event, we keep the master timestamp,
4369 so that seconds behind master shows correct delta (there are events
4370 that are not replayed, so we keep falling behind).
4371
4372 If it is an artificial event, or a relay log event (IO thread generated
4373 event) or ev->when is set to 0, or a FD from master, or a heartbeat
4374 event with server_id '0' then we don't update the last_master_timestamp.
4375 */
4376 if (!(rli->is_parallel_exec() ||
4377 ev->is_artificial_event() || ev->is_relay_log_event() ||
4378 ev->when.tv_sec == 0 || ev->get_type_code() == FORMAT_DESCRIPTION_EVENT ||
4379 ev->server_id == 0))
4380 {
4381 rli->last_master_timestamp= ev->when.tv_sec + (time_t) ev->exec_time;
4382 DBUG_ASSERT(rli->last_master_timestamp >= 0);
4383 }
4384
4385 /*
4386 This tests if the position of the beginning of the current event
4387 hits the UNTIL barrier.
4388 MTS: since the master and the relay-group coordinates change
4389 asynchronously logics of rli->is_until_satisfied() can't apply.
4390 A special UNTIL_SQL_AFTER_MTS_GAPS is still deployed here
4391 temporarily (see is_until_satisfied todo).
4392 */
4393 if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
4394 rli->until_condition != Relay_log_info::UNTIL_SQL_AFTER_GTIDS &&
4395 rli->is_until_satisfied(thd, ev))
4396 {
4397 /*
4398 Setting abort_slave flag because we do not want additional message about
4399 error in query execution to be printed.
4400 */
4401 rli->abort_slave= 1;
4402 mysql_mutex_unlock(&rli->data_lock);
4403 delete ev;
4404 DBUG_RETURN(1);
4405 }
4406
4407 { /**
4408 The following failure injecion works in cooperation with tests
4409 setting @@global.debug= 'd,incomplete_group_in_relay_log'.
4410 Xid or Commit events are not executed to force the slave sql
4411 read hanging if the realy log does not have any more events.
4412 */
4413 DBUG_EXECUTE_IF("incomplete_group_in_relay_log",
4414 if ((ev->get_type_code() == XID_EVENT) ||
4415 ((ev->get_type_code() == QUERY_EVENT) &&
4416 strcmp("COMMIT", ((Query_log_event *) ev)->query) == 0))
4417 {
4418 DBUG_ASSERT(thd->transaction.all.cannot_safely_rollback());
4419 rli->abort_slave= 1;
4420 mysql_mutex_unlock(&rli->data_lock);
4421 delete ev;
4422 rli->inc_event_relay_log_pos();
4423 DBUG_RETURN(0);
4424 };);
4425 }
4426
4427 /*
4428 GTID protocol will put a FORMAT_DESCRIPTION_EVENT from the master with
4429 log_pos != 0 after each (re)connection if auto positioning is enabled.
4430 This means that the SQL thread might have already started to apply the
4431 current group but, as the IO thread had to reconnect, it left this
4432 group incomplete and will start it again from the beginning.
4433 So, before applying this FORMAT_DESCRIPTION_EVENT, we must let the
4434 worker roll back the current group and gracefully finish its work,
4435 before starting to apply the new (complete) copy of the group.
4436 */
4437 if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT &&
4438 ev->server_id != ::server_id && ev->log_pos != 0 &&
4439 rli->is_parallel_exec() && rli->curr_group_seen_gtid)
4440 {
4441 if (coord_handle_partial_binlogged_transaction(rli, ev))
4442 /*
4443 In the case of an error, coord_handle_partial_binlogged_transaction
4444 will not try to get the rli->data_lock again.
4445 */
4446 DBUG_RETURN(1);
4447 }
4448
4449 /* ptr_ev can change to NULL indicating MTS coorinator passed to a Worker */
4450 exec_res= apply_event_and_update_pos(ptr_ev, thd, rli);
4451 /*
4452 Note: the above call to apply_event_and_update_pos executes
4453 mysql_mutex_unlock(&rli->data_lock);
4454 */
4455
4456 /* For deferred events, the ptr_ev is set to NULL
4457 in Deferred_log_events::add() function.
4458 Hence deferred events wont be deleted here.
4459 They will be deleted in Deferred_log_events::rewind() funciton.
4460 */
4461 if (*ptr_ev)
4462 {
4463 DBUG_ASSERT(*ptr_ev == ev); // event remains to belong to Coordinator
4464
4465 DBUG_EXECUTE_IF("dbug.calculate_sbm_after_previous_gtid_log_event",
4466 {
4467 if (ev->get_type_code() == PREVIOUS_GTIDS_LOG_EVENT)
4468 {
4469 const char act[]= "now signal signal.reached wait_for signal.done_sbm_calculation";
4470 DBUG_ASSERT(opt_debug_sync_timeout > 0);
4471 DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act)));
4472 }
4473 };);
4474 DBUG_EXECUTE_IF("dbug.calculate_sbm_after_fake_rotate_log_event",
4475 {
4476 if (ev->get_type_code() == ROTATE_EVENT && ev->is_artificial_event())
4477 {
4478 const char act[]= "now signal signal.reached wait_for signal.done_sbm_calculation";
4479 DBUG_ASSERT(opt_debug_sync_timeout > 0);
4480 DBUG_ASSERT(!debug_sync_set_action(thd,
4481 STRING_WITH_LEN(act)));
4482 }
4483 };);
4484 /*
4485 Format_description_log_event should not be deleted because it will be
4486 used to read info about the relay log's format; it will be deleted when
4487 the SQL thread does not need it, i.e. when this thread terminates.
4488 ROWS_QUERY_LOG_EVENT is destroyed at the end of the current statement
4489 clean-up routine.
4490 */
4491 if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT &&
4492 ev->get_type_code() != ROWS_QUERY_LOG_EVENT)
4493 {
4494 DBUG_PRINT("info", ("Deleting the event after it has been executed"));
4495 delete ev;
4496 ev= NULL;
4497 }
4498 }
4499
4500 /*
4501 exec_res == SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR
4502 update_log_pos failed: this should not happen, so we
4503 don't retry.
4504 exec_res == SLAVE_APPLY_EVENT_AND_UPDATE_POS_APPEND_JOB_ERROR
4505 append_item_to_jobs() failed, this happened because
4506 thread was killed while waiting for enqueue on worker.
4507 */
4508 if (exec_res >= SLAVE_APPLY_EVENT_AND_UPDATE_POS_UPDATE_POS_ERROR)
4509 {
4510 delete ev;
4511 DBUG_RETURN(1);
4512 }
4513
4514 if (slave_trans_retries)
4515 {
4516 int UNINIT_VAR(temp_err);
4517 bool silent= false;
4518 if (exec_res && !is_mts_worker(thd) /* no reexecution in MTS mode */ &&
4519 (temp_err= rli->has_temporary_error(thd, 0, &silent)) &&
4520 !thd->transaction.all.cannot_safely_rollback())
4521 {
4522 const char *errmsg;
4523 /*
4524 We were in a transaction which has been rolled back because of a
4525 temporary error;
4526 let's seek back to BEGIN log event and retry it all again.
4527 Note, if lock wait timeout (innodb_lock_wait_timeout exceeded)
4528 there is no rollback since 5.0.13 (ref: manual).
4529 We have to not only seek but also
4530 a) init_info(), to seek back to hot relay log's start for later
4531 (for when we will come back to this hot log after re-processing the
4532 possibly existing old logs where BEGIN is: check_binlog_magic() will
4533 then need the cache to be at position 0 (see comments at beginning of
4534 init_info()).
4535 b) init_relay_log_pos(), because the BEGIN may be an older relay log.
4536 */
4537 if (rli->trans_retries < slave_trans_retries)
4538 {
4539 /*
4540 The transactions has to be rolled back before global_init_info is
4541 called. Because global_init_info will starts a new transaction if
4542 master_info_repository is TABLE.
4543 */
4544 rli->cleanup_context(thd, 1);
4545 /*
4546 We need to figure out if there is a test case that covers
4547 this part. \Alfranio.
4548 */
4549 if (global_init_info(rli->mi, false, SLAVE_SQL))
4550 sql_print_error("Failed to initialize the master info structure");
4551 else if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
4552 rli->get_group_relay_log_pos(),
4553 true/*need_data_lock=true*/,
4554 &errmsg, 1))
4555 sql_print_error("Error initializing relay log position: %s",
4556 errmsg);
4557 else
4558 {
4559 exec_res= SLAVE_APPLY_EVENT_AND_UPDATE_POS_OK;
4560 /* chance for concurrent connection to get more locks */
4561 slave_sleep(thd, min<ulong>(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
4562 sql_slave_killed, rli);
4563 mysql_mutex_lock(&rli->data_lock); // because of SHOW STATUS
4564 if (!silent)
4565 rli->trans_retries++;
4566
4567 rli->retried_trans++;
4568 mysql_mutex_unlock(&rli->data_lock);
4569 DBUG_PRINT("info", ("Slave retries transaction "
4570 "rli->trans_retries: %lu", rli->trans_retries));
4571 }
4572 }
4573 else
4574 {
4575 thd->is_fatal_error= 1;
4576 rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
4577 "Slave SQL thread retried transaction %lu time(s) "
4578 "in vain, giving up. Consider raising the value of "
4579 "the slave_transaction_retries variable.", rli->trans_retries);
4580 }
4581 }
4582 else if ((exec_res && !temp_err) ||
4583 (opt_using_transactions &&
4584 rli->get_group_relay_log_pos() == rli->get_event_relay_log_pos()))
4585 {
4586 /*
4587 Only reset the retry counter if the entire group succeeded
4588 or failed with a non-transient error. On a successful
4589 event, the execution will proceed as usual; in the case of a
4590 non-transient error, the slave will stop with an error.
4591 */
4592 rli->trans_retries= 0; // restart from fresh
4593 DBUG_PRINT("info", ("Resetting retry counter, rli->trans_retries: %lu",
4594 rli->trans_retries));
4595 }
4596 }
4597 if (exec_res)
4598 delete ev;
4599 DBUG_RETURN(exec_res);
4600 }
4601 mysql_mutex_unlock(&rli->data_lock);
4602 rli->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_READ_FAILURE,
4603 ER(ER_SLAVE_RELAY_LOG_READ_FAILURE), "\
4604 Could not parse relay log event entry. The possible reasons are: the master's \
4605 binary log is corrupted (you can check this by running 'mysqlbinlog' on the \
4606 binary log), the slave's relay log is corrupted (you can check this by running \
4607 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's \
4608 or slave's MySQL code. If you want to check the master's binary log or slave's \
4609 relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' \
4610 on this slave.\
4611 ");
4612 DBUG_RETURN(1);
4613 }
4614
check_io_slave_killed(THD * thd,Master_info * mi,const char * info)4615 static bool check_io_slave_killed(THD *thd, Master_info *mi, const char *info)
4616 {
4617 if (io_slave_killed(thd, mi))
4618 {
4619 if (info && log_warnings)
4620 sql_print_information("%s", info);
4621 return TRUE;
4622 }
4623 return FALSE;
4624 }
4625
4626 /**
4627 @brief Try to reconnect slave IO thread.
4628
4629 @details Terminates current connection to master, sleeps for
4630 @c mi->connect_retry msecs and initiates new connection with
4631 @c safe_reconnect(). Variable pointed by @c retry_count is increased -
4632 if it exceeds @c mi->retry_count then connection is not re-established
4633 and function signals error.
4634 Unless @c suppres_warnings is TRUE, a warning is put in the server error log
4635 when reconnecting. The warning message and messages used to report errors
4636 are taken from @c messages array. In case @c mi->retry_count is exceeded,
4637 no messages are added to the log.
4638
4639 @param[in] thd Thread context.
4640 @param[in] mysql MySQL connection.
4641 @param[in] mi Master connection information.
4642 @param[in,out] retry_count Number of attempts to reconnect.
4643 @param[in] suppress_warnings TRUE when a normal net read timeout
4644 has caused to reconnecting.
4645 @param[in] messages Messages to print/log, see
4646 reconnect_messages[] array.
4647
4648 @retval 0 OK.
4649 @retval 1 There was an error.
4650 */
4651
try_to_reconnect(THD * thd,MYSQL * mysql,Master_info * mi,uint * retry_count,bool suppress_warnings,const char * messages[SLAVE_RECON_MSG_MAX])4652 static int try_to_reconnect(THD *thd, MYSQL *mysql, Master_info *mi,
4653 uint *retry_count, bool suppress_warnings,
4654 const char *messages[SLAVE_RECON_MSG_MAX])
4655 {
4656 mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
4657 thd->proc_info= messages[SLAVE_RECON_MSG_WAIT];
4658 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
4659 thd->clear_active_vio();
4660 #endif
4661 end_server(mysql);
4662 DBUG_EXECUTE_IF("simulate_no_master_reconnect",
4663 {
4664 return 1;
4665 });
4666 if ((*retry_count)++)
4667 {
4668 if (*retry_count > mi->retry_count)
4669 return 1; // Don't retry forever
4670 slave_sleep(thd, mi->connect_retry, io_slave_killed, mi);
4671 }
4672 if (check_io_slave_killed(thd, mi, messages[SLAVE_RECON_MSG_KILLED_WAITING]))
4673 return 1;
4674 thd->proc_info = messages[SLAVE_RECON_MSG_AFTER];
4675 if (!suppress_warnings)
4676 {
4677 char buf[256], llbuff[22];
4678 my_snprintf(buf, sizeof(buf), messages[SLAVE_RECON_MSG_FAILED],
4679 mi->get_io_rpl_log_name(), llstr(mi->get_master_log_pos(),
4680 llbuff));
4681 /*
4682 Raise a warining during registering on master/requesting dump.
4683 Log a message reading event.
4684 */
4685 if (messages[SLAVE_RECON_MSG_COMMAND][0])
4686 {
4687 mi->report(WARNING_LEVEL, ER_SLAVE_MASTER_COM_FAILURE,
4688 ER(ER_SLAVE_MASTER_COM_FAILURE),
4689 messages[SLAVE_RECON_MSG_COMMAND], buf);
4690 }
4691 else
4692 {
4693 sql_print_information("%s", buf);
4694 }
4695 }
4696 if (safe_reconnect(thd, mysql, mi, 1) || io_slave_killed(thd, mi))
4697 {
4698 if (log_warnings)
4699 sql_print_information("%s", messages[SLAVE_RECON_MSG_KILLED_AFTER]);
4700 return 1;
4701 }
4702 return 0;
4703 }
4704
4705
4706 /**
4707 Slave IO thread entry point.
4708
4709 @param arg Pointer to Master_info struct that holds information for
4710 the IO thread.
4711
4712 @return Always 0.
4713 */
handle_slave_io(void * arg)4714 pthread_handler_t handle_slave_io(void *arg)
4715 {
4716 THD *thd= NULL; // needs to be first for thread_stack
4717 bool thd_added= false;
4718 MYSQL *mysql;
4719 Master_info *mi = (Master_info*)arg;
4720 Relay_log_info *rli= mi->rli;
4721 char llbuff[22];
4722 uint retry_count;
4723 bool suppress_warnings;
4724 int ret;
4725 int binlog_version;
4726 #ifndef DBUG_OFF
4727 uint retry_count_reg= 0, retry_count_dump= 0, retry_count_event= 0;
4728 #endif
4729 // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
4730 my_thread_init();
4731 DBUG_ENTER("handle_slave_io");
4732
4733 DBUG_ASSERT(mi->inited);
4734 mysql= NULL ;
4735 retry_count= 0;
4736
4737 mysql_mutex_lock(&mi->run_lock);
4738 /* Inform waiting threads that slave has started */
4739 mi->slave_run_id++;
4740
4741 #ifndef DBUG_OFF
4742 mi->events_until_exit = disconnect_slave_event_count;
4743 #endif
4744
4745 thd= new THD; // note that contructor of THD uses DBUG_ !
4746 THD_CHECK_SENTRY(thd);
4747 mi->info_thd = thd;
4748
4749 pthread_detach_this_thread();
4750 thd->thread_stack= (char*) &thd; // remember where our stack is
4751 mi->clear_error();
4752 if (init_slave_thread(thd, SLAVE_THD_IO))
4753 {
4754 mysql_cond_broadcast(&mi->start_cond);
4755 mysql_mutex_unlock(&mi->run_lock);
4756 sql_print_error("Failed during slave I/O thread initialization");
4757 goto err;
4758 }
4759
4760 mysql_mutex_lock(&LOCK_thread_count);
4761 add_global_thread(thd);
4762 thd_added= true;
4763 mysql_mutex_unlock(&LOCK_thread_count);
4764
4765 mi->slave_running = 1;
4766 mi->abort_slave = 0;
4767 mysql_mutex_unlock(&mi->run_lock);
4768 mysql_cond_broadcast(&mi->start_cond);
4769
4770 DBUG_PRINT("master_info",("log_file_name: '%s' position: %s",
4771 mi->get_master_log_name(),
4772 llstr(mi->get_master_log_pos(), llbuff)));
4773
4774 /* This must be called before run any binlog_relay_io hooks */
4775 my_pthread_setspecific_ptr(RPL_MASTER_INFO, mi);
4776
4777 if (RUN_HOOK(binlog_relay_io, thread_start, (thd, mi)))
4778 {
4779 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4780 ER(ER_SLAVE_FATAL_ERROR), "Failed to run 'thread_start' hook");
4781 goto err;
4782 }
4783
4784 if (!(mi->mysql = mysql = mysql_init(NULL)))
4785 {
4786 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4787 ER(ER_SLAVE_FATAL_ERROR), "error in mysql_init()");
4788 goto err;
4789 }
4790
4791 THD_STAGE_INFO(thd, stage_connecting_to_master);
4792 // we can get killed during safe_connect
4793 if (!safe_connect(thd, mysql, mi))
4794 {
4795 sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',"
4796 "replication started in log '%s' at position %s",
4797 mi->get_user(), mi->host, mi->port,
4798 mi->get_io_rpl_log_name(),
4799 llstr(mi->get_master_log_pos(), llbuff));
4800 }
4801 else
4802 {
4803 sql_print_information("Slave I/O thread killed while connecting to master");
4804 goto err;
4805 }
4806
4807 connected:
4808
4809 DBUG_EXECUTE_IF("dbug.before_get_running_status_yes",
4810 {
4811 const char act[]=
4812 "now "
4813 "wait_for signal.io_thread_let_running";
4814 DBUG_ASSERT(opt_debug_sync_timeout > 0);
4815 DBUG_ASSERT(!debug_sync_set_action(thd,
4816 STRING_WITH_LEN(act)));
4817 };);
4818 DBUG_EXECUTE_IF("dbug.calculate_sbm_after_previous_gtid_log_event",
4819 {
4820 /* Fake that thread started 3 minutes ago */
4821 thd->start_time.tv_sec-=180;
4822 };);
4823 DBUG_EXECUTE_IF("dbug.calculate_sbm_after_fake_rotate_log_event",
4824 {
4825 /* Fake that thread started 3 minutes ago */
4826 thd->start_time.tv_sec-=180;
4827 };);
4828 mysql_mutex_lock(&mi->run_lock);
4829 mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
4830 mysql_mutex_unlock(&mi->run_lock);
4831
4832 thd->slave_net = &mysql->net;
4833 THD_STAGE_INFO(thd, stage_checking_master_version);
4834 ret= get_master_version_and_clock(mysql, mi);
4835 if (!ret)
4836 ret= get_master_uuid(mysql, mi);
4837 if (!ret)
4838 ret= io_thread_init_commands(mysql, mi);
4839
4840 if (ret == 1)
4841 /* Fatal error */
4842 goto err;
4843
4844 if (ret == 2)
4845 {
4846 if (check_io_slave_killed(mi->info_thd, mi, "Slave I/O thread killed"
4847 "while calling get_master_version_and_clock(...)"))
4848 goto err;
4849 suppress_warnings= FALSE;
4850 /* Try to reconnect because the error was caused by a transient network problem */
4851 if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4852 reconnect_messages[SLAVE_RECON_ACT_REG]))
4853 goto err;
4854 goto connected;
4855 }
4856
4857 mysql_mutex_lock(&mi->data_lock);
4858 binlog_version= mi->get_mi_description_event()->binlog_version;
4859 mysql_mutex_unlock(&mi->data_lock);
4860
4861 if (binlog_version > 1)
4862 {
4863 /*
4864 Register ourselves with the master.
4865 */
4866 THD_STAGE_INFO(thd, stage_registering_slave_on_master);
4867 if (register_slave_on_master(mysql, mi, &suppress_warnings))
4868 {
4869 if (!check_io_slave_killed(thd, mi, "Slave I/O thread killed "
4870 "while registering slave on master"))
4871 {
4872 sql_print_error("Slave I/O thread couldn't register on master");
4873 if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4874 reconnect_messages[SLAVE_RECON_ACT_REG]))
4875 goto err;
4876 }
4877 else
4878 goto err;
4879 goto connected;
4880 }
4881 DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_REG",
4882 if (!retry_count_reg)
4883 {
4884 retry_count_reg++;
4885 sql_print_information("Forcing to reconnect slave I/O thread");
4886 if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4887 reconnect_messages[SLAVE_RECON_ACT_REG]))
4888 goto err;
4889 goto connected;
4890 });
4891 }
4892
4893 DBUG_PRINT("info",("Starting reading binary log from master"));
4894 while (!io_slave_killed(thd,mi))
4895 {
4896 THD_STAGE_INFO(thd, stage_requesting_binlog_dump);
4897 if (request_dump(thd, mysql, mi, &suppress_warnings))
4898 {
4899 sql_print_error("Failed on request_dump()");
4900 if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
4901 requesting master dump") ||
4902 try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4903 reconnect_messages[SLAVE_RECON_ACT_DUMP]))
4904 goto err;
4905 goto connected;
4906 }
4907 DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_DUMP",
4908 if (!retry_count_dump)
4909 {
4910 retry_count_dump++;
4911 sql_print_information("Forcing to reconnect slave I/O thread");
4912 if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4913 reconnect_messages[SLAVE_RECON_ACT_DUMP]))
4914 goto err;
4915 goto connected;
4916 });
4917 const char *event_buf;
4918
4919 DBUG_ASSERT(mi->last_error().number == 0);
4920 while (!io_slave_killed(thd,mi))
4921 {
4922 ulong event_len;
4923 /*
4924 We say "waiting" because read_event() will wait if there's nothing to
4925 read. But if there's something to read, it will not wait. The
4926 important thing is to not confuse users by saying "reading" whereas
4927 we're in fact receiving nothing.
4928 */
4929 THD_STAGE_INFO(thd, stage_waiting_for_master_to_send_event);
4930 event_len= read_event(mysql, mi, &suppress_warnings);
4931 if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
4932 reading event"))
4933 goto err;
4934 DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT",
4935 if (!retry_count_event)
4936 {
4937 retry_count_event++;
4938 sql_print_information("Forcing to reconnect slave I/O thread");
4939 if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4940 reconnect_messages[SLAVE_RECON_ACT_EVENT]))
4941 goto err;
4942 goto connected;
4943 });
4944
4945 if (event_len == packet_error)
4946 {
4947 uint mysql_error_number= mysql_errno(mysql);
4948 switch (mysql_error_number) {
4949 case CR_NET_PACKET_TOO_LARGE:
4950 sql_print_error("\
4951 Log entry on master is longer than slave_max_allowed_packet (%lu) on \
4952 slave. If the entry is correct, restart the server with a higher value of \
4953 slave_max_allowed_packet",
4954 slave_max_allowed_packet);
4955 mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE,
4956 "%s", "Got a packet bigger than 'slave_max_allowed_packet' bytes");
4957 goto err;
4958 case ER_MASTER_FATAL_ERROR_READING_BINLOG:
4959 mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG,
4960 ER(ER_MASTER_FATAL_ERROR_READING_BINLOG),
4961 mysql_error_number, mysql_error(mysql));
4962 goto err;
4963 case ER_OUT_OF_RESOURCES:
4964 sql_print_error("\
4965 Stopping slave I/O thread due to out-of-memory error from master");
4966 mi->report(ERROR_LEVEL, ER_OUT_OF_RESOURCES,
4967 "%s", ER(ER_OUT_OF_RESOURCES));
4968 goto err;
4969 }
4970 if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
4971 reconnect_messages[SLAVE_RECON_ACT_EVENT]))
4972 goto err;
4973 goto connected;
4974 } // if (event_len == packet_error)
4975
4976 retry_count=0; // ok event, reset retry counter
4977 THD_STAGE_INFO(thd, stage_queueing_master_event_to_the_relay_log);
4978 event_buf= (const char*)mysql->net.read_pos + 1;
4979 DBUG_PRINT("info", ("IO thread received event of type %s", Log_event::get_type_str((Log_event_type)event_buf[EVENT_TYPE_OFFSET])));
4980 if (RUN_HOOK(binlog_relay_io, after_read_event,
4981 (thd, mi,(const char*)mysql->net.read_pos + 1,
4982 event_len, &event_buf, &event_len)))
4983 {
4984 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4985 ER(ER_SLAVE_FATAL_ERROR),
4986 "Failed to run 'after_read_event' hook");
4987 goto err;
4988 }
4989
4990 /* XXX: 'synced' should be updated by queue_event to indicate
4991 whether event has been synced to disk */
4992 bool synced= 0;
4993 if (queue_event(mi, event_buf, event_len))
4994 {
4995 mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
4996 ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
4997 "could not queue event from master");
4998 goto err;
4999 }
5000 if (RUN_HOOK(binlog_relay_io, after_queue_event,
5001 (thd, mi, event_buf, event_len, synced)))
5002 {
5003 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5004 ER(ER_SLAVE_FATAL_ERROR),
5005 "Failed to run 'after_queue_event' hook");
5006 goto err;
5007 }
5008
5009 mysql_mutex_lock(&mi->data_lock);
5010 if (flush_master_info(mi, FALSE))
5011 {
5012 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5013 ER(ER_SLAVE_FATAL_ERROR),
5014 "Failed to flush master info.");
5015 mysql_mutex_unlock(&mi->data_lock);
5016 goto err;
5017 }
5018 mysql_mutex_unlock(&mi->data_lock);
5019
5020 /*
5021 See if the relay logs take too much space.
5022 We don't lock mi->rli->log_space_lock here; this dirty read saves time
5023 and does not introduce any problem:
5024 - if mi->rli->ignore_log_space_limit is 1 but becomes 0 just after (so
5025 the clean value is 0), then we are reading only one more event as we
5026 should, and we'll block only at the next event. No big deal.
5027 - if mi->rli->ignore_log_space_limit is 0 but becomes 1 just after (so
5028 the clean value is 1), then we are going into wait_for_relay_log_space()
5029 for no reason, but this function will do a clean read, notice the clean
5030 value and exit immediately.
5031 */
5032 #ifndef DBUG_OFF
5033 {
5034 char llbuf1[22], llbuf2[22];
5035 DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
5036 ignore_log_space_limit=%d",
5037 llstr(rli->log_space_limit,llbuf1),
5038 llstr(rli->log_space_total,llbuf2),
5039 (int) rli->ignore_log_space_limit));
5040 }
5041 #endif
5042
5043 if (rli->log_space_limit && rli->log_space_limit <
5044 rli->log_space_total &&
5045 !rli->ignore_log_space_limit)
5046 if (wait_for_relay_log_space(rli))
5047 {
5048 sql_print_error("Slave I/O thread aborted while waiting for relay \
5049 log space");
5050 goto err;
5051 }
5052 DBUG_EXECUTE_IF("flush_after_reading_user_var_event",
5053 {
5054 if (event_buf[EVENT_TYPE_OFFSET] == USER_VAR_EVENT)
5055 {
5056 const char act[]= "now signal Reached wait_for signal.flush_complete_continue";
5057 DBUG_ASSERT(opt_debug_sync_timeout > 0);
5058 DBUG_ASSERT(!debug_sync_set_action(current_thd,
5059 STRING_WITH_LEN(act)));
5060
5061 }
5062 });
5063 DBUG_EXECUTE_IF("stop_io_after_reading_gtid_log_event",
5064 if (event_buf[EVENT_TYPE_OFFSET] == GTID_LOG_EVENT)
5065 thd->killed= THD::KILLED_NO_VALUE;
5066 );
5067 DBUG_EXECUTE_IF("stop_io_after_reading_query_log_event",
5068 if (event_buf[EVENT_TYPE_OFFSET] == QUERY_EVENT)
5069 thd->killed= THD::KILLED_NO_VALUE;
5070 );
5071 DBUG_EXECUTE_IF("stop_io_after_reading_user_var_log_event",
5072 if (event_buf[EVENT_TYPE_OFFSET] == USER_VAR_EVENT)
5073 thd->killed= THD::KILLED_NO_VALUE;
5074 );
5075 DBUG_EXECUTE_IF("stop_io_after_reading_table_map_event",
5076 if (event_buf[EVENT_TYPE_OFFSET] == TABLE_MAP_EVENT)
5077 thd->killed= THD::KILLED_NO_VALUE;
5078 );
5079 DBUG_EXECUTE_IF("stop_io_after_reading_xid_log_event",
5080 if (event_buf[EVENT_TYPE_OFFSET] == XID_EVENT)
5081 thd->killed= THD::KILLED_NO_VALUE;
5082 );
5083 DBUG_EXECUTE_IF("stop_io_after_reading_write_rows_log_event",
5084 if (event_buf[EVENT_TYPE_OFFSET] == WRITE_ROWS_EVENT)
5085 thd->killed= THD::KILLED_NO_VALUE;
5086 );
5087 /*
5088 After event is flushed to relay log file, memory used
5089 by thread's mem_root is not required any more.
5090 Hence adding free_root(thd->mem_root,...) to do the
5091 cleanup, otherwise a long running IO thread can
5092 cause OOM error.
5093 */
5094 free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
5095 }
5096 }
5097
5098 // error = 0;
5099 err:
5100 // print the current replication position
5101 sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
5102 mi->get_io_rpl_log_name(), llstr(mi->get_master_log_pos(), llbuff));
5103 (void) RUN_HOOK(binlog_relay_io, thread_stop, (thd, mi));
5104 thd->reset_query();
5105 thd->reset_db(NULL, 0);
5106 if (mysql)
5107 {
5108 /*
5109 Here we need to clear the active VIO before closing the
5110 connection with the master. The reason is that THD::awake()
5111 might be called from terminate_slave_thread() because somebody
5112 issued a STOP SLAVE. If that happends, the shutdown_active_vio()
5113 can be called in the middle of closing the VIO associated with
5114 the 'mysql' object, causing a crash.
5115 */
5116 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
5117 thd->clear_active_vio();
5118 #endif
5119 mysql_close(mysql);
5120 mi->mysql=0;
5121 }
5122 mysql_mutex_lock(&mi->data_lock);
5123 write_ignored_events_info_to_relay_log(thd, mi);
5124 mysql_mutex_unlock(&mi->data_lock);
5125 THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit);
5126 mysql_mutex_lock(&mi->run_lock);
5127 /*
5128 Clean information used to start slave in order to avoid
5129 security issues.
5130 */
5131 mi->reset_start_info();
5132 /* Forget the relay log's format */
5133 mysql_mutex_lock(&mi->data_lock);
5134 mi->set_mi_description_event(NULL);
5135 mysql_mutex_unlock(&mi->data_lock);
5136
5137 DBUG_ASSERT(thd->net.buff != 0);
5138 net_end(&thd->net); // destructor will not free it, because net.vio is 0
5139
5140 thd->release_resources();
5141 THD_CHECK_SENTRY(thd);
5142 if (thd_added)
5143 remove_global_thread(thd);
5144 delete thd;
5145
5146 mi->abort_slave= 0;
5147 mi->slave_running= 0;
5148 mi->info_thd= 0;
5149 /*
5150 Note: the order of the two following calls (first broadcast, then unlock)
5151 is important. Otherwise a killer_thread can execute between the calls and
5152 delete the mi structure leading to a crash! (see BUG#25306 for details)
5153 */
5154 mysql_cond_broadcast(&mi->stop_cond); // tell the world we are done
5155 DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
5156 mysql_mutex_unlock(&mi->run_lock);
5157 DBUG_LEAVE; // Must match DBUG_ENTER()
5158 my_thread_end();
5159 #if OPENSSL_VERSION_NUMBER < 0x10100000L
5160 ERR_remove_thread_state(0);
5161 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
5162 pthread_exit(0);
5163 return(0); // Avoid compiler warnings
5164 }
5165
5166 /*
5167 Check the temporary directory used by commands like
5168 LOAD DATA INFILE.
5169 */
5170 static
check_temp_dir(char * tmp_file)5171 int check_temp_dir(char* tmp_file)
5172 {
5173 int fd;
5174 MY_DIR *dirp;
5175 char tmp_dir[FN_REFLEN];
5176 size_t tmp_dir_size;
5177
5178 DBUG_ENTER("check_temp_dir");
5179
5180 /*
5181 Get the directory from the temporary file.
5182 */
5183 dirname_part(tmp_dir, tmp_file, &tmp_dir_size);
5184
5185 /*
5186 Check if the directory exists.
5187 */
5188 if (!(dirp=my_dir(tmp_dir,MYF(MY_WME))))
5189 DBUG_RETURN(1);
5190 my_dirend(dirp);
5191
5192 /*
5193 Check permissions to create a file.
5194 */
5195 //append the server UUID to the temp file name.
5196 char *unique_tmp_file_name= (char*)my_malloc((FN_REFLEN+TEMP_FILE_MAX_LEN)*sizeof(char), MYF(0));
5197 sprintf(unique_tmp_file_name, "%s%s", tmp_file, server_uuid);
5198 if ((fd= mysql_file_create(key_file_misc,
5199 unique_tmp_file_name, CREATE_MODE,
5200 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5201 MYF(MY_WME))) < 0)
5202 DBUG_RETURN(1);
5203
5204 /*
5205 Clean up.
5206 */
5207 mysql_file_close(fd, MYF(0));
5208
5209 mysql_file_delete(key_file_misc, unique_tmp_file_name, MYF(0));
5210 my_free(unique_tmp_file_name);
5211 DBUG_RETURN(0);
5212 }
5213
5214 /*
5215 Worker thread for the parallel execution of the replication events.
5216 */
handle_slave_worker(void * arg)5217 pthread_handler_t handle_slave_worker(void *arg)
5218 {
5219 THD *thd; /* needs to be first for thread_stack */
5220 bool thd_added= false;
5221 int error= 0;
5222 Slave_worker *w= (Slave_worker *) arg;
5223 Relay_log_info* rli= w->c_rli;
5224 ulong purge_cnt= 0;
5225 ulonglong purge_size= 0;
5226 struct slave_job_item _item, *job_item= &_item;
5227
5228 my_thread_init();
5229 DBUG_ENTER("handle_slave_worker");
5230
5231 thd= new THD;
5232 if (!thd)
5233 {
5234 sql_print_error("Failed during slave worker initialization");
5235 goto err;
5236 }
5237 w->info_thd= thd;
5238 thd->thread_stack = (char*)&thd;
5239
5240 pthread_detach_this_thread();
5241 if (init_slave_thread(thd, SLAVE_THD_WORKER))
5242 {
5243 // todo make SQL thread killed
5244 sql_print_error("Failed during slave worker initialization");
5245 goto err;
5246 }
5247 thd->init_for_queries(w);
5248
5249 mysql_mutex_lock(&LOCK_thread_count);
5250 add_global_thread(thd);
5251 thd_added= true;
5252 mysql_mutex_unlock(&LOCK_thread_count);
5253
5254 if (w->update_is_transactional())
5255 {
5256 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5257 "Error checking if the worker repository is transactional.");
5258 goto err;
5259 }
5260
5261 mysql_mutex_lock(&w->jobs_lock);
5262 w->running_status= Slave_worker::RUNNING;
5263 mysql_cond_signal(&w->jobs_cond);
5264
5265 mysql_mutex_unlock(&w->jobs_lock);
5266
5267 DBUG_ASSERT(thd->is_slave_error == 0);
5268
5269 while (!error)
5270 {
5271 error= slave_worker_exec_job(w, rli);
5272 }
5273
5274 /*
5275 Cleanup after an error requires clear_error() go first.
5276 Otherwise assert(!all) in binlog_rollback()
5277 */
5278 thd->clear_error();
5279 w->cleanup_context(thd, error);
5280
5281 mysql_mutex_lock(&w->jobs_lock);
5282
5283 while(de_queue(&w->jobs, job_item))
5284 {
5285 purge_cnt++;
5286 purge_size += ((Log_event*) (job_item->data))->data_written;
5287 DBUG_ASSERT(job_item->data);
5288 delete static_cast<Log_event*>(job_item->data);
5289 }
5290
5291 DBUG_ASSERT(w->jobs.len == 0);
5292
5293 mysql_mutex_unlock(&w->jobs_lock);
5294
5295 mysql_mutex_lock(&rli->pending_jobs_lock);
5296 rli->pending_jobs -= purge_cnt;
5297 rli->mts_pending_jobs_size -= purge_size;
5298 DBUG_ASSERT(rli->mts_pending_jobs_size < rli->mts_pending_jobs_size_max);
5299
5300 mysql_mutex_unlock(&rli->pending_jobs_lock);
5301
5302 /*
5303 In MTS case cleanup_after_session() has be called explicitly.
5304 TODO: to make worker thd be deleted before Slave_worker instance.
5305 */
5306 if (thd->rli_slave)
5307 {
5308 w->cleanup_after_session();
5309 thd->rli_slave= NULL;
5310 }
5311 mysql_mutex_lock(&w->jobs_lock);
5312
5313 w->running_status= Slave_worker::NOT_RUNNING;
5314 if (log_warnings > 1)
5315 sql_print_information("Worker %lu statistics: "
5316 "events processed = %lu "
5317 "hungry waits = %lu "
5318 "priv queue overfills = %llu ",
5319 w->id, w->events_done, w->wq_size_waits_cnt,
5320 w->jobs.waited_overfill);
5321 mysql_cond_signal(&w->jobs_cond); // famous last goodbye
5322
5323 mysql_mutex_unlock(&w->jobs_lock);
5324
5325 err:
5326
5327 if (thd)
5328 {
5329 /*
5330 The slave code is very bad. Notice that it is missing
5331 several clean up calls here. I've just added what was
5332 necessary to avoid valgrind errors.
5333
5334 /Alfranio
5335 */
5336 DBUG_ASSERT(thd->net.buff != 0);
5337 net_end(&thd->net);
5338
5339 /*
5340 to avoid close_temporary_tables() closing temp tables as those
5341 are Coordinator's burden.
5342 */
5343 thd->system_thread= NON_SYSTEM_THREAD;
5344 thd->release_resources();
5345 THD_CHECK_SENTRY(thd);
5346 if (thd_added)
5347 remove_global_thread(thd);
5348 delete thd;
5349 }
5350
5351 my_thread_end();
5352 #if OPENSSL_VERSION_NUMBER < 0x10100000L
5353 ERR_remove_thread_state(0);
5354 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
5355 pthread_exit(0);
5356 DBUG_RETURN(0);
5357 }
5358
5359 /**
5360 Orders jobs by comparing relay log information.
5361 */
5362
mts_event_coord_cmp(LOG_POS_COORD * id1,LOG_POS_COORD * id2)5363 int mts_event_coord_cmp(LOG_POS_COORD *id1, LOG_POS_COORD *id2)
5364 {
5365 longlong filecmp= strcmp(id1->file_name, id2->file_name);
5366 longlong poscmp= id1->pos - id2->pos;
5367 return (filecmp < 0 ? -1 : (filecmp > 0 ? 1 :
5368 (poscmp < 0 ? -1 : (poscmp > 0 ? 1 : 0))));
5369 }
5370
mts_recovery_groups(Relay_log_info * rli)5371 int mts_recovery_groups(Relay_log_info *rli)
5372 {
5373 Log_event *ev= NULL;
5374 const char *errmsg= NULL;
5375 bool error= FALSE;
5376 bool flag_group_seen_begin= FALSE;
5377 uint recovery_group_cnt= 0;
5378 bool not_reached_commit= true;
5379 DYNAMIC_ARRAY above_lwm_jobs;
5380 Slave_job_group job_worker;
5381 IO_CACHE log;
5382 File file;
5383 LOG_INFO linfo;
5384 my_off_t offset= 0;
5385 MY_BITMAP *groups= &rli->recovery_groups;
5386 THD *thd= current_thd;
5387
5388 DBUG_ENTER("mts_recovery_groups");
5389
5390 DBUG_ASSERT(rli->slave_parallel_workers == 0);
5391
5392 /*
5393 Although mts_recovery_groups() is reentrant it returns
5394 early if the previous invocation raised any bit in
5395 recovery_groups bitmap.
5396 */
5397 if (rli->is_mts_recovery())
5398 DBUG_RETURN(0);
5399
5400 /*
5401 Save relay log position to compare with worker's position.
5402 */
5403 LOG_POS_COORD cp=
5404 {
5405 (char *) rli->get_group_master_log_name(),
5406 rli->get_group_master_log_pos()
5407 };
5408
5409 Format_description_log_event fdle(BINLOG_VERSION), *p_fdle= &fdle;
5410
5411 if (!p_fdle->is_valid())
5412 DBUG_RETURN(TRUE);
5413
5414 /*
5415 Gathers information on valuable workers and stores it in
5416 above_lwm_jobs in asc ordered by the master binlog coordinates.
5417 */
5418 my_init_dynamic_array(&above_lwm_jobs, sizeof(Slave_job_group),
5419 rli->recovery_parallel_workers,
5420 rli->recovery_parallel_workers);
5421
5422 /*
5423 When info tables are used and autocommit= 0 we force a new
5424 transaction start to avoid table access deadlocks when START SLAVE
5425 is executed after STOP SLAVE with MTS enabled.
5426 */
5427 if (is_autocommit_off_and_infotables(thd))
5428 {
5429 if (trans_begin(thd))
5430 {
5431 error= TRUE;
5432 goto err;
5433 }
5434 }
5435
5436 for (uint id= 0; id < rli->recovery_parallel_workers; id++)
5437 {
5438 Slave_worker *worker=
5439 Rpl_info_factory::create_worker(opt_rli_repository_id, id, rli, true);
5440
5441 if (!worker)
5442 {
5443 if (is_autocommit_off_and_infotables(thd))
5444 trans_rollback(thd);
5445 error= TRUE;
5446 goto err;
5447 }
5448
5449 LOG_POS_COORD w_last= { const_cast<char*>(worker->get_group_master_log_name()),
5450 worker->get_group_master_log_pos() };
5451 if (mts_event_coord_cmp(&w_last, &cp) > 0)
5452 {
5453 /*
5454 Inserts information into a dynamic array for further processing.
5455 The jobs/workers are ordered by the last checkpoint positions
5456 workers have seen.
5457 */
5458 job_worker.worker= worker;
5459 job_worker.checkpoint_log_pos= worker->checkpoint_master_log_pos;
5460 job_worker.checkpoint_log_name= worker->checkpoint_master_log_name;
5461
5462 insert_dynamic(&above_lwm_jobs, (uchar*) &job_worker);
5463 }
5464 else
5465 {
5466 /*
5467 Deletes the worker because its jobs are included in the latest
5468 checkpoint.
5469 */
5470 delete worker;
5471 }
5472 }
5473
5474 /*
5475 When info tables are used and autocommit= 0 we force transaction
5476 commit to avoid table access deadlocks when START SLAVE is executed
5477 after STOP SLAVE with MTS enabled.
5478 */
5479 if (is_autocommit_off_and_infotables(thd))
5480 {
5481 if (trans_commit(thd))
5482 {
5483 error= TRUE;
5484 goto err;
5485 }
5486 }
5487
5488 /*
5489 In what follows, the group Recovery Bitmap is constructed.
5490
5491 seek(lwm);
5492
5493 while(w= next(above_lwm_w))
5494 do
5495 read G
5496 if G == w->last_comm
5497 w.B << group_cnt++;
5498 RB |= w.B;
5499 break;
5500 else
5501 group_cnt++;
5502 while(!eof);
5503 continue;
5504 */
5505 DBUG_ASSERT(!rli->recovery_groups_inited);
5506
5507 if (above_lwm_jobs.elements != 0)
5508 {
5509 bitmap_init(groups, NULL, MTS_MAX_BITS_IN_GROUP, FALSE);
5510 rli->recovery_groups_inited= true;
5511 bitmap_clear_all(groups);
5512 }
5513 rli->mts_recovery_group_cnt= 0;
5514 for (uint it_job= 0; it_job < above_lwm_jobs.elements; it_job++)
5515 {
5516 Slave_worker *w= ((Slave_job_group *)
5517 dynamic_array_ptr(&above_lwm_jobs, it_job))->worker;
5518 LOG_POS_COORD w_last= { const_cast<char*>(w->get_group_master_log_name()),
5519 w->get_group_master_log_pos() };
5520 bool checksum_detected= FALSE;
5521
5522 sql_print_information("Slave: MTS group recovery relay log info based on Worker-Id %lu, "
5523 "group_relay_log_name %s, group_relay_log_pos %llu "
5524 "group_master_log_name %s, group_master_log_pos %llu",
5525 w->id,
5526 w->get_group_relay_log_name(),
5527 w->get_group_relay_log_pos(),
5528 w->get_group_master_log_name(),
5529 w->get_group_master_log_pos());
5530
5531 recovery_group_cnt= 0;
5532 not_reached_commit= true;
5533 if (rli->relay_log.find_log_pos(&linfo, rli->get_group_relay_log_name(), 1))
5534 {
5535 error= TRUE;
5536 sql_print_error("Error looking for %s.", rli->get_group_relay_log_name());
5537 goto err;
5538 }
5539 offset= rli->get_group_relay_log_pos();
5540 for (int checking= 0 ; not_reached_commit; checking++)
5541 {
5542 if ((file= open_binlog_file(&log, linfo.log_file_name, &errmsg)) < 0)
5543 {
5544 error= TRUE;
5545 sql_print_error("%s", errmsg);
5546 goto err;
5547 }
5548 /*
5549 Looking for the actual relay checksum algorithm that is present in
5550 a FD at head events of the relay log.
5551 */
5552 if (!checksum_detected)
5553 {
5554 int i= 0;
5555 while (i < 4 && (ev= Log_event::read_log_event(&log,
5556 (mysql_mutex_t*) 0, p_fdle, 0)))
5557 {
5558 if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
5559 {
5560 p_fdle->checksum_alg= ev->checksum_alg;
5561 checksum_detected= TRUE;
5562 }
5563 delete ev;
5564 i++;
5565 }
5566 if (!checksum_detected)
5567 {
5568 error= TRUE;
5569 sql_print_error("%s", "malformed or very old relay log which "
5570 "does not have FormatDescriptor");
5571 goto err;
5572 }
5573 }
5574
5575 my_b_seek(&log, offset);
5576
5577 while (not_reached_commit &&
5578 (ev= Log_event::read_log_event(&log, 0, p_fdle,
5579 opt_slave_sql_verify_checksum)))
5580 {
5581 DBUG_ASSERT(ev->is_valid());
5582
5583 if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
5584 p_fdle->checksum_alg= ev->checksum_alg;
5585
5586 if (ev->get_type_code() == ROTATE_EVENT ||
5587 ev->get_type_code() == FORMAT_DESCRIPTION_EVENT ||
5588 ev->get_type_code() == PREVIOUS_GTIDS_LOG_EVENT)
5589 {
5590 delete ev;
5591 ev= NULL;
5592 continue;
5593 }
5594
5595 DBUG_PRINT("mts", ("Event Recoverying relay log info "
5596 "group_mster_log_name %s, event_master_log_pos %llu type code %u.",
5597 linfo.log_file_name, ev->log_pos, ev->get_type_code()));
5598
5599 if (ev->starts_group())
5600 {
5601 flag_group_seen_begin= true;
5602 }
5603 else if ((ev->ends_group() || !flag_group_seen_begin) &&
5604 !is_gtid_event(ev))
5605 {
5606 int ret= 0;
5607 LOG_POS_COORD ev_coord= { (char *) rli->get_group_master_log_name(),
5608 ev->log_pos };
5609 flag_group_seen_begin= false;
5610 recovery_group_cnt++;
5611
5612 sql_print_information("Slave: MTS group recovery relay log info "
5613 "group_master_log_name %s, "
5614 "event_master_log_pos %llu.",
5615 rli->get_group_master_log_name(), ev->log_pos);
5616 if ((ret= mts_event_coord_cmp(&ev_coord, &w_last)) == 0)
5617 {
5618 #ifndef DBUG_OFF
5619 for (uint i= 0; i <= w->checkpoint_seqno; i++)
5620 {
5621 if (bitmap_is_set(&w->group_executed, i))
5622 DBUG_PRINT("mts", ("Bit %u is set.", i));
5623 else
5624 DBUG_PRINT("mts", ("Bit %u is not set.", i));
5625 }
5626 #endif
5627 DBUG_PRINT("mts",
5628 ("Doing a shift ini(%lu) end(%lu).",
5629 (w->checkpoint_seqno + 1) - recovery_group_cnt,
5630 w->checkpoint_seqno));
5631
5632 for (uint i= (w->checkpoint_seqno + 1) - recovery_group_cnt,
5633 j= 0; i <= w->checkpoint_seqno; i++, j++)
5634 {
5635 if (bitmap_is_set(&w->group_executed, i))
5636 {
5637 DBUG_PRINT("mts", ("Setting bit %u.", j));
5638 bitmap_fast_test_and_set(groups, j);
5639 }
5640 }
5641 not_reached_commit= false;
5642 }
5643 else
5644 DBUG_ASSERT(ret < 0);
5645 }
5646 delete ev;
5647 ev= NULL;
5648 }
5649 end_io_cache(&log);
5650 mysql_file_close(file, MYF(MY_WME));
5651 offset= BIN_LOG_HEADER_SIZE;
5652 if (not_reached_commit && rli->relay_log.find_next_log(&linfo, 1))
5653 {
5654 error= TRUE;
5655 sql_print_error("Error looking for file after %s.", linfo.log_file_name);
5656 goto err;
5657 }
5658 }
5659
5660 rli->mts_recovery_group_cnt= (rli->mts_recovery_group_cnt < recovery_group_cnt ?
5661 recovery_group_cnt : rli->mts_recovery_group_cnt);
5662 }
5663
5664 DBUG_ASSERT(!rli->recovery_groups_inited ||
5665 rli->mts_recovery_group_cnt <= groups->n_bits);
5666
5667 err:
5668
5669 for (uint it_job= 0; it_job < above_lwm_jobs.elements; it_job++)
5670 {
5671 get_dynamic(&above_lwm_jobs, (uchar *) &job_worker, it_job);
5672 delete job_worker.worker;
5673 }
5674
5675 delete_dynamic(&above_lwm_jobs);
5676 if (rli->mts_recovery_group_cnt == 0)
5677 rli->clear_mts_recovery_groups();
5678
5679 DBUG_RETURN(error ? ER_MTS_RECOVERY_FAILURE : 0);
5680 }
5681
5682 /**
5683 Processing rli->gaq to find out the low-water-mark (lwm) coordinates
5684 which is stored into the cental recovery table.
5685
5686 @param rli pointer to Relay-log-info of Coordinator
5687 @param period period of processing GAQ, normally derived from
5688 @c mts_checkpoint_period
5689 @param force if TRUE then hang in a loop till some progress
5690 @param need_data_lock False if rli->data_lock mutex is aquired by
5691 the caller.
5692
5693 @return FALSE success, TRUE otherwise
5694 */
mts_checkpoint_routine(Relay_log_info * rli,ulonglong period,bool force,bool need_data_lock)5695 bool mts_checkpoint_routine(Relay_log_info *rli, ulonglong period,
5696 bool force, bool need_data_lock)
5697 {
5698 ulong cnt;
5699 bool error= FALSE;
5700 struct timespec curr_clock;
5701
5702 DBUG_ENTER("checkpoint_routine");
5703
5704 #ifndef DBUG_OFF
5705 if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
5706 {
5707 if (!rli->gaq->count_done(rli))
5708 DBUG_RETURN(FALSE);
5709 }
5710 #endif
5711
5712 /*
5713 rli->checkpoint_group can have two possible values due to
5714 two possible status of the last (being scheduled) group.
5715 */
5716 DBUG_ASSERT(!rli->gaq->full() ||
5717 ((rli->checkpoint_seqno == rli->checkpoint_group -1 &&
5718 rli->mts_group_status == Relay_log_info::MTS_IN_GROUP) ||
5719 rli->checkpoint_seqno == rli->checkpoint_group));
5720
5721 /*
5722 Currently, the checkpoint routine is being called by the SQL Thread.
5723 For that reason, this function is called call from appropriate points
5724 in the SQL Thread's execution path and the elapsed time is calculated
5725 here to check if it is time to execute it.
5726 */
5727 set_timespec_nsec(curr_clock, 0);
5728 ulonglong diff= diff_timespec(curr_clock, rli->last_clock);
5729 if (!force && diff < period)
5730 {
5731 /*
5732 We do not need to execute the checkpoint now because
5733 the time elapsed is not enough.
5734 */
5735 DBUG_RETURN(FALSE);
5736 }
5737
5738 do
5739 {
5740 cnt= rli->gaq->move_queue_head(&rli->workers);
5741 #ifndef DBUG_OFF
5742 if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0) &&
5743 cnt != opt_mts_checkpoint_period)
5744 sql_print_error("This an error cnt != mts_checkpoint_period");
5745 #endif
5746 } while (!sql_slave_killed(rli->info_thd, rli) &&
5747 cnt == 0 && force &&
5748 !DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0) &&
5749 (my_sleep(rli->mts_coordinator_basic_nap), 1));
5750 /*
5751 This checks how many consecutive jobs where processed.
5752 If this value is different than zero the checkpoint
5753 routine can proceed. Otherwise, there is nothing to be
5754 done.
5755 */
5756 if (cnt == 0)
5757 goto end;
5758
5759
5760 /* TODO:
5761 to turn the least occupied selection in terms of jobs pieces
5762 */
5763 for (uint i= 0; i < rli->workers.elements; i++)
5764 {
5765 Slave_worker *w_i;
5766 get_dynamic(&rli->workers, (uchar *) &w_i, i);
5767 set_dynamic(&rli->least_occupied_workers, (uchar*) &w_i->jobs.len, w_i->id);
5768 };
5769 sort_dynamic(&rli->least_occupied_workers, (qsort_cmp) ulong_cmp);
5770
5771 if (need_data_lock)
5772 mysql_mutex_lock(&rli->data_lock);
5773 else
5774 mysql_mutex_assert_owner(&rli->data_lock);
5775
5776 /*
5777 "Coordinator::commit_positions" {
5778
5779 rli->gaq->lwm has been updated in move_queue_head() and
5780 to contain all but rli->group_master_log_name which
5781 is altered solely by Coordinator at special checkpoints.
5782 */
5783 rli->set_group_master_log_pos(rli->gaq->lwm.group_master_log_pos);
5784 rli->set_group_relay_log_pos(rli->gaq->lwm.group_relay_log_pos);
5785 DBUG_PRINT("mts", ("New checkpoint %llu %llu %s",
5786 rli->gaq->lwm.group_master_log_pos,
5787 rli->gaq->lwm.group_relay_log_pos,
5788 rli->gaq->lwm.group_relay_log_name));
5789
5790 if (rli->gaq->lwm.group_relay_log_name[0] != 0)
5791 rli->set_group_relay_log_name(rli->gaq->lwm.group_relay_log_name);
5792
5793 /*
5794 todo: uncomment notifies when UNTIL will be supported
5795
5796 rli->notify_group_master_log_name_update();
5797 rli->notify_group_relay_log_name_update();
5798
5799 Todo: optimize with if (wait_flag) broadcast
5800 waiter: set wait_flag; waits....; drops wait_flag;
5801 */
5802
5803 error= rli->flush_info(TRUE);
5804
5805 mysql_cond_broadcast(&rli->data_cond);
5806 if (need_data_lock)
5807 mysql_mutex_unlock(&rli->data_lock);
5808
5809 /*
5810 We need to ensure that this is never called at this point when
5811 cnt is zero. This value means that the checkpoint information
5812 will be completely reset.
5813 */
5814 rli->reset_notified_checkpoint(cnt, rli->gaq->lwm.ts, need_data_lock);
5815
5816 /* end-of "Coordinator::"commit_positions" */
5817
5818 end:
5819 #ifndef DBUG_OFF
5820 if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
5821 DBUG_SUICIDE();
5822 #endif
5823 set_timespec_nsec(rli->last_clock, 0);
5824
5825 DBUG_RETURN(error);
5826 }
5827
5828 /**
5829 Instantiation of a Slave_worker and forking out a single Worker thread.
5830
5831 @param rli Coordinator's Relay_log_info pointer
5832 @param i identifier of the Worker
5833
5834 @return 0 suppress or 1 if fails
5835 */
slave_start_single_worker(Relay_log_info * rli,ulong i)5836 int slave_start_single_worker(Relay_log_info *rli, ulong i)
5837 {
5838 int error= 0;
5839 pthread_t th;
5840 Slave_worker *w= NULL;
5841
5842 mysql_mutex_assert_owner(&rli->run_lock);
5843
5844 if (!(w=
5845 Rpl_info_factory::create_worker(opt_rli_repository_id, i, rli, false)))
5846 {
5847 sql_print_error("Failed during slave worker thread create");
5848 error= 1;
5849 goto err;
5850 }
5851
5852 if (w->init_worker(rli, i))
5853 {
5854 sql_print_error("Failed during slave worker thread create");
5855 error= 1;
5856 goto err;
5857 }
5858 set_dynamic(&rli->workers, (uchar*) &w, i);
5859
5860 if (DBUG_EVALUATE_IF("mts_worker_thread_fails", i == 1, 0) ||
5861 (error= mysql_thread_create(key_thread_slave_worker, &th,
5862 &connection_attrib,
5863 handle_slave_worker, (void*) w)))
5864 {
5865 sql_print_error("Failed during slave worker thread create (errno= %d)",
5866 error);
5867 error= 1;
5868 goto err;
5869 }
5870
5871 mysql_mutex_lock(&w->jobs_lock);
5872 if (w->running_status == Slave_worker::NOT_RUNNING)
5873 mysql_cond_wait(&w->jobs_cond, &w->jobs_lock);
5874 mysql_mutex_unlock(&w->jobs_lock);
5875 // Least occupied inited with zero
5876 insert_dynamic(&rli->least_occupied_workers, (uchar*) &w->jobs.len);
5877
5878 err:
5879 if (error && w)
5880 {
5881 delete w;
5882 /*
5883 Any failure after dynarray inserted must follow with deletion
5884 of just created item.
5885 */
5886 if (rli->workers.elements == i + 1)
5887 delete_dynamic_element(&rli->workers, i);
5888 }
5889 return error;
5890 }
5891
5892 /**
5893 Initialization of the central rli members for Coordinator's role,
5894 communication channels such as Assigned Partition Hash (APH),
5895 and starting the Worker pool.
5896
5897 @param n Number of configured Workers in the upcoming session.
5898
5899 @return 0 success
5900 non-zero as failure
5901 */
slave_start_workers(Relay_log_info * rli,ulong n,bool * mts_inited)5902 int slave_start_workers(Relay_log_info *rli, ulong n, bool *mts_inited)
5903 {
5904 uint i;
5905 int error= 0;
5906
5907 mysql_mutex_assert_owner(&rli->run_lock);
5908
5909 if (n == 0 && rli->mts_recovery_group_cnt == 0)
5910 {
5911 reset_dynamic(&rli->workers);
5912 goto end;
5913 }
5914
5915 *mts_inited= true;
5916
5917 /*
5918 The requested through argument number of Workers can be different
5919 from the previous time which ended with an error. Thereby
5920 the effective number of configured Workers is max of the two.
5921 */
5922 rli->init_workers(max(n, rli->recovery_parallel_workers));
5923
5924 // CGAP dynarray holds id:s of partitions of the Current being executed Group
5925 my_init_dynamic_array(&rli->curr_group_assigned_parts,
5926 sizeof(db_worker_hash_entry*),
5927 SLAVE_INIT_DBS_IN_GROUP, 1);
5928 rli->last_assigned_worker= NULL; // associated with curr_group_assigned
5929 my_init_dynamic_array(&rli->curr_group_da, sizeof(Log_event*), 8, 2);
5930 // Least_occupied_workers array to hold items size of Slave_jobs_queue::len
5931 my_init_dynamic_array(&rli->least_occupied_workers, sizeof(ulong), n, 0);
5932
5933 /*
5934 GAQ queue holds seqno:s of scheduled groups. C polls workers in
5935 @c opt_mts_checkpoint_period to update GAQ (see @c next_event())
5936 The length of GAQ is set to be equal to checkpoint_group.
5937 Notice, the size matters for mts_checkpoint_routine's progress loop.
5938 */
5939
5940 rli->gaq= new Slave_committed_queue(rli->get_group_master_log_name(),
5941 sizeof(Slave_job_group),
5942 rli->checkpoint_group, n);
5943 if (!rli->gaq->inited)
5944 return 1;
5945
5946 // length of WQ is actually constant though can be made configurable
5947 rli->mts_slave_worker_queue_len_max= mts_slave_worker_queue_len_max;
5948 rli->mts_pending_jobs_size= 0;
5949 rli->mts_pending_jobs_size_max= ::opt_mts_pending_jobs_size_max;
5950 rli->mts_wq_underrun_w_id= MTS_WORKER_UNDEF;
5951 rli->mts_wq_excess_cnt= 0;
5952 rli->mts_wq_overrun_cnt= 0;
5953 rli->mts_wq_oversize= FALSE;
5954 rli->mts_coordinator_basic_nap= mts_coordinator_basic_nap;
5955 rli->mts_worker_underrun_level= mts_worker_underrun_level;
5956 rli->curr_group_seen_begin= rli->curr_group_seen_gtid= false;
5957 rli->curr_group_isolated= FALSE;
5958 rli->checkpoint_seqno= 0;
5959 rli->mts_last_online_stat= my_time(0);
5960 rli->mts_group_status= Relay_log_info::MTS_NOT_IN_GROUP;
5961
5962 if (init_hash_workers(n)) // MTS: mapping_db_to_worker
5963 {
5964 sql_print_error("Failed to init partitions hash");
5965 error= 1;
5966 goto err;
5967 }
5968
5969 for (i= 0; i < n; i++)
5970 {
5971 if ((error= slave_start_single_worker(rli, i)))
5972 goto err;
5973 rli->slave_parallel_workers++;
5974 }
5975
5976 end:
5977 // Effective end of the recovery right now when there is no gaps
5978 if (!error && rli->mts_recovery_group_cnt == 0)
5979 {
5980 if ((error= rli->mts_finalize_recovery()))
5981 (void) Rpl_info_factory::reset_workers(rli);
5982 if (!error)
5983 error= rli->flush_info(TRUE);
5984 }
5985
5986 err:
5987 return error;
5988 }
5989
5990 /*
5991 Ending Worker threads.
5992
5993 Not in case Coordinator is killed itself, it first waits for
5994 Workers have finished their assignements, and then updates checkpoint.
5995 Workers are notified with setting KILLED status
5996 and waited for their acknowledgment as specified by
5997 worker's running_status.
5998 Coordinator finalizes with its MTS running status to reset few objects.
5999 */
slave_stop_workers(Relay_log_info * rli,bool * mts_inited)6000 void slave_stop_workers(Relay_log_info *rli, bool *mts_inited)
6001 {
6002 int i;
6003 THD *thd= rli->info_thd;
6004 if (!*mts_inited)
6005 return;
6006 else if (rli->slave_parallel_workers == 0)
6007 goto end;
6008
6009 /*
6010 If request for stop slave is received notify worker
6011 to stop.
6012 */
6013 // Initialize worker exit count and max_updated_index to 0 during each stop.
6014 rli->exit_counter= 0;
6015 rli->max_updated_index= (rli->until_condition !=
6016 Relay_log_info::UNTIL_NONE)?
6017 rli->mts_groups_assigned:0;
6018
6019 for (i= rli->workers.elements - 1; i >= 0; i--)
6020 {
6021 Slave_worker *w;
6022 struct slave_job_item item= {NULL}, *job_item= &item;
6023 get_dynamic((DYNAMIC_ARRAY*)&rli->workers, (uchar*) &w, i);
6024 mysql_mutex_lock(&w->jobs_lock);
6025 //Inform all workers to stop
6026 if (w->running_status != Slave_worker::RUNNING)
6027 {
6028 mysql_mutex_unlock(&w->jobs_lock);
6029 continue;
6030 }
6031
6032 w->running_status= Slave_worker::STOP;
6033 (void) set_max_updated_index_on_stop(w, job_item);
6034 mysql_cond_signal(&w->jobs_cond);
6035
6036 mysql_mutex_unlock(&w->jobs_lock);
6037
6038 if (log_warnings > 1)
6039 sql_print_information("Notifying Worker %lu to exit, thd %p", w->id,
6040 w->info_thd);
6041 }
6042
6043 thd_proc_info(thd, "Waiting for workers to exit");
6044
6045 for (i= rli->workers.elements - 1; i >= 0; i--)
6046 {
6047 Slave_worker *w= NULL;
6048 get_dynamic((DYNAMIC_ARRAY*)&rli->workers, (uchar*) &w, i);
6049
6050 mysql_mutex_lock(&w->jobs_lock);
6051 while (w->running_status != Slave_worker::NOT_RUNNING)
6052 {
6053 PSI_stage_info old_stage;
6054 DBUG_ASSERT(w->running_status == Slave_worker::ERROR_LEAVING ||
6055 w->running_status == Slave_worker::STOP ||
6056 w->running_status == Slave_worker::STOP_ACCEPTED);
6057
6058 thd->ENTER_COND(&w->jobs_cond, &w->jobs_lock,
6059 &stage_slave_waiting_workers_to_exit, &old_stage);
6060 mysql_cond_wait(&w->jobs_cond, &w->jobs_lock);
6061 thd->EXIT_COND(&old_stage);
6062 mysql_mutex_lock(&w->jobs_lock);
6063 }
6064 mysql_mutex_unlock(&w->jobs_lock);
6065 }
6066
6067 if (thd->killed == THD::NOT_KILLED)
6068 (void) mts_checkpoint_routine(rli, 0, false, true/*need_data_lock=true*/); // TODO:consider to propagate an error out of the function
6069
6070 for (i= rli->workers.elements - 1; i >= 0; i--)
6071 {
6072 Slave_worker *w= NULL;
6073 get_dynamic((DYNAMIC_ARRAY*)&rli->workers, (uchar*) &w, i);
6074 delete_dynamic_element(&rli->workers, i);
6075 delete w;
6076 }
6077 if (log_warnings > 1)
6078 sql_print_information("Total MTS session statistics: "
6079 "events processed = %llu; "
6080 "worker queues filled over overrun level = %lu; "
6081 "waited due a Worker queue full = %lu; "
6082 "waited due the total size = %lu; "
6083 "slept when Workers occupied = %lu ",
6084 rli->mts_events_assigned, rli->mts_wq_overrun_cnt,
6085 rli->mts_wq_overfill_cnt, rli->wq_size_waits_cnt,
6086 rli->mts_wq_no_underrun_cnt);
6087
6088 DBUG_ASSERT(rli->pending_jobs == 0);
6089 DBUG_ASSERT(rli->mts_pending_jobs_size == 0);
6090
6091 end:
6092 rli->mts_group_status= Relay_log_info::MTS_NOT_IN_GROUP;
6093 destroy_hash_workers(rli);
6094 delete rli->gaq;
6095 delete_dynamic(&rli->least_occupied_workers); // least occupied
6096
6097 // Destroy buffered events of the current group prior to exit.
6098 for (uint i= 0; i < rli->curr_group_da.elements; i++)
6099 delete *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, i);
6100 delete_dynamic(&rli->curr_group_da); // GCDA
6101
6102 delete_dynamic(&rli->curr_group_assigned_parts); // GCAP
6103 rli->deinit_workers();
6104 rli->slave_parallel_workers= 0;
6105 *mts_inited= false;
6106 }
6107
6108
6109 /**
6110 Slave SQL thread entry point.
6111
6112 @param arg Pointer to Relay_log_info object that holds information
6113 for the SQL thread.
6114
6115 @return Always 0.
6116 */
handle_slave_sql(void * arg)6117 pthread_handler_t handle_slave_sql(void *arg)
6118 {
6119 THD *thd; /* needs to be first for thread_stack */
6120 bool thd_added= false;
6121 char llbuff[22],llbuff1[22];
6122 char saved_log_name[FN_REFLEN];
6123 char saved_master_log_name[FN_REFLEN];
6124 my_off_t saved_log_pos= 0;
6125 my_off_t saved_master_log_pos= 0;
6126 my_off_t saved_skip= 0;
6127
6128 Relay_log_info* rli = ((Master_info*)arg)->rli;
6129 const char *errmsg;
6130 const char *error_string;
6131 bool mts_inited= false;
6132
6133 // needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
6134 my_thread_init();
6135 DBUG_ENTER("handle_slave_sql");
6136
6137 DBUG_ASSERT(rli->inited);
6138 mysql_mutex_lock(&rli->run_lock);
6139 DBUG_ASSERT(!rli->slave_running);
6140 errmsg= 0;
6141 error_string= 0;
6142 #ifndef DBUG_OFF
6143 rli->events_until_exit = abort_slave_event_count;
6144 #endif
6145
6146 thd = new THD; // note that contructor of THD uses DBUG_ !
6147 thd->thread_stack = (char*)&thd; // remember where our stack is
6148 rli->info_thd= thd;
6149
6150 /* Inform waiting threads that slave has started */
6151 rli->slave_run_id++;
6152 rli->slave_running = 1;
6153 rli->reported_unsafe_warning= false;
6154 rli->sql_thread_kill_accepted= false;
6155
6156 pthread_detach_this_thread();
6157 if (init_slave_thread(thd, SLAVE_THD_SQL))
6158 {
6159 /*
6160 TODO: this is currently broken - slave start and change master
6161 will be stuck if we fail here
6162 */
6163 mysql_cond_broadcast(&rli->start_cond);
6164 mysql_mutex_unlock(&rli->run_lock);
6165 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6166 "Failed during slave thread initialization");
6167 goto err;
6168 }
6169 thd->init_for_queries(rli);
6170 thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
6171 set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables
6172
6173 mysql_mutex_lock(&LOCK_thread_count);
6174 add_global_thread(thd);
6175 thd_added= true;
6176 mysql_mutex_unlock(&LOCK_thread_count);
6177
6178 /* MTS: starting the worker pool */
6179 if (slave_start_workers(rli, rli->opt_slave_parallel_workers, &mts_inited) != 0)
6180 {
6181 mysql_cond_broadcast(&rli->start_cond);
6182 mysql_mutex_unlock(&rli->run_lock);
6183 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6184 "Failed during slave workers initialization");
6185 goto err;
6186 }
6187 /*
6188 We are going to set slave_running to 1. Assuming slave I/O thread is
6189 alive and connected, this is going to make Seconds_Behind_Master be 0
6190 i.e. "caught up". Even if we're just at start of thread. Well it's ok, at
6191 the moment we start we can think we are caught up, and the next second we
6192 start receiving data so we realize we are not caught up and
6193 Seconds_Behind_Master grows. No big deal.
6194 */
6195 rli->abort_slave = 0;
6196
6197 /*
6198 Reset errors for a clean start (otherwise, if the master is idle, the SQL
6199 thread may execute no Query_log_event, so the error will remain even
6200 though there's no problem anymore). Do not reset the master timestamp
6201 (imagine the slave has caught everything, the STOP SLAVE and START SLAVE:
6202 as we are not sure that we are going to receive a query, we want to
6203 remember the last master timestamp (to say how many seconds behind we are
6204 now.
6205 But the master timestamp is reset by RESET SLAVE & CHANGE MASTER.
6206 */
6207 rli->clear_error();
6208
6209 if (rli->update_is_transactional())
6210 {
6211 mysql_cond_broadcast(&rli->start_cond);
6212 mysql_mutex_unlock(&rli->run_lock);
6213 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6214 "Error checking if the relay log repository is transactional.");
6215 goto err;
6216 }
6217
6218 if (!rli->is_transactional())
6219 rli->report(WARNING_LEVEL, 0,
6220 "If a crash happens this configuration does not guarantee that the relay "
6221 "log info will be consistent");
6222
6223 mysql_mutex_unlock(&rli->run_lock);
6224 mysql_cond_broadcast(&rli->start_cond);
6225
6226 DEBUG_SYNC(thd, "after_start_slave");
6227
6228 //tell the I/O thread to take relay_log_space_limit into account from now on
6229 mysql_mutex_lock(&rli->log_space_lock);
6230 rli->ignore_log_space_limit= 0;
6231 mysql_mutex_unlock(&rli->log_space_lock);
6232 rli->trans_retries= 0; // start from "no error"
6233 DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries));
6234
6235 if (rli->init_relay_log_pos(rli->get_group_relay_log_name(),
6236 rli->get_group_relay_log_pos(),
6237 true/*need_data_lock=true*/, &errmsg,
6238 1 /*look for a description_event*/))
6239 {
6240 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6241 "Error initializing relay log position: %s", errmsg);
6242 goto err;
6243 }
6244 THD_CHECK_SENTRY(thd);
6245 #ifndef DBUG_OFF
6246 {
6247 char llbuf1[22], llbuf2[22];
6248 DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
6249 llstr(my_b_tell(rli->cur_log),llbuf1),
6250 llstr(rli->get_event_relay_log_pos(),llbuf2)));
6251 DBUG_ASSERT(rli->get_event_relay_log_pos() >= BIN_LOG_HEADER_SIZE);
6252 /*
6253 Wonder if this is correct. I (Guilhem) wonder if my_b_tell() returns the
6254 correct position when it's called just after my_b_seek() (the questionable
6255 stuff is those "seek is done on next read" comments in the my_b_seek()
6256 source code).
6257 The crude reality is that this assertion randomly fails whereas
6258 replication seems to work fine. And there is no easy explanation why it
6259 fails (as we my_b_seek(rli->event_relay_log_pos) at the very end of
6260 init_relay_log_pos() called above). Maybe the assertion would be
6261 meaningful if we held rli->data_lock between the my_b_seek() and the
6262 DBUG_ASSERT().
6263 */
6264 #ifdef SHOULD_BE_CHECKED
6265 DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->get_event_relay_log_pos());
6266 #endif
6267 }
6268 #endif
6269 DBUG_ASSERT(rli->info_thd == thd);
6270
6271 #ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
6272 /* engine specific hook, to be made generic */
6273 if (ndb_wait_setup_func && ndb_wait_setup_func(opt_ndb_wait_setup))
6274 {
6275 sql_print_warning("Slave SQL thread : NDB : Tables not available after %lu"
6276 " seconds. Consider increasing --ndb-wait-setup value",
6277 opt_ndb_wait_setup);
6278 }
6279 #endif
6280
6281 DBUG_PRINT("master_info",("log_file_name: %s position: %s",
6282 rli->get_group_master_log_name(),
6283 llstr(rli->get_group_master_log_pos(),llbuff)));
6284 if (log_warnings)
6285 sql_print_information("Slave SQL thread initialized, starting replication in \
6286 log '%s' at position %s, relay log '%s' position: %s", rli->get_rpl_log_name(),
6287 llstr(rli->get_group_master_log_pos(),llbuff),rli->get_group_relay_log_name(),
6288 llstr(rli->get_group_relay_log_pos(),llbuff1));
6289
6290 if (check_temp_dir(rli->slave_patternload_file))
6291 {
6292 rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
6293 "Unable to use slave's temporary directory %s - %s",
6294 slave_load_tmpdir, thd->get_stmt_da()->message());
6295 goto err;
6296 }
6297
6298 /* execute init_slave variable */
6299 if (opt_init_slave.length)
6300 {
6301 execute_init_command(thd, &opt_init_slave, &LOCK_sys_init_slave);
6302 if (thd->is_slave_error)
6303 {
6304 rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
6305 "Slave SQL thread aborted. Can't execute init_slave query");
6306 goto err;
6307 }
6308 }
6309
6310 /*
6311 First check until condition - probably there is nothing to execute. We
6312 do not want to wait for next event in this case.
6313 */
6314 mysql_mutex_lock(&rli->data_lock);
6315 if (rli->slave_skip_counter)
6316 {
6317 strmake(saved_log_name, rli->get_group_relay_log_name(), FN_REFLEN - 1);
6318 strmake(saved_master_log_name, rli->get_group_master_log_name(), FN_REFLEN - 1);
6319 saved_log_pos= rli->get_group_relay_log_pos();
6320 saved_master_log_pos= rli->get_group_master_log_pos();
6321 saved_skip= rli->slave_skip_counter;
6322 }
6323 if (rli->until_condition != Relay_log_info::UNTIL_NONE &&
6324 rli->is_until_satisfied(thd, NULL))
6325 {
6326 mysql_mutex_unlock(&rli->data_lock);
6327 goto err;
6328 }
6329 mysql_mutex_unlock(&rli->data_lock);
6330
6331 /* Read queries from the IO/THREAD until this thread is killed */
6332
6333 while (!sql_slave_killed(thd,rli))
6334 {
6335 THD_STAGE_INFO(thd, stage_reading_event_from_the_relay_log);
6336 DBUG_ASSERT(rli->info_thd == thd);
6337 THD_CHECK_SENTRY(thd);
6338
6339 if (saved_skip && rli->slave_skip_counter == 0)
6340 {
6341 sql_print_information("'SQL_SLAVE_SKIP_COUNTER=%ld' executed at "
6342 "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
6343 "master_log_pos='%ld' and new position at "
6344 "relay_log_file='%s', relay_log_pos='%ld', master_log_name='%s', "
6345 "master_log_pos='%ld' ",
6346 (ulong) saved_skip, saved_log_name, (ulong) saved_log_pos,
6347 saved_master_log_name, (ulong) saved_master_log_pos,
6348 rli->get_group_relay_log_name(), (ulong) rli->get_group_relay_log_pos(),
6349 rli->get_group_master_log_name(), (ulong) rli->get_group_master_log_pos());
6350 saved_skip= 0;
6351 }
6352
6353 if (exec_relay_log_event(thd,rli))
6354 {
6355 DBUG_PRINT("info", ("exec_relay_log_event() failed"));
6356 // do not scare the user if SQL thread was simply killed or stopped
6357 if (!sql_slave_killed(thd,rli))
6358 {
6359 /*
6360 retrieve as much info as possible from the thd and, error
6361 codes and warnings and print this to the error log as to
6362 allow the user to locate the error
6363 */
6364 uint32 const last_errno= rli->last_error().number;
6365
6366 if (thd->is_error())
6367 {
6368 char const *const errmsg= thd->get_stmt_da()->message();
6369
6370 DBUG_PRINT("info",
6371 ("thd->get_stmt_da()->sql_errno()=%d; "
6372 "rli->last_error.number=%d",
6373 thd->get_stmt_da()->sql_errno(), last_errno));
6374 if (last_errno == 0)
6375 {
6376 /*
6377 This function is reporting an error which was not reported
6378 while executing exec_relay_log_event().
6379 */
6380 rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
6381 "%s", errmsg);
6382 }
6383 else if (last_errno != thd->get_stmt_da()->sql_errno())
6384 {
6385 /*
6386 * An error was reported while executing exec_relay_log_event()
6387 * however the error code differs from what is in the thread.
6388 * This function prints out more information to help finding
6389 * what caused the problem.
6390 */
6391 sql_print_error("Slave (additional info): %s Error_code: %d",
6392 errmsg, thd->get_stmt_da()->sql_errno());
6393 }
6394 }
6395
6396 /* Print any warnings issued */
6397 Diagnostics_area::Sql_condition_iterator it=
6398 thd->get_stmt_da()->sql_conditions();
6399 const Sql_condition *err;
6400 /*
6401 Added controlled slave thread cancel for replication
6402 of user-defined variables.
6403 */
6404 bool udf_error = false;
6405 while ((err= it++))
6406 {
6407 if (err->get_sql_errno() == ER_CANT_OPEN_LIBRARY)
6408 udf_error = true;
6409 sql_print_warning("Slave: %s Error_code: %d", err->get_message_text(), err->get_sql_errno());
6410 }
6411 if (udf_error)
6412 error_string= "Error loading user-defined library, slave SQL "
6413 "thread aborted. Install the missing library, and restart the"
6414 " slave SQL thread with \"SLAVE START\".";
6415 else
6416 error_string= "Error running query, slave SQL thread aborted."
6417 " Fix the problem, and restart the slave SQL thread with "
6418 "\"SLAVE START\".";
6419 }
6420 goto err;
6421 }
6422 }
6423
6424 err:
6425
6426 slave_stop_workers(rli, &mts_inited); // stopping worker pool
6427 /* Thread stopped. Print the current replication position to the log */
6428 if (error_string)
6429 sql_print_error("%s We stopped at log '%s' position %s.", error_string,
6430 rli->get_rpl_log_name(),
6431 llstr(rli->get_group_master_log_pos(), llbuff));
6432 else
6433 sql_print_information("Slave SQL thread exiting, replication stopped in log"
6434 " '%s' at position %s",
6435 rli->get_rpl_log_name(),
6436 llstr(rli->get_group_master_log_pos(), llbuff));
6437 rli->clear_mts_recovery_groups();
6438
6439 /*
6440 Some events set some playgrounds, which won't be cleared because thread
6441 stops. Stopping of this thread may not be known to these events ("stop"
6442 request is detected only by the present function, not by events), so we
6443 must "proactively" clear playgrounds:
6444 */
6445 thd->clear_error();
6446 rli->cleanup_context(thd, 1);
6447 /*
6448 Some extra safety, which should not been needed (normally, event deletion
6449 should already have done these assignments (each event which sets these
6450 variables is supposed to set them to 0 before terminating)).
6451 */
6452 thd->catalog= 0;
6453 thd->reset_query();
6454 thd->reset_db(NULL, 0);
6455
6456 THD_STAGE_INFO(thd, stage_waiting_for_slave_mutex_on_exit);
6457 mysql_mutex_lock(&rli->run_lock);
6458 /* We need data_lock, at least to wake up any waiting master_pos_wait() */
6459 mysql_mutex_lock(&rli->data_lock);
6460 DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun
6461 /* When master_pos_wait() wakes up it will check this and terminate */
6462 rli->slave_running= 0;
6463 /* Forget the relay log's format */
6464 rli->set_rli_description_event(NULL);
6465 /* Wake up master_pos_wait() */
6466 mysql_mutex_unlock(&rli->data_lock);
6467 DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions"));
6468 mysql_cond_broadcast(&rli->data_cond);
6469 rli->ignore_log_space_limit= 0; /* don't need any lock */
6470 /* we die so won't remember charset - re-update them on next thread start */
6471 rli->cached_charset_invalidate();
6472 rli->save_temporary_tables = thd->temporary_tables;
6473
6474 /*
6475 TODO: see if we can do this conditionally in next_event() instead
6476 to avoid unneeded position re-init
6477 */
6478 thd->temporary_tables = 0; // remove tempation from destructor to close them
6479 DBUG_ASSERT(thd->net.buff != 0);
6480 net_end(&thd->net); // destructor will not free it, because we are weird
6481 DBUG_ASSERT(rli->info_thd == thd);
6482 THD_CHECK_SENTRY(thd);
6483 rli->info_thd= 0;
6484 set_thd_in_use_temporary_tables(rli); // (re)set info_thd in use for saved temp tables
6485
6486 thd->release_resources();
6487 THD_CHECK_SENTRY(thd);
6488 if (thd_added)
6489 remove_global_thread(thd);
6490 delete thd;
6491 /*
6492 Note: the order of the broadcast and unlock calls below (first broadcast, then unlock)
6493 is important. Otherwise a killer_thread can execute between the calls and
6494 delete the mi structure leading to a crash! (see BUG#25306 for details)
6495 */
6496 mysql_cond_broadcast(&rli->stop_cond);
6497 DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
6498 mysql_mutex_unlock(&rli->run_lock); // tell the world we are done
6499
6500 DBUG_LEAVE; // Must match DBUG_ENTER()
6501 my_thread_end();
6502 #if OPENSSL_VERSION_NUMBER < 0x10100000L
6503 ERR_remove_thread_state(0);
6504 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
6505 pthread_exit(0);
6506 return 0; // Avoid compiler warnings
6507 }
6508
6509
6510 /*
6511 process_io_create_file()
6512 */
6513
process_io_create_file(Master_info * mi,Create_file_log_event * cev)6514 static int process_io_create_file(Master_info* mi, Create_file_log_event* cev)
6515 {
6516 int error = 1;
6517 ulong num_bytes;
6518 bool cev_not_written;
6519 THD *thd = mi->info_thd;
6520 NET *net = &mi->mysql->net;
6521 DBUG_ENTER("process_io_create_file");
6522
6523 mysql_mutex_assert_owner(&mi->data_lock);
6524
6525 if (unlikely(!cev->is_valid()))
6526 DBUG_RETURN(1);
6527
6528 if (!rpl_filter->db_ok(cev->db))
6529 {
6530 skip_load_data_infile(net);
6531 DBUG_RETURN(0);
6532 }
6533 DBUG_ASSERT(cev->inited_from_old);
6534 thd->file_id = cev->file_id = mi->file_id++;
6535 thd->server_id = cev->server_id;
6536 cev_not_written = 1;
6537
6538 if (unlikely(net_request_file(net,cev->fname)))
6539 {
6540 sql_print_error("Slave I/O: failed requesting download of '%s'",
6541 cev->fname);
6542 goto err;
6543 }
6544
6545 /*
6546 This dummy block is so we could instantiate Append_block_log_event
6547 once and then modify it slightly instead of doing it multiple times
6548 in the loop
6549 */
6550 {
6551 Append_block_log_event aev(thd,0,0,0,0);
6552
6553 for (;;)
6554 {
6555 if (unlikely((num_bytes=my_net_read(net)) == packet_error))
6556 {
6557 sql_print_error("Network read error downloading '%s' from master",
6558 cev->fname);
6559 goto err;
6560 }
6561 if (unlikely(!num_bytes)) /* eof */
6562 {
6563 /* 3.23 master wants it */
6564 net_write_command(net, 0, (uchar*) "", 0, (uchar*) "", 0);
6565 /*
6566 If we wrote Create_file_log_event, then we need to write
6567 Execute_load_log_event. If we did not write Create_file_log_event,
6568 then this is an empty file and we can just do as if the LOAD DATA
6569 INFILE had not existed, i.e. write nothing.
6570 */
6571 if (unlikely(cev_not_written))
6572 break;
6573 Execute_load_log_event xev(thd,0,0);
6574 xev.log_pos = cev->log_pos;
6575 if (unlikely(mi->rli->relay_log.append_event(&xev, mi) != 0))
6576 {
6577 mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
6578 ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
6579 "error writing Exec_load event to relay log");
6580 goto err;
6581 }
6582 mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
6583 break;
6584 }
6585 if (unlikely(cev_not_written))
6586 {
6587 cev->block = net->read_pos;
6588 cev->block_len = num_bytes;
6589 if (unlikely(mi->rli->relay_log.append_event(cev, mi) != 0))
6590 {
6591 mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
6592 ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
6593 "error writing Create_file event to relay log");
6594 goto err;
6595 }
6596 cev_not_written=0;
6597 mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
6598 }
6599 else
6600 {
6601 aev.block = net->read_pos;
6602 aev.block_len = num_bytes;
6603 aev.log_pos = cev->log_pos;
6604 if (unlikely(mi->rli->relay_log.append_event(&aev, mi) != 0))
6605 {
6606 mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE,
6607 ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE),
6608 "error writing Append_block event to relay log");
6609 goto err;
6610 }
6611 mi->rli->relay_log.harvest_bytes_written(mi->rli, true/*need_log_space_lock=true*/);
6612 }
6613 }
6614 }
6615 error=0;
6616 err:
6617 DBUG_RETURN(error);
6618 }
6619
6620
6621 /**
6622 Used by the slave IO thread when it receives a rotate event from the
6623 master.
6624
6625 Updates the master info with the place in the next binary log where
6626 we should start reading. Rotate the relay log to avoid mixed-format
6627 relay logs.
6628
6629 @param mi master_info for the slave
6630 @param rev The rotate log event read from the master
6631
6632 @note The caller must hold mi->data_lock before invoking this function.
6633
6634 @retval 0 ok
6635 @retval 1 error
6636 */
process_io_rotate(Master_info * mi,Rotate_log_event * rev)6637 static int process_io_rotate(Master_info *mi, Rotate_log_event *rev)
6638 {
6639 DBUG_ENTER("process_io_rotate");
6640 mysql_mutex_assert_owner(&mi->data_lock);
6641
6642 if (unlikely(!rev->is_valid()))
6643 DBUG_RETURN(1);
6644
6645 /* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
6646 memcpy(const_cast<char *>(mi->get_master_log_name()),
6647 rev->new_log_ident, rev->ident_len + 1);
6648 mi->set_master_log_pos(rev->pos);
6649 DBUG_PRINT("info", ("new (master_log_name, master_log_pos): ('%s', %lu)",
6650 mi->get_master_log_name(), (ulong) mi->get_master_log_pos()));
6651 #ifndef DBUG_OFF
6652 /*
6653 If we do not do this, we will be getting the first
6654 rotate event forever, so we need to not disconnect after one.
6655 */
6656 if (disconnect_slave_event_count)
6657 mi->events_until_exit++;
6658 #endif
6659
6660 /*
6661 If mi_description_event is format <4, there is conversion in the
6662 relay log to the slave's format (4). And Rotate can mean upgrade or
6663 nothing. If upgrade, it's to 5.0 or newer, so we will get a Format_desc, so
6664 no need to reset mi_description_event now. And if it's nothing (same
6665 master version as before), no need (still using the slave's format).
6666 */
6667 Format_description_log_event *old_fdle= mi->get_mi_description_event();
6668 if (old_fdle->binlog_version >= 4)
6669 {
6670 DBUG_ASSERT(old_fdle->checksum_alg ==
6671 mi->rli->relay_log.relay_log_checksum_alg);
6672 Format_description_log_event *new_fdle= new
6673 Format_description_log_event(3);
6674 new_fdle->checksum_alg= mi->rli->relay_log.relay_log_checksum_alg;
6675 mi->set_mi_description_event(new_fdle);
6676 }
6677 /*
6678 Rotate the relay log makes binlog format detection easier (at next slave
6679 start or mysqlbinlog)
6680 */
6681 int ret= rotate_relay_log(mi, true/*need_log_space_lock=true*/);
6682 DBUG_RETURN(ret);
6683 }
6684
6685 /**
6686 Reads a 3.23 event and converts it to the slave's format. This code was
6687 copied from MySQL 4.0.
6688
6689 @note The caller must hold mi->data_lock before invoking this function.
6690 */
queue_binlog_ver_1_event(Master_info * mi,const char * buf,ulong event_len)6691 static int queue_binlog_ver_1_event(Master_info *mi, const char *buf,
6692 ulong event_len)
6693 {
6694 const char *errmsg = 0;
6695 ulong inc_pos;
6696 bool ignore_event= 0;
6697 char *tmp_buf = 0;
6698 Relay_log_info *rli= mi->rli;
6699 DBUG_ENTER("queue_binlog_ver_1_event");
6700
6701 mysql_mutex_assert_owner(&mi->data_lock);
6702
6703 /*
6704 If we get Load event, we need to pass a non-reusable buffer
6705 to read_log_event, so we do a trick
6706 */
6707 if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT)
6708 {
6709 if (unlikely(!(tmp_buf=(char*)my_malloc(event_len+1,MYF(MY_WME)))))
6710 {
6711 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6712 ER(ER_SLAVE_FATAL_ERROR), "Memory allocation failed");
6713 DBUG_RETURN(1);
6714 }
6715 memcpy(tmp_buf,buf,event_len);
6716 /*
6717 Create_file constructor wants a 0 as last char of buffer, this 0 will
6718 serve as the string-termination char for the file's name (which is at the
6719 end of the buffer)
6720 We must increment event_len, otherwise the event constructor will not see
6721 this end 0, which leads to segfault.
6722 */
6723 tmp_buf[event_len++]=0;
6724 int4store(tmp_buf+EVENT_LEN_OFFSET, event_len);
6725 buf = (const char*)tmp_buf;
6726 }
6727 /*
6728 This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to
6729 send the loaded file, and write it to the relay log in the form of
6730 Append_block/Exec_load (the SQL thread needs the data, as that thread is not
6731 connected to the master).
6732 */
6733 Log_event *ev=
6734 Log_event::read_log_event(buf, event_len, &errmsg,
6735 mi->get_mi_description_event(), 0);
6736 if (unlikely(!ev))
6737 {
6738 sql_print_error("Read invalid event from master: '%s',\
6739 master could be corrupt but a more likely cause of this is a bug",
6740 errmsg);
6741 my_free((char*) tmp_buf);
6742 DBUG_RETURN(1);
6743 }
6744
6745 mi->set_master_log_pos(ev->log_pos); /* 3.23 events don't contain log_pos */
6746 switch (ev->get_type_code()) {
6747 case STOP_EVENT:
6748 ignore_event= 1;
6749 inc_pos= event_len;
6750 break;
6751 case ROTATE_EVENT:
6752 if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
6753 {
6754 delete ev;
6755 DBUG_RETURN(1);
6756 }
6757 inc_pos= 0;
6758 break;
6759 case CREATE_FILE_EVENT:
6760 /*
6761 Yes it's possible to have CREATE_FILE_EVENT here, even if we're in
6762 queue_old_event() which is for 3.23 events which don't comprise
6763 CREATE_FILE_EVENT. This is because read_log_event() above has just
6764 transformed LOAD_EVENT into CREATE_FILE_EVENT.
6765 */
6766 {
6767 /* We come here when and only when tmp_buf != 0 */
6768 DBUG_ASSERT(tmp_buf != 0);
6769 inc_pos=event_len;
6770 ev->log_pos+= inc_pos;
6771 int error = process_io_create_file(mi,(Create_file_log_event*)ev);
6772 delete ev;
6773 mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
6774 DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
6775 my_free((char*)tmp_buf);
6776 DBUG_RETURN(error);
6777 }
6778 default:
6779 inc_pos= event_len;
6780 break;
6781 }
6782 if (likely(!ignore_event))
6783 {
6784 if (ev->log_pos)
6785 /*
6786 Don't do it for fake Rotate events (see comment in
6787 Log_event::Log_event(const char* buf...) in log_event.cc).
6788 */
6789 ev->log_pos+= event_len; /* make log_pos be the pos of the end of the event */
6790 if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
6791 {
6792 delete ev;
6793 DBUG_RETURN(1);
6794 }
6795 rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
6796 }
6797 delete ev;
6798 mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
6799 DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
6800 DBUG_RETURN(0);
6801 }
6802
6803 /**
6804 Reads a 4.0 event and converts it to the slave's format. This code was copied
6805 from queue_binlog_ver_1_event(), with some affordable simplifications.
6806
6807 @note The caller must hold mi->data_lock before invoking this function.
6808 */
queue_binlog_ver_3_event(Master_info * mi,const char * buf,ulong event_len)6809 static int queue_binlog_ver_3_event(Master_info *mi, const char *buf,
6810 ulong event_len)
6811 {
6812 const char *errmsg = 0;
6813 ulong inc_pos;
6814 char *tmp_buf = 0;
6815 Relay_log_info *rli= mi->rli;
6816 DBUG_ENTER("queue_binlog_ver_3_event");
6817
6818 mysql_mutex_assert_owner(&mi->data_lock);
6819
6820 /* read_log_event() will adjust log_pos to be end_log_pos */
6821 Log_event *ev=
6822 Log_event::read_log_event(buf, event_len, &errmsg,
6823 mi->get_mi_description_event(), 0);
6824 if (unlikely(!ev))
6825 {
6826 sql_print_error("Read invalid event from master: '%s',\
6827 master could be corrupt but a more likely cause of this is a bug",
6828 errmsg);
6829 my_free((char*) tmp_buf);
6830 DBUG_RETURN(1);
6831 }
6832 switch (ev->get_type_code()) {
6833 case STOP_EVENT:
6834 goto err;
6835 case ROTATE_EVENT:
6836 if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev)))
6837 {
6838 delete ev;
6839 DBUG_RETURN(1);
6840 }
6841 inc_pos= 0;
6842 break;
6843 default:
6844 inc_pos= event_len;
6845 break;
6846 }
6847
6848 if (unlikely(rli->relay_log.append_event(ev, mi) != 0))
6849 {
6850 delete ev;
6851 DBUG_RETURN(1);
6852 }
6853 rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
6854 delete ev;
6855 mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
6856 err:
6857 DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
6858 DBUG_RETURN(0);
6859 }
6860
6861 /*
6862 queue_old_event()
6863
6864 Writes a 3.23 or 4.0 event to the relay log, after converting it to the 5.0
6865 (exactly, slave's) format. To do the conversion, we create a 5.0 event from
6866 the 3.23/4.0 bytes, then write this event to the relay log.
6867
6868 TODO:
6869 Test this code before release - it has to be tested on a separate
6870 setup with 3.23 master or 4.0 master
6871 */
6872
queue_old_event(Master_info * mi,const char * buf,ulong event_len)6873 static int queue_old_event(Master_info *mi, const char *buf,
6874 ulong event_len)
6875 {
6876 DBUG_ENTER("queue_old_event");
6877
6878 mysql_mutex_assert_owner(&mi->data_lock);
6879
6880 switch (mi->get_mi_description_event()->binlog_version)
6881 {
6882 case 1:
6883 DBUG_RETURN(queue_binlog_ver_1_event(mi,buf,event_len));
6884 case 3:
6885 DBUG_RETURN(queue_binlog_ver_3_event(mi,buf,event_len));
6886 default: /* unsupported format; eg version 2 */
6887 DBUG_PRINT("info",("unsupported binlog format %d in queue_old_event()",
6888 mi->get_mi_description_event()->binlog_version));
6889 DBUG_RETURN(1);
6890 }
6891 }
6892
6893 /*
6894 queue_event()
6895
6896 If the event is 3.23/4.0, passes it to queue_old_event() which will convert
6897 it. Otherwise, writes a 5.0 (or newer) event to the relay log. Then there is
6898 no format conversion, it's pure read/write of bytes.
6899 So a 5.0.0 slave's relay log can contain events in the slave's format or in
6900 any >=5.0.0 format.
6901 */
6902
queue_event(Master_info * mi,const char * buf,ulong event_len)6903 static int queue_event(Master_info* mi,const char* buf, ulong event_len)
6904 {
6905 int error= 0;
6906 String error_msg;
6907 ulong inc_pos= 0;
6908 Relay_log_info *rli= mi->rli;
6909 mysql_mutex_t *log_lock= rli->relay_log.get_log_lock();
6910 ulong s_id;
6911 bool unlock_data_lock= TRUE;
6912 /*
6913 FD_q must have been prepared for the first R_a event
6914 inside get_master_version_and_clock()
6915 Show-up of FD:s affects checksum_alg at once because
6916 that changes FD_queue.
6917 */
6918 uint8 checksum_alg= mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF ?
6919 mi->checksum_alg_before_fd :
6920 mi->rli->relay_log.relay_log_checksum_alg;
6921
6922 char *save_buf= NULL; // needed for checksumming the fake Rotate event
6923 char rot_buf[LOG_EVENT_HEADER_LEN + ROTATE_HEADER_LEN + FN_REFLEN];
6924 Gtid gtid= { 0, 0 };
6925 Gtid old_retrieved_gtid= { 0, 0 };
6926 Log_event_type event_type= (Log_event_type)buf[EVENT_TYPE_OFFSET];
6927
6928 DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_OFF ||
6929 checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
6930 checksum_alg == BINLOG_CHECKSUM_ALG_CRC32);
6931
6932 DBUG_ENTER("queue_event");
6933 /*
6934 FD_queue checksum alg description does not apply in a case of
6935 FD itself. The one carries both parts of the checksum data.
6936 */
6937 if (event_type == FORMAT_DESCRIPTION_EVENT)
6938 {
6939 checksum_alg= get_checksum_alg(buf, event_len);
6940 }
6941 else if (event_type == START_EVENT_V3)
6942 {
6943 // checksum behaviour is similar to the pre-checksum FD handling
6944 mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF;
6945 mysql_mutex_lock(&mi->data_lock);
6946 mi->get_mi_description_event()->checksum_alg=
6947 mi->rli->relay_log.relay_log_checksum_alg= checksum_alg=
6948 BINLOG_CHECKSUM_ALG_OFF;
6949 mysql_mutex_unlock(&mi->data_lock);
6950 }
6951
6952 // does not hold always because of old binlog can work with NM
6953 // DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
6954
6955 // should hold unless manipulations with RL. Tests that do that
6956 // will have to refine the clause.
6957 DBUG_ASSERT(mi->rli->relay_log.relay_log_checksum_alg !=
6958 BINLOG_CHECKSUM_ALG_UNDEF);
6959
6960 // Emulate the network corruption
6961 DBUG_EXECUTE_IF("corrupt_queue_event",
6962 if (event_type != FORMAT_DESCRIPTION_EVENT)
6963 {
6964 char *debug_event_buf_c = (char*) buf;
6965 int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
6966 debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
6967 DBUG_PRINT("info", ("Corrupt the event at queue_event: byte on position %d", debug_cor_pos));
6968 DBUG_SET("");
6969 }
6970 );
6971
6972 if (event_checksum_test((uchar *) buf, event_len, checksum_alg))
6973 {
6974 error= ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE;
6975 unlock_data_lock= FALSE;
6976 goto err;
6977 }
6978
6979 mysql_mutex_lock(&mi->data_lock);
6980
6981 if (mi->get_mi_description_event()->binlog_version < 4 &&
6982 event_type != FORMAT_DESCRIPTION_EVENT /* a way to escape */)
6983 {
6984 int ret= queue_old_event(mi,buf,event_len);
6985 mysql_mutex_unlock(&mi->data_lock);
6986 DBUG_RETURN(ret);
6987 }
6988
6989 switch (event_type) {
6990 case STOP_EVENT:
6991 /*
6992 We needn't write this event to the relay log. Indeed, it just indicates a
6993 master server shutdown. The only thing this does is cleaning. But
6994 cleaning is already done on a per-master-thread basis (as the master
6995 server is shutting down cleanly, it has written all DROP TEMPORARY TABLE
6996 prepared statements' deletion are TODO only when we binlog prep stmts).
6997
6998 We don't even increment mi->get_master_log_pos(), because we may be just after
6999 a Rotate event. Btw, in a few milliseconds we are going to have a Start
7000 event from the next binlog (unless the master is presently running
7001 without --log-bin).
7002 */
7003 goto err;
7004 case ROTATE_EVENT:
7005 {
7006 Rotate_log_event rev(buf, checksum_alg != BINLOG_CHECKSUM_ALG_OFF ?
7007 event_len - BINLOG_CHECKSUM_LEN : event_len,
7008 mi->get_mi_description_event());
7009
7010 if (unlikely(process_io_rotate(mi, &rev)))
7011 {
7012 error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
7013 goto err;
7014 }
7015 /*
7016 Checksum special cases for the fake Rotate (R_f) event caused by the protocol
7017 of events generation and serialization in RL where Rotate of master is
7018 queued right next to FD of slave.
7019 Since it's only FD that carries the alg desc of FD_s has to apply to R_m.
7020 Two special rules apply only to the first R_f which comes in before any FD_m.
7021 The 2nd R_f should be compatible with the FD_s that must have taken over
7022 the last seen FD_m's (A).
7023
7024 RSC_1: If OM \and fake Rotate \and slave is configured to
7025 to compute checksum for its first FD event for RL
7026 the fake Rotate gets checksummed here.
7027 */
7028 if (uint4korr(&buf[0]) == 0 && checksum_alg == BINLOG_CHECKSUM_ALG_OFF &&
7029 mi->rli->relay_log.relay_log_checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
7030 {
7031 ha_checksum rot_crc= my_checksum(0L, NULL, 0);
7032 event_len += BINLOG_CHECKSUM_LEN;
7033 memcpy(rot_buf, buf, event_len - BINLOG_CHECKSUM_LEN);
7034 int4store(&rot_buf[EVENT_LEN_OFFSET],
7035 uint4korr(rot_buf + EVENT_LEN_OFFSET) + BINLOG_CHECKSUM_LEN);
7036 rot_crc= my_checksum(rot_crc, (const uchar *) rot_buf,
7037 event_len - BINLOG_CHECKSUM_LEN);
7038 int4store(&rot_buf[event_len - BINLOG_CHECKSUM_LEN], rot_crc);
7039 DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
7040 DBUG_ASSERT(mi->get_mi_description_event()->checksum_alg ==
7041 mi->rli->relay_log.relay_log_checksum_alg);
7042 /* the first one */
7043 DBUG_ASSERT(mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF);
7044 save_buf= (char *) buf;
7045 buf= rot_buf;
7046 }
7047 else
7048 /*
7049 RSC_2: If NM \and fake Rotate \and slave does not compute checksum
7050 the fake Rotate's checksum is stripped off before relay-logging.
7051 */
7052 if (uint4korr(&buf[0]) == 0 && checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
7053 mi->rli->relay_log.relay_log_checksum_alg == BINLOG_CHECKSUM_ALG_OFF)
7054 {
7055 event_len -= BINLOG_CHECKSUM_LEN;
7056 memcpy(rot_buf, buf, event_len);
7057 int4store(&rot_buf[EVENT_LEN_OFFSET],
7058 uint4korr(rot_buf + EVENT_LEN_OFFSET) - BINLOG_CHECKSUM_LEN);
7059 DBUG_ASSERT(event_len == uint4korr(&rot_buf[EVENT_LEN_OFFSET]));
7060 DBUG_ASSERT(mi->get_mi_description_event()->checksum_alg ==
7061 mi->rli->relay_log.relay_log_checksum_alg);
7062 /* the first one */
7063 DBUG_ASSERT(mi->checksum_alg_before_fd != BINLOG_CHECKSUM_ALG_UNDEF);
7064 save_buf= (char *) buf;
7065 buf= rot_buf;
7066 }
7067 /*
7068 Now the I/O thread has just changed its mi->get_master_log_name(), so
7069 incrementing mi->get_master_log_pos() is nonsense.
7070 */
7071 inc_pos= 0;
7072 break;
7073 }
7074 case FORMAT_DESCRIPTION_EVENT:
7075 {
7076 /*
7077 Create an event, and save it (when we rotate the relay log, we will have
7078 to write this event again).
7079 */
7080 /*
7081 We are the only thread which reads/writes mi_description_event.
7082 The relay_log struct does not move (though some members of it can
7083 change), so we needn't any lock (no rli->data_lock, no log lock).
7084 */
7085 const char* errmsg;
7086 // mark it as undefined that is irrelevant anymore
7087 mi->checksum_alg_before_fd= BINLOG_CHECKSUM_ALG_UNDEF;
7088 Format_description_log_event *new_fdle=
7089 (Format_description_log_event*)
7090 Log_event::read_log_event(buf, event_len, &errmsg,
7091 mi->get_mi_description_event(), 1);
7092 if (new_fdle == NULL)
7093 {
7094 error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
7095 goto err;
7096 }
7097 if (new_fdle->checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
7098 new_fdle->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
7099 mi->set_mi_description_event(new_fdle);
7100
7101 /* installing new value of checksum Alg for relay log */
7102 mi->rli->relay_log.relay_log_checksum_alg= new_fdle->checksum_alg;
7103
7104 /*
7105 Though this does some conversion to the slave's format, this will
7106 preserve the master's binlog format version, and number of event types.
7107 */
7108 /*
7109 If the event was not requested by the slave (the slave did not ask for
7110 it), i.e. has end_log_pos=0, we do not increment mi->get_master_log_pos()
7111 */
7112 inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0;
7113 DBUG_PRINT("info",("binlog format is now %d",
7114 mi->get_mi_description_event()->binlog_version));
7115
7116 }
7117 break;
7118
7119 case HEARTBEAT_LOG_EVENT:
7120 {
7121 /*
7122 HB (heartbeat) cannot come before RL (Relay)
7123 */
7124 char llbuf[22];
7125 Heartbeat_log_event hb(buf,
7126 mi->rli->relay_log.relay_log_checksum_alg
7127 != BINLOG_CHECKSUM_ALG_OFF ?
7128 event_len - BINLOG_CHECKSUM_LEN : event_len,
7129 mi->get_mi_description_event());
7130 if (!hb.is_valid())
7131 {
7132 error= ER_SLAVE_HEARTBEAT_FAILURE;
7133 error_msg.append(STRING_WITH_LEN("inconsistent heartbeat event content;"));
7134 error_msg.append(STRING_WITH_LEN("the event's data: log_file_name "));
7135 error_msg.append(hb.get_log_ident(), (uint) strlen(hb.get_log_ident()));
7136 error_msg.append(STRING_WITH_LEN(" log_pos "));
7137 llstr(hb.log_pos, llbuf);
7138 error_msg.append(llbuf, strlen(llbuf));
7139 goto err;
7140 }
7141 mi->received_heartbeats++;
7142 mi->last_heartbeat= my_time(0);
7143
7144
7145 /*
7146 During GTID protocol, if the master skips transactions,
7147 a heartbeat event is sent to the slave at the end of last
7148 skipped transaction to update coordinates.
7149
7150 I/O thread receives the heartbeat event and updates mi
7151 only if the received heartbeat position is greater than
7152 mi->get_master_log_pos(). This event is written to the
7153 relay log as an ignored Rotate event. SQL thread reads
7154 the rotate event only to update the coordinates corresponding
7155 to the last skipped transaction. Note that,
7156 we update only the positions and not the file names, as a ROTATE
7157 EVENT from the master prior to this will update the file name.
7158 */
7159 if (mi->is_auto_position() && mi->get_master_log_pos() < hb.log_pos
7160 && mi->get_master_log_name() != NULL)
7161 {
7162
7163 DBUG_ASSERT(memcmp(const_cast<char*>(mi->get_master_log_name()),
7164 hb.get_log_ident(), hb.get_ident_len()) == 0);
7165
7166 mi->set_master_log_pos(hb.log_pos);
7167
7168 /*
7169 Put this heartbeat event in the relay log as a Rotate Event.
7170 */
7171 inc_pos= 0;
7172 memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(),
7173 FN_REFLEN);
7174 rli->ign_master_log_pos_end = mi->get_master_log_pos();
7175
7176 if (write_ignored_events_info_to_relay_log(mi->info_thd, mi))
7177 goto err;
7178 }
7179
7180 /*
7181 compare local and event's versions of log_file, log_pos.
7182
7183 Heartbeat is sent only after an event corresponding to the corrdinates
7184 the heartbeat carries.
7185 Slave can not have a difference in coordinates except in the only
7186 special case when mi->get_master_log_name(), mi->get_master_log_pos() have never
7187 been updated by Rotate event i.e when slave does not have any history
7188 with the master (and thereafter mi->get_master_log_pos() is NULL).
7189
7190 TODO: handling `when' for SHOW SLAVE STATUS' snds behind
7191 */
7192 if ((memcmp(const_cast<char *>(mi->get_master_log_name()),
7193 hb.get_log_ident(), hb.get_ident_len())
7194 && mi->get_master_log_name() != NULL)
7195 || ((mi->get_master_log_pos() != hb.log_pos && gtid_mode == 0) ||
7196 /*
7197 When Gtid mode is on only monotocity can be claimed.
7198 Todo: enhance HB event with the skipped events size
7199 and to convert HB.pos == MI.pos to HB.pos - HB.skip_size == MI.pos
7200 */
7201 (mi->get_master_log_pos() > hb.log_pos)))
7202 {
7203 /* missed events of heartbeat from the past */
7204 error= ER_SLAVE_HEARTBEAT_FAILURE;
7205 error_msg.append(STRING_WITH_LEN("heartbeat is not compatible with local info;"));
7206 error_msg.append(STRING_WITH_LEN("the event's data: log_file_name "));
7207 error_msg.append(hb.get_log_ident(), (uint) strlen(hb.get_log_ident()));
7208 error_msg.append(STRING_WITH_LEN(" log_pos "));
7209 llstr(hb.log_pos, llbuf);
7210 error_msg.append(llbuf, strlen(llbuf));
7211 goto err;
7212 }
7213 goto skip_relay_logging;
7214 }
7215 break;
7216
7217 case PREVIOUS_GTIDS_LOG_EVENT:
7218 {
7219 /*
7220 This event does not have any meaning for the slave and
7221 was just sent to show the slave the master is making
7222 progress and avoid possible deadlocks.
7223 So at this point, the event is replaced by a rotate
7224 event what will make the slave to update what it knows
7225 about the master's coordinates.
7226 */
7227 inc_pos= 0;
7228 mi->set_master_log_pos(mi->get_master_log_pos() + event_len);
7229 memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(), FN_REFLEN);
7230 rli->ign_master_log_pos_end= mi->get_master_log_pos();
7231
7232 if (write_ignored_events_info_to_relay_log(mi->info_thd, mi))
7233 goto err;
7234
7235 goto skip_relay_logging;
7236 }
7237 break;
7238
7239 case GTID_LOG_EVENT:
7240 {
7241 if (gtid_mode == 0)
7242 {
7243 error= ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF;
7244 goto err;
7245 }
7246 global_sid_lock->rdlock();
7247 Gtid_log_event gtid_ev(buf, checksum_alg != BINLOG_CHECKSUM_ALG_OFF ?
7248 event_len - BINLOG_CHECKSUM_LEN : event_len,
7249 mi->get_mi_description_event());
7250 gtid.sidno= gtid_ev.get_sidno(false);
7251 global_sid_lock->unlock();
7252 if (gtid.sidno < 0)
7253 goto err;
7254 gtid.gno= gtid_ev.get_gno();
7255 inc_pos= event_len;
7256 }
7257 break;
7258
7259 case ANONYMOUS_GTID_LOG_EVENT:
7260
7261 default:
7262 inc_pos= event_len;
7263 break;
7264 }
7265
7266 /*
7267 Simulate an unknown ignorable log event by rewriting the write_rows log
7268 event and previous_gtids log event before writing them in relay log.
7269 */
7270 DBUG_EXECUTE_IF("simulate_unknown_ignorable_log_event",
7271 if (event_type == WRITE_ROWS_EVENT ||
7272 event_type == PREVIOUS_GTIDS_LOG_EVENT)
7273 {
7274 char *event_buf= const_cast<char*>(buf);
7275 /* Overwrite the log event type with an unknown type. */
7276 event_buf[EVENT_TYPE_OFFSET]= ENUM_END_EVENT + 1;
7277 /* Set LOG_EVENT_IGNORABLE_F for the log event. */
7278 int2store(event_buf + FLAGS_OFFSET,
7279 uint2korr(event_buf + FLAGS_OFFSET) | LOG_EVENT_IGNORABLE_F);
7280 }
7281 );
7282
7283 /*
7284 If this event is originating from this server, don't queue it.
7285 We don't check this for 3.23 events because it's simpler like this; 3.23
7286 will be filtered anyway by the SQL slave thread which also tests the
7287 server id (we must also keep this test in the SQL thread, in case somebody
7288 upgrades a 4.0 slave which has a not-filtered relay log).
7289
7290 ANY event coming from ourselves can be ignored: it is obvious for queries;
7291 for STOP_EVENT/ROTATE_EVENT/START_EVENT: these cannot come from ourselves
7292 (--log-slave-updates would not log that) unless this slave is also its
7293 direct master (an unsupported, useless setup!).
7294 */
7295
7296 mysql_mutex_lock(log_lock);
7297 s_id= uint4korr(buf + SERVER_ID_OFFSET);
7298
7299 /*
7300 If server_id_bits option is set we need to mask out irrelevant bits
7301 when checking server_id, but we still put the full unmasked server_id
7302 into the Relay log so that it can be accessed when applying the event
7303 */
7304 s_id&= opt_server_id_mask;
7305
7306 if ((s_id == ::server_id && !mi->rli->replicate_same_server_id) ||
7307 /*
7308 the following conjunction deals with IGNORE_SERVER_IDS, if set
7309 If the master is on the ignore list, execution of
7310 format description log events and rotate events is necessary.
7311 */
7312 (mi->ignore_server_ids->dynamic_ids.elements > 0 &&
7313 mi->shall_ignore_server_id(s_id) &&
7314 /* everything is filtered out from non-master */
7315 (s_id != mi->master_id ||
7316 /* for the master meta information is necessary */
7317 (event_type != FORMAT_DESCRIPTION_EVENT &&
7318 event_type != ROTATE_EVENT))))
7319 {
7320 /*
7321 Do not write it to the relay log.
7322 a) We still want to increment mi->get_master_log_pos(), so that we won't
7323 re-read this event from the master if the slave IO thread is now
7324 stopped/restarted (more efficient if the events we are ignoring are big
7325 LOAD DATA INFILE).
7326 b) We want to record that we are skipping events, for the information of
7327 the slave SQL thread, otherwise that thread may let
7328 rli->group_relay_log_pos stay too small if the last binlog's event is
7329 ignored.
7330 But events which were generated by this slave and which do not exist in
7331 the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
7332 mi->get_master_log_pos().
7333 If the event is originated remotely and is being filtered out by
7334 IGNORE_SERVER_IDS it increments mi->get_master_log_pos()
7335 as well as rli->group_relay_log_pos.
7336 */
7337 if (!(s_id == ::server_id && !mi->rli->replicate_same_server_id) ||
7338 (event_type != FORMAT_DESCRIPTION_EVENT &&
7339 event_type != ROTATE_EVENT &&
7340 event_type != STOP_EVENT))
7341 {
7342 mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
7343 memcpy(rli->ign_master_log_name_end, mi->get_master_log_name(), FN_REFLEN);
7344 DBUG_ASSERT(rli->ign_master_log_name_end[0]);
7345 rli->ign_master_log_pos_end= mi->get_master_log_pos();
7346 }
7347 rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
7348 DBUG_PRINT("info", ("master_log_pos: %lu, event originating from %u server, ignored",
7349 (ulong) mi->get_master_log_pos(), uint4korr(buf + SERVER_ID_OFFSET)));
7350 }
7351 else
7352 {
7353 DBUG_EXECUTE_IF("flush_after_reading_gtid_event",
7354 if (event_type == GTID_LOG_EVENT && gtid.gno == 4)
7355 DBUG_SET("+d,set_max_size_zero");
7356 );
7357 DBUG_EXECUTE_IF("set_append_buffer_error",
7358 if (event_type == GTID_LOG_EVENT && gtid.gno == 4)
7359 DBUG_SET("+d,simulate_append_buffer_error");
7360 );
7361 /*
7362 Add the GTID to the retrieved set before actually appending it to relay
7363 log. This will ensure that if a rotation happens at this point of time the
7364 new GTID will be reflected as part of Previous_Gtid set and
7365 Retrieved_Gtid_Set will not have any gaps.
7366 */
7367 if (event_type == GTID_LOG_EVENT)
7368 {
7369 global_sid_lock->rdlock();
7370 old_retrieved_gtid= *(mi->rli->get_last_retrieved_gtid());
7371 int ret= rli->add_logged_gtid(gtid.sidno, gtid.gno);
7372 if (!ret)
7373 rli->set_last_retrieved_gtid(gtid);
7374 global_sid_lock->unlock();
7375 if (ret != 0)
7376 {
7377 mysql_mutex_unlock(log_lock);
7378 goto err;
7379 }
7380 }
7381 /* write the event to the relay log */
7382 if (!DBUG_EVALUATE_IF("simulate_append_buffer_error", 1, 0) &&
7383 likely(rli->relay_log.append_buffer(buf, event_len, mi) == 0))
7384 {
7385 mi->set_master_log_pos(mi->get_master_log_pos() + inc_pos);
7386 DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
7387 rli->relay_log.harvest_bytes_written(rli, true/*need_log_space_lock=true*/);
7388 }
7389 else
7390 {
7391 if (event_type == GTID_LOG_EVENT)
7392 {
7393 global_sid_lock->rdlock();
7394 Gtid_set * retrieved_set= (const_cast<Gtid_set *>(mi->rli->get_gtid_set()));
7395 if (retrieved_set->_remove_gtid(gtid) != RETURN_STATUS_OK)
7396 {
7397 global_sid_lock->unlock();
7398 mysql_mutex_unlock(log_lock);
7399 goto err;
7400 }
7401 if (!old_retrieved_gtid.empty())
7402 rli->set_last_retrieved_gtid(old_retrieved_gtid);
7403 global_sid_lock->unlock();
7404 }
7405 error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
7406 }
7407 rli->ign_master_log_name_end[0]= 0; // last event is not ignored
7408 if (save_buf != NULL)
7409 buf= save_buf;
7410 }
7411 mysql_mutex_unlock(log_lock);
7412
7413 skip_relay_logging:
7414
7415 err:
7416 if (unlock_data_lock)
7417 mysql_mutex_unlock(&mi->data_lock);
7418 DBUG_PRINT("info", ("error: %d", error));
7419 if (error)
7420 mi->report(ERROR_LEVEL, error, ER(error),
7421 (error == ER_SLAVE_RELAY_LOG_WRITE_FAILURE)?
7422 "could not queue event from master" :
7423 error_msg.ptr());
7424 DBUG_RETURN(error);
7425 }
7426
7427 /**
7428 Hook to detach the active VIO before closing a connection handle.
7429
7430 The client API might close the connection (and associated data)
7431 in case it encounters a unrecoverable (network) error. This hook
7432 is called from the client code before the VIO handle is deleted
7433 allows the thread to detach the active vio so it does not point
7434 to freed memory.
7435
7436 Other calls to THD::clear_active_vio throughout this module are
7437 redundant due to the hook but are left in place for illustrative
7438 purposes.
7439 */
7440
slave_io_thread_detach_vio()7441 extern "C" void slave_io_thread_detach_vio()
7442 {
7443 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
7444 THD *thd= current_thd;
7445 if (thd && thd->slave_thread)
7446 thd->clear_active_vio();
7447 #endif
7448 }
7449
7450
7451 /*
7452 Try to connect until successful or slave killed
7453
7454 SYNPOSIS
7455 safe_connect()
7456 thd Thread handler for slave
7457 mysql MySQL connection handle
7458 mi Replication handle
7459
7460 RETURN
7461 0 ok
7462 # Error
7463 */
7464
safe_connect(THD * thd,MYSQL * mysql,Master_info * mi)7465 static int safe_connect(THD* thd, MYSQL* mysql, Master_info* mi)
7466 {
7467 DBUG_ENTER("safe_connect");
7468
7469 DBUG_RETURN(connect_to_master(thd, mysql, mi, 0, 0));
7470 }
7471
7472
7473 /*
7474 SYNPOSIS
7475 connect_to_master()
7476
7477 IMPLEMENTATION
7478 Try to connect until successful or slave killed or we have retried
7479 mi->retry_count times
7480 */
7481
connect_to_master(THD * thd,MYSQL * mysql,Master_info * mi,bool reconnect,bool suppress_warnings)7482 static int connect_to_master(THD* thd, MYSQL* mysql, Master_info* mi,
7483 bool reconnect, bool suppress_warnings)
7484 {
7485 int slave_was_killed= 0;
7486 int last_errno= -2; // impossible error
7487 ulong err_count=0;
7488 char llbuff[22];
7489 char password[MAX_PASSWORD_LENGTH + 1];
7490 int password_size= sizeof(password);
7491 DBUG_ENTER("connect_to_master");
7492 set_slave_max_allowed_packet(thd, mysql);
7493 #ifndef DBUG_OFF
7494 mi->events_until_exit = disconnect_slave_event_count;
7495 #endif
7496 ulong client_flag= CLIENT_REMEMBER_OPTIONS;
7497 if (opt_slave_compressed_protocol)
7498 client_flag|= CLIENT_COMPRESS; /* We will use compression */
7499
7500 mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
7501 mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
7502
7503 if (mi->bind_addr[0])
7504 {
7505 DBUG_PRINT("info",("bind_addr: %s", mi->bind_addr));
7506 mysql_options(mysql, MYSQL_OPT_BIND, mi->bind_addr);
7507 }
7508
7509 #ifdef HAVE_OPENSSL
7510 if (mi->ssl)
7511 {
7512 mysql_ssl_set(mysql,
7513 mi->ssl_key[0]?mi->ssl_key:0,
7514 mi->ssl_cert[0]?mi->ssl_cert:0,
7515 mi->ssl_ca[0]?mi->ssl_ca:0,
7516 mi->ssl_capath[0]?mi->ssl_capath:0,
7517 mi->ssl_cipher[0]?mi->ssl_cipher:0);
7518 mysql_options(mysql, MYSQL_OPT_SSL_CRL,
7519 mi->ssl_crl[0] ? mi->ssl_crl : 0);
7520 mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH,
7521 mi->ssl_crlpath[0] ? mi->ssl_crlpath : 0);
7522 mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
7523 &mi->ssl_verify_server_cert);
7524 }
7525 #endif
7526
7527 /*
7528 If server's default charset is not supported (like utf16, utf32) as client
7529 charset, then set client charset to 'latin1' (default client charset).
7530 */
7531 if (is_supported_parser_charset(default_charset_info))
7532 mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset_info->csname);
7533 else
7534 {
7535 sql_print_information("'%s' can not be used as client character set. "
7536 "'%s' will be used as default client character set "
7537 "while connecting to master.",
7538 default_charset_info->csname,
7539 default_client_charset_info->csname);
7540 mysql_options(mysql, MYSQL_SET_CHARSET_NAME,
7541 default_client_charset_info->csname);
7542 }
7543
7544
7545 /* This one is not strictly needed but we have it here for completeness */
7546 mysql_options(mysql, MYSQL_SET_CHARSET_DIR, (char *) charsets_dir);
7547
7548 if (mi->is_start_plugin_auth_configured())
7549 {
7550 DBUG_PRINT("info", ("Slaving is using MYSQL_DEFAULT_AUTH %s",
7551 mi->get_start_plugin_auth()));
7552 mysql_options(mysql, MYSQL_DEFAULT_AUTH, mi->get_start_plugin_auth());
7553 }
7554
7555 if (mi->is_start_plugin_dir_configured())
7556 {
7557 DBUG_PRINT("info", ("Slaving is using MYSQL_PLUGIN_DIR %s",
7558 mi->get_start_plugin_dir()));
7559 mysql_options(mysql, MYSQL_PLUGIN_DIR, mi->get_start_plugin_dir());
7560 }
7561 /* Set MYSQL_PLUGIN_DIR in case master asks for an external authentication plugin */
7562 else if (opt_plugin_dir_ptr && *opt_plugin_dir_ptr)
7563 mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir_ptr);
7564
7565 if (!mi->is_start_user_configured())
7566 sql_print_warning("%s", ER(ER_INSECURE_CHANGE_MASTER));
7567
7568 if (mi->get_password(password, &password_size))
7569 {
7570 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
7571 ER(ER_SLAVE_FATAL_ERROR),
7572 "Unable to configure password when attempting to "
7573 "connect to the master server. Connection attempt "
7574 "terminated.");
7575 DBUG_RETURN(1);
7576 }
7577
7578 const char* user= mi->get_user();
7579 if (user == NULL || user[0] == 0)
7580 {
7581 mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
7582 ER(ER_SLAVE_FATAL_ERROR),
7583 "Invalid (empty) username when attempting to "
7584 "connect to the master server. Connection attempt "
7585 "terminated.");
7586 DBUG_RETURN(1);
7587 }
7588
7589 while (!(slave_was_killed = io_slave_killed(thd,mi))
7590 && (reconnect ? mysql_reconnect(mysql) != 0 :
7591 mysql_real_connect(mysql, mi->host, user,
7592 password, 0, mi->port, 0, client_flag) == 0))
7593 {
7594 /*
7595 SHOW SLAVE STATUS will display the number of retries which
7596 would be real retry counts instead of mi->retry_count for
7597 each connection attempt by 'Last_IO_Error' entry.
7598 */
7599 last_errno=mysql_errno(mysql);
7600 suppress_warnings= 0;
7601 mi->report(ERROR_LEVEL, last_errno,
7602 "error %s to master '%s@%s:%d'"
7603 " - retry-time: %d retries: %lu",
7604 (reconnect ? "reconnecting" : "connecting"),
7605 mi->get_user(), mi->host, mi->port,
7606 mi->connect_retry, err_count + 1);
7607 /*
7608 By default we try forever. The reason is that failure will trigger
7609 master election, so if the user did not set mi->retry_count we
7610 do not want to have election triggered on the first failure to
7611 connect
7612 */
7613 if (++err_count == mi->retry_count)
7614 {
7615 slave_was_killed=1;
7616 break;
7617 }
7618 slave_sleep(thd, mi->connect_retry, io_slave_killed, mi);
7619 }
7620
7621 if (!slave_was_killed)
7622 {
7623 mi->clear_error(); // clear possible left over reconnect error
7624 if (reconnect)
7625 {
7626 if (!suppress_warnings && log_warnings)
7627 sql_print_information("Slave: connected to master '%s@%s:%d',\
7628 replication resumed in log '%s' at position %s", mi->get_user(),
7629 mi->host, mi->port,
7630 mi->get_io_rpl_log_name(),
7631 llstr(mi->get_master_log_pos(),llbuff));
7632 }
7633 else
7634 {
7635 general_log_print(thd, COM_CONNECT_OUT, "%s@%s:%d",
7636 mi->get_user(), mi->host, mi->port);
7637 }
7638 #ifdef SIGNAL_WITH_VIO_SHUTDOWN
7639 thd->set_active_vio(mysql->net.vio);
7640 #endif
7641 }
7642 mysql->reconnect= 1;
7643 DBUG_PRINT("exit",("slave_was_killed: %d", slave_was_killed));
7644 DBUG_RETURN(slave_was_killed);
7645 }
7646
7647
7648 /*
7649 safe_reconnect()
7650
7651 IMPLEMENTATION
7652 Try to connect until successful or slave killed or we have retried
7653 mi->retry_count times
7654 */
7655
safe_reconnect(THD * thd,MYSQL * mysql,Master_info * mi,bool suppress_warnings)7656 static int safe_reconnect(THD* thd, MYSQL* mysql, Master_info* mi,
7657 bool suppress_warnings)
7658 {
7659 DBUG_ENTER("safe_reconnect");
7660 DBUG_RETURN(connect_to_master(thd, mysql, mi, 1, suppress_warnings));
7661 }
7662
7663
7664 /*
7665 Called when we notice that the current "hot" log got rotated under our feet.
7666 */
7667
reopen_relay_log(Relay_log_info * rli,const char ** errmsg)7668 static IO_CACHE *reopen_relay_log(Relay_log_info *rli, const char **errmsg)
7669 {
7670 DBUG_ENTER("reopen_relay_log");
7671 DBUG_ASSERT(rli->cur_log != &rli->cache_buf);
7672 DBUG_ASSERT(rli->cur_log_fd == -1);
7673
7674 IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
7675 if ((rli->cur_log_fd=open_binlog_file(cur_log,rli->get_event_relay_log_name(),
7676 errmsg)) <0)
7677 DBUG_RETURN(0);
7678 /*
7679 We want to start exactly where we was before:
7680 relay_log_pos Current log pos
7681 pending Number of bytes already processed from the event
7682 */
7683 rli->set_event_relay_log_pos(max<ulonglong>(rli->get_event_relay_log_pos(),
7684 BIN_LOG_HEADER_SIZE));
7685 my_b_seek(cur_log,rli->get_event_relay_log_pos());
7686 DBUG_RETURN(cur_log);
7687 }
7688
7689
7690 /**
7691 Reads next event from the relay log. Should be called from the
7692 slave SQL thread.
7693
7694 @param rli Relay_log_info structure for the slave SQL thread.
7695
7696 @return The event read, or NULL on error. If an error occurs, the
7697 error is reported through the sql_print_information() or
7698 sql_print_error() functions.
7699 */
next_event(Relay_log_info * rli)7700 static Log_event* next_event(Relay_log_info* rli)
7701 {
7702 Log_event* ev;
7703 IO_CACHE* cur_log = rli->cur_log;
7704 mysql_mutex_t *log_lock = rli->relay_log.get_log_lock();
7705 const char* errmsg=0;
7706 THD* thd = rli->info_thd;
7707 DBUG_ENTER("next_event");
7708
7709 DBUG_ASSERT(thd != 0);
7710
7711 #ifndef DBUG_OFF
7712 if (abort_slave_event_count && !rli->events_until_exit--)
7713 DBUG_RETURN(0);
7714 #endif
7715
7716 /*
7717 For most operations we need to protect rli members with data_lock,
7718 so we assume calling function acquired this mutex for us and we will
7719 hold it for the most of the loop below However, we will release it
7720 whenever it is worth the hassle, and in the cases when we go into a
7721 mysql_cond_wait() with the non-data_lock mutex
7722 */
7723 mysql_mutex_assert_owner(&rli->data_lock);
7724
7725 while (!sql_slave_killed(thd,rli))
7726 {
7727 /*
7728 We can have two kinds of log reading:
7729 hot_log:
7730 rli->cur_log points at the IO_CACHE of relay_log, which
7731 is actively being updated by the I/O thread. We need to be careful
7732 in this case and make sure that we are not looking at a stale log that
7733 has already been rotated. If it has been, we reopen the log.
7734
7735 The other case is much simpler:
7736 We just have a read only log that nobody else will be updating.
7737 */
7738 bool hot_log;
7739 if ((hot_log = (cur_log != &rli->cache_buf)) ||
7740 DBUG_EVALUATE_IF("force_sql_thread_error", 1, 0))
7741 {
7742 DBUG_ASSERT(rli->cur_log_fd == -1); // foreign descriptor
7743 mysql_mutex_lock(log_lock);
7744
7745 /*
7746 Reading xxx_file_id is safe because the log will only
7747 be rotated when we hold relay_log.LOCK_log
7748 */
7749 if (rli->relay_log.get_open_count() != rli->cur_log_old_open_count &&
7750 DBUG_EVALUATE_IF("force_sql_thread_error", 0, 1))
7751 {
7752 // The master has switched to a new log file; Reopen the old log file
7753 cur_log=reopen_relay_log(rli, &errmsg);
7754 mysql_mutex_unlock(log_lock);
7755 if (!cur_log) // No more log files
7756 goto err;
7757 hot_log=0; // Using old binary log
7758 }
7759 }
7760 /*
7761 As there is no guarantee that the relay is open (for example, an I/O
7762 error during a write by the slave I/O thread may have closed it), we
7763 have to test it.
7764 */
7765 if (!my_b_inited(cur_log) ||
7766 DBUG_EVALUATE_IF("force_sql_thread_error", 1, 0))
7767 {
7768 if (hot_log)
7769 mysql_mutex_unlock(log_lock);
7770 goto err;
7771 }
7772 #ifndef DBUG_OFF
7773 {
7774 DBUG_PRINT("info", ("assertion skip %lu file pos %lu event relay log pos %lu file %s\n",
7775 (ulong) rli->slave_skip_counter, (ulong) my_b_tell(cur_log),
7776 (ulong) rli->get_event_relay_log_pos(),
7777 rli->get_event_relay_log_name()));
7778
7779 /* This is an assertion which sometimes fails, let's try to track it */
7780 char llbuf1[22], llbuf2[22];
7781 DBUG_PRINT("info", ("my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s",
7782 llstr(my_b_tell(cur_log),llbuf1),
7783 llstr(rli->get_event_relay_log_pos(),llbuf2)));
7784
7785 DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE);
7786 DBUG_ASSERT(my_b_tell(cur_log) == rli->get_event_relay_log_pos() || rli->is_parallel_exec());
7787
7788 DBUG_PRINT("info", ("next_event group master %s %lu group relay %s %lu event %s %lu\n",
7789 rli->get_group_master_log_name(),
7790 (ulong) rli->get_group_master_log_pos(),
7791 rli->get_group_relay_log_name(),
7792 (ulong) rli->get_group_relay_log_pos(),
7793 rli->get_event_relay_log_name(),
7794 (ulong) rli->get_event_relay_log_pos()));
7795 }
7796 #endif
7797 /*
7798 Relay log is always in new format - if the master is 3.23, the
7799 I/O thread will convert the format for us.
7800 A problem: the description event may be in a previous relay log. So if
7801 the slave has been shutdown meanwhile, we would have to look in old relay
7802 logs, which may even have been deleted. So we need to write this
7803 description event at the beginning of the relay log.
7804 When the relay log is created when the I/O thread starts, easy: the
7805 master will send the description event and we will queue it.
7806 But if the relay log is created by new_file(): then the solution is:
7807 MYSQL_BIN_LOG::open() will write the buffered description event.
7808 */
7809 if ((ev= Log_event::read_log_event(cur_log, 0,
7810 rli->get_rli_description_event(),
7811 opt_slave_sql_verify_checksum)))
7812 {
7813 DBUG_ASSERT(thd==rli->info_thd);
7814 /*
7815 read it while we have a lock, to avoid a mutex lock in
7816 inc_event_relay_log_pos()
7817 */
7818 rli->set_future_event_relay_log_pos(my_b_tell(cur_log));
7819 ev->future_event_relay_log_pos= rli->get_future_event_relay_log_pos();
7820
7821 if (hot_log)
7822 mysql_mutex_unlock(log_lock);
7823
7824 /*
7825 MTS checkpoint in the successful read branch
7826 */
7827 bool force= (rli->checkpoint_seqno > (rli->checkpoint_group - 1));
7828 if (rli->is_parallel_exec() && (opt_mts_checkpoint_period != 0 || force))
7829 {
7830 ulonglong period= static_cast<ulonglong>(opt_mts_checkpoint_period * 1000000ULL);
7831 mysql_mutex_unlock(&rli->data_lock);
7832 /*
7833 At this point the coordinator has is delegating jobs to workers and
7834 the checkpoint routine must be periodically invoked.
7835 */
7836 (void) mts_checkpoint_routine(rli, period, force, true/*need_data_lock=true*/); // TODO: ALFRANIO ERROR
7837 DBUG_ASSERT(!force ||
7838 (force && (rli->checkpoint_seqno <= (rli->checkpoint_group - 1))) ||
7839 sql_slave_killed(thd, rli));
7840 mysql_mutex_lock(&rli->data_lock);
7841 }
7842 DBUG_RETURN(ev);
7843 }
7844 DBUG_ASSERT(thd==rli->info_thd);
7845 if (opt_reckless_slave) // For mysql-test
7846 cur_log->error = 0;
7847 if (cur_log->error < 0)
7848 {
7849 errmsg = "slave SQL thread aborted because of I/O error";
7850 if (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
7851 /*
7852 MTS group status is set to MTS_KILLED_GROUP, whenever a read event
7853 error happens and there was already a non-terminal event scheduled.
7854 */
7855 rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
7856 if (hot_log)
7857 mysql_mutex_unlock(log_lock);
7858 goto err;
7859 }
7860 if (!cur_log->error) /* EOF */
7861 {
7862 /*
7863 On a hot log, EOF means that there are no more updates to
7864 process and we must block until I/O thread adds some and
7865 signals us to continue
7866 */
7867 if (hot_log)
7868 {
7869 /*
7870 We say in Seconds_Behind_Master that we have "caught up". Note that
7871 for example if network link is broken but I/O slave thread hasn't
7872 noticed it (slave_net_timeout not elapsed), then we'll say "caught
7873 up" whereas we're not really caught up. Fixing that would require
7874 internally cutting timeout in smaller pieces in network read, no
7875 thanks. Another example: SQL has caught up on I/O, now I/O has read
7876 a new event and is queuing it; the false "0" will exist until SQL
7877 finishes executing the new event; it will be look abnormal only if
7878 the events have old timestamps (then you get "many", 0, "many").
7879
7880 Transient phases like this can be fixed with implemeting
7881 Heartbeat event which provides the slave the status of the
7882 master at time the master does not have any new update to send.
7883 Seconds_Behind_Master would be zero only when master has no
7884 more updates in binlog for slave. The heartbeat can be sent
7885 in a (small) fraction of slave_net_timeout. Until it's done
7886 rli->last_master_timestamp is temporarely (for time of
7887 waiting for the following event) reset whenever EOF is
7888 reached.
7889 */
7890
7891 /* shows zero while it is sleeping (and until the next event
7892 is about to be executed). Note, in MTS case
7893 Seconds_Behind_Master resetting follows slightly different
7894 schema where reaching EOF is not enough. The status
7895 parameter is updated per some number of processed group of
7896 events. The number can't be greater than
7897 @@global.slave_checkpoint_group and anyway SBM updating
7898 rate does not exceed @@global.slave_checkpoint_period.
7899 Notice that SBM is set to a new value after processing the
7900 terminal event (e.g Commit) of a group. Coordinator resets
7901 SBM when notices no more groups left neither to read from
7902 Relay-log nor to process by Workers.
7903 */
7904 if (!rli->is_parallel_exec())
7905 rli->last_master_timestamp= 0;
7906
7907 DBUG_ASSERT(rli->relay_log.get_open_count() ==
7908 rli->cur_log_old_open_count);
7909
7910 if (rli->ign_master_log_name_end[0])
7911 {
7912 /* We generate and return a Rotate, to make our positions advance */
7913 DBUG_PRINT("info",("seeing an ignored end segment"));
7914 ev= new Rotate_log_event(rli->ign_master_log_name_end,
7915 0, rli->ign_master_log_pos_end,
7916 Rotate_log_event::DUP_NAME);
7917 rli->ign_master_log_name_end[0]= 0;
7918 mysql_mutex_unlock(log_lock);
7919 if (unlikely(!ev))
7920 {
7921 errmsg= "Slave SQL thread failed to create a Rotate event "
7922 "(out of memory?), SHOW SLAVE STATUS may be inaccurate";
7923 goto err;
7924 }
7925 ev->server_id= 0; // don't be ignored by slave SQL thread
7926 DBUG_RETURN(ev);
7927 }
7928
7929 /*
7930 We can, and should release data_lock while we are waiting for
7931 update. If we do not, show slave status will block
7932 */
7933 mysql_mutex_unlock(&rli->data_lock);
7934
7935 /*
7936 Possible deadlock :
7937 - the I/O thread has reached log_space_limit
7938 - the SQL thread has read all relay logs, but cannot purge for some
7939 reason:
7940 * it has already purged all logs except the current one
7941 * there are other logs than the current one but they're involved in
7942 a transaction that finishes in the current one (or is not finished)
7943 Solution :
7944 Wake up the possibly waiting I/O thread, and set a boolean asking
7945 the I/O thread to temporarily ignore the log_space_limit
7946 constraint, because we do not want the I/O thread to block because of
7947 space (it's ok if it blocks for any other reason (e.g. because the
7948 master does not send anything). Then the I/O thread stops waiting
7949 and reads one more event and starts honoring log_space_limit again.
7950
7951 If the SQL thread needs more events to be able to rotate the log (it
7952 might need to finish the current group first), then it can ask for one
7953 more at a time. Thus we don't outgrow the relay log indefinitely,
7954 but rather in a controlled manner, until the next rotate.
7955
7956 When the SQL thread starts it sets ignore_log_space_limit to false.
7957 We should also reset ignore_log_space_limit to 0 when the user does
7958 RESET SLAVE, but in fact, no need as RESET SLAVE requires that the slave
7959 be stopped, and the SQL thread sets ignore_log_space_limit to 0 when
7960 it stops.
7961 */
7962 mysql_mutex_lock(&rli->log_space_lock);
7963
7964 /*
7965 If we have reached the limit of the relay space and we
7966 are going to sleep, waiting for more events:
7967
7968 1. If outside a group, SQL thread asks the IO thread
7969 to force a rotation so that the SQL thread purges
7970 logs next time it processes an event (thus space is
7971 freed).
7972
7973 2. If in a group, SQL thread asks the IO thread to
7974 ignore the limit and queues yet one more event
7975 so that the SQL thread finishes the group and
7976 is are able to rotate and purge sometime soon.
7977 */
7978 if (rli->log_space_limit &&
7979 rli->log_space_limit < rli->log_space_total)
7980 {
7981 /* force rotation if not in an unfinished group */
7982 if (!rli->is_parallel_exec())
7983 {
7984 rli->sql_force_rotate_relay= !rli->is_in_group();
7985 }
7986 else
7987 {
7988 rli->sql_force_rotate_relay=
7989 (rli->mts_group_status != Relay_log_info::MTS_IN_GROUP);
7990 }
7991 /* ask for one more event */
7992 rli->ignore_log_space_limit= true;
7993 }
7994
7995 /*
7996 If the I/O thread is blocked, unblock it. Ok to broadcast
7997 after unlock, because the mutex is only destroyed in
7998 ~Relay_log_info(), i.e. when rli is destroyed, and rli will
7999 not be destroyed before we exit the present function.
8000 */
8001 mysql_mutex_unlock(&rli->log_space_lock);
8002 mysql_cond_broadcast(&rli->log_space_cond);
8003 // Note that wait_for_update_relay_log unlocks lock_log !
8004
8005 if (rli->is_parallel_exec() && (opt_mts_checkpoint_period != 0 ||
8006 DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0)))
8007 {
8008 int ret= 0;
8009 struct timespec waittime;
8010 ulonglong period= static_cast<ulonglong>(opt_mts_checkpoint_period * 1000000ULL);
8011 ulong signal_cnt= rli->relay_log.signal_cnt;
8012
8013 mysql_mutex_unlock(log_lock);
8014 do
8015 {
8016 /*
8017 At this point the coordinator has no job to delegate to workers.
8018 However, workers are executing their assigned jobs and as such
8019 the checkpoint routine must be periodically invoked.
8020 */
8021 (void) mts_checkpoint_routine(rli, period, false, true/*need_data_lock=true*/); // TODO: ALFRANIO ERROR
8022 mysql_mutex_lock(log_lock);
8023 // More to the empty relay-log all assigned events done so reset it.
8024 if (rli->gaq->empty())
8025 rli->last_master_timestamp= 0;
8026
8027 if (DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
8028 period= 10000000ULL;
8029
8030 set_timespec_nsec(waittime, period);
8031 ret= rli->relay_log.wait_for_update_relay_log(thd, &waittime);
8032 } while ((ret == ETIMEDOUT || ret == ETIME) /* todo:remove */ &&
8033 signal_cnt == rli->relay_log.signal_cnt && !thd->killed);
8034 }
8035 else
8036 {
8037 rli->relay_log.wait_for_update_relay_log(thd, NULL);
8038 }
8039
8040 // re-acquire data lock since we released it earlier
8041 mysql_mutex_lock(&rli->data_lock);
8042 continue;
8043 }
8044 /*
8045 If the log was not hot, we need to move to the next log in
8046 sequence. The next log could be hot or cold, we deal with both
8047 cases separately after doing some common initialization
8048 */
8049 end_io_cache(cur_log);
8050 DBUG_ASSERT(rli->cur_log_fd >= 0);
8051 mysql_file_close(rli->cur_log_fd, MYF(MY_WME));
8052 rli->cur_log_fd = -1;
8053
8054 if (relay_log_purge)
8055 {
8056 /*
8057 purge_first_log will properly set up relay log coordinates in rli.
8058 If the group's coordinates are equal to the event's coordinates
8059 (i.e. the relay log was not rotated in the middle of a group),
8060 we can purge this relay log too.
8061 We do ulonglong and string comparisons, this may be slow but
8062 - purging the last relay log is nice (it can save 1GB of disk), so we
8063 like to detect the case where we can do it, and given this,
8064 - I see no better detection method
8065 - purge_first_log is not called that often
8066 */
8067 if (rli->relay_log.purge_first_log
8068 (rli,
8069 rli->get_group_relay_log_pos() == rli->get_event_relay_log_pos()
8070 && !strcmp(rli->get_group_relay_log_name(),rli->get_event_relay_log_name())))
8071 {
8072 errmsg = "Error purging processed logs";
8073 goto err;
8074 }
8075 DBUG_PRINT("info", ("next_event group master %s %lu group relay %s %lu event %s %lu\n",
8076 rli->get_group_master_log_name(),
8077 (ulong) rli->get_group_master_log_pos(),
8078 rli->get_group_relay_log_name(),
8079 (ulong) rli->get_group_relay_log_pos(),
8080 rli->get_event_relay_log_name(),
8081 (ulong) rli->get_event_relay_log_pos()));
8082 }
8083 else
8084 {
8085 /*
8086 If hot_log is set, then we already have a lock on
8087 LOCK_log. If not, we have to get the lock.
8088
8089 According to Sasha, the only time this code will ever be executed
8090 is if we are recovering from a bug.
8091 */
8092 if (rli->relay_log.find_next_log(&rli->linfo, !hot_log))
8093 {
8094 errmsg = "error switching to the next log";
8095 goto err;
8096 }
8097 rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
8098 rli->set_event_relay_log_name(rli->linfo.log_file_name);
8099 /*
8100 We may update the worker here but this is not extremlly
8101 necessary. /Alfranio
8102 */
8103 rli->flush_info();
8104 }
8105
8106 /* Reset the relay-log-change-notified status of Slave Workers */
8107 if (rli->is_parallel_exec())
8108 {
8109 DBUG_PRINT("info", ("next_event: MTS group relay log changes to %s %lu\n",
8110 rli->get_group_relay_log_name(),
8111 (ulong) rli->get_group_relay_log_pos()));
8112 rli->reset_notified_relay_log_change();
8113 }
8114
8115 /*
8116 Now we want to open this next log. To know if it's a hot log (the one
8117 being written by the I/O thread now) or a cold log, we can use
8118 is_active(); if it is hot, we use the I/O cache; if it's cold we open
8119 the file normally. But if is_active() reports that the log is hot, this
8120 may change between the test and the consequence of the test. So we may
8121 open the I/O cache whereas the log is now cold, which is nonsense.
8122 To guard against this, we need to have LOCK_log.
8123 */
8124
8125 DBUG_PRINT("info",("hot_log: %d",hot_log));
8126 if (!hot_log) /* if hot_log, we already have this mutex */
8127 mysql_mutex_lock(log_lock);
8128 if (rli->relay_log.is_active(rli->linfo.log_file_name))
8129 {
8130 #ifdef EXTRA_DEBUG
8131 if (log_warnings)
8132 sql_print_information("next log '%s' is currently active",
8133 rli->linfo.log_file_name);
8134 #endif
8135 rli->cur_log= cur_log= rli->relay_log.get_log_file();
8136 rli->cur_log_old_open_count= rli->relay_log.get_open_count();
8137 DBUG_ASSERT(rli->cur_log_fd == -1);
8138
8139 /*
8140 When the SQL thread is [stopped and] (re)started the
8141 following may happen:
8142
8143 1. Log was hot at stop time and remains hot at restart
8144
8145 SQL thread reads again from hot_log (SQL thread was
8146 reading from the active log when it was stopped and the
8147 very same log is still active on SQL thread restart).
8148
8149 In this case, my_b_seek is performed on cur_log, while
8150 cur_log points to relay_log.get_log_file();
8151
8152 2. Log was hot at stop time but got cold before restart
8153
8154 The log was hot when SQL thread stopped, but it is not
8155 anymore when the SQL thread restarts.
8156
8157 In this case, the SQL thread reopens the log, using
8158 cache_buf, ie, cur_log points to &cache_buf, and thence
8159 its coordinates are reset.
8160
8161 3. Log was already cold at stop time
8162
8163 The log was not hot when the SQL thread stopped, and, of
8164 course, it will not be hot when it restarts.
8165
8166 In this case, the SQL thread opens the cold log again,
8167 using cache_buf, ie, cur_log points to &cache_buf, and
8168 thence its coordinates are reset.
8169
8170 4. Log was hot at stop time, DBA changes to previous cold
8171 log and restarts SQL thread
8172
8173 The log was hot when the SQL thread was stopped, but the
8174 user changed the coordinates of the SQL thread to
8175 restart from a previous cold log.
8176
8177 In this case, at start time, cur_log points to a cold
8178 log, opened using &cache_buf as cache, and coordinates
8179 are reset. However, as it moves on to the next logs, it
8180 will eventually reach the hot log. If the hot log is the
8181 same at the time the SQL thread was stopped, then
8182 coordinates were not reset - the cur_log will point to
8183 relay_log.get_log_file(), and not a freshly opened
8184 IO_CACHE through cache_buf. For this reason we need to
8185 deploy a my_b_seek before calling check_binlog_magic at
8186 this point of the code (see: BUG#55263 for more
8187 details).
8188
8189 NOTES:
8190 - We must keep the LOCK_log to read the 4 first bytes, as
8191 this is a hot log (same as when we call read_log_event()
8192 above: for a hot log we take the mutex).
8193
8194 - Because of scenario #4 above, we need to have a
8195 my_b_seek here. Otherwise, we might hit the assertion
8196 inside check_binlog_magic.
8197 */
8198
8199 my_b_seek(cur_log, (my_off_t) 0);
8200 if (check_binlog_magic(cur_log,&errmsg))
8201 {
8202 if (!hot_log)
8203 mysql_mutex_unlock(log_lock);
8204 goto err;
8205 }
8206 if (!hot_log)
8207 mysql_mutex_unlock(log_lock);
8208 continue;
8209 }
8210 if (!hot_log)
8211 mysql_mutex_unlock(log_lock);
8212 /*
8213 if we get here, the log was not hot, so we will have to open it
8214 ourselves. We are sure that the log is still not hot now (a log can get
8215 from hot to cold, but not from cold to hot). No need for LOCK_log.
8216 */
8217 #ifdef EXTRA_DEBUG
8218 if (log_warnings)
8219 sql_print_information("next log '%s' is not active",
8220 rli->linfo.log_file_name);
8221 #endif
8222 // open_binlog_file() will check the magic header
8223 if ((rli->cur_log_fd=open_binlog_file(cur_log,rli->linfo.log_file_name,
8224 &errmsg)) <0)
8225 goto err;
8226 }
8227 else
8228 {
8229 /*
8230 Read failed with a non-EOF error.
8231 TODO: come up with something better to handle this error
8232 */
8233 if (hot_log)
8234 mysql_mutex_unlock(log_lock);
8235 sql_print_error("Slave SQL thread: I/O error reading \
8236 event(errno: %d cur_log->error: %d)",
8237 my_errno,cur_log->error);
8238 // set read position to the beginning of the event
8239 my_b_seek(cur_log,rli->get_event_relay_log_pos());
8240 /* otherwise, we have had a partial read */
8241 errmsg = "Aborting slave SQL thread because of partial event read";
8242 break; // To end of function
8243 }
8244 }
8245 if (!errmsg && log_warnings)
8246 {
8247 sql_print_information("Error reading relay log event: %s",
8248 "slave SQL thread was killed");
8249 DBUG_RETURN(0);
8250 }
8251
8252 err:
8253 if (errmsg)
8254 sql_print_error("Error reading relay log event: %s", errmsg);
8255 DBUG_RETURN(0);
8256 }
8257
8258 /*
8259 Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation
8260 because of size is simpler because when we do it we already have all relevant
8261 locks; here we don't, so this function is mainly taking locks).
8262 Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file()
8263 is void).
8264 */
8265
rotate_relay_log(Master_info * mi,bool need_log_space_lock)8266 int rotate_relay_log(Master_info* mi, bool need_log_space_lock)
8267 {
8268 DBUG_ENTER("rotate_relay_log");
8269
8270 mysql_mutex_assert_owner(&mi->data_lock);
8271 DBUG_EXECUTE_IF("crash_before_rotate_relaylog", DBUG_SUICIDE(););
8272
8273 Relay_log_info* rli= mi->rli;
8274 int error= 0;
8275
8276 /*
8277 We need to test inited because otherwise, new_file() will attempt to lock
8278 LOCK_log, which may not be inited (if we're not a slave).
8279 */
8280 if (!rli->inited)
8281 {
8282 DBUG_PRINT("info", ("rli->inited == 0"));
8283 goto end;
8284 }
8285
8286 /* If the relay log is closed, new_file() will do nothing. */
8287 error= rli->relay_log.new_file(mi->get_mi_description_event());
8288 if (error != 0)
8289 goto end;
8290
8291 /*
8292 We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately
8293 be counted, so imagine a succession of FLUSH LOGS and assume the slave
8294 threads are started:
8295 relay_log_space decreases by the size of the deleted relay log, but does
8296 not increase, so flush-after-flush we may become negative, which is wrong.
8297 Even if this will be corrected as soon as a query is replicated on the
8298 slave (because the I/O thread will then call harvest_bytes_written() which
8299 will harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange
8300 output in SHOW SLAVE STATUS meanwhile. So we harvest now.
8301 If the log is closed, then this will just harvest the last writes, probably
8302 0 as they probably have been harvested.
8303 */
8304 rli->relay_log.harvest_bytes_written(rli, need_log_space_lock);
8305 end:
8306 DBUG_RETURN(error);
8307 }
8308
8309
8310 /**
8311 Detects, based on master's version (as found in the relay log), if master
8312 has a certain bug.
8313 @param rli Relay_log_info which tells the master's version
8314 @param bug_id Number of the bug as found in bugs.mysql.com
8315 @param report bool report error message, default TRUE
8316
8317 @param pred Predicate function that will be called with @c param to
8318 check for the bug. If the function return @c true, the bug is present,
8319 otherwise, it is not.
8320
8321 @param param State passed to @c pred function.
8322
8323 @return TRUE if master has the bug, FALSE if it does not.
8324 */
rpl_master_has_bug(const Relay_log_info * rli,uint bug_id,bool report,bool (* pred)(const void *),const void * param)8325 bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report,
8326 bool (*pred)(const void *), const void *param)
8327 {
8328 struct st_version_range_for_one_bug {
8329 uint bug_id;
8330 const uchar introduced_in[3]; // first version with bug
8331 const uchar fixed_in[3]; // first version with fix
8332 };
8333 static struct st_version_range_for_one_bug versions_for_all_bugs[]=
8334 {
8335 {24432, { 5, 0, 24 }, { 5, 0, 38 } },
8336 {24432, { 5, 1, 12 }, { 5, 1, 17 } },
8337 {33029, { 5, 0, 0 }, { 5, 0, 58 } },
8338 {33029, { 5, 1, 0 }, { 5, 1, 12 } },
8339 {37426, { 5, 1, 0 }, { 5, 1, 26 } },
8340 };
8341 const uchar *master_ver=
8342 rli->get_rli_description_event()->server_version_split;
8343
8344 DBUG_ASSERT(sizeof(rli->get_rli_description_event()->server_version_split) == 3);
8345
8346 for (uint i= 0;
8347 i < sizeof(versions_for_all_bugs)/sizeof(*versions_for_all_bugs);i++)
8348 {
8349 const uchar *introduced_in= versions_for_all_bugs[i].introduced_in,
8350 *fixed_in= versions_for_all_bugs[i].fixed_in;
8351 if ((versions_for_all_bugs[i].bug_id == bug_id) &&
8352 (memcmp(introduced_in, master_ver, 3) <= 0) &&
8353 (memcmp(fixed_in, master_ver, 3) > 0) &&
8354 (pred == NULL || (*pred)(param)))
8355 {
8356 enum loglevel report_level= INFORMATION_LEVEL;
8357 if (!report)
8358 return TRUE;
8359 // a short message for SHOW SLAVE STATUS (message length constraints)
8360 my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from"
8361 " http://bugs.mysql.com/bug.php?id=%u"
8362 " so slave stops; check error log on slave"
8363 " for more info", MYF(0), bug_id);
8364 // a verbose message for the error log
8365 if (!ignored_error_code(ER_UNKNOWN_ERROR))
8366 {
8367 report_level= ERROR_LEVEL;
8368 current_thd->is_slave_error= 1;
8369 }
8370 /* In case of ignored errors report warnings only if log_warnings > 1. */
8371 else if (log_warnings > 1)
8372 report_level= WARNING_LEVEL;
8373
8374 if (report_level != INFORMATION_LEVEL)
8375 rli->report(report_level, ER_UNKNOWN_ERROR,
8376 "According to the master's version ('%s'),"
8377 " it is probable that master suffers from this bug:"
8378 " http://bugs.mysql.com/bug.php?id=%u"
8379 " and thus replicating the current binary log event"
8380 " may make the slave's data become different from the"
8381 " master's data."
8382 " To take no risk, slave refuses to replicate"
8383 " this event and stops."
8384 " We recommend that all updates be stopped on the"
8385 " master and slave, that the data of both be"
8386 " manually synchronized,"
8387 " that master's binary logs be deleted,"
8388 " that master be upgraded to a version at least"
8389 " equal to '%d.%d.%d'. Then replication can be"
8390 " restarted.",
8391 rli->get_rli_description_event()->server_version,
8392 bug_id,
8393 fixed_in[0], fixed_in[1], fixed_in[2]);
8394 return TRUE;
8395 }
8396 }
8397 return FALSE;
8398 }
8399
8400 /**
8401 BUG#33029, For all 5.0 up to 5.0.58 exclusive, and 5.1 up to 5.1.12
8402 exclusive, if one statement in a SP generated AUTO_INCREMENT value
8403 by the top statement, all statements after it would be considered
8404 generated AUTO_INCREMENT value by the top statement, and a
8405 erroneous INSERT_ID value might be associated with these statement,
8406 which could cause duplicate entry error and stop the slave.
8407
8408 Detect buggy master to work around.
8409 */
rpl_master_erroneous_autoinc(THD * thd)8410 bool rpl_master_erroneous_autoinc(THD *thd)
8411 {
8412 if (active_mi != NULL && active_mi->rli->info_thd == thd)
8413 {
8414 Relay_log_info *rli= active_mi->rli;
8415 DBUG_EXECUTE_IF("simulate_bug33029", return TRUE;);
8416 return rpl_master_has_bug(rli, 33029, FALSE, NULL, NULL);
8417 }
8418 return FALSE;
8419 }
8420
8421 /**
8422 a copy of active_mi->rli->slave_skip_counter, for showing in SHOW VARIABLES,
8423 INFORMATION_SCHEMA.GLOBAL_VARIABLES and @@sql_slave_skip_counter without
8424 taking all the mutexes needed to access active_mi->rli->slave_skip_counter
8425 properly.
8426 */
8427 uint sql_slave_skip_counter;
8428
8429 /**
8430 Execute a START SLAVE statement.
8431
8432 @param thd Pointer to THD object for the client thread executing the
8433 statement.
8434
8435 @param mi Pointer to Master_info object for the slave's IO thread.
8436
8437 @param net_report If true, saves the exit status into Diagnostics_area.
8438
8439 @retval 0 success
8440 @retval 1 error
8441 */
start_slave(THD * thd,Master_info * mi,bool net_report)8442 int start_slave(THD* thd , Master_info* mi, bool net_report)
8443 {
8444 int slave_errno= 0;
8445 int thread_mask;
8446 DBUG_ENTER("start_slave");
8447
8448 if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0))
8449 DBUG_RETURN(1);
8450
8451 if (thd->lex->slave_connection.user ||
8452 thd->lex->slave_connection.password)
8453 {
8454 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8455 if (thd->vio_ok() && !thd->net.vio->ssl_arg)
8456 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8457 ER_INSECURE_PLAIN_TEXT,
8458 ER(ER_INSECURE_PLAIN_TEXT));
8459 #endif
8460 #if !defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8461 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8462 ER_INSECURE_PLAIN_TEXT,
8463 ER(ER_INSECURE_PLAIN_TEXT));
8464 #endif
8465 }
8466
8467 lock_slave_threads(mi); // this allows us to cleanly read slave_running
8468 // Get a mask of _stopped_ threads
8469 init_thread_mask(&thread_mask,mi,1 /* inverse */);
8470 /*
8471 Below we will start all stopped threads. But if the user wants to
8472 start only one thread, do as if the other thread was running (as we
8473 don't wan't to touch the other thread), so set the bit to 0 for the
8474 other thread
8475 */
8476 if (thd->lex->slave_thd_opt)
8477 thread_mask&= thd->lex->slave_thd_opt;
8478 if (thread_mask) //some threads are stopped, start them
8479 {
8480 if (global_init_info(mi, false, thread_mask))
8481 slave_errno=ER_MASTER_INFO;
8482 else if (server_id_supplied && *mi->host)
8483 {
8484 /*
8485 If we will start IO thread we need to take care of possible
8486 options provided through the START SLAVE if there is any.
8487 */
8488 if (thread_mask & SLAVE_IO)
8489 {
8490 if (thd->lex->slave_connection.user)
8491 {
8492 mi->set_start_user_configured(true);
8493 mi->set_user(thd->lex->slave_connection.user);
8494 }
8495 if (thd->lex->slave_connection.password)
8496 {
8497 mi->set_start_user_configured(true);
8498 mi->set_password(thd->lex->slave_connection.password,
8499 strlen(thd->lex->slave_connection.password));
8500 }
8501 if (thd->lex->slave_connection.plugin_auth)
8502 mi->set_plugin_auth(thd->lex->slave_connection.plugin_auth);
8503 if (thd->lex->slave_connection.plugin_dir)
8504 mi->set_plugin_dir(thd->lex->slave_connection.plugin_dir);
8505 }
8506
8507 /*
8508 If we will start SQL thread we will care about UNTIL options If
8509 not and they are specified we will ignore them and warn user
8510 about this fact.
8511 */
8512 if (thread_mask & SLAVE_SQL)
8513 {
8514 /*
8515 To cache the MTS system var values and used them in the following
8516 runtime. The system var:s can change meanwhile but having no other
8517 effects.
8518 */
8519 mi->rli->opt_slave_parallel_workers= opt_mts_slave_parallel_workers;
8520 #ifndef DBUG_OFF
8521 if (!DBUG_EVALUATE_IF("check_slave_debug_group", 1, 0))
8522 #endif
8523 mi->rli->checkpoint_group= opt_mts_checkpoint_group;
8524
8525 mysql_mutex_lock(&mi->rli->data_lock);
8526
8527 if (thd->lex->mi.pos)
8528 {
8529 if (thd->lex->mi.relay_log_pos)
8530 slave_errno= ER_BAD_SLAVE_UNTIL_COND;
8531 mi->rli->until_condition= Relay_log_info::UNTIL_MASTER_POS;
8532 mi->rli->until_log_pos= thd->lex->mi.pos;
8533 /*
8534 We don't check thd->lex->mi.log_file_name for NULL here
8535 since it is checked in sql_yacc.yy
8536 */
8537 strmake(mi->rli->until_log_name, thd->lex->mi.log_file_name,
8538 sizeof(mi->rli->until_log_name)-1);
8539 }
8540 else if (thd->lex->mi.relay_log_pos)
8541 {
8542 if (thd->lex->mi.pos)
8543 slave_errno= ER_BAD_SLAVE_UNTIL_COND;
8544 mi->rli->until_condition= Relay_log_info::UNTIL_RELAY_POS;
8545 mi->rli->until_log_pos= thd->lex->mi.relay_log_pos;
8546 strmake(mi->rli->until_log_name, thd->lex->mi.relay_log_name,
8547 sizeof(mi->rli->until_log_name)-1);
8548 }
8549 else if (thd->lex->mi.gtid)
8550 {
8551 global_sid_lock->wrlock();
8552 mi->rli->clear_until_condition();
8553 if (mi->rli->until_sql_gtids.add_gtid_text(thd->lex->mi.gtid)
8554 != RETURN_STATUS_OK)
8555 slave_errno= ER_BAD_SLAVE_UNTIL_COND;
8556 else {
8557 mi->rli->until_condition=
8558 LEX_MASTER_INFO::UNTIL_SQL_BEFORE_GTIDS == thd->lex->mi.gtid_until_condition
8559 ? Relay_log_info::UNTIL_SQL_BEFORE_GTIDS
8560 : Relay_log_info::UNTIL_SQL_AFTER_GTIDS;
8561 if ((mi->rli->until_condition ==
8562 Relay_log_info::UNTIL_SQL_AFTER_GTIDS) &&
8563 mi->rli->opt_slave_parallel_workers != 0)
8564 {
8565 mi->rli->opt_slave_parallel_workers= 0;
8566 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
8567 ER_MTS_FEATURE_IS_NOT_SUPPORTED,
8568 ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED),
8569 "UNTIL condtion",
8570 "Slave is started in the sequential execution mode.");
8571 }
8572 }
8573 global_sid_lock->unlock();
8574 }
8575 else if (thd->lex->mi.until_after_gaps)
8576 {
8577 mi->rli->until_condition= Relay_log_info::UNTIL_SQL_AFTER_MTS_GAPS;
8578 mi->rli->opt_slave_parallel_workers=
8579 mi->rli->recovery_parallel_workers;
8580 }
8581 else
8582 mi->rli->clear_until_condition();
8583
8584 if (mi->rli->until_condition == Relay_log_info::UNTIL_MASTER_POS ||
8585 mi->rli->until_condition == Relay_log_info::UNTIL_RELAY_POS)
8586 {
8587 /* Preparing members for effective until condition checking */
8588 const char *p= fn_ext(mi->rli->until_log_name);
8589 char *p_end;
8590 if (*p)
8591 {
8592 //p points to '.'
8593 mi->rli->until_log_name_extension= strtoul(++p,&p_end, 10);
8594 /*
8595 p_end points to the first invalid character. If it equals
8596 to p, no digits were found, error. If it contains '\0' it
8597 means conversion went ok.
8598 */
8599 if (p_end==p || *p_end)
8600 slave_errno=ER_BAD_SLAVE_UNTIL_COND;
8601 }
8602 else
8603 slave_errno=ER_BAD_SLAVE_UNTIL_COND;
8604
8605 /* mark the cached result of the UNTIL comparison as "undefined" */
8606 mi->rli->until_log_names_cmp_result=
8607 Relay_log_info::UNTIL_LOG_NAMES_CMP_UNKNOWN;
8608
8609 /* Issuing warning then started without --skip-slave-start */
8610 if (!opt_skip_slave_start)
8611 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8612 ER_MISSING_SKIP_SLAVE,
8613 ER(ER_MISSING_SKIP_SLAVE));
8614 if (mi->rli->opt_slave_parallel_workers != 0)
8615 {
8616 mi->rli->opt_slave_parallel_workers= 0;
8617 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
8618 ER_MTS_FEATURE_IS_NOT_SUPPORTED,
8619 ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED),
8620 "UNTIL condtion",
8621 "Slave is started in the sequential execution mode.");
8622 }
8623 }
8624
8625 mysql_mutex_unlock(&mi->rli->data_lock);
8626
8627 /* MTS technical limitation no support of trans retry */
8628 if (mi->rli->opt_slave_parallel_workers != 0 && slave_trans_retries != 0)
8629 {
8630 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
8631 ER_MTS_FEATURE_IS_NOT_SUPPORTED,
8632 ER(ER_MTS_FEATURE_IS_NOT_SUPPORTED),
8633 "slave_transaction_retries",
8634 "In the event of a transient failure, the slave will "
8635 "not retry the transaction and will stop.");
8636 }
8637 }
8638 else if (thd->lex->mi.pos || thd->lex->mi.relay_log_pos || thd->lex->mi.gtid)
8639 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_UNTIL_COND_IGNORED,
8640 ER(ER_UNTIL_COND_IGNORED));
8641
8642 if (!slave_errno)
8643 slave_errno = start_slave_threads(false/*need_lock_slave=false*/,
8644 true/*wait_for_start=true*/,
8645 mi,
8646 thread_mask);
8647 }
8648 else
8649 slave_errno = ER_BAD_SLAVE;
8650 }
8651 else
8652 {
8653 /* no error if all threads are already started, only a warning */
8654 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_RUNNING,
8655 ER(ER_SLAVE_WAS_RUNNING));
8656 }
8657
8658 /*
8659 Clean up start information if there was an attempt to start
8660 the IO thread to avoid any security issue.
8661 */
8662 if (slave_errno &&
8663 (thread_mask & SLAVE_IO) == SLAVE_IO)
8664 mi->reset_start_info();
8665
8666 unlock_slave_threads(mi);
8667
8668 if (slave_errno)
8669 {
8670 if (net_report)
8671 my_message(slave_errno, ER(slave_errno), MYF(0));
8672 DBUG_RETURN(1);
8673 }
8674 else if (net_report)
8675 my_ok(thd);
8676
8677 DBUG_RETURN(0);
8678 }
8679
8680
8681 /**
8682 Execute a STOP SLAVE statement.
8683
8684 @param thd Pointer to THD object for the client thread executing the
8685 statement.
8686
8687 @param mi Pointer to Master_info object for the slave's IO thread.
8688
8689 @param net_report If true, saves the exit status into Diagnostics_area.
8690
8691 @retval 0 success
8692 @retval 1 error
8693 */
stop_slave(THD * thd,Master_info * mi,bool net_report)8694 int stop_slave(THD* thd, Master_info* mi, bool net_report )
8695 {
8696 DBUG_ENTER("stop_slave");
8697
8698 int slave_errno;
8699 if (!thd)
8700 thd = current_thd;
8701
8702 if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0))
8703 DBUG_RETURN(1);
8704 THD_STAGE_INFO(thd, stage_killing_slave);
8705 int thread_mask;
8706 lock_slave_threads(mi);
8707 // Get a mask of _running_ threads
8708 init_thread_mask(&thread_mask,mi,0 /* not inverse*/);
8709 /*
8710 Below we will stop all running threads.
8711 But if the user wants to stop only one thread, do as if the other thread
8712 was stopped (as we don't wan't to touch the other thread), so set the
8713 bit to 0 for the other thread
8714 */
8715 if (thd->lex->slave_thd_opt)
8716 thread_mask &= thd->lex->slave_thd_opt;
8717
8718 if (thread_mask)
8719 {
8720 slave_errno= terminate_slave_threads(mi,thread_mask,
8721 false/*need_lock_term=false*/);
8722 }
8723 else
8724 {
8725 //no error if both threads are already stopped, only a warning
8726 slave_errno= 0;
8727 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_SLAVE_WAS_NOT_RUNNING,
8728 ER(ER_SLAVE_WAS_NOT_RUNNING));
8729 }
8730 unlock_slave_threads(mi);
8731
8732 if (slave_errno)
8733 {
8734 if ((slave_errno == ER_STOP_SLAVE_SQL_THREAD_TIMEOUT) ||
8735 (slave_errno == ER_STOP_SLAVE_IO_THREAD_TIMEOUT))
8736 {
8737 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, slave_errno,
8738 ER(slave_errno));
8739 sql_print_warning("%s",ER(slave_errno));
8740 }
8741 if (net_report)
8742 my_message(slave_errno, ER(slave_errno), MYF(0));
8743 DBUG_RETURN(1);
8744 }
8745 else if (net_report)
8746 my_ok(thd);
8747
8748 DBUG_RETURN(0);
8749 }
8750
8751
8752 /**
8753 Execute a RESET SLAVE statement.
8754
8755 @param thd Pointer to THD object of the client thread executing the
8756 statement.
8757
8758 @param mi Pointer to Master_info object for the slave.
8759
8760 @retval 0 success
8761 @retval 1 error
8762 */
reset_slave(THD * thd,Master_info * mi)8763 int reset_slave(THD *thd, Master_info* mi)
8764 {
8765 int thread_mask= 0, error= 0;
8766 uint sql_errno=ER_UNKNOWN_ERROR;
8767 const char* errmsg= "Unknown error occured while reseting slave";
8768 DBUG_ENTER("reset_slave");
8769
8770 lock_slave_threads(mi);
8771 init_thread_mask(&thread_mask,mi,0 /* not inverse */);
8772 if (thread_mask) // We refuse if any slave thread is running
8773 {
8774 sql_errno= ER_SLAVE_MUST_STOP;
8775 error=1;
8776 goto err;
8777 }
8778
8779 ha_reset_slave(thd);
8780
8781 // delete relay logs, clear relay log coordinates
8782 if ((error= mi->rli->purge_relay_logs(thd,
8783 1 /* just reset */,
8784 &errmsg)))
8785 {
8786 sql_errno= ER_RELAY_LOG_FAIL;
8787 goto err;
8788 }
8789
8790 /* Clear master's log coordinates and associated information */
8791 DBUG_ASSERT(!mi->rli || !mi->rli->slave_running); // none writes in rli table
8792 mi->clear_in_memory_info(thd->lex->reset_slave_info.all);
8793
8794 if (remove_info(mi))
8795 {
8796 error= 1;
8797 goto err;
8798 }
8799
8800 (void) RUN_HOOK(binlog_relay_io, after_reset_slave, (thd, mi));
8801 err:
8802 unlock_slave_threads(mi);
8803 if (error)
8804 my_error(sql_errno, MYF(0), errmsg);
8805 DBUG_RETURN(error);
8806 }
8807
8808 /**
8809 Execute a CHANGE MASTER statement. MTS workers info tables data are removed
8810 in the successful branch (i.e. there are no gaps in the execution history).
8811
8812 @param thd Pointer to THD object for the client thread executing the
8813 statement.
8814
8815 @param mi Pointer to Master_info object belonging to the slave's IO
8816 thread.
8817
8818 @retval FALSE success
8819 @retval TRUE error
8820 */
change_master(THD * thd,Master_info * mi)8821 bool change_master(THD* thd, Master_info* mi)
8822 {
8823 int thread_mask;
8824 const char* errmsg= 0;
8825 bool need_relay_log_purge= 1;
8826 char *var_master_log_name= NULL, *var_group_master_log_name= NULL;
8827 bool ret= false;
8828 char saved_host[HOSTNAME_LENGTH + 1], saved_bind_addr[HOSTNAME_LENGTH + 1];
8829 uint saved_port= 0;
8830 char saved_log_name[FN_REFLEN];
8831 my_off_t saved_log_pos= 0;
8832 my_bool save_relay_log_purge= relay_log_purge;
8833 bool mts_remove_workers= false;
8834
8835 DBUG_ENTER("change_master");
8836
8837 lock_slave_threads(mi);
8838 init_thread_mask(&thread_mask,mi,0 /*not inverse*/);
8839 LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
8840 if (thread_mask) // We refuse if any slave thread is running
8841 {
8842 my_message(ER_SLAVE_MUST_STOP, ER(ER_SLAVE_MUST_STOP), MYF(0));
8843 ret= true;
8844 goto err;
8845 }
8846 thread_mask= SLAVE_IO | SLAVE_SQL;
8847
8848 THD_STAGE_INFO(thd, stage_changing_master);
8849 /*
8850 We need to check if there is an empty master_host. Otherwise
8851 change master succeeds, a master.info file is created containing
8852 empty master_host string and when issuing: start slave; an error
8853 is thrown stating that the server is not configured as slave.
8854 (See BUG#28796).
8855 */
8856 if(lex_mi->host && !*lex_mi->host)
8857 {
8858 my_error(ER_WRONG_ARGUMENTS, MYF(0), "MASTER_HOST");
8859 unlock_slave_threads(mi);
8860 DBUG_RETURN(TRUE);
8861 }
8862 if (global_init_info(mi, false, thread_mask))
8863 {
8864 my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
8865 ret= true;
8866 goto err;
8867 }
8868 if (mi->rli->mts_recovery_group_cnt)
8869 {
8870 /*
8871 Change-Master can't be done if there is a mts group gap.
8872 That requires mts-recovery which START SLAVE provides.
8873 */
8874 DBUG_ASSERT(mi->rli->recovery_parallel_workers);
8875
8876 my_message(ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS,
8877 ER(ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS), MYF(0));
8878 ret= true;
8879 goto err;
8880 }
8881 else
8882 {
8883 /*
8884 Lack of mts group gaps makes Workers info stale
8885 regardless of need_relay_log_purge computation.
8886 */
8887 if (mi->rli->recovery_parallel_workers)
8888 mts_remove_workers= true;
8889 }
8890 /*
8891 We cannot specify auto position and set either the coordinates
8892 on master or slave. If we try to do so, an error message is
8893 printed out.
8894 */
8895 if (lex_mi->log_file_name != NULL || lex_mi->pos != 0 ||
8896 lex_mi->relay_log_name != NULL || lex_mi->relay_log_pos != 0)
8897 {
8898 if (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE ||
8899 (lex_mi->auto_position != LEX_MASTER_INFO::LEX_MI_DISABLE &&
8900 mi->is_auto_position()))
8901 {
8902 my_message(ER_BAD_SLAVE_AUTO_POSITION,
8903 ER(ER_BAD_SLAVE_AUTO_POSITION), MYF(0));
8904 ret= true;
8905 goto err;
8906 }
8907 }
8908
8909 // CHANGE MASTER TO MASTER_AUTO_POSITION = 1 requires GTID_MODE = ON
8910 if (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE && gtid_mode != 3)
8911 {
8912 my_message(ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON,
8913 ER(ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON), MYF(0));
8914 ret= true;
8915 goto err;
8916 }
8917
8918 /*
8919 Data lock not needed since we have already stopped the running threads,
8920 and we have the hold on the run locks which will keep all threads that
8921 could possibly modify the data structures from running
8922 */
8923
8924 /*
8925 Before processing the command, save the previous state.
8926 */
8927 strmake(saved_host, mi->host, HOSTNAME_LENGTH);
8928 strmake(saved_bind_addr, mi->bind_addr, HOSTNAME_LENGTH);
8929 saved_port= mi->port;
8930 strmake(saved_log_name, mi->get_master_log_name(), FN_REFLEN - 1);
8931 saved_log_pos= mi->get_master_log_pos();
8932
8933 /*
8934 If the user specified host or port without binlog or position,
8935 reset binlog's name to FIRST and position to 4.
8936 */
8937
8938 if ((lex_mi->host && strcmp(lex_mi->host, mi->host)) ||
8939 (lex_mi->port && lex_mi->port != mi->port))
8940 {
8941 /*
8942 This is necessary because the primary key, i.e. host or port, has
8943 changed.
8944
8945 The repository does not support direct changes on the primary key,
8946 so the row is dropped and re-inserted with a new primary key. If we
8947 don't do that, the master info repository we will end up with several
8948 rows.
8949 */
8950 if (mi->clean_info())
8951 {
8952 ret= true;
8953 goto err;
8954 }
8955 mi->master_uuid[0]= 0;
8956 mi->master_id= 0;
8957 }
8958
8959 if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
8960 {
8961 var_master_log_name= const_cast<char*>(mi->get_master_log_name());
8962 var_master_log_name[0]= '\0';
8963 mi->set_master_log_pos(BIN_LOG_HEADER_SIZE);
8964 }
8965
8966 if (lex_mi->log_file_name)
8967 mi->set_master_log_name(lex_mi->log_file_name);
8968 if (lex_mi->pos)
8969 {
8970 mi->set_master_log_pos(lex_mi->pos);
8971 }
8972 DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
8973
8974 if (lex_mi->user || lex_mi->password)
8975 {
8976 #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8977 if (thd->vio_ok() && !thd->net.vio->ssl_arg)
8978 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8979 ER_INSECURE_PLAIN_TEXT,
8980 ER(ER_INSECURE_PLAIN_TEXT));
8981 #endif
8982 #if !defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
8983 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8984 ER_INSECURE_PLAIN_TEXT,
8985 ER(ER_INSECURE_PLAIN_TEXT));
8986 #endif
8987 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
8988 ER_INSECURE_CHANGE_MASTER,
8989 ER(ER_INSECURE_CHANGE_MASTER));
8990 }
8991
8992 if (lex_mi->user)
8993 mi->set_user(lex_mi->user);
8994
8995 if (lex_mi->password)
8996 {
8997 if (mi->set_password(lex_mi->password, strlen(lex_mi->password)))
8998 {
8999 /*
9000 After implementing WL#5769, we should create a better error message
9001 to denote that the call may have failed due to an error while trying
9002 to encrypt/store the password in a secure key store.
9003 */
9004 my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
9005 ret= false;
9006 goto err;
9007 }
9008 }
9009 if (lex_mi->host)
9010 strmake(mi->host, lex_mi->host, sizeof(mi->host)-1);
9011 if (lex_mi->bind_addr)
9012 strmake(mi->bind_addr, lex_mi->bind_addr, sizeof(mi->bind_addr)-1);
9013 if (lex_mi->port)
9014 mi->port = lex_mi->port;
9015 if (lex_mi->connect_retry)
9016 mi->connect_retry = lex_mi->connect_retry;
9017 if (lex_mi->retry_count_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9018 mi->retry_count = lex_mi->retry_count;
9019 if (lex_mi->heartbeat_opt != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9020 mi->heartbeat_period = lex_mi->heartbeat_period;
9021 else
9022 mi->heartbeat_period= min<float>(SLAVE_MAX_HEARTBEAT_PERIOD,
9023 (slave_net_timeout/2.0));
9024 mi->received_heartbeats= LL(0); // counter lives until master is CHANGEd
9025 /*
9026 reset the last time server_id list if the current CHANGE MASTER
9027 is mentioning IGNORE_SERVER_IDS= (...)
9028 */
9029 if (lex_mi->repl_ignore_server_ids_opt == LEX_MASTER_INFO::LEX_MI_ENABLE)
9030 reset_dynamic(&(mi->ignore_server_ids->dynamic_ids));
9031 for (uint i= 0; i < lex_mi->repl_ignore_server_ids.elements; i++)
9032 {
9033 ulong s_id;
9034 get_dynamic(&lex_mi->repl_ignore_server_ids, (uchar*) &s_id, i);
9035 if (s_id == ::server_id && replicate_same_server_id)
9036 {
9037 my_error(ER_SLAVE_IGNORE_SERVER_IDS, MYF(0), static_cast<int>(s_id));
9038 ret= TRUE;
9039 goto err;
9040 }
9041 else
9042 {
9043 if (bsearch((const ulong *) &s_id,
9044 mi->ignore_server_ids->dynamic_ids.buffer,
9045 mi->ignore_server_ids->dynamic_ids.elements, sizeof(ulong),
9046 (int (*) (const void*, const void*))
9047 change_master_server_id_cmp) == NULL)
9048 insert_dynamic(&(mi->ignore_server_ids->dynamic_ids), (uchar*) &s_id);
9049 }
9050 }
9051 sort_dynamic(&(mi->ignore_server_ids->dynamic_ids), (qsort_cmp) change_master_server_id_cmp);
9052
9053 if (lex_mi->ssl != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9054 mi->ssl= (lex_mi->ssl == LEX_MASTER_INFO::LEX_MI_ENABLE);
9055
9056 if (lex_mi->sql_delay != -1)
9057 mi->rli->set_sql_delay(lex_mi->sql_delay);
9058
9059 if (lex_mi->ssl_verify_server_cert != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9060 mi->ssl_verify_server_cert=
9061 (lex_mi->ssl_verify_server_cert == LEX_MASTER_INFO::LEX_MI_ENABLE);
9062
9063 if (lex_mi->ssl_ca)
9064 strmake(mi->ssl_ca, lex_mi->ssl_ca, sizeof(mi->ssl_ca)-1);
9065 if (lex_mi->ssl_capath)
9066 strmake(mi->ssl_capath, lex_mi->ssl_capath, sizeof(mi->ssl_capath)-1);
9067 if (lex_mi->ssl_cert)
9068 strmake(mi->ssl_cert, lex_mi->ssl_cert, sizeof(mi->ssl_cert)-1);
9069 if (lex_mi->ssl_cipher)
9070 strmake(mi->ssl_cipher, lex_mi->ssl_cipher, sizeof(mi->ssl_cipher)-1);
9071 if (lex_mi->ssl_key)
9072 strmake(mi->ssl_key, lex_mi->ssl_key, sizeof(mi->ssl_key)-1);
9073 if (lex_mi->ssl_crl)
9074 strmake(mi->ssl_crl, lex_mi->ssl_crl, sizeof(mi->ssl_crl)-1);
9075 if (lex_mi->ssl_crlpath)
9076 strmake(mi->ssl_crlpath, lex_mi->ssl_crlpath, sizeof(mi->ssl_crlpath)-1);
9077 #ifndef HAVE_OPENSSL
9078 if (lex_mi->ssl || lex_mi->ssl_ca || lex_mi->ssl_capath ||
9079 lex_mi->ssl_cert || lex_mi->ssl_cipher || lex_mi->ssl_key ||
9080 lex_mi->ssl_verify_server_cert || lex_mi->ssl_crl || lex_mi->ssl_crlpath)
9081 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
9082 ER_SLAVE_IGNORED_SSL_PARAMS, ER(ER_SLAVE_IGNORED_SSL_PARAMS));
9083 #endif
9084
9085 if (lex_mi->relay_log_name)
9086 {
9087 need_relay_log_purge= 0;
9088 char relay_log_name[FN_REFLEN];
9089
9090 mi->rli->relay_log.make_log_name(relay_log_name, lex_mi->relay_log_name);
9091 mi->rli->set_group_relay_log_name(relay_log_name);
9092 mi->rli->set_event_relay_log_name(relay_log_name);
9093 }
9094
9095 if (lex_mi->relay_log_pos)
9096 {
9097 need_relay_log_purge= 0;
9098 mi->rli->set_group_relay_log_pos(lex_mi->relay_log_pos);
9099 mi->rli->set_event_relay_log_pos(lex_mi->relay_log_pos);
9100 }
9101
9102 /*
9103 If user did specify neither host nor port nor any log name nor any log
9104 pos, i.e. he specified only user/password/master_connect_retry, he probably
9105 wants replication to resume from where it had left, i.e. from the
9106 coordinates of the **SQL** thread (imagine the case where the I/O is ahead
9107 of the SQL; restarting from the coordinates of the I/O would lose some
9108 events which is probably unwanted when you are just doing minor changes
9109 like changing master_connect_retry).
9110 A side-effect is that if only the I/O thread was started, this thread may
9111 restart from ''/4 after the CHANGE MASTER. That's a minor problem (it is a
9112 much more unlikely situation than the one we are fixing here).
9113 Note: coordinates of the SQL thread must be read here, before the
9114 'if (need_relay_log_purge)' block which resets them.
9115 */
9116 if (!lex_mi->host && !lex_mi->port &&
9117 !lex_mi->log_file_name && !lex_mi->pos &&
9118 need_relay_log_purge)
9119 {
9120 /*
9121 Sometimes mi->rli->master_log_pos == 0 (it happens when the SQL thread is
9122 not initialized), so we use a max().
9123 What happens to mi->rli->master_log_pos during the initialization stages
9124 of replication is not 100% clear, so we guard against problems using
9125 max().
9126 */
9127 mi->set_master_log_pos(max<ulonglong>(BIN_LOG_HEADER_SIZE,
9128 mi->rli->get_group_master_log_pos()));
9129 mi->set_master_log_name(mi->rli->get_group_master_log_name());
9130 }
9131
9132 /*
9133 Sets if the slave should connect to the master and look for
9134 GTIDs.
9135 */
9136 if (lex_mi->auto_position != LEX_MASTER_INFO::LEX_MI_UNCHANGED)
9137 mi->set_auto_position(
9138 (lex_mi->auto_position == LEX_MASTER_INFO::LEX_MI_ENABLE));
9139
9140 /*
9141 Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never
9142 a slave before).
9143 */
9144 if (flush_master_info(mi, true))
9145 {
9146 my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush master info file");
9147 ret= TRUE;
9148 goto err;
9149 }
9150 if (need_relay_log_purge)
9151 {
9152 relay_log_purge= 1;
9153 THD_STAGE_INFO(thd, stage_purging_old_relay_logs);
9154 if (mi->rli->purge_relay_logs(thd,
9155 0 /* not only reset, but also reinit */,
9156 &errmsg))
9157 {
9158 my_error(ER_RELAY_LOG_FAIL, MYF(0), errmsg);
9159 ret= TRUE;
9160 goto err;
9161 }
9162 }
9163 else
9164 {
9165 const char* msg;
9166 relay_log_purge= 0;
9167 /* Relay log is already initialized */
9168
9169 if (mi->rli->init_relay_log_pos(mi->rli->get_group_relay_log_name(),
9170 mi->rli->get_group_relay_log_pos(),
9171 true/*need_data_lock=true*/,
9172 &msg, 0))
9173 {
9174 my_error(ER_RELAY_LOG_INIT, MYF(0), msg);
9175 ret= TRUE;
9176 goto err;
9177 }
9178 }
9179 relay_log_purge= save_relay_log_purge;
9180
9181 /*
9182 Coordinates in rli were spoilt by the 'if (need_relay_log_purge)' block,
9183 so restore them to good values. If we left them to ''/0, that would work;
9184 but that would fail in the case of 2 successive CHANGE MASTER (without a
9185 START SLAVE in between): because first one would set the coords in mi to
9186 the good values of those in rli, the set those in rli to ''/0, then
9187 second CHANGE MASTER would set the coords in mi to those of rli, i.e. to
9188 ''/0: we have lost all copies of the original good coordinates.
9189 That's why we always save good coords in rli.
9190 */
9191 if (need_relay_log_purge)
9192 {
9193 mi->rli->set_group_master_log_pos(mi->get_master_log_pos());
9194 DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->get_master_log_pos()));
9195 mi->rli->set_group_master_log_name(mi->get_master_log_name());
9196 }
9197 var_group_master_log_name= const_cast<char *>(mi->rli->get_group_master_log_name());
9198 if (!var_group_master_log_name[0]) // uninitialized case
9199 mi->rli->set_group_master_log_pos(0);
9200
9201 mysql_mutex_lock(&mi->rli->data_lock);
9202 mi->rli->abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */
9203 /* Clear the errors, for a clean start */
9204 mi->rli->clear_error();
9205 mi->rli->clear_until_condition();
9206
9207 sql_print_information("'CHANGE MASTER TO executed'. "
9208 "Previous state master_host='%s', master_port= %u, master_log_file='%s', "
9209 "master_log_pos= %ld, master_bind='%s'. "
9210 "New state master_host='%s', master_port= %u, master_log_file='%s', "
9211 "master_log_pos= %ld, master_bind='%s'.",
9212 saved_host, saved_port, saved_log_name, (ulong) saved_log_pos,
9213 saved_bind_addr, mi->host, mi->port, mi->get_master_log_name(),
9214 (ulong) mi->get_master_log_pos(), mi->bind_addr);
9215
9216 /*
9217 If we don't write new coordinates to disk now, then old will remain in
9218 relay-log.info until START SLAVE is issued; but if mysqld is shutdown
9219 before START SLAVE, then old will remain in relay-log.info, and will be the
9220 in-memory value at restart (thus causing errors, as the old relay log does
9221 not exist anymore).
9222
9223 Notice that the rli table is available exclusively as slave is not
9224 running.
9225 */
9226 DBUG_ASSERT(!mi->rli->slave_running);
9227 if ((ret= mi->rli->flush_info(true)))
9228 my_error(ER_RELAY_LOG_INIT, MYF(0), "Failed to flush relay info file.");
9229 mysql_cond_broadcast(&mi->data_cond);
9230 mysql_mutex_unlock(&mi->rli->data_lock);
9231
9232 err:
9233 unlock_slave_threads(mi);
9234 if (ret == FALSE)
9235 {
9236 if (!mts_remove_workers)
9237 my_ok(thd);
9238 else
9239 if (!Rpl_info_factory::reset_workers(mi->rli))
9240 my_ok(thd);
9241 else
9242 my_error(ER_MTS_RESET_WORKERS, MYF(0));
9243 }
9244 DBUG_RETURN(ret);
9245 }
9246 /**
9247 @} (end of group Replication)
9248 */
9249 #endif /* HAVE_REPLICATION */
9250