00001 /* Copyright (C) 2000-2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #ifndef SLAVE_H 00018 #define SLAVE_H 00019 00020 #ifdef HAVE_REPLICATION 00021 00022 #include "log.h" 00023 #include "my_list.h" 00024 #include "rpl_filter.h" 00025 #include "rpl_tblmap.h" 00026 #include "rpl_rli.h" 00027 00028 #define SLAVE_NET_TIMEOUT 3600 00029 00030 #define MAX_SLAVE_ERROR 2000 00031 00032 /***************************************************************************** 00033 00034 MySQL Replication 00035 00036 Replication is implemented via two types of threads: 00037 00038 I/O Thread - One of these threads is started for each master server. 00039 They maintain a connection to their master server, read log 00040 events from the master as they arrive, and queues them into 00041 a single, shared relay log file. A MASTER_INFO struct 00042 represents each of these threads. 00043 00044 SQL Thread - One of these threads is started and reads from the relay log 00045 file, executing each event. A RELAY_LOG_INFO struct 00046 represents this thread. 00047 00048 Buffering in the relay log file makes it unnecessary to reread events from 00049 a master server across a slave restart. It also decouples the slave from 00050 the master where long-running updates and event logging are concerned--ie 00051 it can continue to log new events while a slow query executes on the slave. 00052 00053 *****************************************************************************/ 00054 00055 /* 00056 MUTEXES in replication: 00057 00058 LOCK_active_mi: [note: this was originally meant for multimaster, to switch 00059 from a master to another, to protect active_mi] It is used to SERIALIZE ALL 00060 administrative commands of replication: START SLAVE, STOP SLAVE, CHANGE 00061 MASTER, RESET SLAVE, end_slave() (when mysqld stops) [init_slave() does not 00062 need it it's called early]. Any of these commands holds the mutex from the 00063 start till the end. This thus protects us against a handful of deadlocks 00064 (consider start_slave_thread() which, when starting the I/O thread, releases 00065 mi->run_lock, keeps rli->run_lock, and tries to re-acquire mi->run_lock). 00066 00067 Currently active_mi never moves (it's created at startup and deleted at 00068 shutdown, and not changed: it always points to the same MASTER_INFO struct), 00069 because we don't have multimaster. So for the moment, mi does not move, and 00070 mi->rli does not either. 00071 00072 In MASTER_INFO: run_lock, data_lock 00073 run_lock protects all information about the run state: slave_running, and the 00074 existence of the I/O thread (to stop/start it, you need this mutex). 00075 data_lock protects some moving members of the struct: counters (log name, 00076 position) and relay log (MYSQL_BIN_LOG object). 00077 00078 In RELAY_LOG_INFO: run_lock, data_lock 00079 see MASTER_INFO 00080 00081 Order of acquisition: if you want to have LOCK_active_mi and a run_lock, you 00082 must acquire LOCK_active_mi first. 00083 00084 In MYSQL_BIN_LOG: LOCK_log, LOCK_index of the binlog and the relay log 00085 LOCK_log: when you write to it. LOCK_index: when you create/delete a binlog 00086 (so that you have to update the .index file). 00087 */ 00088 00089 extern ulong master_retry_count; 00090 extern MY_BITMAP slave_error_mask; 00091 extern bool use_slave_mask; 00092 extern char* slave_load_tmpdir; 00093 extern my_string master_info_file,relay_log_info_file; 00094 extern my_string opt_relay_logname, opt_relaylog_index_name; 00095 extern my_bool opt_skip_slave_start, opt_reckless_slave; 00096 extern my_bool opt_log_slave_updates; 00097 extern ulonglong relay_log_space_limit; 00098 struct st_master_info; 00099 00100 /* 00101 3 possible values for MASTER_INFO::slave_running and 00102 RELAY_LOG_INFO::slave_running. 00103 The values 0,1,2 are very important: to keep the diff small, I didn't 00104 substitute places where we use 0/1 with the newly defined symbols. So don't change 00105 these values. 00106 The same way, code is assuming that in RELAY_LOG_INFO we use only values 00107 0/1. 00108 I started with using an enum, but 00109 enum_variable=1; is not legal so would have required many line changes. 00110 */ 00111 #define MYSQL_SLAVE_NOT_RUN 0 00112 #define MYSQL_SLAVE_RUN_NOT_CONNECT 1 00113 #define MYSQL_SLAVE_RUN_CONNECT 2 00114 00115 static Log_event* next_event(RELAY_LOG_INFO* rli); 00116 00117 /***************************************************************************** 00118 00119 Replication IO Thread 00120 00121 st_master_info contains: 00122 - information about how to connect to a master 00123 - current master log name 00124 - current master log offset 00125 - misc control variables 00126 00127 st_master_info is initialized once from the master.info file if such 00128 exists. Otherwise, data members corresponding to master.info fields 00129 are initialized with defaults specified by master-* options. The 00130 initialization is done through init_master_info() call. 00131 00132 The format of master.info file: 00133 00134 log_name 00135 log_pos 00136 master_host 00137 master_user 00138 master_pass 00139 master_port 00140 master_connect_retry 00141 00142 To write out the contents of master.info file to disk ( needed every 00143 time we read and queue data from the master ), a call to 00144 flush_master_info() is required. 00145 00146 To clean up, call end_master_info() 00147 00148 *****************************************************************************/ 00149 00150 typedef struct st_master_info 00151 { 00152 /* the variables below are needed because we can change masters on the fly */ 00153 char master_log_name[FN_REFLEN]; 00154 char host[HOSTNAME_LENGTH+1]; 00155 char user[USERNAME_LENGTH+1]; 00156 char password[MAX_PASSWORD_LENGTH+1]; 00157 my_bool ssl; // enables use of SSL connection if true 00158 char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN]; 00159 char ssl_cipher[FN_REFLEN], ssl_key[FN_REFLEN]; 00160 00161 my_off_t master_log_pos; 00162 File fd; // we keep the file open, so we need to remember the file pointer 00163 IO_CACHE file; 00164 00165 pthread_mutex_t data_lock,run_lock; 00166 pthread_cond_t data_cond,start_cond,stop_cond; 00167 THD *io_thd; 00168 MYSQL* mysql; 00169 uint32 file_id; /* for 3.23 load data infile */ 00170 RELAY_LOG_INFO rli; 00171 uint port; 00172 uint connect_retry; 00173 #ifndef DBUG_OFF 00174 int events_till_disconnect; 00175 #endif 00176 bool inited; 00177 volatile bool abort_slave; 00178 volatile uint slave_running; 00179 volatile ulong slave_run_id; 00180 /* 00181 The difference in seconds between the clock of the master and the clock of 00182 the slave (second - first). It must be signed as it may be <0 or >0. 00183 clock_diff_with_master is computed when the I/O thread starts; for this the 00184 I/O thread does a SELECT UNIX_TIMESTAMP() on the master. 00185 "how late the slave is compared to the master" is computed like this: 00186 clock_of_slave - last_timestamp_executed_by_SQL_thread - clock_diff_with_master 00187 00188 */ 00189 long clock_diff_with_master; 00190 00191 st_master_info() 00192 :ssl(0), fd(-1), io_thd(0), inited(0), 00193 abort_slave(0),slave_running(0), slave_run_id(0) 00194 { 00195 host[0] = 0; user[0] = 0; password[0] = 0; 00196 ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0; 00197 ssl_cipher[0]= 0; ssl_key[0]= 0; 00198 00199 bzero((char*) &file, sizeof(file)); 00200 pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST); 00201 pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST); 00202 pthread_cond_init(&data_cond, NULL); 00203 pthread_cond_init(&start_cond, NULL); 00204 pthread_cond_init(&stop_cond, NULL); 00205 } 00206 00207 ~st_master_info() 00208 { 00209 pthread_mutex_destroy(&run_lock); 00210 pthread_mutex_destroy(&data_lock); 00211 pthread_cond_destroy(&data_cond); 00212 pthread_cond_destroy(&start_cond); 00213 pthread_cond_destroy(&stop_cond); 00214 } 00215 00216 } MASTER_INFO; 00217 00218 00219 int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len); 00220 00221 #define RPL_LOG_NAME (rli->group_master_log_name[0] ? rli->group_master_log_name :\ 00222 "FIRST") 00223 #define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\ 00224 "FIRST") 00225 00226 /* 00227 If the following is set, if first gives an error, second will be 00228 tried. Otherwise, if first fails, we fail. 00229 */ 00230 #define SLAVE_FORCE_ALL 4 00231 00232 int init_slave(); 00233 void init_slave_skip_errors(const char* arg); 00234 int flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache); 00235 bool flush_relay_log_info(RELAY_LOG_INFO* rli); 00236 int register_slave_on_master(MYSQL* mysql); 00237 int terminate_slave_threads(MASTER_INFO* mi, int thread_mask, 00238 bool skip_lock = 0); 00239 int terminate_slave_thread(THD* thd, pthread_mutex_t* term_mutex, 00240 pthread_mutex_t* cond_lock, 00241 pthread_cond_t* term_cond, 00242 volatile uint* slave_running); 00243 int start_slave_threads(bool need_slave_mutex, bool wait_for_start, 00244 MASTER_INFO* mi, const char* master_info_fname, 00245 const char* slave_info_fname, int thread_mask); 00246 /* 00247 cond_lock is usually same as start_lock. It is needed for the case when 00248 start_lock is 0 which happens if start_slave_thread() is called already 00249 inside the start_lock section, but at the same time we want a 00250 pthread_cond_wait() on start_cond,start_lock 00251 */ 00252 int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock, 00253 pthread_mutex_t *cond_lock, 00254 pthread_cond_t* start_cond, 00255 volatile uint *slave_running, 00256 volatile ulong *slave_run_id, 00257 MASTER_INFO* mi, 00258 bool high_priority); 00259 00260 /* If fd is -1, dump to NET */ 00261 int mysql_table_dump(THD* thd, const char* db, 00262 const char* tbl_name, int fd = -1); 00263 00264 /* retrieve table from master and copy to slave*/ 00265 int fetch_master_table(THD* thd, const char* db_name, const char* table_name, 00266 MASTER_INFO* mi, MYSQL* mysql, bool overwrite); 00267 00268 bool show_master_info(THD* thd, MASTER_INFO* mi); 00269 bool show_binlog_info(THD* thd); 00270 00271 const char *print_slave_db_safe(const char *db); 00272 int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code); 00273 void skip_load_data_infile(NET* net); 00274 void slave_print_msg(enum loglevel level, RELAY_LOG_INFO* rli, 00275 int err_code, const char* msg, ...); 00276 00277 void end_slave(); /* clean up */ 00278 void init_master_info_with_options(MASTER_INFO* mi); 00279 void clear_until_condition(RELAY_LOG_INFO* rli); 00280 void clear_slave_error(RELAY_LOG_INFO* rli); 00281 int init_master_info(MASTER_INFO* mi, const char* master_info_fname, 00282 const char* slave_info_fname, 00283 bool abort_if_no_master_info_file, 00284 int thread_mask); 00285 void end_master_info(MASTER_INFO* mi); 00286 void end_relay_log_info(RELAY_LOG_INFO* rli); 00287 void lock_slave_threads(MASTER_INFO* mi); 00288 void unlock_slave_threads(MASTER_INFO* mi); 00289 void init_thread_mask(int* mask,MASTER_INFO* mi,bool inverse); 00290 int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos, 00291 bool need_data_lock, const char** errmsg, 00292 bool look_for_description_event); 00293 00294 int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset, 00295 const char** errmsg); 00296 void set_slave_thread_options(THD* thd); 00297 void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli); 00298 void rotate_relay_log(MASTER_INFO* mi); 00299 00300 pthread_handler_t handle_slave_io(void *arg); 00301 pthread_handler_t handle_slave_sql(void *arg); 00302 extern bool volatile abort_loop; 00303 extern MASTER_INFO main_mi, *active_mi; /* active_mi for multi-master */ 00304 extern LIST master_list; 00305 extern my_bool replicate_same_server_id; 00306 00307 extern int disconnect_slave_event_count, abort_slave_event_count ; 00308 00309 /* the master variables are defaults read from my.cnf or command line */ 00310 extern uint master_port, master_connect_retry, report_port; 00311 extern my_string master_user, master_password, master_host, 00312 master_info_file, relay_log_info_file, report_user, report_host, 00313 report_password; 00314 00315 extern my_bool master_ssl; 00316 extern my_string master_ssl_ca, master_ssl_capath, master_ssl_cert, 00317 master_ssl_cipher, master_ssl_key; 00318 00319 extern I_List<THD> threads; 00320 00321 #endif /* HAVE_REPLICATION */ 00322 00323 /* masks for start/stop operations on io and sql slave threads */ 00324 #define SLAVE_IO 1 00325 #define SLAVE_SQL 2 00326 00327 #endif 00328 00329
1.4.7

