1 | /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. |
2 | Copyright (c) 2009, 2016, MariaDB |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
16 | |
17 | #ifndef SLAVE_H |
18 | #define SLAVE_H |
19 | |
20 | /** |
21 | MASTER_DELAY can be at most (1 << 31) - 1. |
22 | */ |
23 | #define MASTER_DELAY_MAX (0x7FFFFFFF) |
24 | #if INT_MAX < 0x7FFFFFFF |
25 | #error "don't support platforms where INT_MAX < 0x7FFFFFFF" |
26 | #endif |
27 | |
28 | /** |
29 | @defgroup Replication Replication |
30 | @{ |
31 | |
32 | @file |
33 | */ |
34 | |
35 | /** |
36 | Some of defines are need in parser even though replication is not |
37 | compiled in (embedded). |
38 | */ |
39 | |
40 | /** |
41 | The maximum is defined as (ULONG_MAX/1000) with 4 bytes ulong |
42 | */ |
43 | #define SLAVE_MAX_HEARTBEAT_PERIOD 4294967 |
44 | |
45 | #ifdef HAVE_REPLICATION |
46 | |
47 | #include "log.h" |
48 | #include "my_list.h" |
49 | #include "rpl_filter.h" |
50 | #include "rpl_tblmap.h" |
51 | #include "rpl_gtid.h" |
52 | |
53 | #define SLAVE_NET_TIMEOUT 60 |
54 | |
55 | #define MAX_SLAVE_ERROR ER_ERROR_LAST+1 |
56 | |
57 | #define MAX_REPLICATION_THREAD 64 |
58 | |
59 | // Forward declarations |
60 | class Relay_log_info; |
61 | class Master_info; |
62 | class Master_info_index; |
63 | struct rpl_group_info; |
64 | struct rpl_parallel_thread; |
65 | |
66 | int init_intvar_from_file(int* var, IO_CACHE* f, int default_val); |
67 | int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, |
68 | const char *default_val); |
69 | int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val); |
70 | int init_dynarray_intvar_from_file(DYNAMIC_ARRAY* arr, IO_CACHE* f); |
71 | |
72 | /***************************************************************************** |
73 | |
74 | MySQL Replication |
75 | |
76 | Replication is implemented via two types of threads: |
77 | |
78 | I/O Thread - One of these threads is started for each master server. |
79 | They maintain a connection to their master server, read log |
80 | events from the master as they arrive, and queues them into |
81 | a single, shared relay log file. A Master_info |
82 | represents each of these threads. |
83 | |
84 | SQL Thread - One of these threads is started and reads from the relay log |
85 | file, executing each event. A Relay_log_info |
86 | represents this thread. |
87 | |
88 | Buffering in the relay log file makes it unnecessary to reread events from |
89 | a master server across a slave restart. It also decouples the slave from |
90 | the master where long-running updates and event logging are concerned--ie |
91 | it can continue to log new events while a slow query executes on the slave. |
92 | |
93 | *****************************************************************************/ |
94 | |
95 | /* |
96 | MUTEXES in replication: |
97 | |
98 | LOCK_active_mi: [note: this was originally meant for multimaster, to switch |
99 | from a master to another, to protect active_mi] It is used to SERIALIZE ALL |
100 | administrative commands of replication: START SLAVE, STOP SLAVE, CHANGE |
101 | MASTER, RESET SLAVE, end_slave() (when mysqld stops) [init_slave() does not |
102 | need it it's called early]. Any of these commands holds the mutex from the |
103 | start till the end. This thus protects us against a handful of deadlocks |
104 | (consider start_slave_thread() which, when starting the I/O thread, releases |
105 | mi->run_lock, keeps rli->run_lock, and tries to re-acquire mi->run_lock). |
106 | |
107 | Currently active_mi never moves (it's created at startup and deleted at |
108 | shutdown, and not changed: it always points to the same Master_info struct), |
109 | because we don't have multimaster. So for the moment, mi does not move, and |
110 | mi->rli does not either. |
111 | |
112 | In Master_info: run_lock, data_lock |
113 | run_lock protects all information about the run state: slave_running, thd |
114 | and the existence of the I/O thread (to stop/start it, you need this mutex). |
115 | data_lock protects some moving members of the struct: counters (log name, |
116 | position) and relay log (MYSQL_BIN_LOG object). |
117 | |
118 | In Relay_log_info: run_lock, data_lock |
119 | see Master_info |
120 | However, note that run_lock does not protect |
121 | Relay_log_info.run_state; that is protected by data_lock. |
122 | |
123 | Order of acquisition: if you want to have LOCK_active_mi and a run_lock, you |
124 | must acquire LOCK_active_mi first. |
125 | |
126 | In MYSQL_BIN_LOG: LOCK_log, LOCK_index of the binlog and the relay log |
127 | LOCK_log: when you write to it. LOCK_index: when you create/delete a binlog |
128 | (so that you have to update the .index file). |
129 | */ |
130 | |
131 | extern ulong master_retry_count; |
132 | extern MY_BITMAP slave_error_mask; |
133 | extern char slave_skip_error_names[]; |
134 | extern bool use_slave_mask; |
135 | extern char slave_transaction_retry_error_names[]; |
136 | extern uint *slave_transaction_retry_errors; |
137 | extern uint slave_transaction_retry_error_length; |
138 | extern char *slave_load_tmpdir; |
139 | extern char *master_info_file; |
140 | extern MYSQL_PLUGIN_IMPORT char *relay_log_info_file; |
141 | extern char *opt_relay_logname, *opt_relaylog_index_name; |
142 | extern my_bool opt_skip_slave_start, opt_reckless_slave; |
143 | extern my_bool opt_log_slave_updates; |
144 | extern char *opt_slave_skip_errors; |
145 | extern char *opt_slave_transaction_retry_errors; |
146 | extern my_bool opt_replicate_annotate_row_events; |
147 | extern ulonglong relay_log_space_limit; |
148 | extern ulonglong opt_read_binlog_speed_limit; |
149 | extern ulonglong slave_skipped_errors; |
150 | extern const char *relay_log_index; |
151 | extern const char *relay_log_basename; |
152 | |
153 | /* |
154 | 4 possible values for Master_info::slave_running and |
155 | Relay_log_info::slave_running. |
156 | The values 0,1,2,3 are very important: to keep the diff small, I didn't |
157 | substitute places where we use 0/1 with the newly defined symbols. |
158 | So don't change these values. |
159 | The same way, code is assuming that in Relay_log_info we use only values |
160 | 0/1. |
161 | I started with using an enum, but |
162 | enum_variable=1; is not legal so would have required many line changes. |
163 | */ |
164 | #define MYSQL_SLAVE_NOT_RUN 0 |
165 | #define MYSQL_SLAVE_RUN_NOT_CONNECT 1 |
166 | #define MYSQL_SLAVE_RUN_CONNECT 2 |
167 | #define MYSQL_SLAVE_RUN_READING 3 |
168 | |
169 | #define RPL_LOG_NAME (rli->group_master_log_name[0] ? rli->group_master_log_name :\ |
170 | "FIRST") |
171 | #define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\ |
172 | "FIRST") |
173 | |
174 | /* |
175 | If the following is set, if first gives an error, second will be |
176 | tried. Otherwise, if first fails, we fail. |
177 | */ |
178 | #define SLAVE_FORCE_ALL 4 |
179 | |
180 | /* |
181 | Values for the option --replicate-events-marked-for-skip. |
182 | Must match the names in replicate_events_marked_for_skip_names in sys_vars.cc |
183 | */ |
184 | #define RPL_SKIP_REPLICATE 0 |
185 | #define RPL_SKIP_FILTER_ON_SLAVE 1 |
186 | #define RPL_SKIP_FILTER_ON_MASTER 2 |
187 | |
188 | |
189 | int init_slave(); |
190 | int init_recovery(Master_info* mi, const char** errmsg); |
191 | bool init_slave_skip_errors(const char* arg); |
192 | bool init_slave_transaction_retry_errors(const char* arg); |
193 | int register_slave_on_master(MYSQL* mysql); |
194 | int terminate_slave_threads(Master_info* mi, int thread_mask, |
195 | bool skip_lock = 0); |
196 | int start_slave_threads(THD *thd, |
197 | bool need_slave_mutex, bool wait_for_start, |
198 | Master_info* mi, const char* master_info_fname, |
199 | const char* slave_info_fname, int thread_mask); |
200 | /* |
201 | cond_lock is usually same as start_lock. It is needed for the case when |
202 | start_lock is 0 which happens if start_slave_thread() is called already |
203 | inside the start_lock section, but at the same time we want a |
204 | mysql_cond_wait() on start_cond, start_lock |
205 | */ |
206 | int start_slave_thread( |
207 | #ifdef HAVE_PSI_INTERFACE |
208 | PSI_thread_key thread_key, |
209 | #endif |
210 | pthread_handler h_func, |
211 | mysql_mutex_t *start_lock, |
212 | mysql_mutex_t *cond_lock, |
213 | mysql_cond_t *start_cond, |
214 | volatile uint *slave_running, |
215 | volatile ulong *slave_run_id, |
216 | Master_info *mi); |
217 | |
218 | /* If fd is -1, dump to NET */ |
219 | int mysql_table_dump(THD* thd, const char* db, |
220 | const char* tbl_name, int fd = -1); |
221 | |
222 | /* retrieve table from master and copy to slave*/ |
223 | int fetch_master_table(THD* thd, const char* db_name, const char* table_name, |
224 | Master_info* mi, MYSQL* mysql, bool overwrite); |
225 | |
226 | void show_master_info_get_fields(THD *thd, List<Item> *field_list, |
227 | bool full, size_t gtid_pos_length); |
228 | bool show_master_info(THD* thd, Master_info* mi, bool full); |
229 | bool show_all_master_info(THD* thd); |
230 | void show_binlog_info_get_fields(THD *thd, List<Item> *field_list); |
231 | bool show_binlog_info(THD* thd); |
232 | bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report, |
233 | bool (*pred)(const void *), const void *param); |
234 | bool rpl_master_erroneous_autoinc(THD* thd); |
235 | |
236 | const char *print_slave_db_safe(const char *db); |
237 | void skip_load_data_infile(NET* net); |
238 | |
239 | void slave_prepare_for_shutdown(); |
240 | void end_slave(); /* release slave threads */ |
241 | void close_active_mi(); /* clean up slave threads data */ |
242 | void clear_until_condition(Relay_log_info* rli); |
243 | void clear_slave_error(Relay_log_info* rli); |
244 | void end_relay_log_info(Relay_log_info* rli); |
245 | void init_thread_mask(int* mask,Master_info* mi,bool inverse); |
246 | Format_description_log_event * |
247 | read_relay_log_description_event(IO_CACHE *cur_log, ulonglong start_pos, |
248 | const char **errmsg); |
249 | |
250 | int init_relay_log_pos(Relay_log_info* rli,const char* log,ulonglong pos, |
251 | bool need_data_lock, const char** errmsg, |
252 | bool look_for_description_event); |
253 | |
254 | int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, |
255 | const char** errmsg); |
256 | void set_slave_thread_options(THD* thd); |
257 | void set_slave_thread_default_charset(THD *thd, rpl_group_info *rgi); |
258 | int rotate_relay_log(Master_info* mi); |
259 | int has_temporary_error(THD *thd); |
260 | int sql_delay_event(Log_event *ev, THD *thd, rpl_group_info *rgi); |
261 | int apply_event_and_update_pos(Log_event* ev, THD* thd, |
262 | struct rpl_group_info *rgi); |
263 | int apply_event_and_update_pos_for_parallel(Log_event* ev, THD* thd, |
264 | struct rpl_group_info *rgi); |
265 | |
266 | int init_intvar_from_file(int* var, IO_CACHE* f, int default_val); |
267 | int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val); |
268 | int init_strvar_from_file(char *var, int max_size, IO_CACHE *f, |
269 | const char *default_val); |
270 | int init_dynarray_intvar_from_file(DYNAMIC_ARRAY* arr, IO_CACHE* f); |
271 | |
272 | pthread_handler_t handle_slave_io(void *arg); |
273 | void slave_output_error_info(rpl_group_info *rgi, THD *thd); |
274 | pthread_handler_t handle_slave_sql(void *arg); |
275 | bool net_request_file(NET* net, const char* fname); |
276 | void slave_background_kill_request(THD *to_kill); |
277 | void slave_background_gtid_pos_create_request |
278 | (rpl_slave_state::gtid_pos_table *table_entry); |
279 | |
280 | extern bool volatile abort_loop; |
281 | extern Master_info *active_mi; /* active_mi for multi-master */ |
282 | extern Master_info *default_master_info; /* To replace active_mi */ |
283 | extern Master_info_index *master_info_index; |
284 | extern LEX_CSTRING default_master_connection_name; |
285 | extern my_bool replicate_same_server_id; |
286 | |
287 | extern int disconnect_slave_event_count, abort_slave_event_count ; |
288 | |
289 | /* the master variables are defaults read from my.cnf or command line */ |
290 | extern uint report_port; |
291 | extern char *master_info_file, *report_user; |
292 | extern char *report_host, *report_password; |
293 | |
294 | extern I_List<THD> threads; |
295 | |
296 | #else |
297 | #define close_active_mi() /* no-op */ |
298 | #endif /* HAVE_REPLICATION */ |
299 | |
300 | /* masks for start/stop operations on io and sql slave threads */ |
301 | #define SLAVE_IO 1 |
302 | #define SLAVE_SQL 2 |
303 | |
304 | /** |
305 | @} (end of group Replication) |
306 | */ |
307 | |
308 | #endif |
309 | |