1/* Copyright (c) 2006, 2012, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
16#ifndef RPL_MI_H
17#define RPL_MI_H
18
19#ifdef HAVE_REPLICATION
20
21#include "rpl_rli.h"
22#include "rpl_reporting.h"
23#include <my_sys.h>
24#include "rpl_filter.h"
25#include "keycaches.h"
26
27typedef struct st_mysql MYSQL;
28
29/**
30 Domain id based filter to handle DO_DOMAIN_IDS and IGNORE_DOMAIN_IDS used to
31 set filtering on replication slave based on event's GTID domain_id.
32*/
33class Domain_id_filter
34{
35private:
36 /*
37 Flag to tell whether the events in the current GTID group get written to
38 the relay log. It is set according to the domain_id based filtering rule
39 on every GTID_EVENT and reset at the end of current GTID event group.
40 */
41 bool m_filter;
42
43 /*
44 DO_DOMAIN_IDS (0):
45 Ignore all the events which do not belong to any of the domain ids in the
46 list.
47
48 IGNORE_DOMAIN_IDS (1):
49 Ignore the events which belong to one of the domain ids in the list.
50 */
51 DYNAMIC_ARRAY m_domain_ids[2];
52
53public:
54 /* domain id list types */
55 enum enum_list_type {
56 DO_DOMAIN_IDS= 0,
57 IGNORE_DOMAIN_IDS
58 };
59
60 Domain_id_filter();
61
62 ~Domain_id_filter();
63
64 /*
65 Returns whether the current group needs to be filtered.
66 */
67 bool is_group_filtered() { return m_filter; }
68
69 /*
70 Checks whether the group with the specified domain_id needs to be
71 filtered and updates m_filter flag accordingly.
72 */
73 void do_filter(ulong domain_id);
74
75 /*
76 Reset m_filter. It should be called when IO thread receives COMMIT_EVENT or
77 XID_EVENT.
78 */
79 void reset_filter();
80
81 /*
82 Update the do/ignore domain id filter lists.
83
84 @param do_ids [IN] domain ids to be kept
85 @param ignore_ids [IN] domain ids to be filtered out
86 @param using_gtid [IN] use GTID?
87
88 @retval false Success
89 true Error
90 */
91 bool update_ids(DYNAMIC_ARRAY *do_ids, DYNAMIC_ARRAY *ignore_ids,
92 bool using_gtid);
93
94 /*
95 Serialize and store the ids from domain id lists into the thd's protocol
96 buffer.
97
98 @param thd [IN] thread handler
99
100 @retval void
101 */
102 void store_ids(THD *thd);
103
104 /*
105 Initialize the given domain id list (DYNAMIC_ARRAY) with the
106 space-separated list of numbers from the specified IO_CACHE where
107 the first number is the total number of entries to follows.
108
109 @param f [IN] IO_CACHE file
110 @param type [IN] domain id list type
111
112 @retval false Success
113 true Error
114 */
115 bool init_ids(IO_CACHE *f, enum_list_type type);
116
117 /*
118 Return the elements of the give domain id list type as string.
119
120 @param type [IN] domain id list type
121
122 @retval a string buffer storing the total number
123 of elements followed by the individual
124 elements (space-separated) in the
125 specified list.
126
127 Note: Its caller's responsibility to free the returned string buffer.
128 */
129 char *as_string(enum_list_type type);
130
131};
132
133
134extern TYPELIB slave_parallel_mode_typelib;
135
136typedef struct st_rows_event_tracker
137{
138 char binlog_file_name[FN_REFLEN];
139 my_off_t first_seen;
140 my_off_t last_seen;
141 bool stmt_end_seen;
142 void update(const char* file_name, my_off_t pos,
143 const char* buf,
144 const Format_description_log_event *fdle);
145 void reset();
146 bool check_and_report(const char* file_name, my_off_t pos);
147} Rows_event_tracker;
148
149/*****************************************************************************
150 Replication IO Thread
151
152 Master_info contains:
153 - information about how to connect to a master
154 - current master log name
155 - current master log offset
156 - misc control variables
157
158 Master_info is initialized once from the master.info file if such
159 exists. Otherwise, data members corresponding to master.info fields
160 are initialized with defaults specified by master-* options. The
161 initialization is done through init_master_info() call.
162
163 The format of master.info file:
164
165 log_name
166 log_pos
167 master_host
168 master_user
169 master_pass
170 master_port
171 master_connect_retry
172
173 To write out the contents of master.info file to disk ( needed every
174 time we read and queue data from the master ), a call to
175 flush_master_info() is required.
176
177 To clean up, call end_master_info()
178
179*****************************************************************************/
180
181class Master_info : public Slave_reporting_capability
182{
183 public:
184 enum enum_using_gtid {
185 USE_GTID_NO= 0, USE_GTID_CURRENT_POS= 1, USE_GTID_SLAVE_POS= 2
186 };
187
188 Master_info(LEX_CSTRING *connection_name, bool is_slave_recovery);
189 ~Master_info();
190 bool shall_ignore_server_id(ulong s_id);
191 void clear_in_memory_info(bool all);
192 bool error()
193 {
194 /* If malloc() in initialization failed */
195 return connection_name.str == 0;
196 }
197 static const char *using_gtid_astext(enum enum_using_gtid arg);
198 bool using_parallel()
199 {
200 return opt_slave_parallel_threads > 0 &&
201 parallel_mode > SLAVE_PARALLEL_NONE;
202 }
203 void release();
204 void wait_until_free();
205 void lock_slave_threads();
206 void unlock_slave_threads();
207
208 /* the variables below are needed because we can change masters on the fly */
209 char master_log_name[FN_REFLEN+6]; /* Room for multi-*/
210 char host[HOSTNAME_LENGTH*SYSTEM_CHARSET_MBMAXLEN+1];
211 char user[USERNAME_LENGTH+1];
212 char password[MAX_PASSWORD_LENGTH*SYSTEM_CHARSET_MBMAXLEN+1];
213 LEX_CSTRING connection_name; /* User supplied connection name */
214 LEX_CSTRING cmp_connection_name; /* Connection name in lower case */
215 bool ssl; // enables use of SSL connection if true
216 char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN];
217 char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN];
218 char ssl_crl[FN_REFLEN], ssl_crlpath[FN_REFLEN];
219 bool ssl_verify_server_cert;
220
221 my_off_t master_log_pos;
222 File fd; // we keep the file open, so we need to remember the file pointer
223 IO_CACHE file;
224
225 mysql_mutex_t data_lock, run_lock, sleep_lock, start_stop_lock;
226 mysql_cond_t data_cond, start_cond, stop_cond, sleep_cond;
227 THD *io_thd;
228 MYSQL* mysql;
229 uint32 file_id; /* for 3.23 load data infile */
230 Relay_log_info rli;
231 uint port;
232 Rpl_filter* rpl_filter; /* Each replication can set its filter rule*/
233 /*
234 to hold checksum alg in use until IO thread has received FD.
235 Initialized to novalue, then set to the queried from master
236 @@global.binlog_checksum and deactivated once FD has been received.
237 */
238 enum enum_binlog_checksum_alg checksum_alg_before_fd;
239 uint connect_retry;
240#ifndef DBUG_OFF
241 int events_till_disconnect;
242
243 /*
244 The following are auxiliary DBUG variables used to kill IO thread in the
245 middle of a group/transaction (see "kill_slave_io_after_2_events").
246 */
247 bool dbug_do_disconnect;
248 int dbug_event_counter;
249#endif
250 bool inited;
251 volatile bool abort_slave;
252 volatile uint slave_running;
253 volatile ulong slave_run_id;
254 /*
255 The difference in seconds between the clock of the master and the clock of
256 the slave (second - first). It must be signed as it may be <0 or >0.
257 clock_diff_with_master is computed when the I/O thread starts; for this the
258 I/O thread does a SELECT UNIX_TIMESTAMP() on the master.
259 "how late the slave is compared to the master" is computed like this:
260 clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master
261
262 */
263 long clock_diff_with_master;
264 /*
265 Keeps track of the number of events before fsyncing.
266 The option --sync-master-info determines how many
267 events should happen before fsyncing.
268 */
269 uint sync_counter;
270 float heartbeat_period; // interface with CHANGE MASTER or master.info
271 ulonglong received_heartbeats; // counter of received heartbeat events
272 DYNAMIC_ARRAY ignore_server_ids;
273 ulong master_id;
274 /*
275 At reconnect and until the first rotate event is seen, prev_master_id is
276 the value of master_id during the previous connection, used to detect
277 silent change of master server during reconnects.
278 */
279 ulong prev_master_id;
280 /*
281 Which kind of GTID position (if any) is used when connecting to master.
282
283 Note that you can not change the numeric values of these, they are used
284 in master.info.
285 */
286 enum enum_using_gtid using_gtid;
287
288 /*
289 This GTID position records how far we have fetched into the relay logs.
290 This is used to continue fetching when the IO thread reconnects to the
291 master.
292
293 (Full slave stop/start does not use it, as it resets the relay logs).
294 */
295 slave_connection_state gtid_current_pos;
296 /*
297 If events_queued_since_last_gtid is non-zero, it is the number of events
298 queued so far in the relaylog of a GTID-prefixed event group.
299 It is zero when no partial event group has been queued at the moment.
300 */
301 uint64 events_queued_since_last_gtid;
302 /*
303 The GTID of the partially-queued event group, when
304 events_queued_since_last_gtid is non-zero.
305 */
306 rpl_gtid last_queued_gtid;
307 /* Whether last_queued_gtid had the FL_STANDALONE flag set. */
308 bool last_queued_gtid_standalone;
309 /*
310 When slave IO thread needs to reconnect, gtid_reconnect_event_skip_count
311 counts number of events to skip from the first GTID-prefixed event group,
312 to avoid duplicating events in the relay log.
313 */
314 uint64 gtid_reconnect_event_skip_count;
315 /* gtid_event_seen is false until we receive first GTID event from master. */
316 bool gtid_event_seen;
317 /**
318 The struct holds some history of Rows- log-event reading/queuing
319 by the receiver thread. Its fields are updated per each such event
320 at time of queue_event(), and they are checked to detect
321 the Rows- event group integrity violation at time of first non-Rows-
322 event gets handled.
323 */
324 Rows_event_tracker rows_event_tracker;
325 bool in_start_all_slaves, in_stop_all_slaves;
326 bool in_flush_all_relay_logs;
327 uint users; /* Active user for object */
328 uint killed;
329
330
331 /* No of DDL event group */
332 volatile uint64 total_ddl_groups;
333
334 /* No of non-transactional event group*/
335 volatile uint64 total_non_trans_groups;
336
337 /* No of transactional event group*/
338 volatile uint64 total_trans_groups;
339
340 /* domain-id based filter */
341 Domain_id_filter domain_id_filter;
342
343 /* The parallel replication mode. */
344 enum_slave_parallel_mode parallel_mode;
345 /*
346 semi_ack is used to identify if the current binlog event needs an
347 ACK from slave, or if delay_master is enabled.
348 */
349 int semi_ack;
350};
351
352int init_master_info(Master_info* mi, const char* master_info_fname,
353 const char* slave_info_fname,
354 bool abort_if_no_master_info_file,
355 int thread_mask);
356void end_master_info(Master_info* mi);
357int flush_master_info(Master_info* mi,
358 bool flush_relay_log_cache,
359 bool need_lock_relay_log);
360void copy_filter_setting(Rpl_filter* dst_filter, Rpl_filter* src_filter);
361void update_change_master_ids(DYNAMIC_ARRAY *new_ids, DYNAMIC_ARRAY *old_ids);
362void prot_store_ids(THD *thd, DYNAMIC_ARRAY *ids);
363
364/*
365 Multi master are handled trough this struct.
366 Changes to this needs to be protected by LOCK_active_mi;
367*/
368
369class Master_info_index
370{
371private:
372 IO_CACHE index_file;
373 char index_file_name[FN_REFLEN];
374
375public:
376 Master_info_index();
377 ~Master_info_index();
378
379 HASH master_info_hash;
380
381 bool init_all_master_info();
382 bool write_master_name_to_index_file(LEX_CSTRING *connection_name,
383 bool do_sync);
384
385 bool check_duplicate_master_info(LEX_CSTRING *connection_name,
386 const char *host, uint port);
387 bool add_master_info(Master_info *mi, bool write_to_file);
388 bool remove_master_info(Master_info *mi);
389 Master_info *get_master_info(const LEX_CSTRING *connection_name,
390 Sql_condition::enum_warning_level warning);
391 bool start_all_slaves(THD *thd);
392 bool stop_all_slaves(THD *thd);
393 void free_connections();
394 bool flush_all_relay_logs();
395};
396
397
398/*
399 The class rpl_io_thread_info is the THD::system_thread_info for the IO thread.
400*/
401class rpl_io_thread_info
402{
403public:
404};
405
406
407Master_info *get_master_info(const LEX_CSTRING *connection_name,
408 Sql_condition::enum_warning_level warning);
409bool check_master_connection_name(LEX_CSTRING *name);
410void create_logfile_name_with_suffix(char *res_file_name, size_t length,
411 const char *info_file,
412 bool append,
413 LEX_CSTRING *suffix);
414
415uchar *get_key_master_info(Master_info *mi, size_t *length,
416 my_bool not_used __attribute__((unused)));
417void free_key_master_info(Master_info *mi);
418uint any_slave_sql_running(bool already_locked);
419bool give_error_if_slave_running(bool already_lock);
420
421#endif /* HAVE_REPLICATION */
422#endif /* RPL_MI_H */
423