~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/rpl_rli.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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 "mysql_priv.h"
 
17
 
 
18
#include "rpl_mi.h"
 
19
#include "rpl_rli.h"
 
20
#include <my_dir.h>    // For MY_STAT
 
21
#include "sql_repl.h"  // For check_binlog_magic
 
22
#include "rpl_utility.h"
 
23
 
 
24
static int count_relay_log_space(Relay_log_info* rli);
 
25
 
 
26
// Defined in slave.cc
 
27
int init_intvar_from_file(int* var, IO_CACHE* f, int default_val);
 
28
int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
 
29
                          const char *default_val);
 
30
 
 
31
 
 
32
Relay_log_info::Relay_log_info()
 
33
  :Slave_reporting_capability("SQL"),
 
34
   no_storage(FALSE), replicate_same_server_id(::replicate_same_server_id),
 
35
   info_fd(-1), cur_log_fd(-1), save_temporary_tables(0),
 
36
#if HAVE_purify
 
37
   is_fake(FALSE),
 
38
#endif
 
39
   cur_log_old_open_count(0), group_relay_log_pos(0), event_relay_log_pos(0),
 
40
   group_master_log_pos(0), log_space_total(0), ignore_log_space_limit(0),
 
41
   last_master_timestamp(0), slave_skip_counter(0),
 
42
   abort_pos_wait(0), slave_run_id(0), sql_thd(0),
 
43
   inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
 
44
   until_log_pos(0), retried_trans(0),
 
45
   tables_to_lock(0), tables_to_lock_count(0),
 
46
   last_event_start_time(0), m_flags(0)
 
47
{
 
48
  DBUG_ENTER("Relay_log_info::Relay_log_info");
 
49
 
 
50
  group_relay_log_name[0]= event_relay_log_name[0]=
 
51
    group_master_log_name[0]= 0;
 
52
  until_log_name[0]= ign_master_log_name_end[0]= 0;
 
53
  bzero((char*) &info_file, sizeof(info_file));
 
54
  bzero((char*) &cache_buf, sizeof(cache_buf));
 
55
  cached_charset_invalidate();
 
56
  pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST);
 
57
  pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST);
 
58
  pthread_mutex_init(&log_space_lock, MY_MUTEX_INIT_FAST);
 
59
  pthread_cond_init(&data_cond, NULL);
 
60
  pthread_cond_init(&start_cond, NULL);
 
61
  pthread_cond_init(&stop_cond, NULL);
 
62
  pthread_cond_init(&log_space_cond, NULL);
 
63
  relay_log.init_pthread_objects();
 
64
  DBUG_VOID_RETURN;
 
65
}
 
66
 
 
67
 
 
68
Relay_log_info::~Relay_log_info()
 
69
{
 
70
  DBUG_ENTER("Relay_log_info::~Relay_log_info");
 
71
 
 
72
  pthread_mutex_destroy(&run_lock);
 
73
  pthread_mutex_destroy(&data_lock);
 
74
  pthread_mutex_destroy(&log_space_lock);
 
75
  pthread_cond_destroy(&data_cond);
 
76
  pthread_cond_destroy(&start_cond);
 
77
  pthread_cond_destroy(&stop_cond);
 
78
  pthread_cond_destroy(&log_space_cond);
 
79
  relay_log.cleanup();
 
80
  DBUG_VOID_RETURN;
 
81
}
 
82
 
 
83
 
 
84
int init_relay_log_info(Relay_log_info* rli,
 
85
                        const char* info_fname)
 
86
{
 
87
  char fname[FN_REFLEN+128];
 
88
  int info_fd;
 
89
  const char* msg = 0;
 
90
  int error = 0;
 
91
  DBUG_ENTER("init_relay_log_info");
 
92
  DBUG_ASSERT(!rli->no_storage);         // Don't init if there is no storage
 
93
 
 
94
  if (rli->inited)                       // Set if this function called
 
95
    DBUG_RETURN(0);
 
96
  fn_format(fname, info_fname, mysql_data_home, "", 4+32);
 
97
  pthread_mutex_lock(&rli->data_lock);
 
98
  info_fd = rli->info_fd;
 
99
  rli->cur_log_fd = -1;
 
100
  rli->slave_skip_counter=0;
 
101
  rli->abort_pos_wait=0;
 
102
  rli->log_space_limit= relay_log_space_limit;
 
103
  rli->log_space_total= 0;
 
104
  rli->tables_to_lock= 0;
 
105
  rli->tables_to_lock_count= 0;
 
106
 
 
107
  /*
 
108
    The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
 
109
    Note that the I/O thread flushes it to disk after writing every
 
110
    event, in flush_master_info(mi, 1).
 
111
  */
 
112
 
 
113
  /*
 
114
    For the maximum log size, we choose max_relay_log_size if it is
 
115
    non-zero, max_binlog_size otherwise. If later the user does SET
 
116
    GLOBAL on one of these variables, fix_max_binlog_size and
 
117
    fix_max_relay_log_size will reconsider the choice (for example
 
118
    if the user changes max_relay_log_size to zero, we have to
 
119
    switch to using max_binlog_size for the relay log) and update
 
120
    rli->relay_log.max_size (and mysql_bin_log.max_size).
 
121
  */
 
122
  {
 
123
    char buf[FN_REFLEN];
 
124
    const char *ln;
 
125
    static bool name_warning_sent= 0;
 
126
    ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
 
127
                                     1, buf);
 
128
    /* We send the warning only at startup, not after every RESET SLAVE */
 
129
    if (!opt_relay_logname && !opt_relaylog_index_name && !name_warning_sent)
 
130
    {
 
131
      /*
 
132
        User didn't give us info to name the relay log index file.
 
133
        Picking `hostname`-relay-bin.index like we do, causes replication to
 
134
        fail if this slave's hostname is changed later. So, we would like to
 
135
        instead require a name. But as we don't want to break many existing
 
136
        setups, we only give warning, not error.
 
137
      */
 
138
      sql_print_warning("Neither --relay-log nor --relay-log-index were used;"
 
139
                        " so replication "
 
140
                        "may break when this MySQL server acts as a "
 
141
                        "slave and has his hostname changed!! Please "
 
142
                        "use '--relay-log=%s' to avoid this problem.", ln);
 
143
      name_warning_sent= 1;
 
144
    }
 
145
    /*
 
146
      note, that if open() fails, we'll still have index file open
 
147
      but a destructor will take care of that
 
148
    */
 
149
    if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln) ||
 
150
        rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
 
151
                            (max_relay_log_size ? max_relay_log_size :
 
152
                            max_binlog_size), 1))
 
153
    {
 
154
      pthread_mutex_unlock(&rli->data_lock);
 
155
      sql_print_error("Failed in open_log() called from init_relay_log_info()");
 
156
      DBUG_RETURN(1);
 
157
    }
 
158
  }
 
159
 
 
160
  /* if file does not exist */
 
161
  if (access(fname,F_OK))
 
162
  {
 
163
    /*
 
164
      If someone removed the file from underneath our feet, just close
 
165
      the old descriptor and re-create the old file
 
166
    */
 
167
    if (info_fd >= 0)
 
168
      my_close(info_fd, MYF(MY_WME));
 
169
    if ((info_fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
 
170
    {
 
171
      sql_print_error("Failed to create a new relay log info file (\
 
172
file '%s', errno %d)", fname, my_errno);
 
173
      msg= current_thd->main_da.message();
 
174
      goto err;
 
175
    }
 
176
    if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0,
 
177
                      MYF(MY_WME)))
 
178
    {
 
179
      sql_print_error("Failed to create a cache on relay log info file '%s'",
 
180
                      fname);
 
181
      msg= current_thd->main_da.message();
 
182
      goto err;
 
183
    }
 
184
 
 
185
    /* Init relay log with first entry in the relay index file */
 
186
    if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */,
 
187
                           &msg, 0))
 
188
    {
 
189
      sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4)");
 
190
      goto err;
 
191
    }
 
192
    rli->group_master_log_name[0]= 0;
 
193
    rli->group_master_log_pos= 0;
 
194
    rli->info_fd= info_fd;
 
195
  }
 
196
  else // file exists
 
197
  {
 
198
    if (info_fd >= 0)
 
199
      reinit_io_cache(&rli->info_file, READ_CACHE, 0L,0,0);
 
200
    else
 
201
    {
 
202
      int error=0;
 
203
      if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0)
 
204
      {
 
205
        sql_print_error("\
 
206
Failed to open the existing relay log info file '%s' (errno %d)",
 
207
                        fname, my_errno);
 
208
        error= 1;
 
209
      }
 
210
      else if (init_io_cache(&rli->info_file, info_fd,
 
211
                             IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME)))
 
212
      {
 
213
        sql_print_error("Failed to create a cache on relay log info file '%s'",
 
214
                        fname);
 
215
        error= 1;
 
216
      }
 
217
      if (error)
 
218
      {
 
219
        if (info_fd >= 0)
 
220
          my_close(info_fd, MYF(0));
 
221
        rli->info_fd= -1;
 
222
        rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
 
223
        pthread_mutex_unlock(&rli->data_lock);
 
224
        DBUG_RETURN(1);
 
225
      }
 
226
    }
 
227
 
 
228
    rli->info_fd = info_fd;
 
229
    int relay_log_pos, master_log_pos;
 
230
    if (init_strvar_from_file(rli->group_relay_log_name,
 
231
                              sizeof(rli->group_relay_log_name),
 
232
                              &rli->info_file, "") ||
 
233
       init_intvar_from_file(&relay_log_pos,
 
234
                             &rli->info_file, BIN_LOG_HEADER_SIZE) ||
 
235
       init_strvar_from_file(rli->group_master_log_name,
 
236
                             sizeof(rli->group_master_log_name),
 
237
                             &rli->info_file, "") ||
 
238
       init_intvar_from_file(&master_log_pos, &rli->info_file, 0))
 
239
    {
 
240
      msg="Error reading slave log configuration";
 
241
      goto err;
 
242
    }
 
243
    strmake(rli->event_relay_log_name,rli->group_relay_log_name,
 
244
            sizeof(rli->event_relay_log_name)-1);
 
245
    rli->group_relay_log_pos= rli->event_relay_log_pos= relay_log_pos;
 
246
    rli->group_master_log_pos= master_log_pos;
 
247
 
 
248
    if (init_relay_log_pos(rli,
 
249
                           rli->group_relay_log_name,
 
250
                           rli->group_relay_log_pos,
 
251
                           0 /* no data lock*/,
 
252
                           &msg, 0))
 
253
    {
 
254
      char llbuf[22];
 
255
      sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s)",
 
256
                      rli->group_relay_log_name,
 
257
                      llstr(rli->group_relay_log_pos, llbuf));
 
258
      goto err;
 
259
    }
 
260
  }
 
261
 
 
262
#ifndef DBUG_OFF
 
263
  {
 
264
    char llbuf1[22], llbuf2[22];
 
265
    DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
 
266
                        llstr(my_b_tell(rli->cur_log),llbuf1),
 
267
                        llstr(rli->event_relay_log_pos,llbuf2)));
 
268
    DBUG_ASSERT(rli->event_relay_log_pos >= BIN_LOG_HEADER_SIZE);
 
269
    DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->event_relay_log_pos);
 
270
  }
 
271
#endif
 
272
 
 
273
  /*
 
274
    Now change the cache from READ to WRITE - must do this
 
275
    before flush_relay_log_info
 
276
  */
 
277
  reinit_io_cache(&rli->info_file, WRITE_CACHE,0L,0,1);
 
278
  if ((error= flush_relay_log_info(rli)))
 
279
    sql_print_error("Failed to flush relay log info file");
 
280
  if (count_relay_log_space(rli))
 
281
  {
 
282
    msg="Error counting relay log space";
 
283
    goto err;
 
284
  }
 
285
  rli->inited= 1;
 
286
  pthread_mutex_unlock(&rli->data_lock);
 
287
  DBUG_RETURN(error);
 
288
 
 
289
err:
 
290
  sql_print_error(msg);
 
291
  end_io_cache(&rli->info_file);
 
292
  if (info_fd >= 0)
 
293
    my_close(info_fd, MYF(0));
 
294
  rli->info_fd= -1;
 
295
  rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
 
296
  pthread_mutex_unlock(&rli->data_lock);
 
297
  DBUG_RETURN(1);
 
298
}
 
299
 
 
300
 
 
301
static inline int add_relay_log(Relay_log_info* rli,LOG_INFO* linfo)
 
302
{
 
303
  MY_STAT s;
 
304
  DBUG_ENTER("add_relay_log");
 
305
  if (!my_stat(linfo->log_file_name,&s,MYF(0)))
 
306
  {
 
307
    sql_print_error("log %s listed in the index, but failed to stat",
 
308
                    linfo->log_file_name);
 
309
    DBUG_RETURN(1);
 
310
  }
 
311
  rli->log_space_total += s.st_size;
 
312
#ifndef DBUG_OFF
 
313
  char buf[22];
 
314
  DBUG_PRINT("info",("log_space_total: %s", llstr(rli->log_space_total,buf)));
 
315
#endif
 
316
  DBUG_RETURN(0);
 
317
}
 
318
 
 
319
 
 
320
static int count_relay_log_space(Relay_log_info* rli)
 
321
{
 
322
  LOG_INFO linfo;
 
323
  DBUG_ENTER("count_relay_log_space");
 
324
  rli->log_space_total= 0;
 
325
  if (rli->relay_log.find_log_pos(&linfo, NullS, 1))
 
326
  {
 
327
    sql_print_error("Could not find first log while counting relay log space");
 
328
    DBUG_RETURN(1);
 
329
  }
 
330
  do
 
331
  {
 
332
    if (add_relay_log(rli,&linfo))
 
333
      DBUG_RETURN(1);
 
334
  } while (!rli->relay_log.find_next_log(&linfo, 1));
 
335
  /*
 
336
     As we have counted everything, including what may have written in a
 
337
     preceding write, we must reset bytes_written, or we may count some space
 
338
     twice.
 
339
  */
 
340
  rli->relay_log.reset_bytes_written();
 
341
  DBUG_RETURN(0);
 
342
}
 
343
 
 
344
 
 
345
/*
 
346
   Reset UNTIL condition for Relay_log_info
 
347
 
 
348
   SYNOPSYS
 
349
    clear_until_condition()
 
350
      rli - Relay_log_info structure where UNTIL condition should be reset
 
351
 */
 
352
 
 
353
void Relay_log_info::clear_until_condition()
 
354
{
 
355
  DBUG_ENTER("clear_until_condition");
 
356
 
 
357
  until_condition= Relay_log_info::UNTIL_NONE;
 
358
  until_log_name[0]= 0;
 
359
  until_log_pos= 0;
 
360
  DBUG_VOID_RETURN;
 
361
}
 
362
 
 
363
 
 
364
/*
 
365
  Open the given relay log
 
366
 
 
367
  SYNOPSIS
 
368
    init_relay_log_pos()
 
369
    rli                 Relay information (will be initialized)
 
370
    log                 Name of relay log file to read from. NULL = First log
 
371
    pos                 Position in relay log file
 
372
    need_data_lock      Set to 1 if this functions should do mutex locks
 
373
    errmsg              Store pointer to error message here
 
374
    look_for_description_event
 
375
                        1 if we should look for such an event. We only need
 
376
                        this when the SQL thread starts and opens an existing
 
377
                        relay log and has to execute it (possibly from an
 
378
                        offset >4); then we need to read the first event of
 
379
                        the relay log to be able to parse the events we have
 
380
                        to execute.
 
381
 
 
382
  DESCRIPTION
 
383
  - Close old open relay log files.
 
384
  - If we are using the same relay log as the running IO-thread, then set
 
385
    rli->cur_log to point to the same IO_CACHE entry.
 
386
  - If not, open the 'log' binary file.
 
387
 
 
388
  TODO
 
389
    - check proper initialization of group_master_log_name/group_master_log_pos
 
390
 
 
391
  RETURN VALUES
 
392
    0   ok
 
393
    1   error.  errmsg is set to point to the error message
 
394
*/
 
395
 
 
396
int init_relay_log_pos(Relay_log_info* rli,const char* log,
 
397
                       ulonglong pos, bool need_data_lock,
 
398
                       const char** errmsg,
 
399
                       bool look_for_description_event)
 
400
{
 
401
  DBUG_ENTER("init_relay_log_pos");
 
402
  DBUG_PRINT("info", ("pos: %lu", (ulong) pos));
 
403
 
 
404
  *errmsg=0;
 
405
  pthread_mutex_t *log_lock=rli->relay_log.get_log_lock();
 
406
 
 
407
  if (need_data_lock)
 
408
    pthread_mutex_lock(&rli->data_lock);
 
409
 
 
410
  /*
 
411
    Slave threads are not the only users of init_relay_log_pos(). CHANGE MASTER
 
412
    is, too, and init_slave() too; these 2 functions allocate a description
 
413
    event in init_relay_log_pos, which is not freed by the terminating SQL slave
 
414
    thread as that thread is not started by these functions. So we have to free
 
415
    the description_event here, in case, so that there is no memory leak in
 
416
    running, say, CHANGE MASTER.
 
417
  */
 
418
  delete rli->relay_log.description_event_for_exec;
 
419
  /*
 
420
    By default the relay log is in binlog format 3 (4.0).
 
421
    Even if format is 4, this will work enough to read the first event
 
422
    (Format_desc) (remember that format 4 is just lenghtened compared to format
 
423
    3; format 3 is a prefix of format 4).
 
424
  */
 
425
  rli->relay_log.description_event_for_exec= new
 
426
    Format_description_log_event(3);
 
427
 
 
428
  pthread_mutex_lock(log_lock);
 
429
 
 
430
  /* Close log file and free buffers if it's already open */
 
431
  if (rli->cur_log_fd >= 0)
 
432
  {
 
433
    end_io_cache(&rli->cache_buf);
 
434
    my_close(rli->cur_log_fd, MYF(MY_WME));
 
435
    rli->cur_log_fd = -1;
 
436
  }
 
437
 
 
438
  rli->group_relay_log_pos = rli->event_relay_log_pos = pos;
 
439
 
 
440
  /*
 
441
    Test to see if the previous run was with the skip of purging
 
442
    If yes, we do not purge when we restart
 
443
  */
 
444
  if (rli->relay_log.find_log_pos(&rli->linfo, NullS, 1))
 
445
  {
 
446
    *errmsg="Could not find first log during relay log initialization";
 
447
    goto err;
 
448
  }
 
449
 
 
450
  if (log && rli->relay_log.find_log_pos(&rli->linfo, log, 1))
 
451
  {
 
452
    *errmsg="Could not find target log during relay log initialization";
 
453
    goto err;
 
454
  }
 
455
  strmake(rli->group_relay_log_name,rli->linfo.log_file_name,
 
456
          sizeof(rli->group_relay_log_name)-1);
 
457
  strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
 
458
          sizeof(rli->event_relay_log_name)-1);
 
459
  if (rli->relay_log.is_active(rli->linfo.log_file_name))
 
460
  {
 
461
    /*
 
462
      The IO thread is using this log file.
 
463
      In this case, we will use the same IO_CACHE pointer to
 
464
      read data as the IO thread is using to write data.
 
465
    */
 
466
    my_b_seek((rli->cur_log=rli->relay_log.get_log_file()), (off_t)0);
 
467
    if (check_binlog_magic(rli->cur_log,errmsg))
 
468
      goto err;
 
469
    rli->cur_log_old_open_count=rli->relay_log.get_open_count();
 
470
  }
 
471
  else
 
472
  {
 
473
    /*
 
474
      Open the relay log and set rli->cur_log to point at this one
 
475
    */
 
476
    if ((rli->cur_log_fd=open_binlog(&rli->cache_buf,
 
477
                                     rli->linfo.log_file_name,errmsg)) < 0)
 
478
      goto err;
 
479
    rli->cur_log = &rli->cache_buf;
 
480
  }
 
481
  /*
 
482
    In all cases, check_binlog_magic() has been called so we're at offset 4 for
 
483
    sure.
 
484
  */
 
485
  if (pos > BIN_LOG_HEADER_SIZE) /* If pos<=4, we stay at 4 */
 
486
  {
 
487
    Log_event* ev;
 
488
    while (look_for_description_event)
 
489
    {
 
490
      /*
 
491
        Read the possible Format_description_log_event; if position
 
492
        was 4, no need, it will be read naturally.
 
493
      */
 
494
      DBUG_PRINT("info",("looking for a Format_description_log_event"));
 
495
 
 
496
      if (my_b_tell(rli->cur_log) >= pos)
 
497
        break;
 
498
 
 
499
      /*
 
500
        Because of we have rli->data_lock and log_lock, we can safely read an
 
501
        event
 
502
      */
 
503
      if (!(ev=Log_event::read_log_event(rli->cur_log,0,
 
504
                                         rli->relay_log.description_event_for_exec)))
 
505
      {
 
506
        DBUG_PRINT("info",("could not read event, rli->cur_log->error=%d",
 
507
                           rli->cur_log->error));
 
508
        if (rli->cur_log->error) /* not EOF */
 
509
        {
 
510
          *errmsg= "I/O error reading event at position 4";
 
511
          goto err;
 
512
        }
 
513
        break;
 
514
      }
 
515
      else if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT)
 
516
      {
 
517
        DBUG_PRINT("info",("found Format_description_log_event"));
 
518
        delete rli->relay_log.description_event_for_exec;
 
519
        rli->relay_log.description_event_for_exec= (Format_description_log_event*) ev;
 
520
        /*
 
521
          As ev was returned by read_log_event, it has passed is_valid(), so
 
522
          my_malloc() in ctor worked, no need to check again.
 
523
        */
 
524
        /*
 
525
          Ok, we found a Format_description event. But it is not sure that this
 
526
          describes the whole relay log; indeed, one can have this sequence
 
527
          (starting from position 4):
 
528
          Format_desc (of slave)
 
529
          Rotate (of master)
 
530
          Format_desc (of master)
 
531
          So the Format_desc which really describes the rest of the relay log
 
532
          is the 3rd event (it can't be further than that, because we rotate
 
533
          the relay log when we queue a Rotate event from the master).
 
534
          But what describes the Rotate is the first Format_desc.
 
535
          So what we do is:
 
536
          go on searching for Format_description events, until you exceed the
 
537
          position (argument 'pos') or until you find another event than Rotate
 
538
          or Format_desc.
 
539
        */
 
540
      }
 
541
      else
 
542
      {
 
543
        DBUG_PRINT("info",("found event of another type=%d",
 
544
                           ev->get_type_code()));
 
545
        look_for_description_event= (ev->get_type_code() == ROTATE_EVENT);
 
546
        delete ev;
 
547
      }
 
548
    }
 
549
    my_b_seek(rli->cur_log,(off_t)pos);
 
550
#ifndef DBUG_OFF
 
551
  {
 
552
    char llbuf1[22], llbuf2[22];
 
553
    DBUG_PRINT("info", ("my_b_tell(rli->cur_log)=%s rli->event_relay_log_pos=%s",
 
554
                        llstr(my_b_tell(rli->cur_log),llbuf1),
 
555
                        llstr(rli->event_relay_log_pos,llbuf2)));
 
556
  }
 
557
#endif
 
558
 
 
559
  }
 
560
 
 
561
err:
 
562
  /*
 
563
    If we don't purge, we can't honour relay_log_space_limit ;
 
564
    silently discard it
 
565
  */
 
566
  if (!relay_log_purge)
 
567
    rli->log_space_limit= 0;
 
568
  pthread_cond_broadcast(&rli->data_cond);
 
569
 
 
570
  pthread_mutex_unlock(log_lock);
 
571
 
 
572
  if (need_data_lock)
 
573
    pthread_mutex_unlock(&rli->data_lock);
 
574
  if (!rli->relay_log.description_event_for_exec->is_valid() && !*errmsg)
 
575
    *errmsg= "Invalid Format_description log event; could be out of memory";
 
576
 
 
577
  DBUG_RETURN ((*errmsg) ? 1 : 0);
 
578
}
 
579
 
 
580
 
 
581
/*
 
582
  Waits until the SQL thread reaches (has executed up to) the
 
583
  log/position or timed out.
 
584
 
 
585
  SYNOPSIS
 
586
    wait_for_pos()
 
587
    thd             client thread that sent SELECT MASTER_POS_WAIT
 
588
    log_name        log name to wait for
 
589
    log_pos         position to wait for
 
590
    timeout         timeout in seconds before giving up waiting
 
591
 
 
592
  NOTES
 
593
    timeout is longlong whereas it should be ulong ; but this is
 
594
    to catch if the user submitted a negative timeout.
 
595
 
 
596
  RETURN VALUES
 
597
    -2          improper arguments (log_pos<0)
 
598
                or slave not running, or master info changed
 
599
                during the function's execution,
 
600
                or client thread killed. -2 is translated to NULL by caller
 
601
    -1          timed out
 
602
    >=0         number of log events the function had to wait
 
603
                before reaching the desired log/position
 
604
 */
 
605
 
 
606
int Relay_log_info::wait_for_pos(THD* thd, String* log_name,
 
607
                                    longlong log_pos,
 
608
                                    longlong timeout)
 
609
{
 
610
  int event_count = 0;
 
611
  ulong init_abort_pos_wait;
 
612
  int error=0;
 
613
  struct timespec abstime; // for timeout checking
 
614
  const char *msg;
 
615
  DBUG_ENTER("Relay_log_info::wait_for_pos");
 
616
 
 
617
  if (!inited)
 
618
    DBUG_RETURN(-2);
 
619
 
 
620
  DBUG_PRINT("enter",("log_name: '%s'  log_pos: %lu  timeout: %lu",
 
621
                      log_name->c_ptr(), (ulong) log_pos, (ulong) timeout));
 
622
 
 
623
  set_timespec(abstime,timeout);
 
624
  pthread_mutex_lock(&data_lock);
 
625
  msg= thd->enter_cond(&data_cond, &data_lock,
 
626
                       "Waiting for the slave SQL thread to "
 
627
                       "advance position");
 
628
  /*
 
629
     This function will abort when it notices that some CHANGE MASTER or
 
630
     RESET MASTER has changed the master info.
 
631
     To catch this, these commands modify abort_pos_wait ; We just monitor
 
632
     abort_pos_wait and see if it has changed.
 
633
     Why do we have this mechanism instead of simply monitoring slave_running
 
634
     in the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that
 
635
     the SQL thread be stopped?
 
636
     This is becasue if someones does:
 
637
     STOP SLAVE;CHANGE MASTER/RESET SLAVE; START SLAVE;
 
638
     the change may happen very quickly and we may not notice that
 
639
     slave_running briefly switches between 1/0/1.
 
640
  */
 
641
  init_abort_pos_wait= abort_pos_wait;
 
642
 
 
643
  /*
 
644
    We'll need to
 
645
    handle all possible log names comparisons (e.g. 999 vs 1000).
 
646
    We use ulong for string->number conversion ; this is no
 
647
    stronger limitation than in find_uniq_filename in sql/log.cc
 
648
  */
 
649
  ulong log_name_extension;
 
650
  char log_name_tmp[FN_REFLEN]; //make a char[] from String
 
651
 
 
652
  strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
 
653
 
 
654
  char *p= fn_ext(log_name_tmp);
 
655
  char *p_end;
 
656
  if (!*p || log_pos<0)
 
657
  {
 
658
    error= -2; //means improper arguments
 
659
    goto err;
 
660
  }
 
661
  // Convert 0-3 to 4
 
662
  log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
 
663
  /* p points to '.' */
 
664
  log_name_extension= strtoul(++p, &p_end, 10);
 
665
  /*
 
666
    p_end points to the first invalid character.
 
667
    If it equals to p, no digits were found, error.
 
668
    If it contains '\0' it means conversion went ok.
 
669
  */
 
670
  if (p_end==p || *p_end)
 
671
  {
 
672
    error= -2;
 
673
    goto err;
 
674
  }
 
675
 
 
676
  /* The "compare and wait" main loop */
 
677
  while (!thd->killed &&
 
678
         init_abort_pos_wait == abort_pos_wait &&
 
679
         slave_running)
 
680
  {
 
681
    bool pos_reached;
 
682
    int cmp_result= 0;
 
683
 
 
684
    DBUG_PRINT("info",
 
685
               ("init_abort_pos_wait: %ld  abort_pos_wait: %ld",
 
686
                init_abort_pos_wait, abort_pos_wait));
 
687
    DBUG_PRINT("info",("group_master_log_name: '%s'  pos: %lu",
 
688
                       group_master_log_name, (ulong) group_master_log_pos));
 
689
 
 
690
    /*
 
691
      group_master_log_name can be "", if we are just after a fresh
 
692
      replication start or after a CHANGE MASTER TO MASTER_HOST/PORT
 
693
      (before we have executed one Rotate event from the master) or
 
694
      (rare) if the user is doing a weird slave setup (see next
 
695
      paragraph).  If group_master_log_name is "", we assume we don't
 
696
      have enough info to do the comparison yet, so we just wait until
 
697
      more data. In this case master_log_pos is always 0 except if
 
698
      somebody (wrongly) sets this slave to be a slave of itself
 
699
      without using --replicate-same-server-id (an unsupported
 
700
      configuration which does nothing), then group_master_log_pos
 
701
      will grow and group_master_log_name will stay "".
 
702
    */
 
703
    if (*group_master_log_name)
 
704
    {
 
705
      char *basename= (group_master_log_name +
 
706
                       dirname_length(group_master_log_name));
 
707
      /*
 
708
        First compare the parts before the extension.
 
709
        Find the dot in the master's log basename,
 
710
        and protect against user's input error :
 
711
        if the names do not match up to '.' included, return error
 
712
      */
 
713
      char *q= (char*)(fn_ext(basename)+1);
 
714
      if (strncmp(basename, log_name_tmp, (int)(q-basename)))
 
715
      {
 
716
        error= -2;
 
717
        break;
 
718
      }
 
719
      // Now compare extensions.
 
720
      char *q_end;
 
721
      ulong group_master_log_name_extension= strtoul(q, &q_end, 10);
 
722
      if (group_master_log_name_extension < log_name_extension)
 
723
        cmp_result= -1 ;
 
724
      else
 
725
        cmp_result= (group_master_log_name_extension > log_name_extension) ? 1 : 0 ;
 
726
 
 
727
      pos_reached= ((!cmp_result && group_master_log_pos >= (ulonglong)log_pos) ||
 
728
                    cmp_result > 0);
 
729
      if (pos_reached || thd->killed)
 
730
        break;
 
731
    }
 
732
 
 
733
    //wait for master update, with optional timeout.
 
734
 
 
735
    DBUG_PRINT("info",("Waiting for master update"));
 
736
    /*
 
737
      We are going to pthread_cond_(timed)wait(); if the SQL thread stops it
 
738
      will wake us up.
 
739
    */
 
740
    if (timeout > 0)
 
741
    {
 
742
      /*
 
743
        Note that pthread_cond_timedwait checks for the timeout
 
744
        before for the condition ; i.e. it returns ETIMEDOUT
 
745
        if the system time equals or exceeds the time specified by abstime
 
746
        before the condition variable is signaled or broadcast, _or_ if
 
747
        the absolute time specified by abstime has already passed at the time
 
748
        of the call.
 
749
        For that reason, pthread_cond_timedwait will do the "timeoutting" job
 
750
        even if its condition is always immediately signaled (case of a loaded
 
751
        master).
 
752
      */
 
753
      error=pthread_cond_timedwait(&data_cond, &data_lock, &abstime);
 
754
    }
 
755
    else
 
756
      pthread_cond_wait(&data_cond, &data_lock);
 
757
    DBUG_PRINT("info",("Got signal of master update or timed out"));
 
758
    if (error == ETIMEDOUT || error == ETIME)
 
759
    {
 
760
      error= -1;
 
761
      break;
 
762
    }
 
763
    error=0;
 
764
    event_count++;
 
765
    DBUG_PRINT("info",("Testing if killed or SQL thread not running"));
 
766
  }
 
767
 
 
768
err:
 
769
  thd->exit_cond(msg);
 
770
  DBUG_PRINT("exit",("killed: %d  abort: %d  slave_running: %d \
 
771
improper_arguments: %d  timed_out: %d",
 
772
                     thd->killed_errno(),
 
773
                     (int) (init_abort_pos_wait != abort_pos_wait),
 
774
                     (int) slave_running,
 
775
                     (int) (error == -2),
 
776
                     (int) (error == -1)));
 
777
  if (thd->killed || init_abort_pos_wait != abort_pos_wait ||
 
778
      !slave_running)
 
779
  {
 
780
    error= -2;
 
781
  }
 
782
  DBUG_RETURN( error ? error : event_count );
 
783
}
 
784
 
 
785
 
 
786
void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
 
787
                                                bool skip_lock)
 
788
{
 
789
  DBUG_ENTER("Relay_log_info::inc_group_relay_log_pos");
 
790
 
 
791
  if (!skip_lock)
 
792
    pthread_mutex_lock(&data_lock);
 
793
  inc_event_relay_log_pos();
 
794
  group_relay_log_pos= event_relay_log_pos;
 
795
  strmake(group_relay_log_name,event_relay_log_name,
 
796
          sizeof(group_relay_log_name)-1);
 
797
 
 
798
  notify_group_relay_log_name_update();
 
799
 
 
800
  /*
 
801
    If the slave does not support transactions and replicates a transaction,
 
802
    users should not trust group_master_log_pos (which they can display with
 
803
    SHOW SLAVE STATUS or read from relay-log.info), because to compute
 
804
    group_master_log_pos the slave relies on log_pos stored in the master's
 
805
    binlog, but if we are in a master's transaction these positions are always
 
806
    the BEGIN's one (excepted for the COMMIT), so group_master_log_pos does
 
807
    not advance as it should on the non-transactional slave (it advances by
 
808
    big leaps, whereas it should advance by small leaps).
 
809
  */
 
810
  /*
 
811
    In 4.x we used the event's len to compute the positions here. This is
 
812
    wrong if the event was 3.23/4.0 and has been converted to 5.0, because
 
813
    then the event's len is not what is was in the master's binlog, so this
 
814
    will make a wrong group_master_log_pos (yes it's a bug in 3.23->4.0
 
815
    replication: Exec_master_log_pos is wrong). Only way to solve this is to
 
816
    have the original offset of the end of the event the relay log. This is
 
817
    what we do in 5.0: log_pos has become "end_log_pos" (because the real use
 
818
    of log_pos in 4.0 was to compute the end_log_pos; so better to store
 
819
    end_log_pos instead of begin_log_pos.
 
820
    If we had not done this fix here, the problem would also have appeared
 
821
    when the slave and master are 5.0 but with different event length (for
 
822
    example the slave is more recent than the master and features the event
 
823
    UID). It would give false MASTER_POS_WAIT, false Exec_master_log_pos in
 
824
    SHOW SLAVE STATUS, and so the user would do some CHANGE MASTER using this
 
825
    value which would lead to badly broken replication.
 
826
    Even the relay_log_pos will be corrupted in this case, because the len is
 
827
    the relay log is not "val".
 
828
    With the end_log_pos solution, we avoid computations involving lengthes.
 
829
  */
 
830
  DBUG_PRINT("info", ("log_pos: %lu  group_master_log_pos: %lu",
 
831
                      (long) log_pos, (long) group_master_log_pos));
 
832
  if (log_pos) // 3.23 binlogs don't have log_posx
 
833
  {
 
834
    group_master_log_pos= log_pos;
 
835
  }
 
836
  pthread_cond_broadcast(&data_cond);
 
837
  if (!skip_lock)
 
838
    pthread_mutex_unlock(&data_lock);
 
839
  DBUG_VOID_RETURN;
 
840
}
 
841
 
 
842
 
 
843
void Relay_log_info::close_temporary_tables()
 
844
{
 
845
  TABLE *table,*next;
 
846
  DBUG_ENTER("Relay_log_info::close_temporary_tables");
 
847
 
 
848
  for (table=save_temporary_tables ; table ; table=next)
 
849
  {
 
850
    next=table->next;
 
851
    /*
 
852
      Don't ask for disk deletion. For now, anyway they will be deleted when
 
853
      slave restarts, but it is a better intention to not delete them.
 
854
    */
 
855
    DBUG_PRINT("info", ("table: 0x%lx", (long) table));
 
856
    close_temporary(table, 1, 0);
 
857
  }
 
858
  save_temporary_tables= 0;
 
859
  slave_open_temp_tables= 0;
 
860
  DBUG_VOID_RETURN;
 
861
}
 
862
 
 
863
/*
 
864
  purge_relay_logs()
 
865
 
 
866
  NOTES
 
867
    Assumes to have a run lock on rli and that no slave thread are running.
 
868
*/
 
869
 
 
870
int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset,
 
871
                     const char** errmsg)
 
872
{
 
873
  int error=0;
 
874
  DBUG_ENTER("purge_relay_logs");
 
875
 
 
876
  /*
 
877
    Even if rli->inited==0, we still try to empty rli->master_log_* variables.
 
878
    Indeed, rli->inited==0 does not imply that they already are empty.
 
879
    It could be that slave's info initialization partly succeeded :
 
880
    for example if relay-log.info existed but *relay-bin*.*
 
881
    have been manually removed, init_relay_log_info reads the old
 
882
    relay-log.info and fills rli->master_log_*, then init_relay_log_info
 
883
    checks for the existence of the relay log, this fails and
 
884
    init_relay_log_info leaves rli->inited to 0.
 
885
    In that pathological case, rli->master_log_pos* will be properly reinited
 
886
    at the next START SLAVE (as RESET SLAVE or CHANGE
 
887
    MASTER, the callers of purge_relay_logs, will delete bogus *.info files
 
888
    or replace them with correct files), however if the user does SHOW SLAVE
 
889
    STATUS before START SLAVE, he will see old, confusing rli->master_log_*.
 
890
    In other words, we reinit rli->master_log_* for SHOW SLAVE STATUS
 
891
    to display fine in any case.
 
892
  */
 
893
 
 
894
  rli->group_master_log_name[0]= 0;
 
895
  rli->group_master_log_pos= 0;
 
896
 
 
897
  if (!rli->inited)
 
898
  {
 
899
    DBUG_PRINT("info", ("rli->inited == 0"));
 
900
    DBUG_RETURN(0);
 
901
  }
 
902
 
 
903
  DBUG_ASSERT(rli->slave_running == 0);
 
904
  DBUG_ASSERT(rli->mi->slave_running == 0);
 
905
 
 
906
  rli->slave_skip_counter=0;
 
907
  pthread_mutex_lock(&rli->data_lock);
 
908
 
 
909
  /*
 
910
    we close the relay log fd possibly left open by the slave SQL thread,
 
911
    to be able to delete it; the relay log fd possibly left open by the slave
 
912
    I/O thread will be closed naturally in reset_logs() by the
 
913
    close(LOG_CLOSE_TO_BE_OPENED) call
 
914
  */
 
915
  if (rli->cur_log_fd >= 0)
 
916
  {
 
917
    end_io_cache(&rli->cache_buf);
 
918
    my_close(rli->cur_log_fd, MYF(MY_WME));
 
919
    rli->cur_log_fd= -1;
 
920
  }
 
921
 
 
922
  if (rli->relay_log.reset_logs(thd))
 
923
  {
 
924
    *errmsg = "Failed during log reset";
 
925
    error=1;
 
926
    goto err;
 
927
  }
 
928
  /* Save name of used relay log file */
 
929
  strmake(rli->group_relay_log_name, rli->relay_log.get_log_fname(),
 
930
          sizeof(rli->group_relay_log_name)-1);
 
931
  strmake(rli->event_relay_log_name, rli->relay_log.get_log_fname(),
 
932
          sizeof(rli->event_relay_log_name)-1);
 
933
  rli->group_relay_log_pos= rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
 
934
  if (count_relay_log_space(rli))
 
935
  {
 
936
    *errmsg= "Error counting relay log space";
 
937
    goto err;
 
938
  }
 
939
  if (!just_reset)
 
940
    error= init_relay_log_pos(rli, rli->group_relay_log_name,
 
941
                              rli->group_relay_log_pos,
 
942
                              0 /* do not need data lock */, errmsg, 0);
 
943
 
 
944
err:
 
945
#ifndef DBUG_OFF
 
946
  char buf[22];
 
947
#endif
 
948
  DBUG_PRINT("info",("log_space_total: %s",llstr(rli->log_space_total,buf)));
 
949
  pthread_mutex_unlock(&rli->data_lock);
 
950
  DBUG_RETURN(error);
 
951
}
 
952
 
 
953
 
 
954
/*
 
955
     Check if condition stated in UNTIL clause of START SLAVE is reached.
 
956
   SYNOPSYS
 
957
     Relay_log_info::is_until_satisfied()
 
958
     master_beg_pos    position of the beginning of to be executed event
 
959
                       (not log_pos member of the event that points to the
 
960
                        beginning of the following event)
 
961
 
 
962
 
 
963
   DESCRIPTION
 
964
     Checks if UNTIL condition is reached. Uses caching result of last
 
965
     comparison of current log file name and target log file name. So cached
 
966
     value should be invalidated if current log file name changes
 
967
     (see Relay_log_info::notify_... functions).
 
968
 
 
969
     This caching is needed to avoid of expensive string comparisons and
 
970
     strtol() conversions needed for log names comparison. We don't need to
 
971
     compare them each time this function is called, we only need to do this
 
972
     when current log name changes. If we have UNTIL_MASTER_POS condition we
 
973
     need to do this only after Rotate_log_event::do_apply_event() (which is
 
974
     rare, so caching gives real benifit), and if we have UNTIL_RELAY_POS
 
975
     condition then we should invalidate cached comarison value after
 
976
     inc_group_relay_log_pos() which called for each group of events (so we
 
977
     have some benefit if we have something like queries that use
 
978
     autoincrement or if we have transactions).
 
979
 
 
980
     Should be called ONLY if until_condition != UNTIL_NONE !
 
981
   RETURN VALUE
 
982
     true - condition met or error happened (condition seems to have
 
983
            bad log file name)
 
984
     false - condition not met
 
985
*/
 
986
 
 
987
bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos)
 
988
{
 
989
  const char *log_name;
 
990
  ulonglong log_pos;
 
991
  DBUG_ENTER("Relay_log_info::is_until_satisfied");
 
992
 
 
993
  DBUG_ASSERT(until_condition != UNTIL_NONE);
 
994
 
 
995
  if (until_condition == UNTIL_MASTER_POS)
 
996
  {
 
997
    log_name= group_master_log_name;
 
998
    log_pos= master_beg_pos;
 
999
  }
 
1000
  else
 
1001
  { /* until_condition == UNTIL_RELAY_POS */
 
1002
    log_name= group_relay_log_name;
 
1003
    log_pos= group_relay_log_pos;
 
1004
  }
 
1005
 
 
1006
#ifndef DBUG_OFF
 
1007
  {
 
1008
    char buf[32];
 
1009
    DBUG_PRINT("info", ("group_master_log_name='%s', group_master_log_pos=%s",
 
1010
                        group_master_log_name, llstr(group_master_log_pos, buf)));
 
1011
    DBUG_PRINT("info", ("group_relay_log_name='%s', group_relay_log_pos=%s",
 
1012
                        group_relay_log_name, llstr(group_relay_log_pos, buf)));
 
1013
    DBUG_PRINT("info", ("(%s) log_name='%s', log_pos=%s",
 
1014
                        until_condition == UNTIL_MASTER_POS ? "master" : "relay",
 
1015
                        log_name, llstr(log_pos, buf)));
 
1016
    DBUG_PRINT("info", ("(%s) until_log_name='%s', until_log_pos=%s",
 
1017
                        until_condition == UNTIL_MASTER_POS ? "master" : "relay",
 
1018
                        until_log_name, llstr(until_log_pos, buf)));
 
1019
  }
 
1020
#endif
 
1021
 
 
1022
  if (until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_UNKNOWN)
 
1023
  {
 
1024
    /*
 
1025
      We have no cached comparison results so we should compare log names
 
1026
      and cache result.
 
1027
      If we are after RESET SLAVE, and the SQL slave thread has not processed
 
1028
      any event yet, it could be that group_master_log_name is "". In that case,
 
1029
      just wait for more events (as there is no sensible comparison to do).
 
1030
    */
 
1031
 
 
1032
    if (*log_name)
 
1033
    {
 
1034
      const char *basename= log_name + dirname_length(log_name);
 
1035
 
 
1036
      const char *q= (const char*)(fn_ext(basename)+1);
 
1037
      if (strncmp(basename, until_log_name, (int)(q-basename)) == 0)
 
1038
      {
 
1039
        /* Now compare extensions. */
 
1040
        char *q_end;
 
1041
        ulong log_name_extension= strtoul(q, &q_end, 10);
 
1042
        if (log_name_extension < until_log_name_extension)
 
1043
          until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_LESS;
 
1044
        else
 
1045
          until_log_names_cmp_result=
 
1046
            (log_name_extension > until_log_name_extension) ?
 
1047
            UNTIL_LOG_NAMES_CMP_GREATER : UNTIL_LOG_NAMES_CMP_EQUAL ;
 
1048
      }
 
1049
      else
 
1050
      {
 
1051
        /* Probably error so we aborting */
 
1052
        sql_print_error("Slave SQL thread is stopped because UNTIL "
 
1053
                        "condition is bad.");
 
1054
        DBUG_RETURN(TRUE);
 
1055
      }
 
1056
    }
 
1057
    else
 
1058
      DBUG_RETURN(until_log_pos == 0);
 
1059
  }
 
1060
 
 
1061
  DBUG_RETURN(((until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_EQUAL &&
 
1062
           log_pos >= until_log_pos) ||
 
1063
          until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_GREATER));
 
1064
}
 
1065
 
 
1066
 
 
1067
void Relay_log_info::cached_charset_invalidate()
 
1068
{
 
1069
  DBUG_ENTER("Relay_log_info::cached_charset_invalidate");
 
1070
 
 
1071
  /* Full of zeroes means uninitialized. */
 
1072
  bzero(cached_charset, sizeof(cached_charset));
 
1073
  DBUG_VOID_RETURN;
 
1074
}
 
1075
 
 
1076
 
 
1077
bool Relay_log_info::cached_charset_compare(char *charset) const
 
1078
{
 
1079
  DBUG_ENTER("Relay_log_info::cached_charset_compare");
 
1080
 
 
1081
  if (bcmp((uchar*) cached_charset, (uchar*) charset,
 
1082
           sizeof(cached_charset)))
 
1083
  {
 
1084
    memcpy(const_cast<char*>(cached_charset), charset, sizeof(cached_charset));
 
1085
    DBUG_RETURN(1);
 
1086
  }
 
1087
  DBUG_RETURN(0);
 
1088
}
 
1089
 
 
1090
 
 
1091
void Relay_log_info::stmt_done(my_off_t event_master_log_pos,
 
1092
                                  time_t event_creation_time)
 
1093
{
 
1094
#ifndef DBUG_OFF
 
1095
  extern uint debug_not_change_ts_if_art_event;
 
1096
#endif
 
1097
  clear_flag(IN_STMT);
 
1098
 
 
1099
  /*
 
1100
    If in a transaction, and if the slave supports transactions, just
 
1101
    inc_event_relay_log_pos(). We only have to check for OPTION_BEGIN
 
1102
    (not OPTION_NOT_AUTOCOMMIT) as transactions are logged with
 
1103
    BEGIN/COMMIT, not with SET AUTOCOMMIT= .
 
1104
 
 
1105
    CAUTION: opt_using_transactions means innodb || bdb ; suppose the
 
1106
    master supports InnoDB and BDB, but the slave supports only BDB,
 
1107
    problems will arise: - suppose an InnoDB table is created on the
 
1108
    master, - then it will be MyISAM on the slave - but as
 
1109
    opt_using_transactions is true, the slave will believe he is
 
1110
    transactional with the MyISAM table. And problems will come when
 
1111
    one does START SLAVE; STOP SLAVE; START SLAVE; (the slave will
 
1112
    resume at BEGIN whereas there has not been any rollback).  This is
 
1113
    the problem of using opt_using_transactions instead of a finer
 
1114
    "does the slave support _transactional handler used on the
 
1115
    master_".
 
1116
 
 
1117
    More generally, we'll have problems when a query mixes a
 
1118
    transactional handler and MyISAM and STOP SLAVE is issued in the
 
1119
    middle of the "transaction". START SLAVE will resume at BEGIN
 
1120
    while the MyISAM table has already been updated.
 
1121
  */
 
1122
  if ((sql_thd->options & OPTION_BEGIN) && opt_using_transactions)
 
1123
    inc_event_relay_log_pos();
 
1124
  else
 
1125
  {
 
1126
    inc_group_relay_log_pos(event_master_log_pos);
 
1127
    flush_relay_log_info(this);
 
1128
    /*
 
1129
      Note that Rotate_log_event::do_apply_event() does not call this
 
1130
      function, so there is no chance that a fake rotate event resets
 
1131
      last_master_timestamp.  Note that we update without mutex
 
1132
      (probably ok - except in some very rare cases, only consequence
 
1133
      is that value may take some time to display in
 
1134
      Seconds_Behind_Master - not critical).
 
1135
    */
 
1136
#ifndef DBUG_OFF
 
1137
    if (!(event_creation_time == 0 && debug_not_change_ts_if_art_event > 0))
 
1138
#else
 
1139
      if (event_creation_time != 0)
 
1140
#endif
 
1141
        last_master_timestamp= event_creation_time;
 
1142
  }
 
1143
}
 
1144
 
 
1145
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
1146
void Relay_log_info::cleanup_context(THD *thd, bool error)
 
1147
{
 
1148
  DBUG_ENTER("Relay_log_info::cleanup_context");
 
1149
 
 
1150
  DBUG_ASSERT(sql_thd == thd);
 
1151
  /*
 
1152
    1) Instances of Table_map_log_event, if ::do_apply_event() was called on them,
 
1153
    may have opened tables, which we cannot be sure have been closed (because
 
1154
    maybe the Rows_log_event have not been found or will not be, because slave
 
1155
    SQL thread is stopping, or relay log has a missing tail etc). So we close
 
1156
    all thread's tables. And so the table mappings have to be cancelled.
 
1157
    2) Rows_log_event::do_apply_event() may even have started statements or
 
1158
    transactions on them, which we need to rollback in case of error.
 
1159
    3) If finding a Format_description_log_event after a BEGIN, we also need
 
1160
    to rollback before continuing with the next events.
 
1161
    4) so we need this "context cleanup" function.
 
1162
  */
 
1163
  if (error)
 
1164
  {
 
1165
    ha_autocommit_or_rollback(thd, 1); // if a "statement transaction"
 
1166
    end_trans(thd, ROLLBACK); // if a "real transaction"
 
1167
  }
 
1168
  m_table_map.clear_tables();
 
1169
  close_thread_tables(thd);
 
1170
  clear_tables_to_lock();
 
1171
  clear_flag(IN_STMT);
 
1172
  /*
 
1173
    Cleanup for the flags that have been set at do_apply_event.
 
1174
  */
 
1175
  thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
 
1176
  thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
 
1177
  last_event_start_time= 0;
 
1178
  DBUG_VOID_RETURN;
 
1179
}
 
1180
 
 
1181
void Relay_log_info::clear_tables_to_lock()
 
1182
{
 
1183
  while (tables_to_lock)
 
1184
  {
 
1185
    uchar* to_free= reinterpret_cast<uchar*>(tables_to_lock);
 
1186
    if (tables_to_lock->m_tabledef_valid)
 
1187
    {
 
1188
      tables_to_lock->m_tabledef.table_def::~table_def();
 
1189
      tables_to_lock->m_tabledef_valid= FALSE;
 
1190
    }
 
1191
    tables_to_lock=
 
1192
      static_cast<RPL_TABLE_LIST*>(tables_to_lock->next_global);
 
1193
    tables_to_lock_count--;
 
1194
    my_free(to_free, MYF(MY_WME));
 
1195
  }
 
1196
  DBUG_ASSERT(tables_to_lock == NULL && tables_to_lock_count == 0);
 
1197
}
 
1198
 
 
1199
#endif