50
52
pthread_cond_destroy(&stop_cond);
54
void init_master_log_pos(Master_info* mi)
56
mi->master_log_name[0] = 0;
57
mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number
59
always request heartbeat unless master_heartbeat_period is set
60
explicitly zero. Here is the default value for heartbeat period
61
if CHANGE MASTER did not specify it. (no data loss in conversion
62
as hb period has a max)
64
mi->heartbeat_period= (float) cmin((double)SLAVE_MAX_HEARTBEAT_PERIOD,
65
(slave_net_timeout/2.0));
66
assert(mi->heartbeat_period > (float) 0.001
67
|| mi->heartbeat_period == 0);
73
LINES_IN_MASTER_INFO_WITH_SSL= 14,
75
/* 5.1.16 added value of master_ssl_verify_server_cert */
76
LINE_FOR_MASTER_SSL_VERIFY_SERVER_CERT= 15,
78
/* 6.0 added value of master_heartbeat_period */
79
LINE_FOR_MASTER_HEARTBEAT_PERIOD= 16,
81
/* Number of lines currently used when saving master info file */
82
LINES_IN_MASTER_INFO= LINE_FOR_MASTER_HEARTBEAT_PERIOD
86
int init_master_info(Master_info* mi, const char* master_info_fname,
87
const char* slave_info_fname,
88
bool abort_if_no_master_info_file,
92
char fname[FN_REFLEN+128];
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,
97
155
We have to reset read position of relay-log-bin as we may have
108
166
if (thread_mask & SLAVE_SQL)
110
my_b_seek(mi->rli.cur_log, (my_off_t) 0);
168
my_b_seek(rli.cur_log, (my_off_t) 0);
117
fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
176
char fname[FN_REFLEN+128];
178
fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
179
info_filename.assign(fname);
120
183
We need a mutex while we are changing master info parameters to
121
184
keep other threads from reading bogus info
124
pthread_mutex_lock(&mi->data_lock);
187
pthread_mutex_lock(&data_lock);
127
189
/* does master.info exist ? */
129
if (access(fname,F_OK))
191
if (access(info_filename.c_str(), F_OK))
131
if (abort_if_no_master_info_file)
133
pthread_mutex_unlock(&mi->data_lock);
137
if someone removed the file from underneath our feet, just close
138
the old descriptor and re-create the old file
141
my_close(fd, MYF(MY_WME));
142
if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
144
sql_print_error(_("Failed to create a new master info file (file '%s', errno %d)"), fname, my_errno);
147
if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0,
150
sql_print_error(_("Failed to create a cache on master info file (file '%s')"), fname);
155
init_master_log_pos(mi);
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))
158
214
else // file exists
161
reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0);
164
if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 )
166
sql_print_error(_("Failed to open the existing master info file (file '%s', errno %d)"), fname, my_errno);
169
if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,
172
sql_print_error(_("Failed to create a cache on master info file (file '%s')"), fname);
178
int port, connect_retry, master_log_pos, lines;
179
float master_heartbeat_period= 0.0;
180
char *first_non_digit;
183
Starting from 4.1.x master.info has new format. Now its
184
first line contains number of lines in file. By reading this
185
number we will be always distinguish to which version our
186
master.info corresponds to. We can't simply count lines in
187
file since versions before 4.1.x could generate files with more
189
If first line doesn't contain a number or contain number less than
190
LINES_IN_MASTER_INFO_WITH_SSL then such file is treated like file
191
from pre 4.1.1 version.
192
There is no ambiguity when reading an old master.info, as before
193
4.1.1, the first line contained the binlog's name, which is either
194
empty or has an extension (contains a '.'), so can't be confused
197
So we're just reading first line and trying to figure which version
202
The first row is temporarily stored in mi->master_log_name,
203
if it is line count and not binlog name (new format) it will be
204
overwritten by the second row later.
206
if (init_strvar_from_file(mi->master_log_name,
207
sizeof(mi->master_log_name), &mi->file,
211
lines= strtoul(mi->master_log_name, &first_non_digit, 10);
213
if (mi->master_log_name[0]!='\0' &&
214
*first_non_digit=='\0' && lines >= LINES_IN_MASTER_INFO_WITH_SSL)
216
/* Seems to be new format => read master log name from next line */
217
if (init_strvar_from_file(mi->master_log_name,
218
sizeof(mi->master_log_name), &mi->file, ""))
224
if (init_intvar_from_file(&master_log_pos, &mi->file, 4) ||
225
init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file, 0) ||
226
init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file, "test") ||
227
init_strvar_from_file(mi->password, SCRAMBLED_PASSWORD_CHAR_LENGTH+1,
229
init_intvar_from_file(&port, &mi->file, DRIZZLE_PORT) ||
230
init_intvar_from_file(&connect_retry, &mi->file, DEFAULT_CONNECT_RETRY))
234
If file has ssl part use it even if we have server without
235
SSL support. But these option will be ignored later when
236
slave will try connect to master, so in this case warning
239
if (lines >= LINES_IN_MASTER_INFO_WITH_SSL)
242
Starting from 6.0 master_heartbeat_period might be
245
if (lines >= LINE_FOR_MASTER_HEARTBEAT_PERIOD &&
246
init_floatvar_from_file(&master_heartbeat_period, &mi->file, 0.0))
251
This has to be handled here as init_intvar_from_file can't handle
254
mi->master_log_pos= (my_off_t) master_log_pos;
255
mi->port= (uint) port;
256
mi->connect_retry= (uint) connect_retry;
257
mi->heartbeat_period= master_heartbeat_period;
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();
261
if (init_relay_log_info(&mi->rli, slave_info_fname))
243
if (init_relay_log_info(&rli, slave_info_fname))
265
// now change cache READ -> WRITE - must do this before flush_master_info
266
reinit_io_cache(&mi->file, WRITE_CACHE, 0L, 0, 1);
267
if ((error=test(flush_master_info(mi, 1))))
247
if ((error= test(flush())))
268
248
sql_print_error(_("Failed to flush master info file"));
269
pthread_mutex_unlock(&mi->data_lock);
249
pthread_mutex_unlock(&data_lock);
273
sql_print_error(_("Error reading master configuration"));
278
my_close(fd, MYF(0));
279
end_io_cache(&mi->file);
282
pthread_mutex_unlock(&mi->data_lock);
253
pthread_mutex_unlock(&data_lock);
307
275
When we come to this place in code, relay log may or not be initialized;
308
276
the caller is responsible for setting 'flush_relay_log_cache' accordingly.
310
if (flush_relay_log_cache &&
311
flush_io_cache(mi->rli.relay_log.get_log_file()))
315
We flushed the relay log BEFORE the master.info file, because if we crash
316
now, we will get a duplicate event in the relay log at restart. If we
317
flushed in the other order, we would get a hole in the relay log.
318
And duplicate is better than hole (with a duplicate, in later versions we
319
can add detection and scrap one event; with a hole there's nothing we can
324
In certain cases this code may create master.info files that seems
325
corrupted, because of extra lines filled with garbage in the end
326
file (this happens if new contents take less space than previous
327
contents of file). But because of number of lines in the first line
328
of file we don't care about this garbage.
330
char heartbeat_buf[sizeof(mi->heartbeat_period) * 4]; // buffer to suffice always
331
sprintf(heartbeat_buf, "%.3f", mi->heartbeat_period);
334
"%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n",
335
LINES_IN_MASTER_INFO,
336
mi->master_log_name, llstr(mi->master_log_pos, lbuf),
338
mi->password, mi->port, mi->connect_retry,
340
return(-flush_io_cache(file));
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))
344
void end_master_info(Master_info* mi)
303
void Master_info::end_master_info()
348
end_relay_log_info(&mi->rli);
351
end_io_cache(&mi->file);
352
(void)my_close(mi->fd, MYF(MY_WME));
307
end_relay_log_info(&rli);