1 /* Copyright (c) 2000, 2018, 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, Suite 500, Boston, MA 02110-1335 USA */ 22 23 #ifndef RPL_SLAVE_H 24 #define RPL_SLAVE_H 25 26 typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL, SLAVE_THD_WORKER } SLAVE_THD_TYPE; 27 28 /** 29 MASTER_DELAY can be at most (1 << 31) - 1. 30 */ 31 #define MASTER_DELAY_MAX (0x7FFFFFFF) 32 #if INT_MAX < 0x7FFFFFFF 33 #error "don't support platforms where INT_MAX < 0x7FFFFFFF" 34 #endif 35 36 /** 37 @defgroup Replication Replication 38 @{ 39 40 @file 41 */ 42 43 /** 44 Some of defines are need in parser even though replication is not 45 compiled in (embedded). 46 */ 47 48 /** 49 The maximum is defined as (ULONG_MAX/1000) with 4 bytes ulong 50 */ 51 #define SLAVE_MAX_HEARTBEAT_PERIOD 4294967 52 53 #ifdef HAVE_REPLICATION 54 55 #include "log.h" 56 #include "binlog.h" 57 #include "my_list.h" 58 #include "rpl_filter.h" 59 #include "rpl_tblmap.h" 60 61 #define SLAVE_NET_TIMEOUT 3600 62 63 #define MAX_SLAVE_ERROR 2000 64 65 #define MTS_WORKER_UNDEF ((ulong) -1) 66 #define MTS_MAX_WORKERS 1024 67 68 /* 69 When using tables to store the slave workers bitmaps, 70 we use a BLOB field. The maximum size of a BLOB is: 71 72 2^16-1 = 65535 bytes => (2^16-1) * 8 = 524280 bits 73 */ 74 #define MTS_MAX_BITS_IN_GROUP ((1L << 19) - 8) /* 524280 */ 75 76 // Forward declarations 77 class Relay_log_info; 78 class Master_info; 79 80 extern bool server_id_supplied; 81 82 /***************************************************************************** 83 84 MySQL Replication 85 86 Replication is implemented via two types of threads: 87 88 I/O Thread - One of these threads is started for each master server. 89 They maintain a connection to their master server, read log 90 events from the master as they arrive, and queues them into 91 a single, shared relay log file. A Master_info 92 represents each of these threads. 93 94 SQL Thread - One of these threads is started and reads from the relay log 95 file, executing each event. A Relay_log_info 96 represents this thread. 97 98 Buffering in the relay log file makes it unnecessary to reread events from 99 a master server across a slave restart. It also decouples the slave from 100 the master where long-running updates and event logging are concerned--ie 101 it can continue to log new events while a slow query executes on the slave. 102 103 *****************************************************************************/ 104 105 /* 106 MUTEXES in replication: 107 108 LOCK_active_mi: [note: this was originally meant for multimaster, to switch 109 from a master to another, to protect active_mi] It is used to SERIALIZE ALL 110 administrative commands of replication: START SLAVE, STOP SLAVE, CHANGE 111 MASTER, RESET SLAVE, end_slave() (when mysqld stops) [init_slave() does not 112 need it it's called early]. Any of these commands holds the mutex from the 113 start till the end. This thus protects us against a handful of deadlocks 114 (consider start_slave_thread() which, when starting the I/O thread, releases 115 mi->run_lock, keeps rli->run_lock, and tries to re-acquire mi->run_lock). 116 117 Currently active_mi never moves (it's created at startup and deleted at 118 shutdown, and not changed: it always points to the same Master_info struct), 119 because we don't have multimaster. So for the moment, mi does not move, and 120 mi->rli does not either. 121 122 In Master_info: run_lock, data_lock 123 run_lock protects all information about the run state: slave_running, thd 124 and the existence of the I/O thread (to stop/start it, you need this mutex). 125 data_lock protects some moving members of the struct: counters (log name, 126 position) and relay log (MYSQL_BIN_LOG object). 127 128 In Relay_log_info: run_lock, data_lock 129 see Master_info 130 However, note that run_lock does not protect 131 Relay_log_info.run_state; that is protected by data_lock. 132 133 In MYSQL_BIN_LOG: LOCK_log, LOCK_index of the binlog and the relay log 134 LOCK_log: when you write to it. LOCK_index: when you create/delete a binlog 135 (so that you have to update the .index file). 136 137 ==== Order of acquisition ==== 138 139 Here, we list most major functions that acquire multiple locks. 140 141 Notation: For each function, we list the locks it takes, in the 142 order it takes them. If a function holds lock A while taking lock 143 B, then we write "A, B". If a function locks A, unlocks A, then 144 locks B, then we write "A | B". If function F1 invokes function F2, 145 then we write F2's name in parentheses in the list of locks for F1. 146 147 show_master_info: 148 mi.data_lock, rli.data_lock, mi.err_lock, rli.err_lock 149 150 stop_slave: 151 LOCK_active_mi, 152 ( mi.run_lock, thd.LOCK_thd_data 153 | rli.run_lock, thd.LOCK_thd_data 154 | relay.LOCK_log 155 ) 156 157 start_slave: 158 mi.run_lock, rli.run_lock, rli.data_lock, global_sid_lock->wrlock 159 160 reset_logs: 161 LOCK_thread_count, .LOCK_log, .LOCK_index, global_sid_lock->wrlock 162 163 purge_relay_logs: 164 rli.data_lock, (relay.reset_logs) LOCK_thread_count, 165 relay.LOCK_log, relay.LOCK_index, global_sid_lock->wrlock 166 167 reset_master: 168 (binlog.reset_logs) LOCK_thread_count, binlog.LOCK_log, 169 binlog.LOCK_index, global_sid_lock->wrlock 170 171 reset_slave: 172 mi.run_lock, rli.run_lock, (purge_relay_logs) rli.data_lock, 173 LOCK_thread_count, relay.LOCK_log, relay.LOCK_index, 174 global_sid_lock->wrlock 175 176 purge_logs: 177 .LOCK_index, LOCK_thread_count, thd.linfo.lock 178 179 [Note: purge_logs contains a known bug: LOCK_index should not be 180 taken before LOCK_thread_count. This implies that, e.g., 181 purge_master_logs can deadlock with reset_master. However, 182 although purge_first_log and reset_slave take locks in reverse 183 order, they cannot deadlock because they both first acquire 184 rli.data_lock.] 185 186 purge_master_logs, purge_master_logs_before_date, purge: 187 (binlog.purge_logs) binlog.LOCK_index, LOCK_thread_count, thd.linfo.lock 188 189 purge_first_log: 190 rli.data_lock, relay.LOCK_index, rli.log_space_lock, 191 (relay.purge_logs) LOCK_thread_count, thd.linfo.lock 192 193 MYSQL_BIN_LOG::new_file_impl: 194 .LOCK_log, .LOCK_index, 195 ( [ if binlog: LOCK_prep_xids ] 196 | global_sid_lock->wrlock 197 ) 198 199 rotate_relay_log: 200 (relay.new_file_impl) relay.LOCK_log, relay.LOCK_index, 201 global_sid_lock->wrlock 202 203 kill_zombie_dump_threads: 204 LOCK_thread_count, thd.LOCK_thd_data 205 206 init_relay_log_pos: 207 rli.data_lock, relay.log_lock 208 209 rli_init_info: 210 rli.data_lock, 211 ( relay.log_lock 212 | global_sid_lock->wrlock 213 | (relay.open_binlog) 214 | (init_relay_log_pos) rli.data_lock, relay.log_lock 215 ) 216 217 change_master: 218 mi.run_lock, rli.run_lock, (init_relay_log_pos) rli.data_lock, 219 relay.log_lock 220 221 So the DAG of lock acquisition order (not counting the buggy 222 purge_logs) is, empirically: 223 224 LOCK_active_mi, mi.run_lock, rli.run_lock, 225 ( rli.data_lock, 226 ( LOCK_thread_count, 227 ( 228 ( binlog.LOCK_log, binlog.LOCK_index 229 | relay.LOCK_log, relay.LOCK_index 230 ), 231 ( rli.log_space_lock | global_sid_lock->wrlock ) 232 | binlog.LOCK_log, binlog.LOCK_index, LOCK_prep_xids 233 | thd.LOCK_data 234 ) 235 | mi.err_lock, rli.err_lock 236 ) 237 ) 238 ) 239 | mi.data_lock, rli.data_lock 240 */ 241 242 extern ulong master_retry_count; 243 extern MY_BITMAP slave_error_mask; 244 extern char slave_skip_error_names[]; 245 extern bool use_slave_mask; 246 extern char *slave_load_tmpdir; 247 extern char *master_info_file, *relay_log_info_file; 248 extern char *opt_relay_logname, *opt_relaylog_index_name; 249 extern char *opt_binlog_index_name; 250 extern my_bool opt_skip_slave_start, opt_reckless_slave; 251 extern my_bool opt_log_slave_updates; 252 extern char *opt_slave_skip_errors; 253 extern ulonglong relay_log_space_limit; 254 255 extern const char *relay_log_index; 256 extern const char *relay_log_basename; 257 258 /* 259 3 possible values for Master_info::slave_running and 260 Relay_log_info::slave_running. 261 The values 0,1,2 are very important: to keep the diff small, I didn't 262 substitute places where we use 0/1 with the newly defined symbols. So don't change 263 these values. 264 The same way, code is assuming that in Relay_log_info we use only values 265 0/1. 266 I started with using an enum, but 267 enum_variable=1; is not legal so would have required many line changes. 268 */ 269 #define MYSQL_SLAVE_NOT_RUN 0 270 #define MYSQL_SLAVE_RUN_NOT_CONNECT 1 271 #define MYSQL_SLAVE_RUN_CONNECT 2 272 273 /* 274 If the following is set, if first gives an error, second will be 275 tried. Otherwise, if first fails, we fail. 276 */ 277 #define SLAVE_FORCE_ALL 4 278 279 int start_slave(THD* thd, Master_info* mi, bool net_report); 280 int stop_slave(THD* thd, Master_info* mi, bool net_report); 281 bool change_master(THD* thd, Master_info* mi); 282 int reset_slave(THD *thd, Master_info* mi); 283 int init_slave(); 284 int init_recovery(Master_info* mi, const char** errmsg); 285 int global_init_info(Master_info* mi, bool ignore_if_no_info, int thread_mask); 286 void end_info(Master_info* mi); 287 int remove_info(Master_info* mi); 288 int flush_master_info(Master_info* mi, bool force); 289 void add_slave_skip_errors(const char* arg); 290 void set_slave_skip_errors(char** slave_skip_errors_ptr); 291 int register_slave_on_master(MYSQL* mysql); 292 int terminate_slave_threads(Master_info* mi, int thread_mask, 293 bool need_lock_term= true); 294 int start_slave_threads(bool need_lock_slave, bool wait_for_start, 295 Master_info* mi, int thread_mask); 296 /* 297 cond_lock is usually same as start_lock. It is needed for the case when 298 start_lock is 0 which happens if start_slave_thread() is called already 299 inside the start_lock section, but at the same time we want a 300 mysql_cond_wait() on start_cond, start_lock 301 */ 302 int start_slave_thread( 303 #ifdef HAVE_PSI_INTERFACE 304 PSI_thread_key thread_key, 305 #endif 306 pthread_handler h_func, 307 mysql_mutex_t *start_lock, 308 mysql_mutex_t *cond_lock, 309 mysql_cond_t *start_cond, 310 volatile uint *slave_running, 311 volatile ulong *slave_run_id, 312 Master_info *mi); 313 314 /* retrieve table from master and copy to slave*/ 315 int fetch_master_table(THD* thd, const char* db_name, const char* table_name, 316 Master_info* mi, MYSQL* mysql, bool overwrite); 317 318 bool show_slave_status(THD* thd, Master_info* mi); 319 bool rpl_master_has_bug(const Relay_log_info *rli, uint bug_id, bool report, 320 bool (*pred)(const void *), const void *param); 321 bool rpl_master_erroneous_autoinc(THD* thd); 322 323 const char *print_slave_db_safe(const char *db); 324 void skip_load_data_infile(NET* net); 325 326 void end_slave(); /* release slave threads */ 327 void close_active_mi(); /* clean up slave threads data */ 328 void clear_until_condition(Relay_log_info* rli); 329 void clear_slave_error(Relay_log_info* rli); 330 void lock_slave_threads(Master_info* mi); 331 void unlock_slave_threads(Master_info* mi); 332 void init_thread_mask(int* mask,Master_info* mi,bool inverse); 333 void set_slave_thread_options(THD* thd); 334 void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli); 335 int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli); 336 int rotate_relay_log(Master_info* mi, bool need_log_space_lock); 337 338 pthread_handler_t handle_slave_io(void *arg); 339 pthread_handler_t handle_slave_sql(void *arg); 340 bool net_request_file(NET* net, const char* fname); 341 342 extern bool volatile abort_loop; 343 extern Master_info *active_mi; /* active_mi for multi-master */ 344 extern LIST master_list; 345 extern my_bool replicate_same_server_id; 346 347 extern int disconnect_slave_event_count, abort_slave_event_count ; 348 349 /* the master variables are defaults read from my.cnf or command line */ 350 extern uint master_port, master_connect_retry, report_port; 351 extern char * master_user, *master_password, *master_host; 352 extern char *master_info_file, *relay_log_info_file, *report_user; 353 extern char *report_host, *report_password; 354 355 extern my_bool master_ssl; 356 extern char *master_ssl_ca, *master_ssl_capath, *master_ssl_cert; 357 extern char *master_ssl_cipher, *master_ssl_key; 358 359 int mts_recovery_groups(Relay_log_info *rli); 360 bool mts_checkpoint_routine(Relay_log_info *rli, ulonglong period, 361 bool force, bool need_data_lock); 362 #endif /* HAVE_REPLICATION */ 363 364 /* masks for start/stop operations on io and sql slave threads */ 365 #define SLAVE_IO 1 366 #define SLAVE_SQL 2 367 368 /** 369 @} (end of group Replication) 370 */ 371 #endif 372