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>
17
#include <drizzled/replication/mi.h>
18
#include <drizzled/gettext.h>
19
#include <drizzled/slave.h>
20
#include <drizzled/data_home.h>
27
#define DEFAULT_CONNECT_RETRY 60
29
// Defined in slave.cc
30
int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
31
int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
32
const char *default_val);
33
int init_floatvar_from_file(float* var, IO_CACHE* f, float default_val);
35
Master_info::Master_info()
36
:Slave_reporting_capability("I/O"),
37
connect_retry(DEFAULT_CONNECT_RETRY), heartbeat_period(0),
38
received_heartbeats(0), inited(0),
39
abort_slave(0), slave_running(0), slave_run_id(0)
41
host[0] = 0; user[0] = 0; password[0] = 0;
45
pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
46
pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
47
pthread_cond_init(&data_cond, NULL);
48
pthread_cond_init(&start_cond, NULL);
49
pthread_cond_init(&stop_cond, NULL);
52
Master_info::~Master_info()
54
pthread_mutex_destroy(&run_lock);
55
pthread_mutex_destroy(&data_lock);
56
pthread_cond_destroy(&data_cond);
57
pthread_cond_destroy(&start_cond);
58
pthread_cond_destroy(&stop_cond);
61
bool Master_info::setPassword(const char *pword)
63
password.assign(pword);
68
const char *Master_info::getPassword()
70
return password.c_str();
73
bool Master_info::setUsername(const char *username)
75
user.assign(username);
80
const char *Master_info::getUsername()
85
bool Master_info::setHost(const char *hostname, uint16_t new_port)
87
host.assign(hostname);
93
const char *Master_info::getHostname()
98
uint16_t Master_info::getPort()
103
off_t Master_info::getLogPosition()
108
bool Master_info::setLogPosition(off_t position)
115
void Master_info::incrementLogPosition(off_t position)
120
const char *Master_info::getLogName()
122
return log_name.c_str();
125
bool Master_info::setLogName(const char *name)
127
log_name.assign(name);
132
uint32_t Master_info::getConnectionRetry()
134
return connect_retry;
137
bool Master_info::setConnectionRetry(uint32_t retry)
139
connect_retry= retry;
145
void Master_info::reset()
152
int Master_info::init_master_info(const char* master_info_fname,
153
const char* slave_info_fname,
161
We have to reset read position of relay-log-bin as we may have
162
already been reading from 'hotlog' when the slave was stopped
163
last time. If this case pos_in_file would be set and we would
164
get a crash when trying to read the signature for the binary
167
We only rewind the read position if we are starting the SQL
168
thread. The handle_slave_sql thread assumes that the read
169
position is at the beginning of the file, and will read the
170
"signature" and then fast-forward to the last position read.
172
if (thread_mask & SLAVE_SQL)
174
my_b_seek(rli.cur_log, (my_off_t) 0);
182
char fname[FN_REFLEN+128];
184
fn_format(fname, master_info_fname, drizzle_data_home, "", 4+32);
185
info_filename.assign(fname);
189
We need a mutex while we are changing master info parameters to
190
keep other threads from reading bogus info
193
pthread_mutex_lock(&data_lock);
195
/* does master.info exist ? */
197
if (access(info_filename.c_str(), F_OK))
199
drizzle::MasterList_Record *record;
203
/* Write new Master info file here (from info_filename) */
204
record= list.add_record();
205
record->set_hostname(host);
206
record->set_username(user);
207
record->set_password(password);
208
record->set_port(port);
209
record->set_connect_retry(connect_retry);
210
record->set_log_name(log_name);
211
record->set_log_position(log_pos);
213
fstream output(info_filename.c_str(), ios::out | ios::trunc | ios::binary);
214
if (!list.SerializeToOstream(&output))
222
/* Read Master info file here (from info_filename) */
223
fstream input(info_filename.c_str(), ios::in | ios::binary);
224
if (!list.ParseFromIstream(&input))
230
/* We do not support multi-master just yet */
231
assert(list.record_size() == 1);
232
const drizzle::MasterList_Record record= list.record(0);
234
if (record.has_username())
235
user= record.username();
236
if (record.has_password())
237
password= record.password();
238
if (record.has_port())
240
if (record.has_connect_retry())
241
connect_retry= record.connect_retry();
242
if (record.has_log_name())
243
log_name= record.log_name();
244
if (record.has_log_position())
245
log_pos= record.log_position();
249
if (init_relay_log_info(&rli, slave_info_fname))
253
if ((error= test(flush())))
254
errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to flush master info file"));
255
pthread_mutex_unlock(&data_lock);
259
pthread_mutex_unlock(&data_lock);
266
2 - flush relay log failed
267
1 - flush master info failed
270
int Master_info::flush()
273
Flush the relay log to disk. If we don't do it, then the relay log while
274
have some part (its last kilobytes) in memory only, so if the slave server
275
dies now, with, say, from master's position 100 to 150 in memory only (not
276
on disk), and with position 150 in master.info, then when the slave
277
restarts, the I/O thread will fetch binlogs from 150, so in the relay log
278
we will have "[0, 100] U [150, infinity[" and nobody will notice it, so the
279
SQL thread will jump from 100 to 150, and replication will silently break.
281
When we come to this place in code, relay log may or not be initialized;
282
the caller is responsible for setting 'flush_relay_log_cache' accordingly.
285
/* Write Master info file here (from info_filename) */
286
assert(info_filename.length());
287
assert(list.record_size() == 1);
288
drizzle::MasterList_Record *record= list.mutable_record(0);
290
record->set_hostname(host);
291
record->set_username(user);
292
record->set_password(password);
293
record->set_port(port);
294
record->set_connect_retry(connect_retry);
295
record->set_log_name(log_name);
296
record->set_log_position(log_pos);
298
fstream output(info_filename.c_str(), ios::out | ios::trunc | ios::binary);
299
if (!list.SerializeToOstream(&output))
309
void Master_info::end_master_info()
313
end_relay_log_info(&rli);