~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/log.cc

  • Committer: Monty Taylor
  • Date: 2008-07-01 14:33:36 UTC
  • mto: (28.1.12 backport_patch)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: monty@inaugust.com-20080701143336-8uihm7dhpu92rt0q
Somehow missed moving password.c. Duh.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
    Abort logging when we get an error in reading or writing log files
25
25
*/
26
26
 
27
 
#include <drizzled/server_includes.h>
 
27
#include "mysql_priv.h"
28
28
#include "sql_repl.h"
29
29
#include "rpl_filter.h"
30
30
#include "rpl_rli.h"
31
31
 
32
 
#include <mysys/my_dir.h>
 
32
#include <my_dir.h>
33
33
#include <stdarg.h>
 
34
#include <m_ctype.h>                            // For test_if_number
34
35
 
35
 
#include <drizzled/plugin.h>
36
 
#include <drizzled/drizzled_error_messages.h>
37
 
#include <libdrizzle/gettext.h>
 
36
#include <mysql/plugin.h>
38
37
 
39
38
/* max size of the log message */
40
39
#define MAX_LOG_BUFFER_SIZE 1024
46
45
 
47
46
LOGGER logger;
48
47
 
49
 
DRIZZLE_BIN_LOG mysql_bin_log;
 
48
MYSQL_BIN_LOG mysql_bin_log;
50
49
ulong sync_binlog_counter= 0;
51
50
 
52
51
static bool test_if_number(const char *str,
59
58
static int binlog_rollback(handlerton *hton, THD *thd, bool all);
60
59
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
61
60
 
 
61
/**
 
62
  Silence all errors and warnings reported when performing a write
 
63
  to a log table.
 
64
  Errors and warnings are not reported to the client or SQL exception
 
65
  handlers, so that the presence of logging does not interfere and affect
 
66
  the logic of an application.
 
67
*/
 
68
class Silence_log_table_errors : public Internal_error_handler
 
69
{
 
70
  char m_message[MYSQL_ERRMSG_SIZE];
 
71
public:
 
72
  Silence_log_table_errors()
 
73
  {
 
74
    m_message[0]= '\0';
 
75
  }
 
76
 
 
77
  virtual ~Silence_log_table_errors() {}
 
78
 
 
79
  virtual bool handle_error(uint sql_errno, const char *message,
 
80
                            MYSQL_ERROR::enum_warning_level level,
 
81
                            THD *thd);
 
82
  const char *message() const { return m_message; }
 
83
};
 
84
 
 
85
bool
 
86
Silence_log_table_errors::handle_error(uint /* sql_errno */,
 
87
                                       const char *message_arg,
 
88
                                       MYSQL_ERROR::enum_warning_level /* level */,
 
89
                                       THD * /* thd */)
 
90
{
 
91
  strmake(m_message, message_arg, sizeof(m_message)-1);
 
92
  return TRUE;
 
93
}
 
94
 
62
95
 
63
96
sql_print_message_func sql_print_message_handlers[3] =
64
97
{
97
130
  {
98
131
    if (m_mutex)
99
132
      pthread_mutex_unlock(m_mutex);
 
133
#ifndef DBUG_OFF
100
134
    m_mutex= 0;
 
135
#endif
101
136
  }
102
137
 
103
138
private:
121
156
 
122
157
  ~binlog_trx_data()
123
158
  {
124
 
    assert(pending() == NULL);
 
159
    DBUG_ASSERT(pending() == NULL);
125
160
    close_cached_file(&trans_log);
126
161
  }
127
162
 
140
175
   */
141
176
  void truncate(my_off_t pos)
142
177
  {
 
178
    DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos));
 
179
    DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos));
143
180
    delete pending();
144
181
    set_pending(0);
145
182
    reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
204
241
 
205
242
 
206
243
/* Check if a given table is opened log table */
207
 
int check_if_log_table(uint32_t db_len __attribute__((unused)),
208
 
                       const char *db __attribute__((unused)),
209
 
                       uint32_t table_name_len __attribute__((unused)),
210
 
                       const char *table_name __attribute__((unused)),
211
 
                       uint32_t check_if_opened __attribute__((unused)))
 
244
int check_if_log_table(uint db_len, const char *db, uint table_name_len,
 
245
                       const char *table_name, uint check_if_opened)
212
246
{
213
247
  return 0;
214
248
}
215
249
 
 
250
/* log event handlers */
 
251
 
 
252
bool Log_to_file_event_handler::
 
253
  log_error(enum loglevel level, const char *format,
 
254
            va_list args)
 
255
{
 
256
  return vprint_msg_to_log(level, format, args);
 
257
}
 
258
 
 
259
void Log_to_file_event_handler::init_pthread_objects()
 
260
{
 
261
  mysql_log.init_pthread_objects();
 
262
  mysql_slow_log.init_pthread_objects();
 
263
}
 
264
 
 
265
 
 
266
/** Wrapper around MYSQL_LOG::write() for slow log. */
 
267
 
 
268
bool Log_to_file_event_handler::
 
269
  log_slow(THD *thd, time_t current_time, time_t query_start_arg,
 
270
           const char *user_host, uint user_host_len,
 
271
           ulonglong query_utime, ulonglong lock_utime, bool is_command,
 
272
           const char *sql_text, uint sql_text_len)
 
273
{
 
274
  return mysql_slow_log.write(thd, current_time, query_start_arg,
 
275
                              user_host, user_host_len,
 
276
                              query_utime, lock_utime, is_command,
 
277
                              sql_text, sql_text_len);
 
278
}
 
279
 
 
280
 
 
281
/**
 
282
   Wrapper around MYSQL_LOG::write() for general log. We need it since we
 
283
   want all log event handlers to have the same signature.
 
284
*/
 
285
 
 
286
bool Log_to_file_event_handler::
 
287
  log_general(THD *thd, time_t event_time, const char *user_host,
 
288
              uint user_host_len, int thread_id,
 
289
              const char *command_type, uint command_type_len,
 
290
              const char *sql_text, uint sql_text_len,
 
291
              CHARSET_INFO *client_cs)
 
292
{
 
293
  return mysql_log.write(event_time, user_host, user_host_len,
 
294
                         thread_id, command_type, command_type_len,
 
295
                         sql_text, sql_text_len);
 
296
}
 
297
 
 
298
 
 
299
bool Log_to_file_event_handler::init()
 
300
{
 
301
  if (!is_initialized)
 
302
  {
 
303
    if (opt_slow_log)
 
304
      mysql_slow_log.open_slow_log(sys_var_slow_log_path.value);
 
305
 
 
306
    if (opt_log)
 
307
      mysql_log.open_query_log(sys_var_general_log_path.value);
 
308
 
 
309
    is_initialized= TRUE;
 
310
  }
 
311
 
 
312
  return FALSE;
 
313
}
 
314
 
 
315
 
 
316
void Log_to_file_event_handler::cleanup()
 
317
{
 
318
  mysql_log.cleanup();
 
319
  mysql_slow_log.cleanup();
 
320
}
 
321
 
 
322
void Log_to_file_event_handler::flush()
 
323
{
 
324
  /* reopen log files */
 
325
  if (opt_log)
 
326
    mysql_log.reopen_file();
 
327
  if (opt_slow_log)
 
328
    mysql_slow_log.reopen_file();
 
329
}
 
330
 
216
331
/*
217
332
  Log error with all enabled log event handlers
218
333
 
232
347
bool LOGGER::error_log_print(enum loglevel level, const char *format,
233
348
                             va_list args)
234
349
{
235
 
  bool error= false;
 
350
  bool error= FALSE;
236
351
  Log_event_handler **current_handler;
237
352
 
238
353
  /* currently we don't need locking here as there is no error_log table */
245
360
 
246
361
void LOGGER::cleanup_base()
247
362
{
248
 
  assert(inited == 1);
 
363
  DBUG_ASSERT(inited == 1);
249
364
  rwlock_destroy(&LOCK_logger);
 
365
  if (file_log_handler)
 
366
    file_log_handler->cleanup();
250
367
}
251
368
 
252
369
 
253
370
void LOGGER::cleanup_end()
254
371
{
255
 
  assert(inited == 1);
 
372
  DBUG_ASSERT(inited == 1);
 
373
  if (file_log_handler)
 
374
    delete file_log_handler;
256
375
}
257
376
 
258
377
 
262
381
*/
263
382
void LOGGER::init_base()
264
383
{
265
 
  assert(inited == 0);
 
384
  DBUG_ASSERT(inited == 0);
266
385
  inited= 1;
267
386
 
 
387
  /*
 
388
    Here we create file log handler. We don't do it for the table log handler
 
389
    here as it cannot be created so early. The reason is THD initialization,
 
390
    which depends on the system variables (parsed later).
 
391
  */
 
392
  if (!file_log_handler)
 
393
    file_log_handler= new Log_to_file_event_handler;
 
394
 
268
395
  /* by default we use traditional error log */
269
396
  init_error_log(LOG_FILE);
270
397
 
 
398
  file_log_handler->init_pthread_objects();
271
399
  my_rwlock_init(&LOCK_logger, NULL);
272
400
}
273
401
 
274
402
 
275
 
bool LOGGER::flush_logs(THD *thd __attribute__((unused)))
 
403
bool LOGGER::flush_logs(THD *thd)
276
404
{
277
405
  int rc= 0;
278
406
 
282
410
  */
283
411
  logger.lock_exclusive();
284
412
 
 
413
  /* reopen log files */
 
414
  file_log_handler->flush();
 
415
 
285
416
  /* end of log flush */
286
417
  logger.unlock();
287
418
  return rc;
288
419
}
289
420
 
290
 
void LOGGER::init_error_log(uint32_t error_log_printer)
 
421
 
 
422
/*
 
423
  Log slow query with all enabled log event handlers
 
424
 
 
425
  SYNOPSIS
 
426
    slow_log_print()
 
427
 
 
428
    thd                 THD of the query being logged
 
429
    query               The query being logged
 
430
    query_length        The length of the query string
 
431
    current_utime       Current time in microseconds (from undefined start)
 
432
 
 
433
  RETURN
 
434
    FALSE   OK
 
435
    TRUE    error occured
 
436
*/
 
437
 
 
438
bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
 
439
                            ulonglong current_utime)
 
440
 
 
441
{
 
442
  bool error= FALSE;
 
443
  Log_event_handler **current_handler;
 
444
  bool is_command= FALSE;
 
445
  char user_host_buff[MAX_USER_HOST_SIZE];
 
446
  Security_context *sctx= thd->security_ctx;
 
447
  uint user_host_len= 0;
 
448
  ulonglong query_utime, lock_utime;
 
449
 
 
450
  /*
 
451
    Print the message to the buffer if we have slow log enabled
 
452
  */
 
453
 
 
454
  if (*slow_log_handler_list)
 
455
  {
 
456
    time_t current_time;
 
457
 
 
458
    /* do not log slow queries from replication threads */
 
459
    if (thd->slave_thread && !opt_log_slow_slave_statements)
 
460
      return 0;
 
461
 
 
462
    lock_shared();
 
463
    if (!opt_slow_log)
 
464
    {
 
465
      unlock();
 
466
      return 0;
 
467
    }
 
468
 
 
469
    /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
 
470
    user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
 
471
                             sctx->priv_user ? sctx->priv_user : "", "[",
 
472
                             sctx->user ? sctx->user : "", "] @ ",
 
473
                             sctx->host ? sctx->host : "", " [",
 
474
                             sctx->ip ? sctx->ip : "", "]", NullS) -
 
475
                    user_host_buff);
 
476
 
 
477
    current_time= my_time_possible_from_micro(current_utime);
 
478
    if (thd->start_utime)
 
479
    {
 
480
      query_utime= (current_utime - thd->start_utime);
 
481
      lock_utime=  (thd->utime_after_lock - thd->start_utime);
 
482
    }
 
483
    else
 
484
    {
 
485
      query_utime= lock_utime= 0;
 
486
    }
 
487
 
 
488
    if (!query)
 
489
    {
 
490
      is_command= TRUE;
 
491
      query= command_name[thd->command].str;
 
492
      query_length= command_name[thd->command].length;
 
493
    }
 
494
 
 
495
    for (current_handler= slow_log_handler_list; *current_handler ;)
 
496
      error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
 
497
                                            user_host_buff, user_host_len,
 
498
                                            query_utime, lock_utime, is_command,
 
499
                                            query, query_length) || error;
 
500
 
 
501
    unlock();
 
502
  }
 
503
  return error;
 
504
}
 
505
 
 
506
bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
 
507
                               const char *query, uint query_length)
 
508
{
 
509
  bool error= FALSE;
 
510
  Log_event_handler **current_handler= general_log_handler_list;
 
511
  char user_host_buff[MAX_USER_HOST_SIZE];
 
512
  Security_context *sctx= thd->security_ctx;
 
513
  ulong id;
 
514
  uint user_host_len= 0;
 
515
  time_t current_time;
 
516
 
 
517
  if (thd)
 
518
    id= thd->thread_id;                 /* Normal thread */
 
519
  else
 
520
    id= 0;                              /* Log from connect handler */
 
521
 
 
522
  lock_shared();
 
523
  if (!opt_log)
 
524
  {
 
525
    unlock();
 
526
    return 0;
 
527
  }
 
528
  user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
 
529
                          sctx->priv_user ? sctx->priv_user : "", "[",
 
530
                          sctx->user ? sctx->user : "", "] @ ",
 
531
                          sctx->host ? sctx->host : "", " [",
 
532
                          sctx->ip ? sctx->ip : "", "]", NullS) -
 
533
                                                          user_host_buff;
 
534
 
 
535
  current_time= my_time(0);
 
536
 
 
537
  while (*current_handler)
 
538
    error|= (*current_handler++)->
 
539
      log_general(thd, current_time, user_host_buff,
 
540
                  user_host_len, id,
 
541
                  command_name[(uint) command].str,
 
542
                  command_name[(uint) command].length,
 
543
                  query, query_length,
 
544
                  thd->variables.character_set_client) || error;
 
545
  unlock();
 
546
 
 
547
  return error;
 
548
}
 
549
 
 
550
bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
 
551
                               const char *format, va_list args)
 
552
{
 
553
  uint message_buff_len= 0;
 
554
  char message_buff[MAX_LOG_BUFFER_SIZE];
 
555
 
 
556
  /* prepare message */
 
557
  if (format)
 
558
    message_buff_len= my_vsnprintf(message_buff, sizeof(message_buff),
 
559
                                   format, args);
 
560
  else
 
561
    message_buff[0]= '\0';
 
562
 
 
563
  return general_log_write(thd, command, message_buff, message_buff_len);
 
564
}
 
565
 
 
566
void LOGGER::init_error_log(uint error_log_printer)
291
567
{
292
568
  if (error_log_printer & LOG_NONE)
293
569
  {
295
571
    return;
296
572
  }
297
573
 
298
 
}
299
 
 
300
 
int LOGGER::set_handlers(uint32_t error_log_printer)
 
574
  switch (error_log_printer) {
 
575
  case LOG_FILE:
 
576
    error_log_handler_list[0]= file_log_handler;
 
577
    error_log_handler_list[1]= 0;
 
578
    break;
 
579
    /* these two are disabled for now */
 
580
  case LOG_TABLE:
 
581
    DBUG_ASSERT(0);
 
582
    break;
 
583
  case LOG_TABLE|LOG_FILE:
 
584
    DBUG_ASSERT(0);
 
585
    break;
 
586
  }
 
587
}
 
588
 
 
589
void LOGGER::init_slow_log(uint slow_log_printer)
 
590
{
 
591
  if (slow_log_printer & LOG_NONE)
 
592
  {
 
593
    slow_log_handler_list[0]= 0;
 
594
    return;
 
595
  }
 
596
 
 
597
  slow_log_handler_list[0]= file_log_handler;
 
598
  slow_log_handler_list[1]= 0;
 
599
}
 
600
 
 
601
void LOGGER::init_general_log(uint general_log_printer)
 
602
{
 
603
  if (general_log_printer & LOG_NONE)
 
604
  {
 
605
    general_log_handler_list[0]= 0;
 
606
    return;
 
607
  }
 
608
 
 
609
  general_log_handler_list[0]= file_log_handler;
 
610
  general_log_handler_list[1]= 0;
 
611
}
 
612
 
 
613
 
 
614
bool LOGGER::activate_log_handler(THD* thd, uint log_type)
 
615
{
 
616
  MYSQL_QUERY_LOG *file_log;
 
617
  bool res= FALSE;
 
618
  lock_exclusive();
 
619
  switch (log_type) {
 
620
  case QUERY_LOG_SLOW:
 
621
    if (!opt_slow_log)
 
622
    {
 
623
      file_log= file_log_handler->get_mysql_slow_log();
 
624
 
 
625
      file_log->open_slow_log(sys_var_slow_log_path.value);
 
626
      init_slow_log(log_output_options);
 
627
      opt_slow_log= TRUE;
 
628
    }
 
629
    break;
 
630
  case QUERY_LOG_GENERAL:
 
631
    if (!opt_log)
 
632
    {
 
633
      file_log= file_log_handler->get_mysql_log();
 
634
 
 
635
      file_log->open_query_log(sys_var_general_log_path.value);
 
636
      init_general_log(log_output_options);
 
637
      opt_log= TRUE;
 
638
    }
 
639
    break;
 
640
  default:
 
641
    DBUG_ASSERT(0);
 
642
  }
 
643
  unlock();
 
644
  return res;
 
645
}
 
646
 
 
647
 
 
648
void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
 
649
{
 
650
  my_bool *tmp_opt= 0;
 
651
  MYSQL_LOG *file_log;
 
652
 
 
653
  switch (log_type) {
 
654
  case QUERY_LOG_SLOW:
 
655
    tmp_opt= &opt_slow_log;
 
656
    file_log= file_log_handler->get_mysql_slow_log();
 
657
    break;
 
658
  case QUERY_LOG_GENERAL:
 
659
    tmp_opt= &opt_log;
 
660
    file_log= file_log_handler->get_mysql_log();
 
661
    break;
 
662
  default:
 
663
    assert(0);                                  // Impossible
 
664
  }
 
665
 
 
666
  if (!(*tmp_opt))
 
667
    return;
 
668
 
 
669
  lock_exclusive();
 
670
  file_log->close(0);
 
671
  *tmp_opt= FALSE;
 
672
  unlock();
 
673
}
 
674
 
 
675
int LOGGER::set_handlers(uint error_log_printer,
 
676
                         uint slow_log_printer,
 
677
                         uint general_log_printer)
301
678
{
302
679
  /* error log table is not supported yet */
 
680
  DBUG_ASSERT(error_log_printer < LOG_TABLE);
 
681
 
303
682
  lock_exclusive();
304
683
 
305
684
  init_error_log(error_log_printer);
 
685
  init_slow_log(slow_log_printer);
 
686
  init_general_log(general_log_printer);
 
687
 
306
688
  unlock();
307
689
 
308
690
  return 0;
327
709
static void
328
710
binlog_trans_log_savepos(THD *thd, my_off_t *pos)
329
711
{
330
 
  assert(pos != NULL);
 
712
  DBUG_ENTER("binlog_trans_log_savepos");
 
713
  DBUG_ASSERT(pos != NULL);
331
714
  if (thd_get_ha_data(thd, binlog_hton) == NULL)
332
715
    thd->binlog_setup_trx_data();
333
716
  binlog_trx_data *const trx_data=
334
717
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
335
 
  assert(mysql_bin_log.is_open());
 
718
  DBUG_ASSERT(mysql_bin_log.is_open());
336
719
  *pos= trx_data->position();
337
 
  return;
 
720
  DBUG_PRINT("return", ("*pos: %lu", (ulong) *pos));
 
721
  DBUG_VOID_RETURN;
338
722
}
339
723
 
340
724
 
356
740
static void
357
741
binlog_trans_log_truncate(THD *thd, my_off_t pos)
358
742
{
359
 
  assert(thd_get_ha_data(thd, binlog_hton) != NULL);
 
743
  DBUG_ENTER("binlog_trans_log_truncate");
 
744
  DBUG_PRINT("enter", ("pos: %lu", (ulong) pos));
 
745
 
 
746
  DBUG_ASSERT(thd_get_ha_data(thd, binlog_hton) != NULL);
360
747
  /* Only true if binlog_trans_log_savepos() wasn't called before */
361
 
  assert(pos != ~(my_off_t) 0);
 
748
  DBUG_ASSERT(pos != ~(my_off_t) 0);
362
749
 
363
750
  binlog_trx_data *const trx_data=
364
751
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
365
752
  trx_data->truncate(pos);
366
 
  return;
 
753
  DBUG_VOID_RETURN;
367
754
}
368
755
 
369
756
 
370
757
/*
371
758
  this function is mostly a placeholder.
372
 
  conceptually, binlog initialization (now mostly done in DRIZZLE_BIN_LOG::open)
 
759
  conceptually, binlog initialization (now mostly done in MYSQL_BIN_LOG::open)
373
760
  should be moved here.
374
761
*/
375
762
 
377
764
{
378
765
  binlog_hton= (handlerton *)p;
379
766
  binlog_hton->state=opt_bin_log ? SHOW_OPTION_YES : SHOW_OPTION_NO;
 
767
  binlog_hton->db_type=DB_TYPE_BINLOG;
380
768
  binlog_hton->savepoint_offset= sizeof(my_off_t);
381
769
  binlog_hton->close_connection= binlog_close_connection;
382
770
  binlog_hton->savepoint_set= binlog_savepoint_set;
385
773
  binlog_hton->rollback= binlog_rollback;
386
774
  binlog_hton->prepare= binlog_prepare;
387
775
  binlog_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN;
388
 
 
389
776
  return 0;
390
777
}
391
778
 
392
 
static int binlog_close_connection(handlerton *hton __attribute__((unused)),
393
 
                                   THD *thd)
 
779
static int binlog_close_connection(handlerton *hton, THD *thd)
394
780
{
395
781
  binlog_trx_data *const trx_data=
396
782
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
397
 
  assert(trx_data->empty());
 
783
  DBUG_ASSERT(trx_data->empty());
398
784
  thd_set_ha_data(thd, binlog_hton, NULL);
399
785
  trx_data->~binlog_trx_data();
400
 
  free((unsigned char*)trx_data);
 
786
  my_free((uchar*)trx_data, MYF(0));
401
787
  return 0;
402
788
}
403
789
 
428
814
binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
429
815
                 Log_event *end_ev, bool all)
430
816
{
 
817
  DBUG_ENTER("binlog_end_trans");
431
818
  int error=0;
432
819
  IO_CACHE *trans_log= &trx_data->trans_log;
 
820
  DBUG_PRINT("enter", ("transaction: %s  end_ev: 0x%lx",
 
821
                       all ? "all" : "stmt", (long) end_ev));
 
822
  DBUG_PRINT("info", ("thd->options={ %s%s}",
 
823
                      FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
 
824
                      FLAGSTR(thd->options, OPTION_BEGIN)));
433
825
 
434
826
  /*
435
827
    NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of
449
841
      were, we would have to ensure that we're not ending a statement
450
842
      inside a stored function.
451
843
     */
452
 
    thd->binlog_flush_pending_rows_event(true);
 
844
    thd->binlog_flush_pending_rows_event(TRUE);
453
845
 
454
846
    error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev);
455
847
    trx_data->reset();
479
871
    {
480
872
      trx_data->reset();
481
873
 
482
 
      assert(!thd->binlog_get_pending_rows_event());
 
874
      DBUG_ASSERT(!thd->binlog_get_pending_rows_event());
483
875
      thd->clear_binlog_table_maps();
484
876
    }
485
877
    else                                        // ...statement
493
885
    mysql_bin_log.update_table_map_version();
494
886
  }
495
887
 
496
 
  return(error);
 
888
  DBUG_RETURN(error);
497
889
}
498
890
 
499
 
static int binlog_prepare(handlerton *hton __attribute__((unused)),
500
 
                          THD *thd __attribute__((unused)),
501
 
                          bool all __attribute__((unused)))
 
891
static int binlog_prepare(handlerton *hton, THD *thd, bool all)
502
892
{
503
893
  /*
504
894
    do nothing.
505
895
    just pretend we can do 2pc, so that MySQL won't
506
896
    switch to 1pc.
507
 
    real work will be done in DRIZZLE_BIN_LOG::log_xid()
 
897
    real work will be done in MYSQL_BIN_LOG::log_xid()
508
898
  */
509
899
  return 0;
510
900
}
524
914
 
525
915
  @see handlerton::commit
526
916
*/
527
 
static int binlog_commit(handlerton *hton __attribute__((unused)),
528
 
                         THD *thd, bool all)
 
917
static int binlog_commit(handlerton *hton, THD *thd, bool all)
529
918
{
 
919
  DBUG_ENTER("binlog_commit");
530
920
  binlog_trx_data *const trx_data=
531
921
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
532
922
 
533
923
  if (trx_data->empty())
534
924
  {
535
 
    // we're here because trans_log was flushed in DRIZZLE_BIN_LOG::log_xid()
 
925
    // we're here because trans_log was flushed in MYSQL_BIN_LOG::log_xid()
536
926
    trx_data->reset();
537
 
    return(0);
 
927
    DBUG_RETURN(0);
538
928
  }
539
929
 
540
930
  /*
595
985
 
596
986
    Otherwise, we accumulate the statement
597
987
  */
598
 
  uint64_t const in_transaction=
 
988
  ulonglong const in_transaction=
599
989
    thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
 
990
  DBUG_PRINT("debug",
 
991
             ("all: %d, empty: %s, in_transaction: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
 
992
              all,
 
993
              YESNO(trx_data->empty()),
 
994
              YESNO(in_transaction),
 
995
              YESNO(thd->transaction.all.modified_non_trans_table),
 
996
              YESNO(thd->transaction.stmt.modified_non_trans_table)));
600
997
  if ((in_transaction && (all || (!trx_data->at_least_one_stmt && thd->transaction.stmt.modified_non_trans_table))) || (!in_transaction && !all))
601
998
  {
602
 
    Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), true, false);
603
 
    qev.error_code= 0; // see comment in DRIZZLE_LOG::write(THD, IO_CACHE)
 
999
    Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
 
1000
    qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
604
1001
    int error= binlog_end_trans(thd, trx_data, &qev, all);
605
 
    return(error);
 
1002
    DBUG_RETURN(error);
606
1003
  }
607
 
  return(0);
 
1004
  DBUG_RETURN(0);
608
1005
}
609
1006
 
610
1007
/**
622
1019
 
623
1020
  @see handlerton::rollback
624
1021
*/
625
 
static int binlog_rollback(handlerton *hton __attribute__((unused)),
626
 
                           THD *thd, bool all)
 
1022
static int binlog_rollback(handlerton *hton, THD *thd, bool all)
627
1023
{
 
1024
  DBUG_ENTER("binlog_rollback");
628
1025
  int error=0;
629
1026
  binlog_trx_data *const trx_data=
630
1027
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
631
1028
 
632
1029
  if (trx_data->empty()) {
633
1030
    trx_data->reset();
634
 
    return(0);
 
1031
    DBUG_RETURN(0);
635
1032
  }
636
1033
 
 
1034
  DBUG_PRINT("debug", ("all: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
 
1035
                       YESNO(all),
 
1036
                       YESNO(thd->transaction.all.modified_non_trans_table),
 
1037
                       YESNO(thd->transaction.stmt.modified_non_trans_table)));
637
1038
  if ((all && thd->transaction.all.modified_non_trans_table) ||
638
1039
      (!all && thd->transaction.stmt.modified_non_trans_table) ||
639
1040
      (thd->options & OPTION_KEEP_LOG))
646
1047
      transactional table in that statement as well, which needs to be
647
1048
      rolled back on the slave.
648
1049
    */
649
 
    Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), true, false);
650
 
    qev.error_code= 0; // see comment in DRIZZLE_LOG::write(THD, IO_CACHE)
 
1050
    Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
 
1051
    qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
651
1052
    error= binlog_end_trans(thd, trx_data, &qev, all);
652
1053
  }
653
1054
  else if ((all && !thd->transaction.all.modified_non_trans_table) ||
660
1061
     */
661
1062
    error= binlog_end_trans(thd, trx_data, 0, all);
662
1063
  }
663
 
  return(error);
 
1064
  DBUG_RETURN(error);
664
1065
}
665
1066
 
666
1067
/**
687
1088
  that case there is no need to have it in the binlog).
688
1089
*/
689
1090
 
690
 
static int binlog_savepoint_set(handlerton *hton __attribute__((unused)),
691
 
                                THD *thd, void *sv)
 
1091
static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
692
1092
{
 
1093
  DBUG_ENTER("binlog_savepoint_set");
 
1094
 
693
1095
  binlog_trans_log_savepos(thd, (my_off_t*) sv);
694
1096
  /* Write it to the binary log */
695
1097
  
696
1098
  int const error=
697
1099
    thd->binlog_query(THD::STMT_QUERY_TYPE,
698
 
                      thd->query, thd->query_length, true, false);
699
 
  return(error);
 
1100
                      thd->query, thd->query_length, TRUE, FALSE);
 
1101
  DBUG_RETURN(error);
700
1102
}
701
1103
 
702
 
static int binlog_savepoint_rollback(handlerton *hton __attribute__((unused)),
703
 
                                     THD *thd, void *sv)
 
1104
static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
704
1105
{
 
1106
  DBUG_ENTER("binlog_savepoint_rollback");
 
1107
 
705
1108
  /*
706
1109
    Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
707
1110
    non-transactional table. Otherwise, truncate the binlog cache starting
712
1115
  {
713
1116
    int error=
714
1117
      thd->binlog_query(THD::STMT_QUERY_TYPE,
715
 
                        thd->query, thd->query_length, true, false);
716
 
    return(error);
 
1118
                        thd->query, thd->query_length, TRUE, FALSE);
 
1119
    DBUG_RETURN(error);
717
1120
  }
718
1121
  binlog_trans_log_truncate(thd, *(my_off_t*)sv);
719
 
  return(0);
 
1122
  DBUG_RETURN(0);
720
1123
}
721
1124
 
722
1125
 
723
1126
int check_binlog_magic(IO_CACHE* log, const char** errmsg)
724
1127
{
725
1128
  char magic[4];
726
 
  assert(my_b_tell(log) == 0);
 
1129
  DBUG_ASSERT(my_b_tell(log) == 0);
727
1130
 
728
 
  if (my_b_read(log, (unsigned char*) magic, sizeof(magic)))
 
1131
  if (my_b_read(log, (uchar*) magic, sizeof(magic)))
729
1132
  {
730
 
    *errmsg = _("I/O error reading the header from the binary log");
 
1133
    *errmsg = "I/O error reading the header from the binary log";
731
1134
    sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
732
1135
                    log->error);
733
1136
    return 1;
734
1137
  }
735
1138
  if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
736
1139
  {
737
 
    *errmsg = _("Binlog has bad magic number;  It's not a binary log file "
738
 
                "that can be used by this version of Drizzle");
 
1140
    *errmsg = "Binlog has bad magic number;  It's not a binary log file that can be used by this version of MySQL";
739
1141
    return 1;
740
1142
  }
741
1143
  return 0;
745
1147
File open_binlog(IO_CACHE *log, const char *log_file_name, const char **errmsg)
746
1148
{
747
1149
  File file;
 
1150
  DBUG_ENTER("open_binlog");
748
1151
 
749
 
  if ((file = my_open(log_file_name, O_RDONLY, 
 
1152
  if ((file = my_open(log_file_name, O_RDONLY | O_BINARY | O_SHARE, 
750
1153
                      MYF(MY_WME))) < 0)
751
1154
  {
752
 
    sql_print_error(_("Failed to open log (file '%s', errno %d)"),
 
1155
    sql_print_error("Failed to open log (file '%s', errno %d)",
753
1156
                    log_file_name, my_errno);
754
 
    *errmsg = _("Could not open log file");
 
1157
    *errmsg = "Could not open log file";
755
1158
    goto err;
756
1159
  }
757
1160
  if (init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
758
1161
                    MYF(MY_WME|MY_DONT_CHECK_FILESIZE)))
759
1162
  {
760
 
    sql_print_error(_("Failed to create a cache on log (file '%s')"),
 
1163
    sql_print_error("Failed to create a cache on log (file '%s')",
761
1164
                    log_file_name);
762
 
    *errmsg = _("Could not open log file");
 
1165
    *errmsg = "Could not open log file";
763
1166
    goto err;
764
1167
  }
765
1168
  if (check_binlog_magic(log,errmsg))
766
1169
    goto err;
767
 
  return(file);
 
1170
  DBUG_RETURN(file);
768
1171
 
769
1172
err:
770
1173
  if (file >= 0)
772
1175
    my_close(file,MYF(0));
773
1176
    end_io_cache(log);
774
1177
  }
775
 
  return(-1);
 
1178
  DBUG_RETURN(-1);
776
1179
}
777
1180
 
778
1181
 
788
1191
static int find_uniq_filename(char *name)
789
1192
{
790
1193
  long                  number;
791
 
  uint32_t                  i;
 
1194
  uint                  i;
792
1195
  char                  buff[FN_REFLEN];
793
1196
  struct st_my_dir     *dir_info;
794
1197
  register struct fileinfo *file_info;
795
1198
  ulong                 max_found=0;
796
1199
  size_t                buf_length, length;
797
1200
  char                  *start, *end;
 
1201
  DBUG_ENTER("find_uniq_filename");
798
1202
 
799
1203
  length= dirname_part(buff, name, &buf_length);
800
1204
  start=  name + length;
801
 
  end= strchr(start, '\0');
 
1205
  end=    strend(start);
802
1206
 
803
1207
  *end='.';
804
1208
  length= (size_t) (end-start+1);
805
1209
 
806
1210
  if (!(dir_info = my_dir(buff,MYF(MY_DONT_SORT))))
807
1211
  {                                             // This shouldn't happen
808
 
    my_stpcpy(end,".1");                                // use name+1
809
 
    return(0);
 
1212
    strmov(end,".1");                           // use name+1
 
1213
    DBUG_RETURN(0);
810
1214
  }
811
1215
  file_info= dir_info->dir_entry;
812
1216
  for (i=dir_info->number_off_files ; i-- ; file_info++)
813
1217
  {
814
 
    if (memcmp(file_info->name, start, length) == 0 &&
 
1218
    if (bcmp((uchar*) file_info->name, (uchar*) start, length) == 0 &&
815
1219
        test_if_number(file_info->name+length, &number,0))
816
1220
    {
817
1221
      set_if_bigger(max_found,(ulong) number);
821
1225
 
822
1226
  *end++='.';
823
1227
  sprintf(end,"%06ld",max_found+1);
824
 
  return(0);
 
1228
  DBUG_RETURN(0);
825
1229
}
826
1230
 
827
1231
 
828
 
void DRIZZLE_LOG::init(enum_log_type log_type_arg,
 
1232
void MYSQL_LOG::init(enum_log_type log_type_arg,
829
1233
                     enum cache_type io_cache_type_arg)
830
1234
{
 
1235
  DBUG_ENTER("MYSQL_LOG::init");
831
1236
  log_type= log_type_arg;
832
1237
  io_cache_type= io_cache_type_arg;
833
 
  return;
 
1238
  DBUG_PRINT("info",("log_type: %d", log_type));
 
1239
  DBUG_VOID_RETURN;
834
1240
}
835
1241
 
836
1242
 
855
1261
    1   error
856
1262
*/
857
1263
 
858
 
bool DRIZZLE_LOG::open(const char *log_name, enum_log_type log_type_arg,
 
1264
bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
859
1265
                     const char *new_name, enum cache_type io_cache_type_arg)
860
1266
{
861
1267
  char buff[FN_REFLEN];
862
1268
  File file= -1;
863
 
  int open_flags= O_CREAT;
 
1269
  int open_flags= O_CREAT | O_BINARY;
 
1270
  DBUG_ENTER("MYSQL_LOG::open");
 
1271
  DBUG_PRINT("enter", ("log_type: %d", (int) log_type_arg));
864
1272
 
865
1273
  write_error= 0;
866
1274
 
873
1281
  }
874
1282
 
875
1283
  if (new_name)
876
 
    my_stpcpy(log_file_name, new_name);
 
1284
    strmov(log_file_name, new_name);
877
1285
  else if (generate_new_name(log_file_name, name))
878
1286
    goto err;
879
1287
 
895
1303
  if (log_type == LOG_NORMAL)
896
1304
  {
897
1305
    char *end;
898
 
    int len=snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
899
 
                     "started with:\nTCP Port: %d, Named Pipe: %s\n",
900
 
                     my_progname, server_version, DRIZZLE_COMPILATION_COMMENT,
901
 
                     mysqld_port, ""
902
 
                     );
903
 
    end= my_stpncpy(buff + len, "Time                 Id Command    Argument\n",
 
1306
    int len=my_snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
 
1307
                        "started with:\nTCP Port: %d, Named Pipe: %s\n",
 
1308
                        my_progname, server_version, MYSQL_COMPILATION_COMMENT,
 
1309
                        mysqld_port, ""
 
1310
                       );
 
1311
    end= strnmov(buff + len, "Time                 Id Command    Argument\n",
904
1312
                 sizeof(buff) - len);
905
 
    if (my_b_write(&log_file, (unsigned char*) buff, (uint) (end-buff)) ||
 
1313
    if (my_b_write(&log_file, (uchar*) buff, (uint) (end-buff)) ||
906
1314
        flush_io_cache(&log_file))
907
1315
      goto err;
908
1316
  }
909
1317
 
910
1318
  log_state= LOG_OPENED;
911
 
  return(0);
 
1319
  DBUG_RETURN(0);
912
1320
 
913
1321
err:
914
 
  sql_print_error(_("Could not use %s for logging (error %d). "
915
 
                    "Turning logging off for the whole duration of the "
916
 
                    "Drizzle server process. "
917
 
                    "To turn it on again: fix the cause, "
918
 
                    "shutdown the Drizzle server and restart it."),
919
 
                    name, errno);
 
1322
  sql_print_error("Could not use %s for logging (error %d). \
 
1323
Turning logging off for the whole duration of the MySQL server process. \
 
1324
To turn it on again: fix the cause, \
 
1325
shutdown the MySQL server and restart it.", name, errno);
920
1326
  if (file >= 0)
921
1327
    my_close(file, MYF(0));
922
1328
  end_io_cache(&log_file);
923
 
  if (name)
924
 
  {
925
 
    free(name);
926
 
    name= NULL;
927
 
  }
 
1329
  safeFree(name);
928
1330
  log_state= LOG_CLOSED;
929
 
  return(1);
 
1331
  DBUG_RETURN(1);
930
1332
}
931
1333
 
932
 
DRIZZLE_LOG::DRIZZLE_LOG()
933
 
  : name(0), write_error(false), inited(false), log_type(LOG_UNKNOWN),
 
1334
MYSQL_LOG::MYSQL_LOG()
 
1335
  : name(0), write_error(FALSE), inited(FALSE), log_type(LOG_UNKNOWN),
934
1336
    log_state(LOG_CLOSED)
935
1337
{
936
1338
  /*
939
1341
    called only in main(). Doing initialization here would make it happen
940
1342
    before main().
941
1343
  */
942
 
  memset(&log_file, 0, sizeof(log_file));
 
1344
  bzero((char*) &log_file, sizeof(log_file));
943
1345
}
944
1346
 
945
 
void DRIZZLE_LOG::init_pthread_objects()
 
1347
void MYSQL_LOG::init_pthread_objects()
946
1348
{
947
 
  assert(inited == 0);
 
1349
  DBUG_ASSERT(inited == 0);
948
1350
  inited= 1;
949
1351
  (void) pthread_mutex_init(&LOCK_log, MY_MUTEX_INIT_SLOW);
950
1352
}
963
1365
    The internal structures are not freed until cleanup() is called
964
1366
*/
965
1367
 
966
 
void DRIZZLE_LOG::close(uint32_t exiting)
 
1368
void MYSQL_LOG::close(uint exiting)
967
1369
{                                       // One can't set log_type here!
 
1370
  DBUG_ENTER("MYSQL_LOG::close");
 
1371
  DBUG_PRINT("enter",("exiting: %d", (int) exiting));
968
1372
  if (log_state == LOG_OPENED)
969
1373
  {
970
1374
    end_io_cache(&log_file);
983
1387
  }
984
1388
 
985
1389
  log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
986
 
  if (name)
987
 
  {
988
 
    free(name);
989
 
    name= NULL;
990
 
  }
991
 
  return;
 
1390
  safeFree(name);
 
1391
  DBUG_VOID_RETURN;
992
1392
}
993
1393
 
994
1394
/** This is called only once. */
995
1395
 
996
 
void DRIZZLE_LOG::cleanup()
 
1396
void MYSQL_LOG::cleanup()
997
1397
{
 
1398
  DBUG_ENTER("cleanup");
998
1399
  if (inited)
999
1400
  {
1000
1401
    inited= 0;
1001
1402
    (void) pthread_mutex_destroy(&LOCK_log);
1002
1403
    close(0);
1003
1404
  }
1004
 
  return;
 
1405
  DBUG_VOID_RETURN;
1005
1406
}
1006
1407
 
1007
1408
 
1008
 
int DRIZZLE_LOG::generate_new_name(char *new_name, const char *log_name)
 
1409
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
1009
1410
{
1010
1411
  fn_format(new_name, log_name, mysql_data_home, "", 4);
1011
1412
  if (log_type == LOG_BIN)
1023
1424
}
1024
1425
 
1025
1426
 
 
1427
/*
 
1428
  Reopen the log file
 
1429
 
 
1430
  SYNOPSIS
 
1431
    reopen_file()
 
1432
 
 
1433
  DESCRIPTION
 
1434
    Reopen the log file. The method is used during FLUSH LOGS
 
1435
    and locks LOCK_log mutex
 
1436
*/
 
1437
 
 
1438
 
 
1439
void MYSQL_QUERY_LOG::reopen_file()
 
1440
{
 
1441
  char *save_name;
 
1442
 
 
1443
  DBUG_ENTER("MYSQL_LOG::reopen_file");
 
1444
  if (!is_open())
 
1445
  {
 
1446
    DBUG_PRINT("info",("log is closed"));
 
1447
    DBUG_VOID_RETURN;
 
1448
  }
 
1449
 
 
1450
  pthread_mutex_lock(&LOCK_log);
 
1451
 
 
1452
  save_name= name;
 
1453
  name= 0;                              // Don't free name
 
1454
  close(LOG_CLOSE_TO_BE_OPENED);
 
1455
 
 
1456
  /*
 
1457
     Note that at this point, log_state != LOG_CLOSED (important for is_open()).
 
1458
  */
 
1459
 
 
1460
  open(save_name, log_type, 0, io_cache_type);
 
1461
  my_free(save_name, MYF(0));
 
1462
 
 
1463
  pthread_mutex_unlock(&LOCK_log);
 
1464
 
 
1465
  DBUG_VOID_RETURN;
 
1466
}
 
1467
 
 
1468
 
 
1469
/*
 
1470
  Write a command to traditional general log file
 
1471
 
 
1472
  SYNOPSIS
 
1473
    write()
 
1474
 
 
1475
    event_time        command start timestamp
 
1476
    user_host         the pointer to the string with user@host info
 
1477
    user_host_len     length of the user_host string. this is computed once
 
1478
                      and passed to all general log  event handlers
 
1479
    thread_id         Id of the thread, issued a query
 
1480
    command_type      the type of the command being logged
 
1481
    command_type_len  the length of the string above
 
1482
    sql_text          the very text of the query being executed
 
1483
    sql_text_len      the length of sql_text string
 
1484
 
 
1485
  DESCRIPTION
 
1486
 
 
1487
   Log given command to to normal (not rotable) log file
 
1488
 
 
1489
  RETURN
 
1490
    FASE - OK
 
1491
    TRUE - error occured
 
1492
*/
 
1493
 
 
1494
bool MYSQL_QUERY_LOG::write(time_t event_time, const char *user_host,
 
1495
                            uint user_host_len, int thread_id,
 
1496
                            const char *command_type, uint command_type_len,
 
1497
                            const char *sql_text, uint sql_text_len)
 
1498
{
 
1499
  char buff[32];
 
1500
  uint length= 0;
 
1501
  char local_time_buff[MAX_TIME_SIZE];
 
1502
  struct tm start;
 
1503
  uint time_buff_len= 0;
 
1504
 
 
1505
  (void) pthread_mutex_lock(&LOCK_log);
 
1506
 
 
1507
  /* Test if someone closed between the is_open test and lock */
 
1508
  if (is_open())
 
1509
  {
 
1510
    /* Note that my_b_write() assumes it knows the length for this */
 
1511
      if (event_time != last_time)
 
1512
      {
 
1513
        last_time= event_time;
 
1514
 
 
1515
        localtime_r(&event_time, &start);
 
1516
 
 
1517
        time_buff_len= my_snprintf(local_time_buff, MAX_TIME_SIZE,
 
1518
                                   "%02d%02d%02d %2d:%02d:%02d",
 
1519
                                   start.tm_year % 100, start.tm_mon + 1,
 
1520
                                   start.tm_mday, start.tm_hour,
 
1521
                                   start.tm_min, start.tm_sec);
 
1522
 
 
1523
        if (my_b_write(&log_file, (uchar*) local_time_buff, time_buff_len))
 
1524
          goto err;
 
1525
      }
 
1526
      else
 
1527
        if (my_b_write(&log_file, (uchar*) "\t\t" ,2) < 0)
 
1528
          goto err;
 
1529
 
 
1530
      /* command_type, thread_id */
 
1531
      length= my_snprintf(buff, 32, "%5ld ", (long) thread_id);
 
1532
 
 
1533
    if (my_b_write(&log_file, (uchar*) buff, length))
 
1534
      goto err;
 
1535
 
 
1536
    if (my_b_write(&log_file, (uchar*) command_type, command_type_len))
 
1537
      goto err;
 
1538
 
 
1539
    if (my_b_write(&log_file, (uchar*) "\t", 1))
 
1540
      goto err;
 
1541
 
 
1542
    /* sql_text */
 
1543
    if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len))
 
1544
      goto err;
 
1545
 
 
1546
    if (my_b_write(&log_file, (uchar*) "\n", 1) ||
 
1547
        flush_io_cache(&log_file))
 
1548
      goto err;
 
1549
  }
 
1550
 
 
1551
  (void) pthread_mutex_unlock(&LOCK_log);
 
1552
  return FALSE;
 
1553
err:
 
1554
 
 
1555
  if (!write_error)
 
1556
  {
 
1557
    write_error= 1;
 
1558
    sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
 
1559
  }
 
1560
  (void) pthread_mutex_unlock(&LOCK_log);
 
1561
  return TRUE;
 
1562
}
 
1563
 
 
1564
 
 
1565
/*
 
1566
  Log a query to the traditional slow log file
 
1567
 
 
1568
  SYNOPSIS
 
1569
    write()
 
1570
 
 
1571
    thd               THD of the query
 
1572
    current_time      current timestamp
 
1573
    query_start_arg   command start timestamp
 
1574
    user_host         the pointer to the string with user@host info
 
1575
    user_host_len     length of the user_host string. this is computed once
 
1576
                      and passed to all general log event handlers
 
1577
    query_utime       Amount of time the query took to execute (in microseconds)
 
1578
    lock_utime        Amount of time the query was locked (in microseconds)
 
1579
    is_command        The flag, which determines, whether the sql_text is a
 
1580
                      query or an administrator command.
 
1581
    sql_text          the very text of the query or administrator command
 
1582
                      processed
 
1583
    sql_text_len      the length of sql_text string
 
1584
 
 
1585
  DESCRIPTION
 
1586
 
 
1587
   Log a query to the slow log file.
 
1588
 
 
1589
  RETURN
 
1590
    FALSE - OK
 
1591
    TRUE - error occured
 
1592
*/
 
1593
 
 
1594
bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
 
1595
                            time_t query_start_arg, const char *user_host,
 
1596
                            uint user_host_len, ulonglong query_utime,
 
1597
                            ulonglong lock_utime, bool is_command,
 
1598
                            const char *sql_text, uint sql_text_len)
 
1599
{
 
1600
  bool error= 0;
 
1601
  DBUG_ENTER("MYSQL_QUERY_LOG::write");
 
1602
 
 
1603
  (void) pthread_mutex_lock(&LOCK_log);
 
1604
 
 
1605
  if (!is_open())
 
1606
  {
 
1607
    (void) pthread_mutex_unlock(&LOCK_log);
 
1608
    DBUG_RETURN(0);
 
1609
  }
 
1610
 
 
1611
  if (is_open())
 
1612
  {                                             // Safety agains reopen
 
1613
    int tmp_errno= 0;
 
1614
    char buff[80], *end;
 
1615
    char query_time_buff[22+7], lock_time_buff[22+7];
 
1616
    uint buff_len;
 
1617
    end= buff;
 
1618
 
 
1619
    if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT))
 
1620
    {
 
1621
      if (current_time != last_time)
 
1622
      {
 
1623
        last_time= current_time;
 
1624
        struct tm start;
 
1625
        localtime_r(&current_time, &start);
 
1626
 
 
1627
        buff_len= my_snprintf(buff, sizeof buff,
 
1628
                              "# Time: %02d%02d%02d %2d:%02d:%02d\n",
 
1629
                              start.tm_year % 100, start.tm_mon + 1,
 
1630
                              start.tm_mday, start.tm_hour,
 
1631
                              start.tm_min, start.tm_sec);
 
1632
 
 
1633
        /* Note that my_b_write() assumes it knows the length for this */
 
1634
        if (my_b_write(&log_file, (uchar*) buff, buff_len))
 
1635
          tmp_errno= errno;
 
1636
      }
 
1637
      const uchar uh[]= "# User@Host: ";
 
1638
      if (my_b_write(&log_file, uh, sizeof(uh) - 1))
 
1639
        tmp_errno= errno;
 
1640
      if (my_b_write(&log_file, (uchar*) user_host, user_host_len))
 
1641
        tmp_errno= errno;
 
1642
      if (my_b_write(&log_file, (uchar*) "\n", 1))
 
1643
        tmp_errno= errno;
 
1644
    }
 
1645
    /* For slow query log */
 
1646
    sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
 
1647
    sprintf(lock_time_buff,  "%.6f", ulonglong2double(lock_utime)/1000000.0);
 
1648
    if (my_b_printf(&log_file,
 
1649
                    "# Query_time: %s  Lock_time: %s"
 
1650
                    " Rows_sent: %lu  Rows_examined: %lu\n",
 
1651
                    query_time_buff, lock_time_buff,
 
1652
                    (ulong) thd->sent_row_count,
 
1653
                    (ulong) thd->examined_row_count) == (uint) -1)
 
1654
      tmp_errno= errno;
 
1655
    if (thd->db && strcmp(thd->db, db))
 
1656
    {                                           // Database changed
 
1657
      if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
 
1658
        tmp_errno= errno;
 
1659
      strmov(db,thd->db);
 
1660
    }
 
1661
    if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
 
1662
    {
 
1663
      end=strmov(end, ",last_insert_id=");
 
1664
      end=longlong10_to_str((longlong)
 
1665
                            thd->first_successful_insert_id_in_prev_stmt_for_binlog,
 
1666
                            end, -10);
 
1667
    }
 
1668
    // Save value if we do an insert.
 
1669
    if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
 
1670
    {
 
1671
      if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT))
 
1672
      {
 
1673
        end=strmov(end,",insert_id=");
 
1674
        end=longlong10_to_str((longlong)
 
1675
                              thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(),
 
1676
                              end, -10);
 
1677
      }
 
1678
    }
 
1679
 
 
1680
    /*
 
1681
      This info used to show up randomly, depending on whether the query
 
1682
      checked the query start time or not. now we always write current
 
1683
      timestamp to the slow log
 
1684
    */
 
1685
    end= strmov(end, ",timestamp=");
 
1686
    end= int10_to_str((long) current_time, end, 10);
 
1687
 
 
1688
    if (end != buff)
 
1689
    {
 
1690
      *end++=';';
 
1691
      *end='\n';
 
1692
      if (my_b_write(&log_file, (uchar*) "SET ", 4) ||
 
1693
          my_b_write(&log_file, (uchar*) buff + 1, (uint) (end-buff)))
 
1694
        tmp_errno= errno;
 
1695
    }
 
1696
    if (is_command)
 
1697
    {
 
1698
      end= strxmov(buff, "# administrator command: ", NullS);
 
1699
      buff_len= (ulong) (end - buff);
 
1700
      my_b_write(&log_file, (uchar*) buff, buff_len);
 
1701
    }
 
1702
    if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len) ||
 
1703
        my_b_write(&log_file, (uchar*) ";\n",2) ||
 
1704
        flush_io_cache(&log_file))
 
1705
      tmp_errno= errno;
 
1706
    if (tmp_errno)
 
1707
    {
 
1708
      error= 1;
 
1709
      if (! write_error)
 
1710
      {
 
1711
        write_error= 1;
 
1712
        sql_print_error(ER(ER_ERROR_ON_WRITE), name, error);
 
1713
      }
 
1714
    }
 
1715
  }
 
1716
  (void) pthread_mutex_unlock(&LOCK_log);
 
1717
  DBUG_RETURN(error);
 
1718
}
 
1719
 
 
1720
 
1026
1721
/**
1027
1722
  @todo
1028
1723
  The following should be using fn_format();  We just need to
1029
1724
  first change fn_format() to cut the file name if it's too long.
1030
1725
*/
1031
 
const char *DRIZZLE_LOG::generate_name(const char *log_name,
 
1726
const char *MYSQL_LOG::generate_name(const char *log_name,
1032
1727
                                      const char *suffix,
1033
1728
                                      bool strip_ext, char *buff)
1034
1729
{
1042
1737
  if (strip_ext)
1043
1738
  {
1044
1739
    char *p= fn_ext(log_name);
1045
 
    uint32_t length= (uint) (p - log_name);
1046
 
    strmake(buff, log_name, cmin(length, (uint)FN_REFLEN));
 
1740
    uint length= (uint) (p - log_name);
 
1741
    strmake(buff, log_name, min(length, FN_REFLEN));
1047
1742
    return (const char*)buff;
1048
1743
  }
1049
1744
  return log_name;
1051
1746
 
1052
1747
 
1053
1748
 
1054
 
DRIZZLE_BIN_LOG::DRIZZLE_BIN_LOG()
 
1749
MYSQL_BIN_LOG::MYSQL_BIN_LOG()
1055
1750
  :bytes_written(0), prepared_xids(0), file_id(1), open_count(1),
1056
 
   need_start_event(true), m_table_map_version(0),
 
1751
   need_start_event(TRUE), m_table_map_version(0),
1057
1752
   description_event_for_exec(0), description_event_for_queue(0)
1058
1753
{
1059
1754
  /*
1063
1758
    before main().
1064
1759
  */
1065
1760
  index_file_name[0] = 0;
1066
 
  memset(&index_file, 0, sizeof(index_file));
 
1761
  bzero((char*) &index_file, sizeof(index_file));
1067
1762
}
1068
1763
 
1069
1764
/* this is called only once */
1070
1765
 
1071
 
void DRIZZLE_BIN_LOG::cleanup()
 
1766
void MYSQL_BIN_LOG::cleanup()
1072
1767
{
 
1768
  DBUG_ENTER("cleanup");
1073
1769
  if (inited)
1074
1770
  {
1075
1771
    inited= 0;
1080
1776
    (void) pthread_mutex_destroy(&LOCK_index);
1081
1777
    (void) pthread_cond_destroy(&update_cond);
1082
1778
  }
1083
 
  return;
 
1779
  DBUG_VOID_RETURN;
1084
1780
}
1085
1781
 
1086
1782
 
1087
1783
/* Init binlog-specific vars */
1088
 
void DRIZZLE_BIN_LOG::init(bool no_auto_events_arg, ulong max_size_arg)
 
1784
void MYSQL_BIN_LOG::init(bool no_auto_events_arg, ulong max_size_arg)
1089
1785
{
 
1786
  DBUG_ENTER("MYSQL_BIN_LOG::init");
1090
1787
  no_auto_events= no_auto_events_arg;
1091
1788
  max_size= max_size_arg;
1092
 
  return;
 
1789
  DBUG_PRINT("info",("max_size: %lu", max_size));
 
1790
  DBUG_VOID_RETURN;
1093
1791
}
1094
1792
 
1095
1793
 
1096
 
void DRIZZLE_BIN_LOG::init_pthread_objects()
 
1794
void MYSQL_BIN_LOG::init_pthread_objects()
1097
1795
{
1098
 
  assert(inited == 0);
 
1796
  DBUG_ASSERT(inited == 0);
1099
1797
  inited= 1;
1100
1798
  (void) pthread_mutex_init(&LOCK_log, MY_MUTEX_INIT_SLOW);
1101
1799
  (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
1103
1801
}
1104
1802
 
1105
1803
 
1106
 
bool DRIZZLE_BIN_LOG::open_index_file(const char *index_file_name_arg,
 
1804
bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
1107
1805
                                const char *log_name)
1108
1806
{
1109
1807
  File index_file_nr= -1;
1110
 
  assert(!my_b_inited(&index_file));
 
1808
  DBUG_ASSERT(!my_b_inited(&index_file));
1111
1809
 
1112
1810
  /*
1113
1811
    First open of this class instance
1123
1821
  fn_format(index_file_name, index_file_name_arg, mysql_data_home,
1124
1822
            ".index", opt);
1125
1823
  if ((index_file_nr= my_open(index_file_name,
1126
 
                              O_RDWR | O_CREAT,
 
1824
                              O_RDWR | O_CREAT | O_BINARY ,
1127
1825
                              MYF(MY_WME))) < 0 ||
1128
1826
       my_sync(index_file_nr, MYF(MY_WME)) ||
1129
1827
       init_io_cache(&index_file, index_file_nr,
1138
1836
    */
1139
1837
    if (index_file_nr >= 0)
1140
1838
      my_close(index_file_nr,MYF(0));
1141
 
    return true;
 
1839
    return TRUE;
1142
1840
  }
1143
 
  return false;
 
1841
  return FALSE;
1144
1842
}
1145
1843
 
1146
1844
 
1158
1856
    1   error
1159
1857
*/
1160
1858
 
1161
 
bool DRIZZLE_BIN_LOG::open(const char *log_name,
 
1859
bool MYSQL_BIN_LOG::open(const char *log_name,
1162
1860
                         enum_log_type log_type_arg,
1163
1861
                         const char *new_name,
1164
1862
                         enum cache_type io_cache_type_arg,
1167
1865
                         bool null_created_arg)
1168
1866
{
1169
1867
  File file= -1;
 
1868
  DBUG_ENTER("MYSQL_BIN_LOG::open");
 
1869
  DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
1170
1870
 
1171
1871
  write_error=0;
1172
1872
 
1173
1873
  /* open the main log file */
1174
 
  if (DRIZZLE_LOG::open(log_name, log_type_arg, new_name, io_cache_type_arg))
1175
 
    return(1);                            /* all warnings issued */
 
1874
  if (MYSQL_LOG::open(log_name, log_type_arg, new_name, io_cache_type_arg))
 
1875
    DBUG_RETURN(1);                            /* all warnings issued */
1176
1876
 
1177
1877
  init(no_auto_events_arg, max_size_arg);
1178
1878
 
1179
1879
  open_count++;
1180
1880
 
1181
 
  assert(log_type == LOG_BIN);
 
1881
  DBUG_ASSERT(log_type == LOG_BIN);
1182
1882
 
1183
1883
  {
1184
1884
    bool write_file_name_to_index_file=0;
1191
1891
        an extension for the binary log files.
1192
1892
        In this case we write a standard header to it.
1193
1893
      */
1194
 
      if (my_b_safe_write(&log_file, (unsigned char*) BINLOG_MAGIC,
 
1894
      if (my_b_safe_write(&log_file, (uchar*) BINLOG_MAGIC,
1195
1895
                          BIN_LOG_HEADER_SIZE))
1196
1896
        goto err;
1197
1897
      bytes_written+= BIN_LOG_HEADER_SIZE;
1198
1898
      write_file_name_to_index_file= 1;
1199
1899
    }
1200
1900
 
1201
 
    assert(my_b_inited(&index_file) != 0);
 
1901
    DBUG_ASSERT(my_b_inited(&index_file) != 0);
1202
1902
    reinit_io_cache(&index_file, WRITE_CACHE,
1203
1903
                    my_b_filelength(&index_file), 0, 0);
1204
1904
    if (need_start_event && !no_auto_events)
1262
1962
        As this is a new log file, we write the file name to the index
1263
1963
        file. As every time we write to the index file, we sync it.
1264
1964
      */
1265
 
      if (my_b_write(&index_file, (unsigned char*) log_file_name,
 
1965
      if (my_b_write(&index_file, (uchar*) log_file_name,
1266
1966
                     strlen(log_file_name)) ||
1267
 
          my_b_write(&index_file, (unsigned char*) "\n", 1) ||
 
1967
          my_b_write(&index_file, (uchar*) "\n", 1) ||
1268
1968
          flush_io_cache(&index_file) ||
1269
1969
          my_sync(index_file.file, MYF(MY_WME)))
1270
1970
        goto err;
1272
1972
  }
1273
1973
  log_state= LOG_OPENED;
1274
1974
 
1275
 
  return(0);
 
1975
  DBUG_RETURN(0);
1276
1976
 
1277
1977
err:
1278
 
  sql_print_error(_("Could not use %s for logging (error %d). "
1279
 
                    "Turning logging off for the whole duration of the "
1280
 
                    "Drizzle server process. "
1281
 
                    "To turn it on again: fix the cause, "
1282
 
                    "shutdown the Drizzle server and restart it."),
1283
 
                    name, errno);
 
1978
  sql_print_error("Could not use %s for logging (error %d). \
 
1979
Turning logging off for the whole duration of the MySQL server process. \
 
1980
To turn it on again: fix the cause, \
 
1981
shutdown the MySQL server and restart it.", name, errno);
1284
1982
  if (file >= 0)
1285
1983
    my_close(file,MYF(0));
1286
1984
  end_io_cache(&log_file);
1287
1985
  end_io_cache(&index_file);
1288
 
  if (name)
1289
 
  {
1290
 
    free(name);
1291
 
    name= NULL;
1292
 
  }
 
1986
  safeFree(name);
1293
1987
  log_state= LOG_CLOSED;
1294
 
  return(1);
 
1988
  DBUG_RETURN(1);
1295
1989
}
1296
1990
 
1297
1991
 
1298
 
int DRIZZLE_BIN_LOG::get_current_log(LOG_INFO* linfo)
 
1992
int MYSQL_BIN_LOG::get_current_log(LOG_INFO* linfo)
1299
1993
{
1300
1994
  pthread_mutex_lock(&LOCK_log);
1301
1995
  int ret = raw_get_current_log(linfo);
1303
1997
  return ret;
1304
1998
}
1305
1999
 
1306
 
int DRIZZLE_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
 
2000
int MYSQL_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
1307
2001
{
1308
2002
  strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name)-1);
1309
2003
  linfo->pos = my_b_tell(&log_file);
1327
2021
    0   ok
1328
2022
*/
1329
2023
 
 
2024
#ifdef HAVE_REPLICATION
 
2025
 
1330
2026
static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t offset)
1331
2027
{
1332
2028
  int bytes_read;
1333
2029
  my_off_t init_offset= offset;
1334
2030
  File file= index_file->file;
1335
 
  unsigned char io_buf[IO_SIZE*2];
 
2031
  uchar io_buf[IO_SIZE*2];
 
2032
  DBUG_ENTER("copy_up_file_and_fill");
1336
2033
 
1337
2034
  for (;; offset+= bytes_read)
1338
2035
  {
1352
2049
 
1353
2050
  /* Reset data in old index cache */
1354
2051
  reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 1);
1355
 
  return(0);
 
2052
  DBUG_RETURN(0);
1356
2053
 
1357
2054
err:
1358
 
  return(1);
 
2055
  DBUG_RETURN(1);
1359
2056
}
1360
2057
 
 
2058
#endif /* HAVE_REPLICATION */
 
2059
 
1361
2060
/**
1362
2061
  Find the position in the log-index-file for the given log name.
1363
2062
 
1380
2079
    LOG_INFO_IO         Got IO error while reading file
1381
2080
*/
1382
2081
 
1383
 
int DRIZZLE_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
 
2082
int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
1384
2083
                            bool need_lock)
1385
2084
{
1386
2085
  int error= 0;
1387
2086
  char *fname= linfo->log_file_name;
1388
 
  uint32_t log_name_len= log_name ? (uint) strlen(log_name) : 0;
 
2087
  uint log_name_len= log_name ? (uint) strlen(log_name) : 0;
 
2088
  DBUG_ENTER("find_log_pos");
 
2089
  DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));
1389
2090
 
1390
2091
  /*
1391
2092
    Mutex needed because we need to make sure the file pointer does not
1400
2101
 
1401
2102
  for (;;)
1402
2103
  {
1403
 
    uint32_t length;
 
2104
    uint length;
1404
2105
    my_off_t offset= my_b_tell(&index_file);
1405
2106
    /* If we get 0 or 1 characters, this is the end of the file */
1406
2107
 
1416
2117
        (log_name_len == length-1 && fname[log_name_len] == '\n' &&
1417
2118
         !memcmp(fname, log_name, log_name_len)))
1418
2119
    {
 
2120
      DBUG_PRINT("info",("Found log file entry"));
1419
2121
      fname[length-1]=0;                        // remove last \n
1420
2122
      linfo->index_file_start_offset= offset;
1421
2123
      linfo->index_file_offset = my_b_tell(&index_file);
1425
2127
 
1426
2128
  if (need_lock)
1427
2129
    pthread_mutex_unlock(&LOCK_index);
1428
 
  return(error);
 
2130
  DBUG_RETURN(error);
1429
2131
}
1430
2132
 
1431
2133
 
1453
2155
    LOG_INFO_IO         Got IO error while reading file
1454
2156
*/
1455
2157
 
1456
 
int DRIZZLE_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
 
2158
int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
1457
2159
{
1458
2160
  int error= 0;
1459
 
  uint32_t length;
 
2161
  uint length;
1460
2162
  char *fname= linfo->log_file_name;
1461
2163
 
1462
2164
  if (need_lock)
1500
2202
    1   error
1501
2203
*/
1502
2204
 
1503
 
bool DRIZZLE_BIN_LOG::reset_logs(THD* thd)
 
2205
bool MYSQL_BIN_LOG::reset_logs(THD* thd)
1504
2206
{
1505
2207
  LOG_INFO linfo;
1506
2208
  bool error=0;
1507
2209
  const char* save_name;
 
2210
  DBUG_ENTER("reset_logs");
1508
2211
 
 
2212
  ha_reset_logs(thd);
1509
2213
  /*
1510
2214
    We need to get both locks to be sure that no one is trying to
1511
2215
    write to the index log file.
1519
2223
    thread. If the transaction involved MyISAM tables, it should go
1520
2224
    into binlog even on rollback.
1521
2225
  */
1522
 
  pthread_mutex_lock(&LOCK_thread_count);
 
2226
  VOID(pthread_mutex_lock(&LOCK_thread_count));
1523
2227
 
1524
2228
  /* Save variables so that we can reopen the log */
1525
2229
  save_name=name;
1528
2232
 
1529
2233
  /* First delete all old log files */
1530
2234
 
1531
 
  if (find_log_pos(&linfo, NULL, 0))
 
2235
  if (find_log_pos(&linfo, NullS, 0))
1532
2236
  {
1533
2237
    error=1;
1534
2238
    goto err;
1540
2244
    {
1541
2245
      if (my_errno == ENOENT) 
1542
2246
      {
1543
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2247
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1544
2248
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1545
2249
                            linfo.log_file_name);
1546
 
        sql_print_information(_("Failed to delete file '%s'"),
 
2250
        sql_print_information("Failed to delete file '%s'",
1547
2251
                              linfo.log_file_name);
1548
2252
        my_errno= 0;
1549
2253
        error= 0;
1550
2254
      }
1551
2255
      else
1552
2256
      {
1553
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2257
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1554
2258
                            ER_BINLOG_PURGE_FATAL_ERR,
1555
 
                            _("a problem with deleting %s; "
 
2259
                            "a problem with deleting %s; "
1556
2260
                            "consider examining correspondence "
1557
2261
                            "of your binlog index file "
1558
 
                            "to the actual binlog files"),
 
2262
                            "to the actual binlog files",
1559
2263
                            linfo.log_file_name);
1560
2264
        error= 1;
1561
2265
        goto err;
1571
2275
  {
1572
2276
    if (my_errno == ENOENT) 
1573
2277
    {
1574
 
      push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2278
      push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1575
2279
                          ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1576
2280
                          index_file_name);
1577
 
      sql_print_information(_("Failed to delete file '%s'"),
 
2281
      sql_print_information("Failed to delete file '%s'",
1578
2282
                            index_file_name);
1579
2283
      my_errno= 0;
1580
2284
      error= 0;
1581
2285
    }
1582
2286
    else
1583
2287
    {
1584
 
      push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2288
      push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1585
2289
                          ER_BINLOG_PURGE_FATAL_ERR,
1586
2290
                          "a problem with deleting %s; "
1587
2291
                          "consider examining correspondence "
1596
2300
    need_start_event=1;
1597
2301
  if (!open_index_file(index_file_name, 0))
1598
2302
    open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0);
1599
 
  free((unsigned char*) save_name);
 
2303
  my_free((uchar*) save_name, MYF(0));
1600
2304
 
1601
2305
err:
1602
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
2306
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
1603
2307
  pthread_mutex_unlock(&LOCK_index);
1604
2308
  pthread_mutex_unlock(&LOCK_log);
1605
 
  return(error);
 
2309
  DBUG_RETURN(error);
1606
2310
}
1607
2311
 
1608
2312
 
1643
2347
    LOG_INFO_IO         Got IO error while reading file
1644
2348
*/
1645
2349
 
 
2350
#ifdef HAVE_REPLICATION
1646
2351
 
1647
 
int DRIZZLE_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
 
2352
int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
1648
2353
{
1649
2354
  int error;
 
2355
  DBUG_ENTER("purge_first_log");
1650
2356
 
1651
 
  assert(is_open());
1652
 
  assert(rli->slave_running == 1);
1653
 
  assert(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name.c_str()));
 
2357
  DBUG_ASSERT(is_open());
 
2358
  DBUG_ASSERT(rli->slave_running == 1);
 
2359
  DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name));
1654
2360
 
1655
2361
  pthread_mutex_lock(&LOCK_index);
1656
2362
  pthread_mutex_lock(&rli->log_space_lock);
1657
 
  rli->relay_log.purge_logs(rli->group_relay_log_name.c_str(), included,
 
2363
  rli->relay_log.purge_logs(rli->group_relay_log_name, included,
1658
2364
                            0, 0, &rli->log_space_total);
1659
2365
  // Tell the I/O thread to take the relay_log_space_limit into account
1660
2366
  rli->ignore_log_space_limit= 0;
1673
2379
    If included is true, we want the first relay log;
1674
2380
    otherwise we want the one after event_relay_log_name.
1675
2381
  */
1676
 
  if ((included && (error=find_log_pos(&rli->linfo, NULL, 0))) ||
 
2382
  if ((included && (error=find_log_pos(&rli->linfo, NullS, 0))) ||
1677
2383
      (!included &&
1678
 
       ((error=find_log_pos(&rli->linfo, rli->event_relay_log_name.c_str(), 0)) ||
 
2384
       ((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) ||
1679
2385
        (error=find_next_log(&rli->linfo, 0)))))
1680
2386
  {
1681
2387
    char buff[22];
1682
 
    sql_print_error(_("next log error: %d  offset: %s  log: %s included: %d"),
 
2388
    sql_print_error("next log error: %d  offset: %s  log: %s included: %d",
1683
2389
                    error,
1684
2390
                    llstr(rli->linfo.index_file_offset,buff),
1685
 
                    rli->group_relay_log_name.c_str(),
 
2391
                    rli->group_relay_log_name,
1686
2392
                    included);
1687
2393
    goto err;
1688
2394
  }
1691
2397
    Reset rli's coordinates to the current log.
1692
2398
  */
1693
2399
  rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
1694
 
  rli->event_relay_log_name.assign(rli->linfo.log_file_name);
 
2400
  strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
 
2401
          sizeof(rli->event_relay_log_name)-1);
1695
2402
 
1696
2403
  /*
1697
2404
    If we removed the rli->group_relay_log_name file,
1701
2408
  if (included)
1702
2409
  {
1703
2410
    rli->group_relay_log_pos = BIN_LOG_HEADER_SIZE;
1704
 
    rli->group_relay_log_name.assign(rli->linfo.log_file_name);
 
2411
    strmake(rli->group_relay_log_name,rli->linfo.log_file_name,
 
2412
            sizeof(rli->group_relay_log_name)-1);
1705
2413
    rli->notify_group_relay_log_name_update();
1706
2414
  }
1707
2415
 
1710
2418
 
1711
2419
err:
1712
2420
  pthread_mutex_unlock(&LOCK_index);
1713
 
  return(error);
 
2421
  DBUG_RETURN(error);
1714
2422
}
1715
2423
 
1716
2424
/**
1717
2425
  Update log index_file.
1718
2426
*/
1719
2427
 
1720
 
int DRIZZLE_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
 
2428
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
1721
2429
{
1722
2430
  if (copy_up_file_and_fill(&index_file, log_info->index_file_start_offset))
1723
2431
    return LOG_INFO_IO;
1752
2460
                                stat() or my_delete()
1753
2461
*/
1754
2462
 
1755
 
int DRIZZLE_BIN_LOG::purge_logs(const char *to_log, 
 
2463
int MYSQL_BIN_LOG::purge_logs(const char *to_log, 
1756
2464
                          bool included,
1757
2465
                          bool need_mutex, 
1758
2466
                          bool need_update_threads, 
1759
 
                          uint64_t *decrease_log_space)
 
2467
                          ulonglong *decrease_log_space)
1760
2468
{
1761
2469
  int error;
1762
2470
  int ret = 0;
1763
2471
  bool exit_loop= 0;
1764
2472
  LOG_INFO log_info;
 
2473
  DBUG_ENTER("purge_logs");
 
2474
  DBUG_PRINT("info",("to_log= %s",to_log));
1765
2475
 
1766
2476
  if (need_mutex)
1767
2477
    pthread_mutex_lock(&LOCK_index);
1772
2482
    File name exists in index file; delete until we find this file
1773
2483
    or a file that is used.
1774
2484
  */
1775
 
  if ((error=find_log_pos(&log_info, NULL, 0 /*no mutex*/)))
 
2485
  if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
1776
2486
    goto err;
1777
2487
  while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
1778
2488
         !log_in_use(log_info.log_file_name))
1786
2496
          It's not fatal if we can't stat a log file that does not exist;
1787
2497
          If we could not stat, we won't delete.
1788
2498
        */     
1789
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2499
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1790
2500
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1791
2501
                            log_info.log_file_name);
1792
 
        sql_print_information(_("Failed to execute stat() on file '%s'"),
 
2502
        sql_print_information("Failed to execute stat on file '%s'",
1793
2503
                              log_info.log_file_name);
1794
2504
        my_errno= 0;
1795
2505
      }
1798
2508
        /*
1799
2509
          Other than ENOENT are fatal
1800
2510
        */
1801
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2511
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1802
2512
                            ER_BINLOG_PURGE_FATAL_ERR,
1803
 
                            _("a problem with getting info on being purged %s; "
 
2513
                            "a problem with getting info on being purged %s; "
1804
2514
                            "consider examining correspondence "
1805
2515
                            "of your binlog index file "
1806
 
                            "to the actual binlog files"),
 
2516
                            "to the actual binlog files",
1807
2517
                            log_info.log_file_name);
1808
2518
        error= LOG_INFO_FATAL;
1809
2519
        goto err;
1811
2521
    }
1812
2522
    else
1813
2523
    {
 
2524
      DBUG_PRINT("info",("purging %s",log_info.log_file_name));
1814
2525
      if (!my_delete(log_info.log_file_name, MYF(0)))
1815
2526
      {
1816
2527
        if (decrease_log_space)
1820
2531
      {
1821
2532
        if (my_errno == ENOENT) 
1822
2533
        {
1823
 
          push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2534
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1824
2535
                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1825
2536
                              log_info.log_file_name);
1826
 
          sql_print_information(_("Failed to delete file '%s'"),
 
2537
          sql_print_information("Failed to delete file '%s'",
1827
2538
                                log_info.log_file_name);
1828
2539
          my_errno= 0;
1829
2540
        }
1830
2541
        else
1831
2542
        {
1832
 
          push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2543
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1833
2544
                              ER_BINLOG_PURGE_FATAL_ERR,
1834
 
                              _("a problem with deleting %s; "
 
2545
                              "a problem with deleting %s; "
1835
2546
                              "consider examining correspondence "
1836
2547
                              "of your binlog index file "
1837
 
                              "to the actual binlog files"),
 
2548
                              "to the actual binlog files",
1838
2549
                              log_info.log_file_name);
1839
2550
          if (my_errno == EMFILE)
1840
2551
          {
 
2552
            DBUG_PRINT("info",
 
2553
                       ("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
1841
2554
            error= LOG_INFO_EMFILE;
1842
2555
          }
1843
2556
          error= LOG_INFO_FATAL;
1846
2559
      }
1847
2560
    }
1848
2561
 
 
2562
    ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
 
2563
 
1849
2564
    if (find_next_log(&log_info, 0) || exit_loop)
1850
2565
      break;
1851
2566
  }
1862
2577
err:
1863
2578
  if (need_mutex)
1864
2579
    pthread_mutex_unlock(&LOCK_index);
1865
 
  return(error);
 
2580
  DBUG_RETURN(error);
1866
2581
}
1867
2582
 
1868
2583
/**
1884
2599
                                stat() or my_delete()
1885
2600
*/
1886
2601
 
1887
 
int DRIZZLE_BIN_LOG::purge_logs_before_date(time_t purge_time)
 
2602
int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
1888
2603
{
1889
2604
  int error;
1890
2605
  LOG_INFO log_info;
1891
2606
  struct stat stat_area;
1892
2607
 
 
2608
  DBUG_ENTER("purge_logs_before_date");
 
2609
 
1893
2610
  pthread_mutex_lock(&LOCK_index);
1894
2611
 
1895
2612
  /*
1897
2614
    or a file that is used or a file
1898
2615
    that is older than purge_time.
1899
2616
  */
1900
 
  if ((error=find_log_pos(&log_info, NULL, 0 /*no mutex*/)))
 
2617
  if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
1901
2618
    goto err;
1902
2619
 
1903
2620
  while (strcmp(log_file_name, log_info.log_file_name) &&
1910
2627
        /*
1911
2628
          It's not fatal if we can't stat a log file that does not exist.
1912
2629
        */     
1913
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2630
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1914
2631
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1915
2632
                            log_info.log_file_name);
1916
 
        sql_print_information(_("Failed to execute stat() on file '%s'"),
 
2633
        sql_print_information("Failed to execute stat on file '%s'",
1917
2634
                              log_info.log_file_name);
1918
2635
        my_errno= 0;
1919
2636
      }
1922
2639
        /*
1923
2640
          Other than ENOENT are fatal
1924
2641
        */
1925
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2642
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1926
2643
                            ER_BINLOG_PURGE_FATAL_ERR,
1927
 
                            _("a problem with getting info on being purged %s; "
 
2644
                            "a problem with getting info on being purged %s; "
1928
2645
                            "consider examining correspondence "
1929
2646
                            "of your binlog index file "
1930
 
                            "to the actual binlog files"),
 
2647
                            "to the actual binlog files",
1931
2648
                            log_info.log_file_name);
1932
2649
        error= LOG_INFO_FATAL;
1933
2650
        goto err;
1942
2659
        if (my_errno == ENOENT) 
1943
2660
        {
1944
2661
          /* It's not fatal even if we can't delete a log file */
1945
 
          push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2662
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1946
2663
                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1947
2664
                              log_info.log_file_name);
1948
 
          sql_print_information(_("Failed to delete file '%s'"),
 
2665
          sql_print_information("Failed to delete file '%s'",
1949
2666
                                log_info.log_file_name);
1950
2667
          my_errno= 0;
1951
2668
        }
1952
2669
        else
1953
2670
        {
1954
 
          push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2671
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1955
2672
                              ER_BINLOG_PURGE_FATAL_ERR,
1956
 
                              _("a problem with deleting %s; "
 
2673
                              "a problem with deleting %s; "
1957
2674
                              "consider examining correspondence "
1958
2675
                              "of your binlog index file "
1959
 
                              "to the actual binlog files"),
 
2676
                              "to the actual binlog files",
1960
2677
                              log_info.log_file_name);
1961
2678
          error= LOG_INFO_FATAL;
1962
2679
          goto err;
1963
2680
        }
1964
2681
      }
 
2682
      ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
1965
2683
    }
1966
2684
    if (find_next_log(&log_info, 0))
1967
2685
      break;
1975
2693
 
1976
2694
err:
1977
2695
  pthread_mutex_unlock(&LOCK_index);
1978
 
  return(error);
 
2696
  DBUG_RETURN(error);
1979
2697
}
 
2698
#endif /* HAVE_REPLICATION */
1980
2699
 
1981
2700
 
1982
2701
/**
1988
2707
    If file name will be longer then FN_REFLEN it will be truncated
1989
2708
*/
1990
2709
 
1991
 
void DRIZZLE_BIN_LOG::make_log_name(char* buf, const char* log_ident)
 
2710
void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
1992
2711
{
1993
 
  uint32_t dir_len = dirname_length(log_file_name); 
 
2712
  uint dir_len = dirname_length(log_file_name); 
1994
2713
  if (dir_len >= FN_REFLEN)
1995
2714
    dir_len=FN_REFLEN-1;
1996
 
  my_stpncpy(buf, log_file_name, dir_len);
 
2715
  strnmov(buf, log_file_name, dir_len);
1997
2716
  strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len -1);
1998
2717
}
1999
2718
 
2002
2721
  Check if we are writing/reading to the given log file.
2003
2722
*/
2004
2723
 
2005
 
bool DRIZZLE_BIN_LOG::is_active(const char *log_file_name_arg)
 
2724
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
2006
2725
{
2007
2726
  return !strcmp(log_file_name, log_file_name_arg);
2008
2727
}
2016
2735
  method).
2017
2736
*/
2018
2737
 
2019
 
void DRIZZLE_BIN_LOG::new_file()
 
2738
void MYSQL_BIN_LOG::new_file()
2020
2739
{
2021
2740
  new_file_impl(1);
2022
2741
}
2023
2742
 
2024
2743
 
2025
 
void DRIZZLE_BIN_LOG::new_file_without_locking()
 
2744
void MYSQL_BIN_LOG::new_file_without_locking()
2026
2745
{
2027
2746
  new_file_impl(0);
2028
2747
}
2037
2756
    The new file name is stored last in the index file
2038
2757
*/
2039
2758
 
2040
 
void DRIZZLE_BIN_LOG::new_file_impl(bool need_lock)
 
2759
void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
2041
2760
{
2042
2761
  char new_name[FN_REFLEN], *new_name_ptr, *old_name;
2043
2762
 
 
2763
  DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
2044
2764
  if (!is_open())
2045
2765
  {
2046
 
    return;
 
2766
    DBUG_PRINT("info",("log is closed"));
 
2767
    DBUG_VOID_RETURN;
2047
2768
  }
2048
2769
 
2049
2770
  if (need_lock)
2067
2788
    tc_log_page_waits++;
2068
2789
    pthread_mutex_lock(&LOCK_prep_xids);
2069
2790
    while (prepared_xids) {
 
2791
      DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
2070
2792
      pthread_cond_wait(&COND_prep_xids, &LOCK_prep_xids);
2071
2793
    }
2072
2794
    pthread_mutex_unlock(&LOCK_prep_xids);
2123
2845
 
2124
2846
  open(old_name, log_type, new_name_ptr,
2125
2847
       io_cache_type, no_auto_events, max_size, 1);
2126
 
  free(old_name);
 
2848
  my_free(old_name,MYF(0));
2127
2849
 
2128
2850
end:
2129
2851
  if (need_lock)
2130
2852
    pthread_mutex_unlock(&LOCK_log);
2131
2853
  pthread_mutex_unlock(&LOCK_index);
2132
2854
 
2133
 
  return;
 
2855
  DBUG_VOID_RETURN;
2134
2856
}
2135
2857
 
2136
2858
 
2137
 
bool DRIZZLE_BIN_LOG::append(Log_event* ev)
 
2859
bool MYSQL_BIN_LOG::append(Log_event* ev)
2138
2860
{
2139
2861
  bool error = 0;
2140
2862
  pthread_mutex_lock(&LOCK_log);
 
2863
  DBUG_ENTER("MYSQL_BIN_LOG::append");
2141
2864
 
2142
 
  assert(log_file.type == SEQ_READ_APPEND);
 
2865
  DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
2143
2866
  /*
2144
2867
    Log_event::write() is smart enough to use my_b_write() or
2145
2868
    my_b_append() depending on the kind of cache we have.
2150
2873
    goto err;
2151
2874
  }
2152
2875
  bytes_written+= ev->data_written;
 
2876
  DBUG_PRINT("info",("max_size: %lu",max_size));
2153
2877
  if ((uint) my_b_append_tell(&log_file) > max_size)
2154
2878
    new_file_without_locking();
2155
2879
 
2156
2880
err:
2157
2881
  pthread_mutex_unlock(&LOCK_log);
2158
2882
  signal_update();                              // Safe as we don't call close
2159
 
  return(error);
 
2883
  DBUG_RETURN(error);
2160
2884
}
2161
2885
 
2162
2886
 
2163
 
bool DRIZZLE_BIN_LOG::appendv(const char* buf, uint32_t len,...)
 
2887
bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...)
2164
2888
{
2165
2889
  bool error= 0;
 
2890
  DBUG_ENTER("MYSQL_BIN_LOG::appendv");
2166
2891
  va_list(args);
2167
2892
  va_start(args,len);
2168
2893
 
2169
 
  assert(log_file.type == SEQ_READ_APPEND);
 
2894
  DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
2170
2895
 
2171
2896
  safe_mutex_assert_owner(&LOCK_log);
2172
2897
  do
2173
2898
  {
2174
 
    if (my_b_append(&log_file,(unsigned char*) buf,len))
 
2899
    if (my_b_append(&log_file,(uchar*) buf,len))
2175
2900
    {
2176
2901
      error= 1;
2177
2902
      goto err;
2178
2903
    }
2179
2904
    bytes_written += len;
2180
2905
  } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
 
2906
  DBUG_PRINT("info",("max_size: %lu",max_size));
2181
2907
  if ((uint) my_b_append_tell(&log_file) > max_size)
2182
2908
    new_file_without_locking();
2183
2909
 
2184
2910
err:
2185
2911
  if (!error)
2186
2912
    signal_update();
2187
 
  return(error);
 
2913
  DBUG_RETURN(error);
2188
2914
}
2189
2915
 
2190
2916
 
2191
 
bool DRIZZLE_BIN_LOG::flush_and_sync()
 
2917
bool MYSQL_BIN_LOG::flush_and_sync()
2192
2918
{
2193
2919
  int err=0, fd=log_file.file;
2194
2920
  safe_mutex_assert_owner(&LOCK_log);
2202
2928
  return err;
2203
2929
}
2204
2930
 
2205
 
void DRIZZLE_BIN_LOG::start_union_events(THD *thd, query_id_t query_id_param)
 
2931
void MYSQL_BIN_LOG::start_union_events(THD *thd, query_id_t query_id_param)
2206
2932
{
2207
 
  assert(!thd->binlog_evt_union.do_union);
2208
 
  thd->binlog_evt_union.do_union= true;
2209
 
  thd->binlog_evt_union.unioned_events= false;
2210
 
  thd->binlog_evt_union.unioned_events_trans= false;
 
2933
  DBUG_ASSERT(!thd->binlog_evt_union.do_union);
 
2934
  thd->binlog_evt_union.do_union= TRUE;
 
2935
  thd->binlog_evt_union.unioned_events= FALSE;
 
2936
  thd->binlog_evt_union.unioned_events_trans= FALSE;
2211
2937
  thd->binlog_evt_union.first_query_id= query_id_param;
2212
2938
}
2213
2939
 
2214
 
void DRIZZLE_BIN_LOG::stop_union_events(THD *thd)
 
2940
void MYSQL_BIN_LOG::stop_union_events(THD *thd)
2215
2941
{
2216
 
  assert(thd->binlog_evt_union.do_union);
2217
 
  thd->binlog_evt_union.do_union= false;
 
2942
  DBUG_ASSERT(thd->binlog_evt_union.do_union);
 
2943
  thd->binlog_evt_union.do_union= FALSE;
2218
2944
}
2219
2945
 
2220
 
bool DRIZZLE_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
 
2946
bool MYSQL_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
2221
2947
{
2222
2948
  return (thd->binlog_evt_union.do_union && 
2223
2949
          query_id_param >= thd->binlog_evt_union.first_query_id);
2231
2957
 
2232
2958
int THD::binlog_setup_trx_data()
2233
2959
{
 
2960
  DBUG_ENTER("THD::binlog_setup_trx_data");
2234
2961
  binlog_trx_data *trx_data=
2235
2962
    (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2236
2963
 
2237
2964
  if (trx_data)
2238
 
    return(0);                             // Already set up
 
2965
    DBUG_RETURN(0);                             // Already set up
2239
2966
 
2240
2967
  trx_data= (binlog_trx_data*) my_malloc(sizeof(binlog_trx_data), MYF(MY_ZEROFILL));
2241
2968
  if (!trx_data ||
2242
2969
      open_cached_file(&trx_data->trans_log, mysql_tmpdir,
2243
2970
                       LOG_PREFIX, binlog_cache_size, MYF(MY_WME)))
2244
2971
  {
2245
 
    free((unsigned char*)trx_data);
2246
 
    return(1);                      // Didn't manage to set it up
 
2972
    my_free((uchar*)trx_data, MYF(MY_ALLOW_ZERO_PTR));
 
2973
    DBUG_RETURN(1);                      // Didn't manage to set it up
2247
2974
  }
2248
2975
  thd_set_ha_data(this, binlog_hton, trx_data);
2249
2976
 
2250
2977
  trx_data= new (thd_get_ha_data(this, binlog_hton)) binlog_trx_data;
2251
2978
 
2252
 
  return(0);
 
2979
  DBUG_RETURN(0);
2253
2980
}
2254
2981
 
2255
2982
/*
2284
3011
THD::binlog_start_trans_and_stmt()
2285
3012
{
2286
3013
  binlog_trx_data *trx_data= (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
 
3014
  DBUG_ENTER("binlog_start_trans_and_stmt");
 
3015
  DBUG_PRINT("enter", ("trx_data: 0x%lx  trx_data->before_stmt_pos: %lu",
 
3016
                       (long) trx_data,
 
3017
                       (trx_data ? (ulong) trx_data->before_stmt_pos :
 
3018
                        (ulong) 0)));
2287
3019
 
2288
3020
  if (trx_data == NULL ||
2289
3021
      trx_data->before_stmt_pos == MY_OFF_T_UNDEF)
2290
3022
  {
2291
3023
    this->binlog_set_stmt_begin();
2292
3024
    if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2293
 
      trans_register_ha(this, true, binlog_hton);
2294
 
    trans_register_ha(this, false, binlog_hton);
 
3025
      trans_register_ha(this, TRUE, binlog_hton);
 
3026
    trans_register_ha(this, FALSE, binlog_hton);
2295
3027
    /*
2296
3028
      Mark statement transaction as read/write. We never start
2297
3029
      a binary log transaction and keep it read-only,
2303
3035
    */
2304
3036
    ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
2305
3037
  }
2306
 
  return;
 
3038
  DBUG_VOID_RETURN;
2307
3039
}
2308
3040
 
2309
3041
void THD::binlog_set_stmt_begin() {
2327
3059
  Write a table map to the binary log.
2328
3060
 */
2329
3061
 
2330
 
int THD::binlog_write_table_map(Table *table, bool is_trans)
 
3062
int THD::binlog_write_table_map(TABLE *table, bool is_trans)
2331
3063
{
2332
3064
  int error;
 
3065
  DBUG_ENTER("THD::binlog_write_table_map");
 
3066
  DBUG_PRINT("enter", ("table: 0x%lx  (%s: #%lu)",
 
3067
                       (long) table, table->s->table_name.str,
 
3068
                       table->s->table_map_id));
2333
3069
 
2334
3070
  /* Pre-conditions */
2335
 
  assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2336
 
  assert(table->s->table_map_id != UINT32_MAX);
 
3071
  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
3072
  DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
2337
3073
 
2338
3074
  Table_map_log_event::flag_set const
2339
3075
    flags= Table_map_log_event::TM_NO_FLAGS;
2345
3081
    binlog_start_trans_and_stmt();
2346
3082
 
2347
3083
  if ((error= mysql_bin_log.write(&the_event)))
2348
 
    return(error);
 
3084
    DBUG_RETURN(error);
2349
3085
 
2350
3086
  binlog_table_maps++;
2351
3087
  table->s->table_map_version= mysql_bin_log.table_map_version();
2352
 
  return(0);
 
3088
  DBUG_RETURN(0);
2353
3089
}
2354
3090
 
2355
3091
Rows_log_event*
2375
3111
  binlog_trx_data *const trx_data=
2376
3112
    (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2377
3113
 
2378
 
  assert(trx_data);
 
3114
  DBUG_ASSERT(trx_data);
2379
3115
  trx_data->set_pending(ev);
2380
3116
}
2381
3117
 
2386
3122
  event.
2387
3123
*/
2388
3124
int
2389
 
DRIZZLE_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
 
3125
MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
2390
3126
                                                Rows_log_event* event)
2391
3127
{
2392
 
  assert(mysql_bin_log.is_open());
 
3128
  DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)");
 
3129
  DBUG_ASSERT(mysql_bin_log.is_open());
 
3130
  DBUG_PRINT("enter", ("event: 0x%lx", (long) event));
2393
3131
 
2394
3132
  int error= 0;
2395
3133
 
2396
3134
  binlog_trx_data *const trx_data=
2397
3135
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
2398
3136
 
2399
 
  assert(trx_data);
 
3137
  DBUG_ASSERT(trx_data);
 
3138
 
 
3139
  DBUG_PRINT("info", ("trx_data->pending(): 0x%lx", (long) trx_data->pending()));
2400
3140
 
2401
3141
  if (Rows_log_event* pending= trx_data->pending())
2402
3142
  {
2423
3163
    if (pending->write(file))
2424
3164
    {
2425
3165
      pthread_mutex_unlock(&LOCK_log);
2426
 
      return(1);
 
3166
      DBUG_RETURN(1);
2427
3167
    }
2428
3168
 
2429
3169
    /*
2461
3201
 
2462
3202
  thd->binlog_set_pending_rows_event(event);
2463
3203
 
2464
 
  return(error);
 
3204
  DBUG_RETURN(error);
2465
3205
}
2466
3206
 
2467
3207
/**
2468
3208
  Write an event to the binary log.
2469
3209
*/
2470
3210
 
2471
 
bool DRIZZLE_BIN_LOG::write(Log_event *event_info)
 
3211
bool MYSQL_BIN_LOG::write(Log_event *event_info)
2472
3212
{
2473
3213
  THD *thd= event_info->thd;
2474
3214
  bool error= 1;
 
3215
  DBUG_ENTER("MYSQL_BIN_LOG::write(Log_event *)");
2475
3216
 
2476
3217
  if (thd->binlog_evt_union.do_union)
2477
3218
  {
2479
3220
      In Stored function; Remember that function call caused an update.
2480
3221
      We will log the function call to the binary log on function exit
2481
3222
    */
2482
 
    thd->binlog_evt_union.unioned_events= true;
 
3223
    thd->binlog_evt_union.unioned_events= TRUE;
2483
3224
    thd->binlog_evt_union.unioned_events_trans |= event_info->cache_stmt;
2484
 
    return(0);
 
3225
    DBUG_RETURN(0);
2485
3226
  }
2486
3227
 
2487
3228
  /*
2516
3257
    if ((thd && !(thd->options & OPTION_BIN_LOG)) ||
2517
3258
        (!binlog_filter->db_ok(local_db)))
2518
3259
    {
2519
 
      pthread_mutex_unlock(&LOCK_log);
2520
 
      return(0);
 
3260
      VOID(pthread_mutex_unlock(&LOCK_log));
 
3261
      DBUG_RETURN(0);
2521
3262
    }
2522
3263
 
2523
3264
    /*
2540
3281
      my_off_t trans_log_pos= my_b_tell(trans_log);
2541
3282
      if (event_info->get_cache_stmt() || trans_log_pos != 0)
2542
3283
      {
 
3284
        DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu",
 
3285
                            event_info->get_cache_stmt(),
 
3286
                            (ulong) trans_log_pos));
2543
3287
        if (trans_log_pos == 0)
2544
3288
          thd->binlog_start_trans_and_stmt();
2545
3289
        file= trans_log;
2551
3295
        LOCK_log.
2552
3296
      */
2553
3297
    }
 
3298
    DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
2554
3299
 
2555
3300
    /*
2556
3301
      No check for auto events flag here - this write method should
2572
3317
      {
2573
3318
        if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
2574
3319
        {
2575
 
          Intvar_log_event e(thd,(unsigned char) LAST_INSERT_ID_EVENT,
 
3320
          Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
2576
3321
                             thd->first_successful_insert_id_in_prev_stmt_for_binlog);
2577
3322
          if (e.write(file))
2578
3323
            goto err;
2579
3324
        }
2580
3325
        if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
2581
3326
        {
 
3327
          DBUG_PRINT("info",("number of auto_inc intervals: %u",
 
3328
                             thd->auto_inc_intervals_in_cur_stmt_for_binlog.
 
3329
                             nb_elements()));
2582
3330
          /*
2583
3331
            If the auto_increment was second in a table's index (possible with
2584
3332
            MyISAM or BDB) (table->next_number_keypart != 0), such event is
2585
3333
            in fact not necessary. We could avoid logging it.
2586
3334
          */
2587
 
          Intvar_log_event e(thd, (unsigned char) INSERT_ID_EVENT,
 
3335
          Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT,
2588
3336
                             thd->auto_inc_intervals_in_cur_stmt_for_binlog.
2589
3337
                             minimum());
2590
3338
          if (e.write(file))
2598
3346
        }
2599
3347
        if (thd->user_var_events.elements)
2600
3348
        {
2601
 
          for (uint32_t i= 0; i < thd->user_var_events.elements; i++)
 
3349
          for (uint i= 0; i < thd->user_var_events.elements; i++)
2602
3350
          {
2603
3351
            BINLOG_USER_VAR_EVENT *user_var_event;
2604
 
            get_dynamic(&thd->user_var_events,(unsigned char*) &user_var_event, i);
 
3352
            get_dynamic(&thd->user_var_events,(uchar*) &user_var_event, i);
2605
3353
            User_var_log_event e(thd, user_var_event->user_var_event->name.str,
2606
3354
                                 user_var_event->user_var_event->name.length,
2607
3355
                                 user_var_event->value,
2646
3394
    ++m_table_map_version;
2647
3395
 
2648
3396
  pthread_mutex_unlock(&LOCK_log);
2649
 
  return(error);
 
3397
  DBUG_RETURN(error);
2650
3398
}
2651
3399
 
2652
3400
 
2656
3404
  return logger.error_log_print(level, format, args);
2657
3405
}
2658
3406
 
2659
 
void DRIZZLE_BIN_LOG::rotate_and_purge(uint32_t flags)
 
3407
 
 
3408
bool slow_log_print(THD *thd, const char *query, uint query_length,
 
3409
                    ulonglong current_utime)
 
3410
{
 
3411
  return logger.slow_log_print(thd, query, query_length, current_utime);
 
3412
}
 
3413
 
 
3414
 
 
3415
bool LOGGER::log_command(THD *thd, enum enum_server_command command)
 
3416
{
 
3417
  /*
 
3418
    Log command if we have at least one log event handler enabled and want
 
3419
    to log this king of commands
 
3420
  */
 
3421
  if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
 
3422
  {
 
3423
    if (thd->options & OPTION_LOG_OFF)
 
3424
    {
 
3425
      /* No logging */
 
3426
      return FALSE;
 
3427
    }
 
3428
 
 
3429
    return TRUE;
 
3430
  }
 
3431
 
 
3432
  return FALSE;
 
3433
}
 
3434
 
 
3435
 
 
3436
bool general_log_print(THD *thd, enum enum_server_command command,
 
3437
                       const char *format, ...)
 
3438
{
 
3439
  va_list args;
 
3440
  uint error= 0;
 
3441
 
 
3442
  /* Print the message to the buffer if we want to log this king of commands */
 
3443
  if (! logger.log_command(thd, command))
 
3444
    return FALSE;
 
3445
 
 
3446
  va_start(args, format);
 
3447
  error= logger.general_log_print(thd, command, format, args);
 
3448
  va_end(args);
 
3449
 
 
3450
  return error;
 
3451
}
 
3452
 
 
3453
bool general_log_write(THD *thd, enum enum_server_command command,
 
3454
                       const char *query, uint query_length)
 
3455
{
 
3456
  /* Write the message to the log if we want to log this king of commands */
 
3457
  if (logger.log_command(thd, command))
 
3458
    return logger.general_log_write(thd, command, query, query_length);
 
3459
 
 
3460
  return FALSE;
 
3461
}
 
3462
 
 
3463
void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
2660
3464
{
2661
3465
  if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
2662
3466
    pthread_mutex_lock(&LOCK_log);
2664
3468
      (my_b_tell(&log_file) >= (my_off_t) max_size))
2665
3469
  {
2666
3470
    new_file_without_locking();
 
3471
#ifdef HAVE_REPLICATION
2667
3472
    if (expire_logs_days)
2668
3473
    {
2669
3474
      time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
2670
3475
      if (purge_time >= 0)
2671
3476
        purge_logs_before_date(purge_time);
2672
3477
    }
 
3478
#endif
2673
3479
  }
2674
3480
  if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
2675
3481
    pthread_mutex_unlock(&LOCK_log);
2676
3482
}
2677
3483
 
2678
 
uint32_t DRIZZLE_BIN_LOG::next_file_id()
 
3484
uint MYSQL_BIN_LOG::next_file_id()
2679
3485
{
2680
 
  uint32_t res;
 
3486
  uint res;
2681
3487
  pthread_mutex_lock(&LOCK_log);
2682
3488
  res = file_id++;
2683
3489
  pthread_mutex_unlock(&LOCK_log);
2699
3505
    be reset as a READ_CACHE to be able to read the contents from it.
2700
3506
 */
2701
3507
 
2702
 
int DRIZZLE_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
 
3508
int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
2703
3509
{
2704
3510
  Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
2705
3511
 
2706
3512
  if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
2707
3513
    return ER_ERROR_ON_WRITE;
2708
 
  uint32_t length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
 
3514
  uint length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
2709
3515
  long val;
2710
 
  unsigned char header[LOG_EVENT_HEADER_LEN];
 
3516
  uchar header[LOG_EVENT_HEADER_LEN];
2711
3517
 
2712
3518
  /*
2713
3519
    The events in the buffer have incorrect end_log_pos data
2735
3541
    */
2736
3542
    if (unlikely(carry > 0))
2737
3543
    {
2738
 
      assert(carry < LOG_EVENT_HEADER_LEN);
 
3544
      DBUG_ASSERT(carry < LOG_EVENT_HEADER_LEN);
2739
3545
 
2740
3546
      /* assemble both halves */
2741
 
      memcpy(&header[carry], cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
 
3547
      memcpy(&header[carry], (char *)cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
2742
3548
 
2743
3549
      /* fix end_log_pos */
2744
3550
      val= uint4korr(&header[LOG_POS_OFFSET]) + group;
2752
3558
        copy fixed second half of header to cache so the correct
2753
3559
        version will be written later.
2754
3560
      */
2755
 
      memcpy(cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
 
3561
      memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
2756
3562
 
2757
3563
      /* next event header at ... */
2758
3564
      hdr_offs = uint4korr(&header[EVENT_LEN_OFFSET]) - carry;
2781
3587
        if (hdr_offs + LOG_EVENT_HEADER_LEN > length)
2782
3588
        {
2783
3589
          carry= length - hdr_offs;
2784
 
          memcpy(header, cache->read_pos + hdr_offs, carry);
 
3590
          memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
2785
3591
          length= hdr_offs;
2786
3592
        }
2787
3593
        else
2788
3594
        {
2789
3595
          /* we've got a full event-header, and it came in one piece */
2790
3596
 
2791
 
          unsigned char *log_pos= (unsigned char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
 
3597
          uchar *log_pos= (uchar *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
2792
3598
 
2793
3599
          /* fix end_log_pos */
2794
3600
          val= uint4korr(log_pos) + group;
2795
3601
          int4store(log_pos, val);
2796
3602
 
2797
3603
          /* next event header at ... */
2798
 
          log_pos= (unsigned char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
 
3604
          log_pos= (uchar *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
2799
3605
          hdr_offs += uint4korr(log_pos);
2800
3606
 
2801
3607
        }
2818
3624
    cache->read_pos=cache->read_end;            // Mark buffer used up
2819
3625
  } while ((length= my_b_fill(cache)));
2820
3626
 
2821
 
  assert(carry == 0);
 
3627
  DBUG_ASSERT(carry == 0);
2822
3628
 
2823
3629
  if (sync_log)
2824
3630
    flush_and_sync();
2847
3653
    'cache' needs to be reinitialized after this functions returns.
2848
3654
*/
2849
3655
 
2850
 
bool DRIZZLE_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
 
3656
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
2851
3657
{
2852
 
  pthread_mutex_lock(&LOCK_log);
 
3658
  DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)");
 
3659
  VOID(pthread_mutex_lock(&LOCK_log));
2853
3660
 
2854
3661
  /* NULL would represent nothing to replicate after ROLLBACK */
2855
 
  assert(commit_event != NULL);
 
3662
  DBUG_ASSERT(commit_event != NULL);
2856
3663
 
2857
 
  assert(is_open());
 
3664
  DBUG_ASSERT(is_open());
2858
3665
  if (likely(is_open()))                       // Should always be true
2859
3666
  {
2860
3667
    /*
2868
3675
        transaction is either a BEGIN..COMMIT block or a single
2869
3676
        statement in autocommit mode.
2870
3677
      */
2871
 
      Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), true, false);
 
3678
      Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
2872
3679
      /*
2873
3680
        Imagine this is rollback due to net timeout, after all
2874
3681
        statements of the transaction succeeded. Then we want a
2892
3699
      if (qinfo.write(&log_file))
2893
3700
        goto err;
2894
3701
 
 
3702
      DBUG_EXECUTE_IF("crash_before_writing_xid",
 
3703
                      {
 
3704
                        if ((write_error= write_cache(cache, false, true)))
 
3705
                          DBUG_PRINT("info", ("error writing binlog cache: %d",
 
3706
                                               write_error));
 
3707
                        DBUG_PRINT("info", ("crashing before writing xid"));
 
3708
                        abort();
 
3709
                      });
 
3710
 
2895
3711
      if ((write_error= write_cache(cache, false, false)))
2896
3712
        goto err;
2897
3713
 
2899
3715
        goto err;
2900
3716
      if (flush_and_sync())
2901
3717
        goto err;
 
3718
      DBUG_EXECUTE_IF("half_binlogged_transaction", abort(););
2902
3719
      if (cache->error)                         // Error on read
2903
3720
      {
2904
3721
        sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
2925
3742
    else
2926
3743
      rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
2927
3744
  }
2928
 
  pthread_mutex_unlock(&LOCK_log);
 
3745
  VOID(pthread_mutex_unlock(&LOCK_log));
2929
3746
 
2930
 
  return(0);
 
3747
  DBUG_RETURN(0);
2931
3748
 
2932
3749
err:
2933
3750
  if (!write_error)
2935
3752
    write_error= 1;
2936
3753
    sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
2937
3754
  }
2938
 
  pthread_mutex_unlock(&LOCK_log);
2939
 
  return(1);
 
3755
  VOID(pthread_mutex_unlock(&LOCK_log));
 
3756
  DBUG_RETURN(1);
2940
3757
}
2941
3758
 
2942
3759
 
2949
3766
    It will be released at the end of the function.
2950
3767
*/
2951
3768
 
2952
 
void DRIZZLE_BIN_LOG::wait_for_update_relay_log(THD* thd)
 
3769
void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
2953
3770
{
2954
3771
  const char *old_msg;
 
3772
  DBUG_ENTER("wait_for_update_relay_log");
2955
3773
  old_msg= thd->enter_cond(&update_cond, &LOCK_log,
2956
3774
                           "Slave has read all relay log; " 
2957
3775
                           "waiting for the slave I/O "
2958
3776
                           "thread to update it" );
2959
3777
  pthread_cond_wait(&update_cond, &LOCK_log);
2960
3778
  thd->exit_cond(old_msg);
2961
 
  return;
 
3779
  DBUG_VOID_RETURN;
2962
3780
}
2963
3781
 
2964
3782
 
2978
3796
    LOCK_log is released by the caller.
2979
3797
*/
2980
3798
 
2981
 
int DRIZZLE_BIN_LOG::wait_for_update_bin_log(THD* thd,
 
3799
int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
2982
3800
                                           const struct timespec *timeout)
2983
3801
{
2984
3802
  int ret= 0;
2985
 
  const char* old_msg = thd->get_proc_info();
 
3803
  const char* old_msg = thd->proc_info;
 
3804
  DBUG_ENTER("wait_for_update_bin_log");
2986
3805
  old_msg= thd->enter_cond(&update_cond, &LOCK_log,
2987
3806
                           "Master has sent all binlog to slave; "
2988
3807
                           "waiting for binlog to be updated");
2991
3810
  else
2992
3811
    ret= pthread_cond_timedwait(&update_cond, &LOCK_log,
2993
3812
                                const_cast<struct timespec *>(timeout));
2994
 
  return(ret);
 
3813
  DBUG_RETURN(ret);
2995
3814
}
2996
3815
 
2997
3816
 
3009
3828
    The internal structures are not freed until cleanup() is called
3010
3829
*/
3011
3830
 
3012
 
void DRIZZLE_BIN_LOG::close(uint32_t exiting)
 
3831
void MYSQL_BIN_LOG::close(uint exiting)
3013
3832
{                                       // One can't set log_type here!
 
3833
  DBUG_ENTER("MYSQL_BIN_LOG::close");
 
3834
  DBUG_PRINT("enter",("exiting: %d", (int) exiting));
3014
3835
  if (log_state == LOG_OPENED)
3015
3836
  {
 
3837
#ifdef HAVE_REPLICATION
3016
3838
    if (log_type == LOG_BIN && !no_auto_events &&
3017
3839
        (exiting & LOG_CLOSE_STOP_EVENT))
3018
3840
    {
3021
3843
      bytes_written+= s.data_written;
3022
3844
      signal_update();
3023
3845
    }
 
3846
#endif /* HAVE_REPLICATION */
3024
3847
 
3025
3848
    /* don't pwrite in a file opened with O_APPEND - it doesn't work */
3026
3849
    if (log_file.type == WRITE_CACHE && log_type == LOG_BIN)
3027
3850
    {
3028
3851
      my_off_t offset= BIN_LOG_HEADER_SIZE + FLAGS_OFFSET;
3029
 
      unsigned char flags= 0;            // clearing LOG_EVENT_BINLOG_IN_USE_F
3030
 
      pwrite(log_file.file, &flags, 1, offset);
 
3852
      my_off_t org_position= my_tell(log_file.file, MYF(0));
 
3853
      uchar flags= 0;            // clearing LOG_EVENT_BINLOG_IN_USE_F
 
3854
      my_pwrite(log_file.file, &flags, 1, offset, MYF(0));
 
3855
      /*
 
3856
        Restore position so that anything we have in the IO_cache is written
 
3857
        to the correct position.
 
3858
        We need the seek here, as my_pwrite() is not guaranteed to keep the
 
3859
        original position on system that doesn't support pwrite().
 
3860
      */
 
3861
      my_seek(log_file.file, org_position, MY_SEEK_SET, MYF(0));
3031
3862
    }
3032
3863
 
3033
3864
    /* this will cleanup IO_CACHE, sync and close the file */
3034
 
    DRIZZLE_LOG::close(exiting);
 
3865
    MYSQL_LOG::close(exiting);
3035
3866
  }
3036
3867
 
3037
3868
  /*
3049
3880
    }
3050
3881
  }
3051
3882
  log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
3052
 
  if (name)
3053
 
  {
3054
 
    free(name);
3055
 
    name= NULL;
3056
 
  }
3057
 
  return;
 
3883
  safeFree(name);
 
3884
  DBUG_VOID_RETURN;
3058
3885
}
3059
3886
 
3060
3887
 
3061
 
void DRIZZLE_BIN_LOG::set_max_size(ulong max_size_arg)
 
3888
void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg)
3062
3889
{
3063
3890
  /*
3064
3891
    We need to take locks, otherwise this may happen:
3067
3894
    uses the old_max_size argument, so max_size_arg has been overwritten and
3068
3895
    it's like if the SET command was never run.
3069
3896
  */
 
3897
  DBUG_ENTER("MYSQL_BIN_LOG::set_max_size");
3070
3898
  pthread_mutex_lock(&LOCK_log);
3071
3899
  if (is_open())
3072
3900
    max_size= max_size_arg;
3073
3901
  pthread_mutex_unlock(&LOCK_log);
3074
 
  return;
 
3902
  DBUG_VOID_RETURN;
3075
3903
}
3076
3904
 
3077
3905
 
3097
3925
{
3098
3926
  register int flag;
3099
3927
  const char *start;
 
3928
  DBUG_ENTER("test_if_number");
3100
3929
 
3101
3930
  flag= 0; 
3102
3931
  start= str;
3117
3946
         str++, flag=1) ;
3118
3947
  }
3119
3948
  if (*str != 0 || flag == 0)
3120
 
    return(0);
 
3949
    DBUG_RETURN(0);
3121
3950
  if (res)
3122
3951
    *res=atol(start);
3123
 
  return(1);                    /* Number ok */
 
3952
  DBUG_RETURN(1);                       /* Number ok */
3124
3953
} /* test_if_number */
3125
3954
 
3126
3955
 
3127
3956
void sql_perror(const char *message)
3128
3957
{
 
3958
#ifdef HAVE_STRERROR
3129
3959
  sql_print_error("%s: %s",message, strerror(errno));
 
3960
#else
 
3961
  perror(message);
 
3962
#endif
3130
3963
}
3131
3964
 
3132
3965
 
3137
3970
  {
3138
3971
    char err_renamed[FN_REFLEN], *end;
3139
3972
    end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
3140
 
    my_stpcpy(end, "-old");
3141
 
    pthread_mutex_lock(&LOCK_error_log);
 
3973
    strmov(end, "-old");
 
3974
    VOID(pthread_mutex_lock(&LOCK_error_log));
3142
3975
    char err_temp[FN_REFLEN+4];
3143
3976
    /*
3144
3977
     On Windows is necessary a temporary file for to rename
3145
3978
     the current error file.
3146
3979
    */
3147
 
    strxmov(err_temp, err_renamed,"-tmp",NULL);
 
3980
    strxmov(err_temp, err_renamed,"-tmp",NullS);
3148
3981
    (void) my_delete(err_temp, MYF(0)); 
3149
3982
    if (freopen(err_temp,"a+",stdout))
3150
3983
    {
3151
3984
      int fd;
3152
3985
      size_t bytes;
3153
 
      unsigned char buf[IO_SIZE];
 
3986
      uchar buf[IO_SIZE];
3154
3987
 
3155
3988
      freopen(err_temp,"a+",stderr);
3156
3989
      (void) my_delete(err_renamed, MYF(0));
3169
4002
    }
3170
4003
    else
3171
4004
     result= 1;
3172
 
    pthread_mutex_unlock(&LOCK_error_log);
 
4005
    VOID(pthread_mutex_unlock(&LOCK_error_log));
3173
4006
  }
3174
4007
   return result;
3175
4008
}
3176
4009
 
3177
 
void DRIZZLE_BIN_LOG::signal_update()
 
4010
void MYSQL_BIN_LOG::signal_update()
3178
4011
{
 
4012
  DBUG_ENTER("MYSQL_BIN_LOG::signal_update");
3179
4013
  pthread_cond_broadcast(&update_cond);
3180
 
  return;
 
4014
  DBUG_VOID_RETURN;
3181
4015
}
3182
4016
 
3183
4017
/**
3196
4030
    signature to be compatible with other logging routines, which could
3197
4031
    return an error (e.g. logging to the log tables)
3198
4032
*/
3199
 
static void print_buffer_to_file(enum loglevel level,
3200
 
                                 int error_code __attribute__((unused)),
3201
 
                                 const char *buffer,
3202
 
                                 size_t buffer_length __attribute__((unused)))
 
4033
static void print_buffer_to_file(enum loglevel level, int error_code,
 
4034
                                 const char *buffer, size_t buffer_length)
3203
4035
{
3204
4036
  time_t skr;
3205
4037
  struct tm tm_tmp;
3206
4038
  struct tm *start;
 
4039
  DBUG_ENTER("print_buffer_to_file");
 
4040
  DBUG_PRINT("enter",("buffer: %s", buffer));
3207
4041
 
3208
 
  pthread_mutex_lock(&LOCK_error_log);
 
4042
  VOID(pthread_mutex_lock(&LOCK_error_log));
3209
4043
 
3210
4044
  skr= my_time(0);
3211
4045
  localtime_r(&skr, &tm_tmp);
3224
4058
 
3225
4059
  fflush(stderr);
3226
4060
 
3227
 
  pthread_mutex_unlock(&LOCK_error_log);
3228
 
  return;
 
4061
  VOID(pthread_mutex_unlock(&LOCK_error_log));
 
4062
  DBUG_VOID_RETURN;
3229
4063
}
3230
4064
 
3231
4065
 
3234
4068
  char   buff[1024];
3235
4069
  size_t length;
3236
4070
  int error_code= errno;
 
4071
  DBUG_ENTER("vprint_msg_to_log");
3237
4072
 
3238
 
  length= vsnprintf(buff, sizeof(buff), format, args);
 
4073
  length= my_vsnprintf(buff, sizeof(buff), format, args);
3239
4074
 
3240
4075
  print_buffer_to_file(level, error_code, buff, length);
3241
4076
 
3242
 
  return(0);
 
4077
  DBUG_RETURN(0);
3243
4078
}
3244
4079
 
3245
4080
 
3246
4081
void sql_print_error(const char *format, ...) 
3247
4082
{
3248
4083
  va_list args;
 
4084
  DBUG_ENTER("sql_print_error");
3249
4085
 
3250
4086
  va_start(args, format);
3251
4087
  error_log_print(ERROR_LEVEL, format, args);
3252
4088
  va_end(args);
3253
4089
 
3254
 
  return;
 
4090
  DBUG_VOID_RETURN;
3255
4091
}
3256
4092
 
3257
4093
 
3258
4094
void sql_print_warning(const char *format, ...) 
3259
4095
{
3260
4096
  va_list args;
 
4097
  DBUG_ENTER("sql_print_warning");
3261
4098
 
3262
4099
  va_start(args, format);
3263
4100
  error_log_print(WARNING_LEVEL, format, args);
3264
4101
  va_end(args);
3265
4102
 
3266
 
  return;
 
4103
  DBUG_VOID_RETURN;
3267
4104
}
3268
4105
 
3269
4106
 
3270
4107
void sql_print_information(const char *format, ...) 
3271
4108
{
3272
4109
  va_list args;
 
4110
  DBUG_ENTER("sql_print_information");
3273
4111
 
3274
4112
  va_start(args, format);
3275
4113
  error_log_print(INFORMATION_LEVEL, format, args);
3276
4114
  va_end(args);
3277
4115
 
3278
 
  return;
 
4116
  DBUG_VOID_RETURN;
3279
4117
}
3280
4118
 
3281
4119
 
3330
4168
 
3331
4169
int TC_LOG_MMAP::open(const char *opt_name)
3332
4170
{
3333
 
  uint32_t i;
3334
 
  bool crashed= false;
 
4171
  uint i;
 
4172
  bool crashed=FALSE;
3335
4173
  PAGE *pg;
3336
4174
 
3337
 
  assert(total_ha_2pc > 1);
3338
 
  assert(opt_name && opt_name[0]);
 
4175
  DBUG_ASSERT(total_ha_2pc > 1);
 
4176
  DBUG_ASSERT(opt_name && opt_name[0]);
3339
4177
 
3340
 
  tc_log_page_size= getpagesize();
3341
 
  assert(TC_LOG_PAGE_SIZE % tc_log_page_size == 0);
 
4178
  tc_log_page_size= my_getpagesize();
 
4179
  DBUG_ASSERT(TC_LOG_PAGE_SIZE % tc_log_page_size == 0);
3342
4180
 
3343
4181
  fn_format(logname,opt_name,mysql_data_home,"",MY_UNPACK_FILENAME);
3344
4182
  if ((fd= my_open(logname, O_RDWR, MYF(0))) < 0)
3357
4195
  else
3358
4196
  {
3359
4197
    inited= 1;
3360
 
    crashed= true;
3361
 
    sql_print_information(_("Recovering after a crash using %s"), opt_name);
 
4198
    crashed= TRUE;
 
4199
    sql_print_information("Recovering after a crash using %s", opt_name);
3362
4200
    if (tc_heuristic_recover)
3363
4201
    {
3364
 
      sql_print_error(_("Cannot perform automatic crash recovery when "
3365
 
                      "--tc-heuristic-recover is used"));
 
4202
      sql_print_error("Cannot perform automatic crash recovery when "
 
4203
                      "--tc-heuristic-recover is used");
3366
4204
      goto err;
3367
4205
    }
3368
4206
    file_length= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
3370
4208
      goto err;
3371
4209
  }
3372
4210
 
3373
 
  data= (unsigned char *)my_mmap(0, (size_t)file_length, PROT_READ|PROT_WRITE,
 
4211
  data= (uchar *)my_mmap(0, (size_t)file_length, PROT_READ|PROT_WRITE,
3374
4212
                        MAP_NOSYNC|MAP_SHARED, fd, 0);
3375
4213
  if (data == MAP_FAILED)
3376
4214
  {
3380
4218
  inited=2;
3381
4219
 
3382
4220
  npages=(uint)file_length/tc_log_page_size;
3383
 
  assert(npages >= 3);             // to guarantee non-empty pool
 
4221
  DBUG_ASSERT(npages >= 3);             // to guarantee non-empty pool
3384
4222
  if (!(pages=(PAGE *)my_malloc(npages*sizeof(PAGE), MYF(MY_WME|MY_ZEROFILL))))
3385
4223
    goto err;
3386
4224
  inited=3;
3406
4244
      goto err;
3407
4245
 
3408
4246
  memcpy(data, tc_log_magic, sizeof(tc_log_magic));
3409
 
  data[sizeof(tc_log_magic)]= (unsigned char)total_ha_2pc;
 
4247
  data[sizeof(tc_log_magic)]= (uchar)total_ha_2pc;
3410
4248
  msync(data, tc_log_page_size, MS_SYNC);
3411
4249
  my_sync(fd, MYF(0));
3412
4250
  inited=5;
3514
4352
    threads waiting for a page, but then all these threads will be waiting
3515
4353
    for a fsync() anyway
3516
4354
 
3517
 
   If tc_log == DRIZZLE_LOG then tc_log writes transaction to binlog and
 
4355
   If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
3518
4356
   records XID in a special Xid_log_event.
3519
4357
   If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
3520
4358
   log.
3528
4366
    to the position in memory where xid was logged to.
3529
4367
*/
3530
4368
 
3531
 
int TC_LOG_MMAP::log_xid(THD *thd __attribute__((unused)), my_xid xid)
 
4369
int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
3532
4370
{
3533
4371
  int err;
3534
4372
  PAGE *p;
3557
4395
  while (*p->ptr)
3558
4396
  {
3559
4397
    p->ptr++;
3560
 
    assert(p->ptr < p->end);               // because p->free > 0
 
4398
    DBUG_ASSERT(p->ptr < p->end);               // because p->free > 0
3561
4399
  }
3562
4400
 
3563
4401
  /* found! store xid there and mark the page dirty */
3564
 
  cookie= (ulong)((unsigned char *)p->ptr - data);      // can never be zero
 
4402
  cookie= (ulong)((uchar *)p->ptr - data);      // can never be zero
3565
4403
  *p->ptr++= xid;
3566
4404
  p->free--;
3567
4405
  p->state= DIRTY;
3590
4428
      goto done;                             // we're done
3591
4429
    }
3592
4430
  }                                          // page was not synced! do it now
3593
 
  assert(active == p && syncing == 0);
 
4431
  DBUG_ASSERT(active == p && syncing == 0);
3594
4432
  pthread_mutex_lock(&LOCK_active);
3595
4433
  syncing=p;                                 // place is vacant - take it
3596
4434
  active=0;                                  // page is not active anymore
3607
4445
{
3608
4446
  int err;
3609
4447
 
3610
 
  assert(syncing != active);
 
4448
  DBUG_ASSERT(syncing != active);
3611
4449
 
3612
4450
  /*
3613
4451
    sit down and relax - this can take a while...
3640
4478
  cookie points directly to the memory where xid was logged.
3641
4479
*/
3642
4480
 
3643
 
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid __attribute__((unused)))
 
4481
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
3644
4482
{
3645
4483
  PAGE *p=pages+(cookie/tc_log_page_size);
3646
4484
  my_xid *x=(my_xid *)(data+cookie);
3647
4485
 
3648
 
  assert(*x == xid);
3649
 
  assert(x >= p->start && x < p->end);
 
4486
  DBUG_ASSERT(*x == xid);
 
4487
  DBUG_ASSERT(x >= p->start && x < p->end);
3650
4488
  *x=0;
3651
4489
 
3652
4490
  pthread_mutex_lock(&p->lock);
3653
4491
  p->free++;
3654
 
  assert(p->free <= p->size);
 
4492
  DBUG_ASSERT(p->free <= p->size);
3655
4493
  set_if_smaller(p->ptr, x);
3656
4494
  if (p->free == p->size)               // the page is completely empty
3657
4495
    statistic_decrement(tc_log_cur_pages_used, &LOCK_status);
3662
4500
 
3663
4501
void TC_LOG_MMAP::close()
3664
4502
{
3665
 
  uint32_t i;
 
4503
  uint i;
3666
4504
  switch (inited) {
3667
4505
  case 6:
3668
4506
    pthread_mutex_destroy(&LOCK_sync);
3680
4518
      pthread_cond_destroy(&pages[i].cond);
3681
4519
    }
3682
4520
  case 3:
3683
 
    free((unsigned char*)pages);
 
4521
    my_free((uchar*)pages, MYF(0));
3684
4522
  case 2:
3685
4523
    my_munmap((char*)data, (size_t)file_length);
3686
4524
  case 1:
3698
4536
 
3699
4537
  if (memcmp(data, tc_log_magic, sizeof(tc_log_magic)))
3700
4538
  {
3701
 
    sql_print_error(_("Bad magic header in tc log"));
 
4539
    sql_print_error("Bad magic header in tc log");
3702
4540
    goto err1;
3703
4541
  }
3704
4542
 
3708
4546
  */
3709
4547
  if (data[sizeof(tc_log_magic)] != total_ha_2pc)
3710
4548
  {
3711
 
    sql_print_error(_("Recovery failed! You must enable "
 
4549
    sql_print_error("Recovery failed! You must enable "
3712
4550
                    "exactly %d storage engines that support "
3713
 
                    "two-phase commit protocol"),
 
4551
                    "two-phase commit protocol",
3714
4552
                    data[sizeof(tc_log_magic)]);
3715
4553
    goto err1;
3716
4554
  }
3722
4560
  for ( ; p < end_p ; p++)
3723
4561
  {
3724
4562
    for (my_xid *x=p->start; x < p->end; x++)
3725
 
      if (*x && my_hash_insert(&xids, (unsigned char *)x))
 
4563
      if (*x && my_hash_insert(&xids, (uchar *)x))
3726
4564
        goto err2; // OOM
3727
4565
  }
3728
4566
 
3730
4568
    goto err2;
3731
4569
 
3732
4570
  hash_free(&xids);
3733
 
  memset(data, 0, (size_t)file_length);
 
4571
  bzero(data, (size_t)file_length);
3734
4572
  return 0;
3735
4573
 
3736
4574
err2:
3737
4575
  hash_free(&xids);
3738
4576
err1:
3739
 
  sql_print_error(_("Crash recovery failed. Either correct the problem "
 
4577
  sql_print_error("Crash recovery failed. Either correct the problem "
3740
4578
                  "(if it's, for example, out of memory error) and restart, "
3741
 
                  "or delete tc log and start drizzled with "
3742
 
                  "--tc-heuristic-recover={commit|rollback}"));
 
4579
                  "or delete tc log and start mysqld with "
 
4580
                  "--tc-heuristic-recover={commit|rollback}");
3743
4581
  return 1;
3744
4582
}
3745
4583
#endif
3766
4604
  if (!tc_heuristic_recover)
3767
4605
    return 0;
3768
4606
 
3769
 
  sql_print_information(_("Heuristic crash recovery mode"));
 
4607
  sql_print_information("Heuristic crash recovery mode");
3770
4608
  if (ha_recover(0))
3771
 
    sql_print_error(_("Heuristic crash recovery failed"));
3772
 
  sql_print_information(_("Please restart mysqld without --tc-heuristic-recover"));
 
4609
    sql_print_error("Heuristic crash recovery failed");
 
4610
  sql_print_information("Please restart mysqld without --tc-heuristic-recover");
3773
4611
  return 1;
3774
4612
}
3775
4613
 
3776
4614
/****** transaction coordinator log for 2pc - binlog() based solution ******/
3777
 
#define TC_LOG_BINLOG DRIZZLE_BIN_LOG
 
4615
#define TC_LOG_BINLOG MYSQL_BIN_LOG
3778
4616
 
3779
4617
/**
3780
4618
  @todo
3789
4627
  LOG_INFO log_info;
3790
4628
  int      error= 1;
3791
4629
 
3792
 
  assert(total_ha_2pc > 1);
3793
 
  assert(opt_name && opt_name[0]);
 
4630
  DBUG_ASSERT(total_ha_2pc > 1);
 
4631
  DBUG_ASSERT(opt_name && opt_name[0]);
3794
4632
 
3795
4633
  pthread_mutex_init(&LOCK_prep_xids, MY_MUTEX_INIT_FAST);
3796
4634
  pthread_cond_init (&COND_prep_xids, 0);
3810
4648
    return 1;
3811
4649
  }
3812
4650
 
3813
 
  if ((error= find_log_pos(&log_info, NULL, 1)))
 
4651
  if ((error= find_log_pos(&log_info, NullS, 1)))
3814
4652
  {
3815
4653
    if (error != LOG_INFO_EOF)
3816
 
      sql_print_error(_("find_log_pos() failed (error: %d)"), error);
 
4654
      sql_print_error("find_log_pos() failed (error: %d)", error);
3817
4655
    else
3818
4656
      error= 0;
3819
4657
    goto err;
3837
4675
 
3838
4676
    if (error !=  LOG_INFO_EOF)
3839
4677
    {
3840
 
      sql_print_error(_("find_log_pos() failed (error: %d)"), error);
 
4678
      sql_print_error("find_log_pos() failed (error: %d)", error);
3841
4679
      goto err;
3842
4680
    }
3843
4681
 
3851
4689
        ev->get_type_code() == FORMAT_DESCRIPTION_EVENT &&
3852
4690
        ev->flags & LOG_EVENT_BINLOG_IN_USE_F)
3853
4691
    {
3854
 
      sql_print_information(_("Recovering after a crash using %s"), opt_name);
 
4692
      sql_print_information("Recovering after a crash using %s", opt_name);
3855
4693
      error= recover(&log, (Format_description_log_event *)ev);
3856
4694
    }
3857
4695
    else
3872
4710
/** This is called on shutdown, after ha_panic. */
3873
4711
void TC_LOG_BINLOG::close()
3874
4712
{
3875
 
  assert(prepared_xids==0);
 
4713
  DBUG_ASSERT(prepared_xids==0);
3876
4714
  pthread_mutex_destroy(&LOCK_prep_xids);
3877
4715
  pthread_cond_destroy (&COND_prep_xids);
3878
4716
}
3888
4726
*/
3889
4727
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
3890
4728
{
 
4729
  DBUG_ENTER("TC_LOG_BINLOG::log");
3891
4730
  Xid_log_event xle(thd, xid);
3892
4731
  binlog_trx_data *trx_data=
3893
4732
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
3895
4734
    We always commit the entire transaction when writing an XID. Also
3896
4735
    note that the return value is inverted.
3897
4736
   */
3898
 
  return(!binlog_end_trans(thd, trx_data, &xle, true));
 
4737
  DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
3899
4738
}
3900
4739
 
3901
 
void TC_LOG_BINLOG::unlog(ulong cookie __attribute__((unused)),
3902
 
                          my_xid xid __attribute__((unused)))
 
4740
void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
3903
4741
{
3904
4742
  pthread_mutex_lock(&LOCK_prep_xids);
3905
 
  assert(prepared_xids > 0);
 
4743
  DBUG_ASSERT(prepared_xids > 0);
3906
4744
  if (--prepared_xids == 0) {
 
4745
    DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
3907
4746
    pthread_cond_signal(&COND_prep_xids);
3908
4747
  }
3909
4748
  pthread_mutex_unlock(&LOCK_prep_xids);
3930
4769
    if (ev->get_type_code() == XID_EVENT)
3931
4770
    {
3932
4771
      Xid_log_event *xev=(Xid_log_event *)ev;
3933
 
      unsigned char *x= (unsigned char *) memdup_root(&mem_root, (unsigned char*) &xev->xid,
 
4772
      uchar *x= (uchar *) memdup_root(&mem_root, (uchar*) &xev->xid,
3934
4773
                                      sizeof(xev->xid));
3935
4774
      if (! x)
3936
4775
        goto err2;
3950
4789
  free_root(&mem_root, MYF(0));
3951
4790
  hash_free(&xids);
3952
4791
err1:
3953
 
  sql_print_error(_("Crash recovery failed. Either correct the problem "
 
4792
  sql_print_error("Crash recovery failed. Either correct the problem "
3954
4793
                  "(if it's, for example, out of memory error) and restart, "
3955
4794
                  "or delete (or rename) binary log and start mysqld with "
3956
 
                  "--tc-heuristic-recover={commit|rollback}"));
 
4795
                  "--tc-heuristic-recover={commit|rollback}");
3957
4796
  return 1;
3958
4797
}
3959
4798
 
3973
4812
  @return byte offset from the beginning of the binlog
3974
4813
*/
3975
4814
extern "C"
3976
 
uint64_t mysql_bin_log_file_pos(void)
 
4815
ulonglong mysql_bin_log_file_pos(void)
3977
4816
{
3978
 
  return (uint64_t) mysql_bin_log.get_log_file()->pos_in_file;
 
4817
  return (ulonglong) mysql_bin_log.get_log_file()->pos_in_file;
3979
4818
}
3980
4819
#endif /* INNODB_COMPATIBILITY_HOOKS */
3981
4820
 
3982
4821
 
 
4822
struct st_mysql_storage_engine binlog_storage_engine=
 
4823
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
 
4824
 
3983
4825
mysql_declare_plugin(binlog)
3984
4826
{
3985
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
 
4827
  MYSQL_STORAGE_ENGINE_PLUGIN,
 
4828
  &binlog_storage_engine,
3986
4829
  "binlog",
3987
 
  "1.0",
3988
4830
  "MySQL AB",
3989
4831
  "This is a pseudo storage engine to represent the binlog in a transaction",
3990
4832
  PLUGIN_LICENSE_GPL,
3991
4833
  binlog_init, /* Plugin Init */
3992
4834
  NULL, /* Plugin Deinit */
 
4835
  0x0100 /* 1.0 */,
3993
4836
  NULL,                       /* status variables                */
3994
4837
  NULL,                       /* system variables                */
3995
4838
  NULL                        /* config options                  */