~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/log.cc

Removed SCCS references.

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
  {
1347
2044
      goto err;
1348
2045
  }
1349
2046
  /* The following will either truncate the file or fill the end with \n' */
1350
 
  if (ftruncate(file, offset - init_offset) || my_sync(file, MYF(MY_WME)))
 
2047
  if (my_chsize(file, offset - init_offset, '\n', MYF(MY_WME)) ||
 
2048
      my_sync(file, MYF(MY_WME)))
1351
2049
    goto err;
1352
2050
 
1353
2051
  /* Reset data in old index cache */
1354
2052
  reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 1);
1355
 
  return(0);
 
2053
  DBUG_RETURN(0);
1356
2054
 
1357
2055
err:
1358
 
  return(1);
 
2056
  DBUG_RETURN(1);
1359
2057
}
1360
2058
 
 
2059
#endif /* HAVE_REPLICATION */
 
2060
 
1361
2061
/**
1362
2062
  Find the position in the log-index-file for the given log name.
1363
2063
 
1380
2080
    LOG_INFO_IO         Got IO error while reading file
1381
2081
*/
1382
2082
 
1383
 
int DRIZZLE_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
 
2083
int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
1384
2084
                            bool need_lock)
1385
2085
{
1386
2086
  int error= 0;
1387
2087
  char *fname= linfo->log_file_name;
1388
 
  uint32_t log_name_len= log_name ? (uint) strlen(log_name) : 0;
 
2088
  uint log_name_len= log_name ? (uint) strlen(log_name) : 0;
 
2089
  DBUG_ENTER("find_log_pos");
 
2090
  DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));
1389
2091
 
1390
2092
  /*
1391
2093
    Mutex needed because we need to make sure the file pointer does not
1400
2102
 
1401
2103
  for (;;)
1402
2104
  {
1403
 
    uint32_t length;
 
2105
    uint length;
1404
2106
    my_off_t offset= my_b_tell(&index_file);
1405
2107
    /* If we get 0 or 1 characters, this is the end of the file */
1406
2108
 
1416
2118
        (log_name_len == length-1 && fname[log_name_len] == '\n' &&
1417
2119
         !memcmp(fname, log_name, log_name_len)))
1418
2120
    {
 
2121
      DBUG_PRINT("info",("Found log file entry"));
1419
2122
      fname[length-1]=0;                        // remove last \n
1420
2123
      linfo->index_file_start_offset= offset;
1421
2124
      linfo->index_file_offset = my_b_tell(&index_file);
1425
2128
 
1426
2129
  if (need_lock)
1427
2130
    pthread_mutex_unlock(&LOCK_index);
1428
 
  return(error);
 
2131
  DBUG_RETURN(error);
1429
2132
}
1430
2133
 
1431
2134
 
1453
2156
    LOG_INFO_IO         Got IO error while reading file
1454
2157
*/
1455
2158
 
1456
 
int DRIZZLE_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
 
2159
int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
1457
2160
{
1458
2161
  int error= 0;
1459
 
  uint32_t length;
 
2162
  uint length;
1460
2163
  char *fname= linfo->log_file_name;
1461
2164
 
1462
2165
  if (need_lock)
1500
2203
    1   error
1501
2204
*/
1502
2205
 
1503
 
bool DRIZZLE_BIN_LOG::reset_logs(THD* thd)
 
2206
bool MYSQL_BIN_LOG::reset_logs(THD* thd)
1504
2207
{
1505
2208
  LOG_INFO linfo;
1506
2209
  bool error=0;
1507
2210
  const char* save_name;
 
2211
  DBUG_ENTER("reset_logs");
1508
2212
 
 
2213
  ha_reset_logs(thd);
1509
2214
  /*
1510
2215
    We need to get both locks to be sure that no one is trying to
1511
2216
    write to the index log file.
1519
2224
    thread. If the transaction involved MyISAM tables, it should go
1520
2225
    into binlog even on rollback.
1521
2226
  */
1522
 
  pthread_mutex_lock(&LOCK_thread_count);
 
2227
  VOID(pthread_mutex_lock(&LOCK_thread_count));
1523
2228
 
1524
2229
  /* Save variables so that we can reopen the log */
1525
2230
  save_name=name;
1528
2233
 
1529
2234
  /* First delete all old log files */
1530
2235
 
1531
 
  if (find_log_pos(&linfo, NULL, 0))
 
2236
  if (find_log_pos(&linfo, NullS, 0))
1532
2237
  {
1533
2238
    error=1;
1534
2239
    goto err;
1540
2245
    {
1541
2246
      if (my_errno == ENOENT) 
1542
2247
      {
1543
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2248
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1544
2249
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1545
2250
                            linfo.log_file_name);
1546
 
        sql_print_information(_("Failed to delete file '%s'"),
 
2251
        sql_print_information("Failed to delete file '%s'",
1547
2252
                              linfo.log_file_name);
1548
2253
        my_errno= 0;
1549
2254
        error= 0;
1550
2255
      }
1551
2256
      else
1552
2257
      {
1553
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2258
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1554
2259
                            ER_BINLOG_PURGE_FATAL_ERR,
1555
 
                            _("a problem with deleting %s; "
 
2260
                            "a problem with deleting %s; "
1556
2261
                            "consider examining correspondence "
1557
2262
                            "of your binlog index file "
1558
 
                            "to the actual binlog files"),
 
2263
                            "to the actual binlog files",
1559
2264
                            linfo.log_file_name);
1560
2265
        error= 1;
1561
2266
        goto err;
1571
2276
  {
1572
2277
    if (my_errno == ENOENT) 
1573
2278
    {
1574
 
      push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2279
      push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1575
2280
                          ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1576
2281
                          index_file_name);
1577
 
      sql_print_information(_("Failed to delete file '%s'"),
 
2282
      sql_print_information("Failed to delete file '%s'",
1578
2283
                            index_file_name);
1579
2284
      my_errno= 0;
1580
2285
      error= 0;
1581
2286
    }
1582
2287
    else
1583
2288
    {
1584
 
      push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2289
      push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1585
2290
                          ER_BINLOG_PURGE_FATAL_ERR,
1586
2291
                          "a problem with deleting %s; "
1587
2292
                          "consider examining correspondence "
1596
2301
    need_start_event=1;
1597
2302
  if (!open_index_file(index_file_name, 0))
1598
2303
    open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0);
1599
 
  free((unsigned char*) save_name);
 
2304
  my_free((uchar*) save_name, MYF(0));
1600
2305
 
1601
2306
err:
1602
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
2307
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
1603
2308
  pthread_mutex_unlock(&LOCK_index);
1604
2309
  pthread_mutex_unlock(&LOCK_log);
1605
 
  return(error);
 
2310
  DBUG_RETURN(error);
1606
2311
}
1607
2312
 
1608
2313
 
1643
2348
    LOG_INFO_IO         Got IO error while reading file
1644
2349
*/
1645
2350
 
 
2351
#ifdef HAVE_REPLICATION
1646
2352
 
1647
 
int DRIZZLE_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
 
2353
int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
1648
2354
{
1649
2355
  int error;
 
2356
  DBUG_ENTER("purge_first_log");
1650
2357
 
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()));
 
2358
  DBUG_ASSERT(is_open());
 
2359
  DBUG_ASSERT(rli->slave_running == 1);
 
2360
  DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name));
1654
2361
 
1655
2362
  pthread_mutex_lock(&LOCK_index);
1656
2363
  pthread_mutex_lock(&rli->log_space_lock);
1657
 
  rli->relay_log.purge_logs(rli->group_relay_log_name.c_str(), included,
 
2364
  rli->relay_log.purge_logs(rli->group_relay_log_name, included,
1658
2365
                            0, 0, &rli->log_space_total);
1659
2366
  // Tell the I/O thread to take the relay_log_space_limit into account
1660
2367
  rli->ignore_log_space_limit= 0;
1673
2380
    If included is true, we want the first relay log;
1674
2381
    otherwise we want the one after event_relay_log_name.
1675
2382
  */
1676
 
  if ((included && (error=find_log_pos(&rli->linfo, NULL, 0))) ||
 
2383
  if ((included && (error=find_log_pos(&rli->linfo, NullS, 0))) ||
1677
2384
      (!included &&
1678
 
       ((error=find_log_pos(&rli->linfo, rli->event_relay_log_name.c_str(), 0)) ||
 
2385
       ((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) ||
1679
2386
        (error=find_next_log(&rli->linfo, 0)))))
1680
2387
  {
1681
2388
    char buff[22];
1682
 
    sql_print_error(_("next log error: %d  offset: %s  log: %s included: %d"),
 
2389
    sql_print_error("next log error: %d  offset: %s  log: %s included: %d",
1683
2390
                    error,
1684
2391
                    llstr(rli->linfo.index_file_offset,buff),
1685
 
                    rli->group_relay_log_name.c_str(),
 
2392
                    rli->group_relay_log_name,
1686
2393
                    included);
1687
2394
    goto err;
1688
2395
  }
1691
2398
    Reset rli's coordinates to the current log.
1692
2399
  */
1693
2400
  rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
1694
 
  rli->event_relay_log_name.assign(rli->linfo.log_file_name);
 
2401
  strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
 
2402
          sizeof(rli->event_relay_log_name)-1);
1695
2403
 
1696
2404
  /*
1697
2405
    If we removed the rli->group_relay_log_name file,
1701
2409
  if (included)
1702
2410
  {
1703
2411
    rli->group_relay_log_pos = BIN_LOG_HEADER_SIZE;
1704
 
    rli->group_relay_log_name.assign(rli->linfo.log_file_name);
 
2412
    strmake(rli->group_relay_log_name,rli->linfo.log_file_name,
 
2413
            sizeof(rli->group_relay_log_name)-1);
1705
2414
    rli->notify_group_relay_log_name_update();
1706
2415
  }
1707
2416
 
1710
2419
 
1711
2420
err:
1712
2421
  pthread_mutex_unlock(&LOCK_index);
1713
 
  return(error);
 
2422
  DBUG_RETURN(error);
1714
2423
}
1715
2424
 
1716
2425
/**
1717
2426
  Update log index_file.
1718
2427
*/
1719
2428
 
1720
 
int DRIZZLE_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
 
2429
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
1721
2430
{
1722
2431
  if (copy_up_file_and_fill(&index_file, log_info->index_file_start_offset))
1723
2432
    return LOG_INFO_IO;
1752
2461
                                stat() or my_delete()
1753
2462
*/
1754
2463
 
1755
 
int DRIZZLE_BIN_LOG::purge_logs(const char *to_log, 
 
2464
int MYSQL_BIN_LOG::purge_logs(const char *to_log, 
1756
2465
                          bool included,
1757
2466
                          bool need_mutex, 
1758
2467
                          bool need_update_threads, 
1759
 
                          uint64_t *decrease_log_space)
 
2468
                          ulonglong *decrease_log_space)
1760
2469
{
1761
2470
  int error;
1762
2471
  int ret = 0;
1763
2472
  bool exit_loop= 0;
1764
2473
  LOG_INFO log_info;
 
2474
  DBUG_ENTER("purge_logs");
 
2475
  DBUG_PRINT("info",("to_log= %s",to_log));
1765
2476
 
1766
2477
  if (need_mutex)
1767
2478
    pthread_mutex_lock(&LOCK_index);
1772
2483
    File name exists in index file; delete until we find this file
1773
2484
    or a file that is used.
1774
2485
  */
1775
 
  if ((error=find_log_pos(&log_info, NULL, 0 /*no mutex*/)))
 
2486
  if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
1776
2487
    goto err;
1777
2488
  while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
1778
2489
         !log_in_use(log_info.log_file_name))
1786
2497
          It's not fatal if we can't stat a log file that does not exist;
1787
2498
          If we could not stat, we won't delete.
1788
2499
        */     
1789
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2500
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1790
2501
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1791
2502
                            log_info.log_file_name);
1792
 
        sql_print_information(_("Failed to execute stat() on file '%s'"),
 
2503
        sql_print_information("Failed to execute stat on file '%s'",
1793
2504
                              log_info.log_file_name);
1794
2505
        my_errno= 0;
1795
2506
      }
1798
2509
        /*
1799
2510
          Other than ENOENT are fatal
1800
2511
        */
1801
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2512
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1802
2513
                            ER_BINLOG_PURGE_FATAL_ERR,
1803
 
                            _("a problem with getting info on being purged %s; "
 
2514
                            "a problem with getting info on being purged %s; "
1804
2515
                            "consider examining correspondence "
1805
2516
                            "of your binlog index file "
1806
 
                            "to the actual binlog files"),
 
2517
                            "to the actual binlog files",
1807
2518
                            log_info.log_file_name);
1808
2519
        error= LOG_INFO_FATAL;
1809
2520
        goto err;
1811
2522
    }
1812
2523
    else
1813
2524
    {
 
2525
      DBUG_PRINT("info",("purging %s",log_info.log_file_name));
1814
2526
      if (!my_delete(log_info.log_file_name, MYF(0)))
1815
2527
      {
1816
2528
        if (decrease_log_space)
1820
2532
      {
1821
2533
        if (my_errno == ENOENT) 
1822
2534
        {
1823
 
          push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2535
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1824
2536
                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1825
2537
                              log_info.log_file_name);
1826
 
          sql_print_information(_("Failed to delete file '%s'"),
 
2538
          sql_print_information("Failed to delete file '%s'",
1827
2539
                                log_info.log_file_name);
1828
2540
          my_errno= 0;
1829
2541
        }
1830
2542
        else
1831
2543
        {
1832
 
          push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2544
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1833
2545
                              ER_BINLOG_PURGE_FATAL_ERR,
1834
 
                              _("a problem with deleting %s; "
 
2546
                              "a problem with deleting %s; "
1835
2547
                              "consider examining correspondence "
1836
2548
                              "of your binlog index file "
1837
 
                              "to the actual binlog files"),
 
2549
                              "to the actual binlog files",
1838
2550
                              log_info.log_file_name);
1839
2551
          if (my_errno == EMFILE)
1840
2552
          {
 
2553
            DBUG_PRINT("info",
 
2554
                       ("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
1841
2555
            error= LOG_INFO_EMFILE;
1842
2556
          }
1843
2557
          error= LOG_INFO_FATAL;
1846
2560
      }
1847
2561
    }
1848
2562
 
 
2563
    ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
 
2564
 
1849
2565
    if (find_next_log(&log_info, 0) || exit_loop)
1850
2566
      break;
1851
2567
  }
1862
2578
err:
1863
2579
  if (need_mutex)
1864
2580
    pthread_mutex_unlock(&LOCK_index);
1865
 
  return(error);
 
2581
  DBUG_RETURN(error);
1866
2582
}
1867
2583
 
1868
2584
/**
1884
2600
                                stat() or my_delete()
1885
2601
*/
1886
2602
 
1887
 
int DRIZZLE_BIN_LOG::purge_logs_before_date(time_t purge_time)
 
2603
int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
1888
2604
{
1889
2605
  int error;
1890
2606
  LOG_INFO log_info;
1891
2607
  struct stat stat_area;
1892
2608
 
 
2609
  DBUG_ENTER("purge_logs_before_date");
 
2610
 
1893
2611
  pthread_mutex_lock(&LOCK_index);
1894
2612
 
1895
2613
  /*
1897
2615
    or a file that is used or a file
1898
2616
    that is older than purge_time.
1899
2617
  */
1900
 
  if ((error=find_log_pos(&log_info, NULL, 0 /*no mutex*/)))
 
2618
  if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
1901
2619
    goto err;
1902
2620
 
1903
2621
  while (strcmp(log_file_name, log_info.log_file_name) &&
1910
2628
        /*
1911
2629
          It's not fatal if we can't stat a log file that does not exist.
1912
2630
        */     
1913
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2631
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1914
2632
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1915
2633
                            log_info.log_file_name);
1916
 
        sql_print_information(_("Failed to execute stat() on file '%s'"),
 
2634
        sql_print_information("Failed to execute stat on file '%s'",
1917
2635
                              log_info.log_file_name);
1918
2636
        my_errno= 0;
1919
2637
      }
1922
2640
        /*
1923
2641
          Other than ENOENT are fatal
1924
2642
        */
1925
 
        push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2643
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1926
2644
                            ER_BINLOG_PURGE_FATAL_ERR,
1927
 
                            _("a problem with getting info on being purged %s; "
 
2645
                            "a problem with getting info on being purged %s; "
1928
2646
                            "consider examining correspondence "
1929
2647
                            "of your binlog index file "
1930
 
                            "to the actual binlog files"),
 
2648
                            "to the actual binlog files",
1931
2649
                            log_info.log_file_name);
1932
2650
        error= LOG_INFO_FATAL;
1933
2651
        goto err;
1942
2660
        if (my_errno == ENOENT) 
1943
2661
        {
1944
2662
          /* It's not fatal even if we can't delete a log file */
1945
 
          push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2663
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1946
2664
                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1947
2665
                              log_info.log_file_name);
1948
 
          sql_print_information(_("Failed to delete file '%s'"),
 
2666
          sql_print_information("Failed to delete file '%s'",
1949
2667
                                log_info.log_file_name);
1950
2668
          my_errno= 0;
1951
2669
        }
1952
2670
        else
1953
2671
        {
1954
 
          push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2672
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1955
2673
                              ER_BINLOG_PURGE_FATAL_ERR,
1956
 
                              _("a problem with deleting %s; "
 
2674
                              "a problem with deleting %s; "
1957
2675
                              "consider examining correspondence "
1958
2676
                              "of your binlog index file "
1959
 
                              "to the actual binlog files"),
 
2677
                              "to the actual binlog files",
1960
2678
                              log_info.log_file_name);
1961
2679
          error= LOG_INFO_FATAL;
1962
2680
          goto err;
1963
2681
        }
1964
2682
      }
 
2683
      ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
1965
2684
    }
1966
2685
    if (find_next_log(&log_info, 0))
1967
2686
      break;
1975
2694
 
1976
2695
err:
1977
2696
  pthread_mutex_unlock(&LOCK_index);
1978
 
  return(error);
 
2697
  DBUG_RETURN(error);
1979
2698
}
 
2699
#endif /* HAVE_REPLICATION */
1980
2700
 
1981
2701
 
1982
2702
/**
1988
2708
    If file name will be longer then FN_REFLEN it will be truncated
1989
2709
*/
1990
2710
 
1991
 
void DRIZZLE_BIN_LOG::make_log_name(char* buf, const char* log_ident)
 
2711
void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
1992
2712
{
1993
 
  uint32_t dir_len = dirname_length(log_file_name); 
 
2713
  uint dir_len = dirname_length(log_file_name); 
1994
2714
  if (dir_len >= FN_REFLEN)
1995
2715
    dir_len=FN_REFLEN-1;
1996
 
  my_stpncpy(buf, log_file_name, dir_len);
 
2716
  strnmov(buf, log_file_name, dir_len);
1997
2717
  strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len -1);
1998
2718
}
1999
2719
 
2002
2722
  Check if we are writing/reading to the given log file.
2003
2723
*/
2004
2724
 
2005
 
bool DRIZZLE_BIN_LOG::is_active(const char *log_file_name_arg)
 
2725
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
2006
2726
{
2007
2727
  return !strcmp(log_file_name, log_file_name_arg);
2008
2728
}
2016
2736
  method).
2017
2737
*/
2018
2738
 
2019
 
void DRIZZLE_BIN_LOG::new_file()
 
2739
void MYSQL_BIN_LOG::new_file()
2020
2740
{
2021
2741
  new_file_impl(1);
2022
2742
}
2023
2743
 
2024
2744
 
2025
 
void DRIZZLE_BIN_LOG::new_file_without_locking()
 
2745
void MYSQL_BIN_LOG::new_file_without_locking()
2026
2746
{
2027
2747
  new_file_impl(0);
2028
2748
}
2037
2757
    The new file name is stored last in the index file
2038
2758
*/
2039
2759
 
2040
 
void DRIZZLE_BIN_LOG::new_file_impl(bool need_lock)
 
2760
void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
2041
2761
{
2042
2762
  char new_name[FN_REFLEN], *new_name_ptr, *old_name;
2043
2763
 
 
2764
  DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
2044
2765
  if (!is_open())
2045
2766
  {
2046
 
    return;
 
2767
    DBUG_PRINT("info",("log is closed"));
 
2768
    DBUG_VOID_RETURN;
2047
2769
  }
2048
2770
 
2049
2771
  if (need_lock)
2067
2789
    tc_log_page_waits++;
2068
2790
    pthread_mutex_lock(&LOCK_prep_xids);
2069
2791
    while (prepared_xids) {
 
2792
      DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
2070
2793
      pthread_cond_wait(&COND_prep_xids, &LOCK_prep_xids);
2071
2794
    }
2072
2795
    pthread_mutex_unlock(&LOCK_prep_xids);
2123
2846
 
2124
2847
  open(old_name, log_type, new_name_ptr,
2125
2848
       io_cache_type, no_auto_events, max_size, 1);
2126
 
  free(old_name);
 
2849
  my_free(old_name,MYF(0));
2127
2850
 
2128
2851
end:
2129
2852
  if (need_lock)
2130
2853
    pthread_mutex_unlock(&LOCK_log);
2131
2854
  pthread_mutex_unlock(&LOCK_index);
2132
2855
 
2133
 
  return;
 
2856
  DBUG_VOID_RETURN;
2134
2857
}
2135
2858
 
2136
2859
 
2137
 
bool DRIZZLE_BIN_LOG::append(Log_event* ev)
 
2860
bool MYSQL_BIN_LOG::append(Log_event* ev)
2138
2861
{
2139
2862
  bool error = 0;
2140
2863
  pthread_mutex_lock(&LOCK_log);
 
2864
  DBUG_ENTER("MYSQL_BIN_LOG::append");
2141
2865
 
2142
 
  assert(log_file.type == SEQ_READ_APPEND);
 
2866
  DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
2143
2867
  /*
2144
2868
    Log_event::write() is smart enough to use my_b_write() or
2145
2869
    my_b_append() depending on the kind of cache we have.
2150
2874
    goto err;
2151
2875
  }
2152
2876
  bytes_written+= ev->data_written;
 
2877
  DBUG_PRINT("info",("max_size: %lu",max_size));
2153
2878
  if ((uint) my_b_append_tell(&log_file) > max_size)
2154
2879
    new_file_without_locking();
2155
2880
 
2156
2881
err:
2157
2882
  pthread_mutex_unlock(&LOCK_log);
2158
2883
  signal_update();                              // Safe as we don't call close
2159
 
  return(error);
 
2884
  DBUG_RETURN(error);
2160
2885
}
2161
2886
 
2162
2887
 
2163
 
bool DRIZZLE_BIN_LOG::appendv(const char* buf, uint32_t len,...)
 
2888
bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...)
2164
2889
{
2165
2890
  bool error= 0;
 
2891
  DBUG_ENTER("MYSQL_BIN_LOG::appendv");
2166
2892
  va_list(args);
2167
2893
  va_start(args,len);
2168
2894
 
2169
 
  assert(log_file.type == SEQ_READ_APPEND);
 
2895
  DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
2170
2896
 
2171
2897
  safe_mutex_assert_owner(&LOCK_log);
2172
2898
  do
2173
2899
  {
2174
 
    if (my_b_append(&log_file,(unsigned char*) buf,len))
 
2900
    if (my_b_append(&log_file,(uchar*) buf,len))
2175
2901
    {
2176
2902
      error= 1;
2177
2903
      goto err;
2178
2904
    }
2179
2905
    bytes_written += len;
2180
2906
  } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
 
2907
  DBUG_PRINT("info",("max_size: %lu",max_size));
2181
2908
  if ((uint) my_b_append_tell(&log_file) > max_size)
2182
2909
    new_file_without_locking();
2183
2910
 
2184
2911
err:
2185
2912
  if (!error)
2186
2913
    signal_update();
2187
 
  return(error);
 
2914
  DBUG_RETURN(error);
2188
2915
}
2189
2916
 
2190
2917
 
2191
 
bool DRIZZLE_BIN_LOG::flush_and_sync()
 
2918
bool MYSQL_BIN_LOG::flush_and_sync()
2192
2919
{
2193
2920
  int err=0, fd=log_file.file;
2194
2921
  safe_mutex_assert_owner(&LOCK_log);
2202
2929
  return err;
2203
2930
}
2204
2931
 
2205
 
void DRIZZLE_BIN_LOG::start_union_events(THD *thd, query_id_t query_id_param)
 
2932
void MYSQL_BIN_LOG::start_union_events(THD *thd, query_id_t query_id_param)
2206
2933
{
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;
 
2934
  DBUG_ASSERT(!thd->binlog_evt_union.do_union);
 
2935
  thd->binlog_evt_union.do_union= TRUE;
 
2936
  thd->binlog_evt_union.unioned_events= FALSE;
 
2937
  thd->binlog_evt_union.unioned_events_trans= FALSE;
2211
2938
  thd->binlog_evt_union.first_query_id= query_id_param;
2212
2939
}
2213
2940
 
2214
 
void DRIZZLE_BIN_LOG::stop_union_events(THD *thd)
 
2941
void MYSQL_BIN_LOG::stop_union_events(THD *thd)
2215
2942
{
2216
 
  assert(thd->binlog_evt_union.do_union);
2217
 
  thd->binlog_evt_union.do_union= false;
 
2943
  DBUG_ASSERT(thd->binlog_evt_union.do_union);
 
2944
  thd->binlog_evt_union.do_union= FALSE;
2218
2945
}
2219
2946
 
2220
 
bool DRIZZLE_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
 
2947
bool MYSQL_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
2221
2948
{
2222
2949
  return (thd->binlog_evt_union.do_union && 
2223
2950
          query_id_param >= thd->binlog_evt_union.first_query_id);
2231
2958
 
2232
2959
int THD::binlog_setup_trx_data()
2233
2960
{
 
2961
  DBUG_ENTER("THD::binlog_setup_trx_data");
2234
2962
  binlog_trx_data *trx_data=
2235
2963
    (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2236
2964
 
2237
2965
  if (trx_data)
2238
 
    return(0);                             // Already set up
 
2966
    DBUG_RETURN(0);                             // Already set up
2239
2967
 
2240
2968
  trx_data= (binlog_trx_data*) my_malloc(sizeof(binlog_trx_data), MYF(MY_ZEROFILL));
2241
2969
  if (!trx_data ||
2242
2970
      open_cached_file(&trx_data->trans_log, mysql_tmpdir,
2243
2971
                       LOG_PREFIX, binlog_cache_size, MYF(MY_WME)))
2244
2972
  {
2245
 
    free((unsigned char*)trx_data);
2246
 
    return(1);                      // Didn't manage to set it up
 
2973
    my_free((uchar*)trx_data, MYF(MY_ALLOW_ZERO_PTR));
 
2974
    DBUG_RETURN(1);                      // Didn't manage to set it up
2247
2975
  }
2248
2976
  thd_set_ha_data(this, binlog_hton, trx_data);
2249
2977
 
2250
2978
  trx_data= new (thd_get_ha_data(this, binlog_hton)) binlog_trx_data;
2251
2979
 
2252
 
  return(0);
 
2980
  DBUG_RETURN(0);
2253
2981
}
2254
2982
 
2255
2983
/*
2284
3012
THD::binlog_start_trans_and_stmt()
2285
3013
{
2286
3014
  binlog_trx_data *trx_data= (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
 
3015
  DBUG_ENTER("binlog_start_trans_and_stmt");
 
3016
  DBUG_PRINT("enter", ("trx_data: 0x%lx  trx_data->before_stmt_pos: %lu",
 
3017
                       (long) trx_data,
 
3018
                       (trx_data ? (ulong) trx_data->before_stmt_pos :
 
3019
                        (ulong) 0)));
2287
3020
 
2288
3021
  if (trx_data == NULL ||
2289
3022
      trx_data->before_stmt_pos == MY_OFF_T_UNDEF)
2290
3023
  {
2291
3024
    this->binlog_set_stmt_begin();
2292
3025
    if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2293
 
      trans_register_ha(this, true, binlog_hton);
2294
 
    trans_register_ha(this, false, binlog_hton);
 
3026
      trans_register_ha(this, TRUE, binlog_hton);
 
3027
    trans_register_ha(this, FALSE, binlog_hton);
2295
3028
    /*
2296
3029
      Mark statement transaction as read/write. We never start
2297
3030
      a binary log transaction and keep it read-only,
2303
3036
    */
2304
3037
    ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
2305
3038
  }
2306
 
  return;
 
3039
  DBUG_VOID_RETURN;
2307
3040
}
2308
3041
 
2309
3042
void THD::binlog_set_stmt_begin() {
2327
3060
  Write a table map to the binary log.
2328
3061
 */
2329
3062
 
2330
 
int THD::binlog_write_table_map(Table *table, bool is_trans)
 
3063
int THD::binlog_write_table_map(TABLE *table, bool is_trans)
2331
3064
{
2332
3065
  int error;
 
3066
  DBUG_ENTER("THD::binlog_write_table_map");
 
3067
  DBUG_PRINT("enter", ("table: 0x%lx  (%s: #%lu)",
 
3068
                       (long) table, table->s->table_name.str,
 
3069
                       table->s->table_map_id));
2333
3070
 
2334
3071
  /* Pre-conditions */
2335
 
  assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2336
 
  assert(table->s->table_map_id != UINT32_MAX);
 
3072
  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
3073
  DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
2337
3074
 
2338
3075
  Table_map_log_event::flag_set const
2339
3076
    flags= Table_map_log_event::TM_NO_FLAGS;
2345
3082
    binlog_start_trans_and_stmt();
2346
3083
 
2347
3084
  if ((error= mysql_bin_log.write(&the_event)))
2348
 
    return(error);
 
3085
    DBUG_RETURN(error);
2349
3086
 
2350
3087
  binlog_table_maps++;
2351
3088
  table->s->table_map_version= mysql_bin_log.table_map_version();
2352
 
  return(0);
 
3089
  DBUG_RETURN(0);
2353
3090
}
2354
3091
 
2355
3092
Rows_log_event*
2375
3112
  binlog_trx_data *const trx_data=
2376
3113
    (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2377
3114
 
2378
 
  assert(trx_data);
 
3115
  DBUG_ASSERT(trx_data);
2379
3116
  trx_data->set_pending(ev);
2380
3117
}
2381
3118
 
2386
3123
  event.
2387
3124
*/
2388
3125
int
2389
 
DRIZZLE_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
 
3126
MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
2390
3127
                                                Rows_log_event* event)
2391
3128
{
2392
 
  assert(mysql_bin_log.is_open());
 
3129
  DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)");
 
3130
  DBUG_ASSERT(mysql_bin_log.is_open());
 
3131
  DBUG_PRINT("enter", ("event: 0x%lx", (long) event));
2393
3132
 
2394
3133
  int error= 0;
2395
3134
 
2396
3135
  binlog_trx_data *const trx_data=
2397
3136
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
2398
3137
 
2399
 
  assert(trx_data);
 
3138
  DBUG_ASSERT(trx_data);
 
3139
 
 
3140
  DBUG_PRINT("info", ("trx_data->pending(): 0x%lx", (long) trx_data->pending()));
2400
3141
 
2401
3142
  if (Rows_log_event* pending= trx_data->pending())
2402
3143
  {
2423
3164
    if (pending->write(file))
2424
3165
    {
2425
3166
      pthread_mutex_unlock(&LOCK_log);
2426
 
      return(1);
 
3167
      DBUG_RETURN(1);
2427
3168
    }
2428
3169
 
2429
3170
    /*
2461
3202
 
2462
3203
  thd->binlog_set_pending_rows_event(event);
2463
3204
 
2464
 
  return(error);
 
3205
  DBUG_RETURN(error);
2465
3206
}
2466
3207
 
2467
3208
/**
2468
3209
  Write an event to the binary log.
2469
3210
*/
2470
3211
 
2471
 
bool DRIZZLE_BIN_LOG::write(Log_event *event_info)
 
3212
bool MYSQL_BIN_LOG::write(Log_event *event_info)
2472
3213
{
2473
3214
  THD *thd= event_info->thd;
2474
3215
  bool error= 1;
 
3216
  DBUG_ENTER("MYSQL_BIN_LOG::write(Log_event *)");
2475
3217
 
2476
3218
  if (thd->binlog_evt_union.do_union)
2477
3219
  {
2479
3221
      In Stored function; Remember that function call caused an update.
2480
3222
      We will log the function call to the binary log on function exit
2481
3223
    */
2482
 
    thd->binlog_evt_union.unioned_events= true;
 
3224
    thd->binlog_evt_union.unioned_events= TRUE;
2483
3225
    thd->binlog_evt_union.unioned_events_trans |= event_info->cache_stmt;
2484
 
    return(0);
 
3226
    DBUG_RETURN(0);
2485
3227
  }
2486
3228
 
2487
3229
  /*
2516
3258
    if ((thd && !(thd->options & OPTION_BIN_LOG)) ||
2517
3259
        (!binlog_filter->db_ok(local_db)))
2518
3260
    {
2519
 
      pthread_mutex_unlock(&LOCK_log);
2520
 
      return(0);
 
3261
      VOID(pthread_mutex_unlock(&LOCK_log));
 
3262
      DBUG_RETURN(0);
2521
3263
    }
2522
3264
 
2523
3265
    /*
2540
3282
      my_off_t trans_log_pos= my_b_tell(trans_log);
2541
3283
      if (event_info->get_cache_stmt() || trans_log_pos != 0)
2542
3284
      {
 
3285
        DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu",
 
3286
                            event_info->get_cache_stmt(),
 
3287
                            (ulong) trans_log_pos));
2543
3288
        if (trans_log_pos == 0)
2544
3289
          thd->binlog_start_trans_and_stmt();
2545
3290
        file= trans_log;
2551
3296
        LOCK_log.
2552
3297
      */
2553
3298
    }
 
3299
    DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
2554
3300
 
2555
3301
    /*
2556
3302
      No check for auto events flag here - this write method should
2572
3318
      {
2573
3319
        if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
2574
3320
        {
2575
 
          Intvar_log_event e(thd,(unsigned char) LAST_INSERT_ID_EVENT,
 
3321
          Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
2576
3322
                             thd->first_successful_insert_id_in_prev_stmt_for_binlog);
2577
3323
          if (e.write(file))
2578
3324
            goto err;
2579
3325
        }
2580
3326
        if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
2581
3327
        {
 
3328
          DBUG_PRINT("info",("number of auto_inc intervals: %u",
 
3329
                             thd->auto_inc_intervals_in_cur_stmt_for_binlog.
 
3330
                             nb_elements()));
2582
3331
          /*
2583
3332
            If the auto_increment was second in a table's index (possible with
2584
3333
            MyISAM or BDB) (table->next_number_keypart != 0), such event is
2585
3334
            in fact not necessary. We could avoid logging it.
2586
3335
          */
2587
 
          Intvar_log_event e(thd, (unsigned char) INSERT_ID_EVENT,
 
3336
          Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT,
2588
3337
                             thd->auto_inc_intervals_in_cur_stmt_for_binlog.
2589
3338
                             minimum());
2590
3339
          if (e.write(file))
2598
3347
        }
2599
3348
        if (thd->user_var_events.elements)
2600
3349
        {
2601
 
          for (uint32_t i= 0; i < thd->user_var_events.elements; i++)
 
3350
          for (uint i= 0; i < thd->user_var_events.elements; i++)
2602
3351
          {
2603
3352
            BINLOG_USER_VAR_EVENT *user_var_event;
2604
 
            get_dynamic(&thd->user_var_events,(unsigned char*) &user_var_event, i);
 
3353
            get_dynamic(&thd->user_var_events,(uchar*) &user_var_event, i);
2605
3354
            User_var_log_event e(thd, user_var_event->user_var_event->name.str,
2606
3355
                                 user_var_event->user_var_event->name.length,
2607
3356
                                 user_var_event->value,
2646
3395
    ++m_table_map_version;
2647
3396
 
2648
3397
  pthread_mutex_unlock(&LOCK_log);
2649
 
  return(error);
 
3398
  DBUG_RETURN(error);
2650
3399
}
2651
3400
 
2652
3401
 
2656
3405
  return logger.error_log_print(level, format, args);
2657
3406
}
2658
3407
 
2659
 
void DRIZZLE_BIN_LOG::rotate_and_purge(uint32_t flags)
 
3408
 
 
3409
bool slow_log_print(THD *thd, const char *query, uint query_length,
 
3410
                    ulonglong current_utime)
 
3411
{
 
3412
  return logger.slow_log_print(thd, query, query_length, current_utime);
 
3413
}
 
3414
 
 
3415
 
 
3416
bool LOGGER::log_command(THD *thd, enum enum_server_command command)
 
3417
{
 
3418
  /*
 
3419
    Log command if we have at least one log event handler enabled and want
 
3420
    to log this king of commands
 
3421
  */
 
3422
  if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
 
3423
  {
 
3424
    if (thd->options & OPTION_LOG_OFF)
 
3425
    {
 
3426
      /* No logging */
 
3427
      return FALSE;
 
3428
    }
 
3429
 
 
3430
    return TRUE;
 
3431
  }
 
3432
 
 
3433
  return FALSE;
 
3434
}
 
3435
 
 
3436
 
 
3437
bool general_log_print(THD *thd, enum enum_server_command command,
 
3438
                       const char *format, ...)
 
3439
{
 
3440
  va_list args;
 
3441
  uint error= 0;
 
3442
 
 
3443
  /* Print the message to the buffer if we want to log this king of commands */
 
3444
  if (! logger.log_command(thd, command))
 
3445
    return FALSE;
 
3446
 
 
3447
  va_start(args, format);
 
3448
  error= logger.general_log_print(thd, command, format, args);
 
3449
  va_end(args);
 
3450
 
 
3451
  return error;
 
3452
}
 
3453
 
 
3454
bool general_log_write(THD *thd, enum enum_server_command command,
 
3455
                       const char *query, uint query_length)
 
3456
{
 
3457
  /* Write the message to the log if we want to log this king of commands */
 
3458
  if (logger.log_command(thd, command))
 
3459
    return logger.general_log_write(thd, command, query, query_length);
 
3460
 
 
3461
  return FALSE;
 
3462
}
 
3463
 
 
3464
void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
2660
3465
{
2661
3466
  if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
2662
3467
    pthread_mutex_lock(&LOCK_log);
2664
3469
      (my_b_tell(&log_file) >= (my_off_t) max_size))
2665
3470
  {
2666
3471
    new_file_without_locking();
 
3472
#ifdef HAVE_REPLICATION
2667
3473
    if (expire_logs_days)
2668
3474
    {
2669
3475
      time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
2670
3476
      if (purge_time >= 0)
2671
3477
        purge_logs_before_date(purge_time);
2672
3478
    }
 
3479
#endif
2673
3480
  }
2674
3481
  if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
2675
3482
    pthread_mutex_unlock(&LOCK_log);
2676
3483
}
2677
3484
 
2678
 
uint32_t DRIZZLE_BIN_LOG::next_file_id()
 
3485
uint MYSQL_BIN_LOG::next_file_id()
2679
3486
{
2680
 
  uint32_t res;
 
3487
  uint res;
2681
3488
  pthread_mutex_lock(&LOCK_log);
2682
3489
  res = file_id++;
2683
3490
  pthread_mutex_unlock(&LOCK_log);
2699
3506
    be reset as a READ_CACHE to be able to read the contents from it.
2700
3507
 */
2701
3508
 
2702
 
int DRIZZLE_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
 
3509
int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
2703
3510
{
2704
3511
  Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
2705
3512
 
2706
3513
  if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
2707
3514
    return ER_ERROR_ON_WRITE;
2708
 
  uint32_t length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
 
3515
  uint length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
2709
3516
  long val;
2710
 
  unsigned char header[LOG_EVENT_HEADER_LEN];
 
3517
  uchar header[LOG_EVENT_HEADER_LEN];
2711
3518
 
2712
3519
  /*
2713
3520
    The events in the buffer have incorrect end_log_pos data
2735
3542
    */
2736
3543
    if (unlikely(carry > 0))
2737
3544
    {
2738
 
      assert(carry < LOG_EVENT_HEADER_LEN);
 
3545
      DBUG_ASSERT(carry < LOG_EVENT_HEADER_LEN);
2739
3546
 
2740
3547
      /* assemble both halves */
2741
 
      memcpy(&header[carry], cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
 
3548
      memcpy(&header[carry], (char *)cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
2742
3549
 
2743
3550
      /* fix end_log_pos */
2744
3551
      val= uint4korr(&header[LOG_POS_OFFSET]) + group;
2752
3559
        copy fixed second half of header to cache so the correct
2753
3560
        version will be written later.
2754
3561
      */
2755
 
      memcpy(cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
 
3562
      memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
2756
3563
 
2757
3564
      /* next event header at ... */
2758
3565
      hdr_offs = uint4korr(&header[EVENT_LEN_OFFSET]) - carry;
2781
3588
        if (hdr_offs + LOG_EVENT_HEADER_LEN > length)
2782
3589
        {
2783
3590
          carry= length - hdr_offs;
2784
 
          memcpy(header, cache->read_pos + hdr_offs, carry);
 
3591
          memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
2785
3592
          length= hdr_offs;
2786
3593
        }
2787
3594
        else
2788
3595
        {
2789
3596
          /* we've got a full event-header, and it came in one piece */
2790
3597
 
2791
 
          unsigned char *log_pos= (unsigned char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
 
3598
          uchar *log_pos= (uchar *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
2792
3599
 
2793
3600
          /* fix end_log_pos */
2794
3601
          val= uint4korr(log_pos) + group;
2795
3602
          int4store(log_pos, val);
2796
3603
 
2797
3604
          /* next event header at ... */
2798
 
          log_pos= (unsigned char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
 
3605
          log_pos= (uchar *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
2799
3606
          hdr_offs += uint4korr(log_pos);
2800
3607
 
2801
3608
        }
2818
3625
    cache->read_pos=cache->read_end;            // Mark buffer used up
2819
3626
  } while ((length= my_b_fill(cache)));
2820
3627
 
2821
 
  assert(carry == 0);
 
3628
  DBUG_ASSERT(carry == 0);
2822
3629
 
2823
3630
  if (sync_log)
2824
3631
    flush_and_sync();
2847
3654
    'cache' needs to be reinitialized after this functions returns.
2848
3655
*/
2849
3656
 
2850
 
bool DRIZZLE_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
 
3657
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
2851
3658
{
2852
 
  pthread_mutex_lock(&LOCK_log);
 
3659
  DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)");
 
3660
  VOID(pthread_mutex_lock(&LOCK_log));
2853
3661
 
2854
3662
  /* NULL would represent nothing to replicate after ROLLBACK */
2855
 
  assert(commit_event != NULL);
 
3663
  DBUG_ASSERT(commit_event != NULL);
2856
3664
 
2857
 
  assert(is_open());
 
3665
  DBUG_ASSERT(is_open());
2858
3666
  if (likely(is_open()))                       // Should always be true
2859
3667
  {
2860
3668
    /*
2868
3676
        transaction is either a BEGIN..COMMIT block or a single
2869
3677
        statement in autocommit mode.
2870
3678
      */
2871
 
      Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), true, false);
 
3679
      Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
2872
3680
      /*
2873
3681
        Imagine this is rollback due to net timeout, after all
2874
3682
        statements of the transaction succeeded. Then we want a
2892
3700
      if (qinfo.write(&log_file))
2893
3701
        goto err;
2894
3702
 
 
3703
      DBUG_EXECUTE_IF("crash_before_writing_xid",
 
3704
                      {
 
3705
                        if ((write_error= write_cache(cache, false, true)))
 
3706
                          DBUG_PRINT("info", ("error writing binlog cache: %d",
 
3707
                                               write_error));
 
3708
                        DBUG_PRINT("info", ("crashing before writing xid"));
 
3709
                        abort();
 
3710
                      });
 
3711
 
2895
3712
      if ((write_error= write_cache(cache, false, false)))
2896
3713
        goto err;
2897
3714
 
2899
3716
        goto err;
2900
3717
      if (flush_and_sync())
2901
3718
        goto err;
 
3719
      DBUG_EXECUTE_IF("half_binlogged_transaction", abort(););
2902
3720
      if (cache->error)                         // Error on read
2903
3721
      {
2904
3722
        sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
2925
3743
    else
2926
3744
      rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
2927
3745
  }
2928
 
  pthread_mutex_unlock(&LOCK_log);
 
3746
  VOID(pthread_mutex_unlock(&LOCK_log));
2929
3747
 
2930
 
  return(0);
 
3748
  DBUG_RETURN(0);
2931
3749
 
2932
3750
err:
2933
3751
  if (!write_error)
2935
3753
    write_error= 1;
2936
3754
    sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
2937
3755
  }
2938
 
  pthread_mutex_unlock(&LOCK_log);
2939
 
  return(1);
 
3756
  VOID(pthread_mutex_unlock(&LOCK_log));
 
3757
  DBUG_RETURN(1);
2940
3758
}
2941
3759
 
2942
3760
 
2949
3767
    It will be released at the end of the function.
2950
3768
*/
2951
3769
 
2952
 
void DRIZZLE_BIN_LOG::wait_for_update_relay_log(THD* thd)
 
3770
void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
2953
3771
{
2954
3772
  const char *old_msg;
 
3773
  DBUG_ENTER("wait_for_update_relay_log");
2955
3774
  old_msg= thd->enter_cond(&update_cond, &LOCK_log,
2956
3775
                           "Slave has read all relay log; " 
2957
3776
                           "waiting for the slave I/O "
2958
3777
                           "thread to update it" );
2959
3778
  pthread_cond_wait(&update_cond, &LOCK_log);
2960
3779
  thd->exit_cond(old_msg);
2961
 
  return;
 
3780
  DBUG_VOID_RETURN;
2962
3781
}
2963
3782
 
2964
3783
 
2978
3797
    LOCK_log is released by the caller.
2979
3798
*/
2980
3799
 
2981
 
int DRIZZLE_BIN_LOG::wait_for_update_bin_log(THD* thd,
 
3800
int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
2982
3801
                                           const struct timespec *timeout)
2983
3802
{
2984
3803
  int ret= 0;
2985
 
  const char* old_msg = thd->get_proc_info();
 
3804
  const char* old_msg = thd->proc_info;
 
3805
  DBUG_ENTER("wait_for_update_bin_log");
2986
3806
  old_msg= thd->enter_cond(&update_cond, &LOCK_log,
2987
3807
                           "Master has sent all binlog to slave; "
2988
3808
                           "waiting for binlog to be updated");
2991
3811
  else
2992
3812
    ret= pthread_cond_timedwait(&update_cond, &LOCK_log,
2993
3813
                                const_cast<struct timespec *>(timeout));
2994
 
  return(ret);
 
3814
  DBUG_RETURN(ret);
2995
3815
}
2996
3816
 
2997
3817
 
3009
3829
    The internal structures are not freed until cleanup() is called
3010
3830
*/
3011
3831
 
3012
 
void DRIZZLE_BIN_LOG::close(uint32_t exiting)
 
3832
void MYSQL_BIN_LOG::close(uint exiting)
3013
3833
{                                       // One can't set log_type here!
 
3834
  DBUG_ENTER("MYSQL_BIN_LOG::close");
 
3835
  DBUG_PRINT("enter",("exiting: %d", (int) exiting));
3014
3836
  if (log_state == LOG_OPENED)
3015
3837
  {
 
3838
#ifdef HAVE_REPLICATION
3016
3839
    if (log_type == LOG_BIN && !no_auto_events &&
3017
3840
        (exiting & LOG_CLOSE_STOP_EVENT))
3018
3841
    {
3021
3844
      bytes_written+= s.data_written;
3022
3845
      signal_update();
3023
3846
    }
 
3847
#endif /* HAVE_REPLICATION */
3024
3848
 
3025
3849
    /* don't pwrite in a file opened with O_APPEND - it doesn't work */
3026
3850
    if (log_file.type == WRITE_CACHE && log_type == LOG_BIN)
3027
3851
    {
3028
3852
      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);
 
3853
      my_off_t org_position= my_tell(log_file.file, MYF(0));
 
3854
      uchar flags= 0;            // clearing LOG_EVENT_BINLOG_IN_USE_F
 
3855
      my_pwrite(log_file.file, &flags, 1, offset, MYF(0));
 
3856
      /*
 
3857
        Restore position so that anything we have in the IO_cache is written
 
3858
        to the correct position.
 
3859
        We need the seek here, as my_pwrite() is not guaranteed to keep the
 
3860
        original position on system that doesn't support pwrite().
 
3861
      */
 
3862
      my_seek(log_file.file, org_position, MY_SEEK_SET, MYF(0));
3031
3863
    }
3032
3864
 
3033
3865
    /* this will cleanup IO_CACHE, sync and close the file */
3034
 
    DRIZZLE_LOG::close(exiting);
 
3866
    MYSQL_LOG::close(exiting);
3035
3867
  }
3036
3868
 
3037
3869
  /*
3049
3881
    }
3050
3882
  }
3051
3883
  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;
 
3884
  safeFree(name);
 
3885
  DBUG_VOID_RETURN;
3058
3886
}
3059
3887
 
3060
3888
 
3061
 
void DRIZZLE_BIN_LOG::set_max_size(ulong max_size_arg)
 
3889
void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg)
3062
3890
{
3063
3891
  /*
3064
3892
    We need to take locks, otherwise this may happen:
3067
3895
    uses the old_max_size argument, so max_size_arg has been overwritten and
3068
3896
    it's like if the SET command was never run.
3069
3897
  */
 
3898
  DBUG_ENTER("MYSQL_BIN_LOG::set_max_size");
3070
3899
  pthread_mutex_lock(&LOCK_log);
3071
3900
  if (is_open())
3072
3901
    max_size= max_size_arg;
3073
3902
  pthread_mutex_unlock(&LOCK_log);
3074
 
  return;
 
3903
  DBUG_VOID_RETURN;
3075
3904
}
3076
3905
 
3077
3906
 
3097
3926
{
3098
3927
  register int flag;
3099
3928
  const char *start;
 
3929
  DBUG_ENTER("test_if_number");
3100
3930
 
3101
3931
  flag= 0; 
3102
3932
  start= str;
3117
3947
         str++, flag=1) ;
3118
3948
  }
3119
3949
  if (*str != 0 || flag == 0)
3120
 
    return(0);
 
3950
    DBUG_RETURN(0);
3121
3951
  if (res)
3122
3952
    *res=atol(start);
3123
 
  return(1);                    /* Number ok */
 
3953
  DBUG_RETURN(1);                       /* Number ok */
3124
3954
} /* test_if_number */
3125
3955
 
3126
3956
 
3127
3957
void sql_perror(const char *message)
3128
3958
{
 
3959
#ifdef HAVE_STRERROR
3129
3960
  sql_print_error("%s: %s",message, strerror(errno));
 
3961
#else
 
3962
  perror(message);
 
3963
#endif
3130
3964
}
3131
3965
 
3132
3966
 
3137
3971
  {
3138
3972
    char err_renamed[FN_REFLEN], *end;
3139
3973
    end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
3140
 
    my_stpcpy(end, "-old");
3141
 
    pthread_mutex_lock(&LOCK_error_log);
 
3974
    strmov(end, "-old");
 
3975
    VOID(pthread_mutex_lock(&LOCK_error_log));
3142
3976
    char err_temp[FN_REFLEN+4];
3143
3977
    /*
3144
3978
     On Windows is necessary a temporary file for to rename
3145
3979
     the current error file.
3146
3980
    */
3147
 
    strxmov(err_temp, err_renamed,"-tmp",NULL);
 
3981
    strxmov(err_temp, err_renamed,"-tmp",NullS);
3148
3982
    (void) my_delete(err_temp, MYF(0)); 
3149
3983
    if (freopen(err_temp,"a+",stdout))
3150
3984
    {
3151
3985
      int fd;
3152
3986
      size_t bytes;
3153
 
      unsigned char buf[IO_SIZE];
 
3987
      uchar buf[IO_SIZE];
3154
3988
 
3155
3989
      freopen(err_temp,"a+",stderr);
3156
3990
      (void) my_delete(err_renamed, MYF(0));
3169
4003
    }
3170
4004
    else
3171
4005
     result= 1;
3172
 
    pthread_mutex_unlock(&LOCK_error_log);
 
4006
    VOID(pthread_mutex_unlock(&LOCK_error_log));
3173
4007
  }
3174
4008
   return result;
3175
4009
}
3176
4010
 
3177
 
void DRIZZLE_BIN_LOG::signal_update()
 
4011
void MYSQL_BIN_LOG::signal_update()
3178
4012
{
 
4013
  DBUG_ENTER("MYSQL_BIN_LOG::signal_update");
3179
4014
  pthread_cond_broadcast(&update_cond);
3180
 
  return;
 
4015
  DBUG_VOID_RETURN;
3181
4016
}
3182
4017
 
3183
4018
/**
3196
4031
    signature to be compatible with other logging routines, which could
3197
4032
    return an error (e.g. logging to the log tables)
3198
4033
*/
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)))
 
4034
static void print_buffer_to_file(enum loglevel level, int error_code,
 
4035
                                 const char *buffer, size_t buffer_length)
3203
4036
{
3204
4037
  time_t skr;
3205
4038
  struct tm tm_tmp;
3206
4039
  struct tm *start;
 
4040
  DBUG_ENTER("print_buffer_to_file");
 
4041
  DBUG_PRINT("enter",("buffer: %s", buffer));
3207
4042
 
3208
 
  pthread_mutex_lock(&LOCK_error_log);
 
4043
  VOID(pthread_mutex_lock(&LOCK_error_log));
3209
4044
 
3210
4045
  skr= my_time(0);
3211
4046
  localtime_r(&skr, &tm_tmp);
3224
4059
 
3225
4060
  fflush(stderr);
3226
4061
 
3227
 
  pthread_mutex_unlock(&LOCK_error_log);
3228
 
  return;
 
4062
  VOID(pthread_mutex_unlock(&LOCK_error_log));
 
4063
  DBUG_VOID_RETURN;
3229
4064
}
3230
4065
 
3231
4066
 
3234
4069
  char   buff[1024];
3235
4070
  size_t length;
3236
4071
  int error_code= errno;
 
4072
  DBUG_ENTER("vprint_msg_to_log");
3237
4073
 
3238
 
  length= vsnprintf(buff, sizeof(buff), format, args);
 
4074
  length= my_vsnprintf(buff, sizeof(buff), format, args);
3239
4075
 
3240
4076
  print_buffer_to_file(level, error_code, buff, length);
3241
4077
 
3242
 
  return(0);
 
4078
  DBUG_RETURN(0);
3243
4079
}
3244
4080
 
3245
4081
 
3246
4082
void sql_print_error(const char *format, ...) 
3247
4083
{
3248
4084
  va_list args;
 
4085
  DBUG_ENTER("sql_print_error");
3249
4086
 
3250
4087
  va_start(args, format);
3251
4088
  error_log_print(ERROR_LEVEL, format, args);
3252
4089
  va_end(args);
3253
4090
 
3254
 
  return;
 
4091
  DBUG_VOID_RETURN;
3255
4092
}
3256
4093
 
3257
4094
 
3258
4095
void sql_print_warning(const char *format, ...) 
3259
4096
{
3260
4097
  va_list args;
 
4098
  DBUG_ENTER("sql_print_warning");
3261
4099
 
3262
4100
  va_start(args, format);
3263
4101
  error_log_print(WARNING_LEVEL, format, args);
3264
4102
  va_end(args);
3265
4103
 
3266
 
  return;
 
4104
  DBUG_VOID_RETURN;
3267
4105
}
3268
4106
 
3269
4107
 
3270
4108
void sql_print_information(const char *format, ...) 
3271
4109
{
3272
4110
  va_list args;
 
4111
  DBUG_ENTER("sql_print_information");
3273
4112
 
3274
4113
  va_start(args, format);
3275
4114
  error_log_print(INFORMATION_LEVEL, format, args);
3276
4115
  va_end(args);
3277
4116
 
3278
 
  return;
 
4117
  DBUG_VOID_RETURN;
3279
4118
}
3280
4119
 
3281
4120
 
3330
4169
 
3331
4170
int TC_LOG_MMAP::open(const char *opt_name)
3332
4171
{
3333
 
  uint32_t i;
3334
 
  bool crashed= false;
 
4172
  uint i;
 
4173
  bool crashed=FALSE;
3335
4174
  PAGE *pg;
3336
4175
 
3337
 
  assert(total_ha_2pc > 1);
3338
 
  assert(opt_name && opt_name[0]);
 
4176
  DBUG_ASSERT(total_ha_2pc > 1);
 
4177
  DBUG_ASSERT(opt_name && opt_name[0]);
3339
4178
 
3340
 
  tc_log_page_size= getpagesize();
3341
 
  assert(TC_LOG_PAGE_SIZE % tc_log_page_size == 0);
 
4179
  tc_log_page_size= my_getpagesize();
 
4180
  DBUG_ASSERT(TC_LOG_PAGE_SIZE % tc_log_page_size == 0);
3342
4181
 
3343
4182
  fn_format(logname,opt_name,mysql_data_home,"",MY_UNPACK_FILENAME);
3344
4183
  if ((fd= my_open(logname, O_RDWR, MYF(0))) < 0)
3351
4190
      goto err;
3352
4191
    inited=1;
3353
4192
    file_length= opt_tc_log_size;
3354
 
    if (ftruncate(fd, file_length))
 
4193
    if (my_chsize(fd, file_length, 0, MYF(MY_WME)))
3355
4194
      goto err;
3356
4195
  }
3357
4196
  else
3358
4197
  {
3359
4198
    inited= 1;
3360
 
    crashed= true;
3361
 
    sql_print_information(_("Recovering after a crash using %s"), opt_name);
 
4199
    crashed= TRUE;
 
4200
    sql_print_information("Recovering after a crash using %s", opt_name);
3362
4201
    if (tc_heuristic_recover)
3363
4202
    {
3364
 
      sql_print_error(_("Cannot perform automatic crash recovery when "
3365
 
                      "--tc-heuristic-recover is used"));
 
4203
      sql_print_error("Cannot perform automatic crash recovery when "
 
4204
                      "--tc-heuristic-recover is used");
3366
4205
      goto err;
3367
4206
    }
3368
4207
    file_length= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
3370
4209
      goto err;
3371
4210
  }
3372
4211
 
3373
 
  data= (unsigned char *)my_mmap(0, (size_t)file_length, PROT_READ|PROT_WRITE,
 
4212
  data= (uchar *)my_mmap(0, (size_t)file_length, PROT_READ|PROT_WRITE,
3374
4213
                        MAP_NOSYNC|MAP_SHARED, fd, 0);
3375
4214
  if (data == MAP_FAILED)
3376
4215
  {
3380
4219
  inited=2;
3381
4220
 
3382
4221
  npages=(uint)file_length/tc_log_page_size;
3383
 
  assert(npages >= 3);             // to guarantee non-empty pool
 
4222
  DBUG_ASSERT(npages >= 3);             // to guarantee non-empty pool
3384
4223
  if (!(pages=(PAGE *)my_malloc(npages*sizeof(PAGE), MYF(MY_WME|MY_ZEROFILL))))
3385
4224
    goto err;
3386
4225
  inited=3;
3406
4245
      goto err;
3407
4246
 
3408
4247
  memcpy(data, tc_log_magic, sizeof(tc_log_magic));
3409
 
  data[sizeof(tc_log_magic)]= (unsigned char)total_ha_2pc;
 
4248
  data[sizeof(tc_log_magic)]= (uchar)total_ha_2pc;
3410
4249
  msync(data, tc_log_page_size, MS_SYNC);
3411
4250
  my_sync(fd, MYF(0));
3412
4251
  inited=5;
3514
4353
    threads waiting for a page, but then all these threads will be waiting
3515
4354
    for a fsync() anyway
3516
4355
 
3517
 
   If tc_log == DRIZZLE_LOG then tc_log writes transaction to binlog and
 
4356
   If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
3518
4357
   records XID in a special Xid_log_event.
3519
4358
   If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
3520
4359
   log.
3528
4367
    to the position in memory where xid was logged to.
3529
4368
*/
3530
4369
 
3531
 
int TC_LOG_MMAP::log_xid(THD *thd __attribute__((unused)), my_xid xid)
 
4370
int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
3532
4371
{
3533
4372
  int err;
3534
4373
  PAGE *p;
3557
4396
  while (*p->ptr)
3558
4397
  {
3559
4398
    p->ptr++;
3560
 
    assert(p->ptr < p->end);               // because p->free > 0
 
4399
    DBUG_ASSERT(p->ptr < p->end);               // because p->free > 0
3561
4400
  }
3562
4401
 
3563
4402
  /* found! store xid there and mark the page dirty */
3564
 
  cookie= (ulong)((unsigned char *)p->ptr - data);      // can never be zero
 
4403
  cookie= (ulong)((uchar *)p->ptr - data);      // can never be zero
3565
4404
  *p->ptr++= xid;
3566
4405
  p->free--;
3567
4406
  p->state= DIRTY;
3590
4429
      goto done;                             // we're done
3591
4430
    }
3592
4431
  }                                          // page was not synced! do it now
3593
 
  assert(active == p && syncing == 0);
 
4432
  DBUG_ASSERT(active == p && syncing == 0);
3594
4433
  pthread_mutex_lock(&LOCK_active);
3595
4434
  syncing=p;                                 // place is vacant - take it
3596
4435
  active=0;                                  // page is not active anymore
3607
4446
{
3608
4447
  int err;
3609
4448
 
3610
 
  assert(syncing != active);
 
4449
  DBUG_ASSERT(syncing != active);
3611
4450
 
3612
4451
  /*
3613
4452
    sit down and relax - this can take a while...
3640
4479
  cookie points directly to the memory where xid was logged.
3641
4480
*/
3642
4481
 
3643
 
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid __attribute__((unused)))
 
4482
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
3644
4483
{
3645
4484
  PAGE *p=pages+(cookie/tc_log_page_size);
3646
4485
  my_xid *x=(my_xid *)(data+cookie);
3647
4486
 
3648
 
  assert(*x == xid);
3649
 
  assert(x >= p->start && x < p->end);
 
4487
  DBUG_ASSERT(*x == xid);
 
4488
  DBUG_ASSERT(x >= p->start && x < p->end);
3650
4489
  *x=0;
3651
4490
 
3652
4491
  pthread_mutex_lock(&p->lock);
3653
4492
  p->free++;
3654
 
  assert(p->free <= p->size);
 
4493
  DBUG_ASSERT(p->free <= p->size);
3655
4494
  set_if_smaller(p->ptr, x);
3656
4495
  if (p->free == p->size)               // the page is completely empty
3657
4496
    statistic_decrement(tc_log_cur_pages_used, &LOCK_status);
3662
4501
 
3663
4502
void TC_LOG_MMAP::close()
3664
4503
{
3665
 
  uint32_t i;
 
4504
  uint i;
3666
4505
  switch (inited) {
3667
4506
  case 6:
3668
4507
    pthread_mutex_destroy(&LOCK_sync);
3680
4519
      pthread_cond_destroy(&pages[i].cond);
3681
4520
    }
3682
4521
  case 3:
3683
 
    free((unsigned char*)pages);
 
4522
    my_free((uchar*)pages, MYF(0));
3684
4523
  case 2:
3685
4524
    my_munmap((char*)data, (size_t)file_length);
3686
4525
  case 1:
3698
4537
 
3699
4538
  if (memcmp(data, tc_log_magic, sizeof(tc_log_magic)))
3700
4539
  {
3701
 
    sql_print_error(_("Bad magic header in tc log"));
 
4540
    sql_print_error("Bad magic header in tc log");
3702
4541
    goto err1;
3703
4542
  }
3704
4543
 
3708
4547
  */
3709
4548
  if (data[sizeof(tc_log_magic)] != total_ha_2pc)
3710
4549
  {
3711
 
    sql_print_error(_("Recovery failed! You must enable "
 
4550
    sql_print_error("Recovery failed! You must enable "
3712
4551
                    "exactly %d storage engines that support "
3713
 
                    "two-phase commit protocol"),
 
4552
                    "two-phase commit protocol",
3714
4553
                    data[sizeof(tc_log_magic)]);
3715
4554
    goto err1;
3716
4555
  }
3722
4561
  for ( ; p < end_p ; p++)
3723
4562
  {
3724
4563
    for (my_xid *x=p->start; x < p->end; x++)
3725
 
      if (*x && my_hash_insert(&xids, (unsigned char *)x))
 
4564
      if (*x && my_hash_insert(&xids, (uchar *)x))
3726
4565
        goto err2; // OOM
3727
4566
  }
3728
4567
 
3730
4569
    goto err2;
3731
4570
 
3732
4571
  hash_free(&xids);
3733
 
  memset(data, 0, (size_t)file_length);
 
4572
  bzero(data, (size_t)file_length);
3734
4573
  return 0;
3735
4574
 
3736
4575
err2:
3737
4576
  hash_free(&xids);
3738
4577
err1:
3739
 
  sql_print_error(_("Crash recovery failed. Either correct the problem "
 
4578
  sql_print_error("Crash recovery failed. Either correct the problem "
3740
4579
                  "(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}"));
 
4580
                  "or delete tc log and start mysqld with "
 
4581
                  "--tc-heuristic-recover={commit|rollback}");
3743
4582
  return 1;
3744
4583
}
3745
4584
#endif
3766
4605
  if (!tc_heuristic_recover)
3767
4606
    return 0;
3768
4607
 
3769
 
  sql_print_information(_("Heuristic crash recovery mode"));
 
4608
  sql_print_information("Heuristic crash recovery mode");
3770
4609
  if (ha_recover(0))
3771
 
    sql_print_error(_("Heuristic crash recovery failed"));
3772
 
  sql_print_information(_("Please restart mysqld without --tc-heuristic-recover"));
 
4610
    sql_print_error("Heuristic crash recovery failed");
 
4611
  sql_print_information("Please restart mysqld without --tc-heuristic-recover");
3773
4612
  return 1;
3774
4613
}
3775
4614
 
3776
4615
/****** transaction coordinator log for 2pc - binlog() based solution ******/
3777
 
#define TC_LOG_BINLOG DRIZZLE_BIN_LOG
 
4616
#define TC_LOG_BINLOG MYSQL_BIN_LOG
3778
4617
 
3779
4618
/**
3780
4619
  @todo
3789
4628
  LOG_INFO log_info;
3790
4629
  int      error= 1;
3791
4630
 
3792
 
  assert(total_ha_2pc > 1);
3793
 
  assert(opt_name && opt_name[0]);
 
4631
  DBUG_ASSERT(total_ha_2pc > 1);
 
4632
  DBUG_ASSERT(opt_name && opt_name[0]);
3794
4633
 
3795
4634
  pthread_mutex_init(&LOCK_prep_xids, MY_MUTEX_INIT_FAST);
3796
4635
  pthread_cond_init (&COND_prep_xids, 0);
3810
4649
    return 1;
3811
4650
  }
3812
4651
 
3813
 
  if ((error= find_log_pos(&log_info, NULL, 1)))
 
4652
  if ((error= find_log_pos(&log_info, NullS, 1)))
3814
4653
  {
3815
4654
    if (error != LOG_INFO_EOF)
3816
 
      sql_print_error(_("find_log_pos() failed (error: %d)"), error);
 
4655
      sql_print_error("find_log_pos() failed (error: %d)", error);
3817
4656
    else
3818
4657
      error= 0;
3819
4658
    goto err;
3837
4676
 
3838
4677
    if (error !=  LOG_INFO_EOF)
3839
4678
    {
3840
 
      sql_print_error(_("find_log_pos() failed (error: %d)"), error);
 
4679
      sql_print_error("find_log_pos() failed (error: %d)", error);
3841
4680
      goto err;
3842
4681
    }
3843
4682
 
3851
4690
        ev->get_type_code() == FORMAT_DESCRIPTION_EVENT &&
3852
4691
        ev->flags & LOG_EVENT_BINLOG_IN_USE_F)
3853
4692
    {
3854
 
      sql_print_information(_("Recovering after a crash using %s"), opt_name);
 
4693
      sql_print_information("Recovering after a crash using %s", opt_name);
3855
4694
      error= recover(&log, (Format_description_log_event *)ev);
3856
4695
    }
3857
4696
    else
3872
4711
/** This is called on shutdown, after ha_panic. */
3873
4712
void TC_LOG_BINLOG::close()
3874
4713
{
3875
 
  assert(prepared_xids==0);
 
4714
  DBUG_ASSERT(prepared_xids==0);
3876
4715
  pthread_mutex_destroy(&LOCK_prep_xids);
3877
4716
  pthread_cond_destroy (&COND_prep_xids);
3878
4717
}
3888
4727
*/
3889
4728
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
3890
4729
{
 
4730
  DBUG_ENTER("TC_LOG_BINLOG::log");
3891
4731
  Xid_log_event xle(thd, xid);
3892
4732
  binlog_trx_data *trx_data=
3893
4733
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
3895
4735
    We always commit the entire transaction when writing an XID. Also
3896
4736
    note that the return value is inverted.
3897
4737
   */
3898
 
  return(!binlog_end_trans(thd, trx_data, &xle, true));
 
4738
  DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
3899
4739
}
3900
4740
 
3901
 
void TC_LOG_BINLOG::unlog(ulong cookie __attribute__((unused)),
3902
 
                          my_xid xid __attribute__((unused)))
 
4741
void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
3903
4742
{
3904
4743
  pthread_mutex_lock(&LOCK_prep_xids);
3905
 
  assert(prepared_xids > 0);
 
4744
  DBUG_ASSERT(prepared_xids > 0);
3906
4745
  if (--prepared_xids == 0) {
 
4746
    DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
3907
4747
    pthread_cond_signal(&COND_prep_xids);
3908
4748
  }
3909
4749
  pthread_mutex_unlock(&LOCK_prep_xids);
3930
4770
    if (ev->get_type_code() == XID_EVENT)
3931
4771
    {
3932
4772
      Xid_log_event *xev=(Xid_log_event *)ev;
3933
 
      unsigned char *x= (unsigned char *) memdup_root(&mem_root, (unsigned char*) &xev->xid,
 
4773
      uchar *x= (uchar *) memdup_root(&mem_root, (uchar*) &xev->xid,
3934
4774
                                      sizeof(xev->xid));
3935
4775
      if (! x)
3936
4776
        goto err2;
3950
4790
  free_root(&mem_root, MYF(0));
3951
4791
  hash_free(&xids);
3952
4792
err1:
3953
 
  sql_print_error(_("Crash recovery failed. Either correct the problem "
 
4793
  sql_print_error("Crash recovery failed. Either correct the problem "
3954
4794
                  "(if it's, for example, out of memory error) and restart, "
3955
4795
                  "or delete (or rename) binary log and start mysqld with "
3956
 
                  "--tc-heuristic-recover={commit|rollback}"));
 
4796
                  "--tc-heuristic-recover={commit|rollback}");
3957
4797
  return 1;
3958
4798
}
3959
4799
 
3973
4813
  @return byte offset from the beginning of the binlog
3974
4814
*/
3975
4815
extern "C"
3976
 
uint64_t mysql_bin_log_file_pos(void)
 
4816
ulonglong mysql_bin_log_file_pos(void)
3977
4817
{
3978
 
  return (uint64_t) mysql_bin_log.get_log_file()->pos_in_file;
 
4818
  return (ulonglong) mysql_bin_log.get_log_file()->pos_in_file;
3979
4819
}
3980
4820
#endif /* INNODB_COMPATIBILITY_HOOKS */
3981
4821
 
3982
4822
 
 
4823
struct st_mysql_storage_engine binlog_storage_engine=
 
4824
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
 
4825
 
3983
4826
mysql_declare_plugin(binlog)
3984
4827
{
3985
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
 
4828
  MYSQL_STORAGE_ENGINE_PLUGIN,
 
4829
  &binlog_storage_engine,
3986
4830
  "binlog",
3987
 
  "1.0",
3988
4831
  "MySQL AB",
3989
4832
  "This is a pseudo storage engine to represent the binlog in a transaction",
3990
4833
  PLUGIN_LICENSE_GPL,
3991
4834
  binlog_init, /* Plugin Init */
3992
4835
  NULL, /* Plugin Deinit */
 
4836
  0x0100 /* 1.0 */,
3993
4837
  NULL,                       /* status variables                */
3994
4838
  NULL,                       /* system variables                */
3995
4839
  NULL                        /* config options                  */