1
/* Copyright (C) 2000-2003 MySQL AB
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include <drizzled/server_includes.h>
21
#define DEFAULT_CONNECT_RETRY 60
23
// Defined in slave.cc
24
int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
25
int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
26
const char *default_val);
27
int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val);
29
Master_info::Master_info()
30
:Slave_reporting_capability("I/O"),
31
connect_retry(DEFAULT_CONNECT_RETRY), heartbeat_period(0),
32
received_heartbeats(0), inited(0),
33
abort_slave(0), slave_running(0), slave_run_id(0)
35
host[0] = 0; user[0] = 0; password[0] = 0;
39
pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
40
pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
41
pthread_cond_init(&data_cond, NULL);
42
pthread_cond_init(&start_cond, NULL);
43
pthread_cond_init(&stop_cond, NULL);
46
Master_info::~Master_info()
48
pthread_mutex_destroy(&run_lock);
49
pthread_mutex_destroy(&data_lock);
50
pthread_cond_destroy(&data_cond);
51
pthread_cond_destroy(&start_cond);
52
pthread_cond_destroy(&stop_cond);
55
bool Master_info::setPassword(const char *pword)
57
password.assign(pword);
62
const char *Master_info::getPassword()
64
return password.c_str();
67
bool Master_info::setUsername(const char *username)
69
user.assign(username);
74
const char *Master_info::getUsername()
79
bool Master_info::setHost(const char *hostname, uint16_t new_port)
81
host.assign(hostname);
87
const char *Master_info::getHostname()
92
uint16_t Master_info::getPort()
97
off_t Master_info::getLogPosition()
102
bool Master_info::setLogPosition(off_t position)
109
void Master_info::incrementLogPosition(off_t position)
114
const char *Master_info::getLogName()
116
return log_name.c_str();
119
bool Master_info::setLogName(const char *name)
121
log_name.assign(name);
126
uint32_t Master_info::getConnectionRetry()
128
return connect_retry;
131
bool Master_info::setConnectionRetry(uint32_t retry)
133
connect_retry= retry;
139
void Master_info::reset()
146
int Master_info::init_master_info(const char* master_info_fname,
147
const char* slave_info_fname,
155
We have to reset read position of relay-log-bin as we may have
156
already been reading from 'hotlog' when the slave was stopped
157
last time. If this case pos_in_file would be set and we would
158
get a crash when trying to read the signature for the binary
161
We only rewind the read position if we are starting the SQL
162
thread. The handle_slave_sql thread assumes that the read
163
position is at the beginning of the file, and will read the
164
"signature" and then fast-forward to the last position read.
166
if (thread_mask & SLAVE_SQL)
168
my_b_seek(rli.cur_log, (my_off_t) 0);
176
char fname[FN_REFLEN+128];
178
fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
179
info_filename.assign(fname);
183
We need a mutex while we are changing master info parameters to
184
keep other threads from reading bogus info
187
pthread_mutex_lock(&data_lock);
189
/* does master.info exist ? */
191
if (access(info_filename.c_str(), F_OK))
193
drizzle::MasterList_Record *record;
197
/* Write new Master info file here (from info_filename) */
198
record= list.add_record();
199
record->set_hostname(host);
200
record->set_username(user);
201
record->set_password(password);
202
record->set_port(port);
203
record->set_connect_retry(connect_retry);
204
record->set_log_name(log_name);
205
record->set_log_position(log_pos);
207
fstream output(info_filename.c_str(), ios::out | ios::trunc | ios::binary);
208
if (!list.SerializeToOstream(&output))
216
/* Read Master info file here (from info_filename) */
217
fstream input(info_filename.c_str(), ios::in | ios::binary);
218
if (!list.ParseFromIstream(&input))
224
/* We do not support multi-master just yet */
225
assert(list.record_size() == 1);
226
const drizzle::MasterList_Record record= list.record(0);
228
if (record.has_username())
229
user= record.username();
230
if (record.has_password())
231
password= record.password();
232
if (record.has_port())
234
if (record.has_connect_retry())
235
connect_retry= record.connect_retry();
236
if (record.has_log_name())
237
log_name= record.log_name();
238
if (record.has_log_position())
239
log_pos= record.log_position();
243
if (init_relay_log_info(&rli, slave_info_fname))
247
if ((error= test(flush())))
248
sql_print_error(_("Failed to flush master info file"));
249
pthread_mutex_unlock(&data_lock);
253
pthread_mutex_unlock(&data_lock);
260
2 - flush relay log failed
261
1 - flush master info failed
264
int Master_info::flush()
267
Flush the relay log to disk. If we don't do it, then the relay log while
268
have some part (its last kilobytes) in memory only, so if the slave server
269
dies now, with, say, from master's position 100 to 150 in memory only (not
270
on disk), and with position 150 in master.info, then when the slave
271
restarts, the I/O thread will fetch binlogs from 150, so in the relay log
272
we will have "[0, 100] U [150, infinity[" and nobody will notice it, so the
273
SQL thread will jump from 100 to 150, and replication will silently break.
275
When we come to this place in code, relay log may or not be initialized;
276
the caller is responsible for setting 'flush_relay_log_cache' accordingly.
279
/* Write Master info file here (from info_filename) */
280
assert(info_filename.length());
281
assert(list.record_size() == 1);
282
drizzle::MasterList_Record *record= list.mutable_record(0);
284
record->set_hostname(host);
285
record->set_username(user);
286
record->set_password(password);
287
record->set_port(port);
288
record->set_connect_retry(connect_retry);
289
record->set_log_name(log_name);
290
record->set_log_position(log_pos);
292
fstream output(info_filename.c_str(), ios::out | ios::trunc | ios::binary);
293
if (!list.SerializeToOstream(&output))
303
void Master_info::end_master_info()
307
end_relay_log_info(&rli);