~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/rpl_mi.cc

  • Committer: Monty Taylor
  • Date: 2008-10-30 19:42:06 UTC
  • mto: (520.4.38 devel)
  • mto: This revision was merged to the branch mainline in revision 572.
  • Revision ID: monty@inaugust.com-20081030194206-fzus6yqlw1ekru65
Removed handler from common_includes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2003 MySQL AB
 
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 as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
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.
 
11
 
 
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 */
 
15
 
 
16
#include <drizzled/server_includes.h>
 
17
#include <drizzled/rpl_mi.h>
 
18
#include <drizzled/gettext.h>
 
19
#include <drizzled/slave.h>
 
20
#include <drizzled/data_home.h>
 
21
 
 
22
#include <iostream>
 
23
#include <fstream>
 
24
 
 
25
using namespace std;
 
26
 
 
27
#define DEFAULT_CONNECT_RETRY 60
 
28
 
 
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);
 
34
 
 
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)
 
40
{
 
41
  host[0] = 0; user[0] = 0; password[0] = 0;
 
42
  io_session= NULL;
 
43
  port= DRIZZLE_PORT;
 
44
 
 
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);
 
50
}
 
51
 
 
52
Master_info::~Master_info()
 
53
{
 
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);
 
59
}
 
60
 
 
61
bool Master_info::setPassword(const char *pword)
 
62
{
 
63
  password.assign(pword);
 
64
 
 
65
  return true;
 
66
}
 
67
 
 
68
const char *Master_info::getPassword()
 
69
{
 
70
  return password.c_str();
 
71
}
 
72
 
 
73
bool Master_info::setUsername(const char *username)
 
74
{
 
75
  user.assign(username);
 
76
 
 
77
  return true;
 
78
}
 
79
 
 
80
const char *Master_info::getUsername()
 
81
{
 
82
  return user.c_str();
 
83
}
 
84
 
 
85
bool Master_info::setHost(const char *hostname, uint16_t new_port)
 
86
{
 
87
  host.assign(hostname);
 
88
  port= new_port;
 
89
 
 
90
  return true;
 
91
}
 
92
 
 
93
const char *Master_info::getHostname()
 
94
{
 
95
  return host.c_str();
 
96
}
 
97
 
 
98
uint16_t Master_info::getPort()
 
99
{
 
100
  return port;
 
101
}
 
102
 
 
103
off_t Master_info::getLogPosition()
 
104
{
 
105
  return log_pos;
 
106
}
 
107
 
 
108
bool Master_info::setLogPosition(off_t position)
 
109
{
 
110
  log_pos= position;
 
111
 
 
112
  return true;
 
113
}
 
114
 
 
115
void Master_info::incrementLogPosition(off_t position)
 
116
{
 
117
  log_pos+= position;
 
118
}
 
119
 
 
120
const char *Master_info::getLogName()
 
121
{
 
122
  return log_name.c_str();
 
123
}
 
124
 
 
125
bool Master_info::setLogName(const char *name)
 
126
{
 
127
 log_name.assign(name);
 
128
 
 
129
  return true;
 
130
}
 
131
 
 
132
uint32_t Master_info::getConnectionRetry()
 
133
{
 
134
  return connect_retry;
 
135
}
 
136
 
 
137
bool Master_info::setConnectionRetry(uint32_t retry)
 
138
{
 
139
  connect_retry= retry;
 
140
 
 
141
  return true;
 
142
}
 
143
 
 
144
 
 
145
void Master_info::reset()
 
146
{
 
147
  log_name.clear();
 
148
  log_pos= 0; 
 
149
}
 
150
 
 
151
 
 
152
int Master_info::init_master_info(const char* master_info_fname,
 
153
                                  const char* slave_info_fname,
 
154
                                  int thread_mask)
 
155
{
 
156
  int error;
 
157
 
 
158
  if (inited)
 
159
  {
 
160
    /*
 
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
 
165
      relay log.
 
166
 
 
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.
 
171
    */
 
172
    if (thread_mask & SLAVE_SQL)
 
173
    {
 
174
      my_b_seek(rli.cur_log, (my_off_t) 0);
 
175
    }
 
176
    return(0);
 
177
  }
 
178
 
 
179
  drizzle= 0;
 
180
  file_id= 1;
 
181
  {
 
182
    char fname[FN_REFLEN+128];
 
183
 
 
184
    fn_format(fname, master_info_fname, mysql_data_home, "", 4+32);
 
185
    info_filename.assign(fname);
 
186
  }
 
187
 
 
188
  /*
 
189
    We need a mutex while we are changing master info parameters to
 
190
    keep other threads from reading bogus info
 
191
  */
 
192
 
 
193
  pthread_mutex_lock(&data_lock);
 
194
 
 
195
  /* does master.info exist ? */
 
196
 
 
197
  if (access(info_filename.c_str(), F_OK))
 
198
  {
 
199
    drizzle::MasterList_Record *record;
 
200
 
 
201
    reset();
 
202
 
 
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);
 
212
 
 
213
    fstream output(info_filename.c_str(), ios::out | ios::trunc | ios::binary);
 
214
    if (!list.SerializeToOstream(&output)) 
 
215
    { 
 
216
      assert(0);
 
217
      return -1;
 
218
    }
 
219
  }
 
220
  else // file exists
 
221
  {
 
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)) 
 
225
    {
 
226
      assert(0);
 
227
      return -1;
 
228
    }
 
229
 
 
230
    /* We do not support multi-master just yet */
 
231
    assert(list.record_size() == 1);
 
232
    const drizzle::MasterList_Record record= list.record(0);
 
233
 
 
234
    if (record.has_username())
 
235
      user= record.username();
 
236
    if (record.has_password())
 
237
      password= record.password();
 
238
    if (record.has_port())
 
239
      port= record.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();
 
246
  }
 
247
 
 
248
  rli.mi = this;
 
249
  if (init_relay_log_info(&rli, slave_info_fname))
 
250
    goto err;
 
251
 
 
252
  inited= 1;
 
253
  if ((error= test(flush())))
 
254
    sql_print_error(_("Failed to flush master info file"));
 
255
  pthread_mutex_unlock(&data_lock);
 
256
  return(error);
 
257
 
 
258
err:
 
259
  pthread_mutex_unlock(&data_lock);
 
260
  return 1;
 
261
}
 
262
 
 
263
 
 
264
/*
 
265
  RETURN
 
266
     2 - flush relay log failed
 
267
     1 - flush master info failed
 
268
     0 - all ok
 
269
*/
 
270
int Master_info::flush()
 
271
{
 
272
  /*
 
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.
 
280
 
 
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.
 
283
  */
 
284
 
 
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);
 
289
 
 
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);
 
297
 
 
298
  fstream output(info_filename.c_str(), ios::out | ios::trunc | ios::binary);
 
299
  if (!list.SerializeToOstream(&output)) 
 
300
  { 
 
301
    assert(0);
 
302
    return 1;
 
303
  }
 
304
 
 
305
  return 0;
 
306
}
 
307
 
 
308
 
 
309
void Master_info::end_master_info()
 
310
{
 
311
  if (!inited)
 
312
    return;
 
313
  end_relay_log_info(&rli);
 
314
  inited = 0;
 
315
 
 
316
  return;
 
317
}