~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/log.cc

  • Committer: Monty Taylor
  • Date: 2008-07-09 15:52:52 UTC
  • mto: (77.6.1 glibclient-merge)
  • mto: This revision was merged to the branch mainline in revision 112.
  • Revision ID: monty@inaugust.com-20080709155252-lnzmxxje1g40z3a7
Warning fixes. 

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/error.h>
37
 
#include <drizzled/gettext.h>
 
36
#include <mysql/plugin.h>
38
37
 
39
38
/* max size of the log message */
 
39
#define MAX_LOG_BUFFER_SIZE 1024
 
40
#define MAX_USER_HOST_SIZE 512
 
41
#define MAX_TIME_SIZE 32
40
42
#define MY_OFF_T_UNDEF (~(my_off_t)0UL)
41
43
 
 
44
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
 
45
 
42
46
LOGGER logger;
43
47
 
44
 
DRIZZLE_BIN_LOG mysql_bin_log;
 
48
MYSQL_BIN_LOG mysql_bin_log;
45
49
ulong sync_binlog_counter= 0;
46
50
 
47
51
static bool test_if_number(const char *str,
48
52
                           long *res, bool allow_wildcards);
49
53
static int binlog_init(void *p);
50
 
static int binlog_close_connection(handlerton *hton, Session *session);
51
 
static int binlog_savepoint_set(handlerton *hton, Session *session, void *sv);
52
 
static int binlog_savepoint_rollback(handlerton *hton, Session *session, void *sv);
53
 
static int binlog_commit(handlerton *hton, Session *session, bool all);
54
 
static int binlog_rollback(handlerton *hton, Session *session, bool all);
55
 
static int binlog_prepare(handlerton *hton, Session *session, bool all);
 
54
static int binlog_close_connection(handlerton *hton, THD *thd);
 
55
static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv);
 
56
static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv);
 
57
static int binlog_commit(handlerton *hton, THD *thd, bool all);
 
58
static int binlog_rollback(handlerton *hton, THD *thd, bool all);
 
59
static int binlog_prepare(handlerton *hton, THD *thd, bool all);
 
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
}
56
94
 
57
95
 
58
96
sql_print_message_func sql_print_message_handlers[3] =
92
130
  {
93
131
    if (m_mutex)
94
132
      pthread_mutex_unlock(m_mutex);
 
133
#ifndef DBUG_OFF
95
134
    m_mutex= 0;
 
135
#endif
96
136
  }
97
137
 
98
138
private:
116
156
 
117
157
  ~binlog_trx_data()
118
158
  {
119
 
    assert(pending() == NULL);
 
159
    DBUG_ASSERT(pending() == NULL);
120
160
    close_cached_file(&trans_log);
121
161
  }
122
162
 
135
175
   */
136
176
  void truncate(my_off_t pos)
137
177
  {
 
178
    DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos));
 
179
    DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos));
138
180
    delete pending();
139
181
    set_pending(0);
140
182
    reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
199
241
 
200
242
 
201
243
/* Check if a given table is opened log table */
202
 
int check_if_log_table(uint32_t db_len __attribute__((unused)),
203
 
                       const char *db __attribute__((unused)),
204
 
                       uint32_t table_name_len __attribute__((unused)),
205
 
                       const char *table_name __attribute__((unused)),
206
 
                       uint32_t check_if_opened __attribute__((unused)))
 
244
int check_if_log_table(uint db_len __attribute__((__unused__)),
 
245
                       const char *db __attribute__((__unused__)),
 
246
                       uint table_name_len __attribute__((__unused__)),
 
247
                       const char *table_name __attribute__((__unused__)),
 
248
                       uint check_if_opened __attribute__((__unused__)))
207
249
{
208
250
  return 0;
209
251
}
210
252
 
 
253
/* log event handlers */
 
254
 
 
255
bool Log_to_file_event_handler::
 
256
  log_error(enum loglevel level, const char *format,
 
257
            va_list args)
 
258
{
 
259
  return vprint_msg_to_log(level, format, args);
 
260
}
 
261
 
 
262
void Log_to_file_event_handler::init_pthread_objects()
 
263
{
 
264
  mysql_log.init_pthread_objects();
 
265
  mysql_slow_log.init_pthread_objects();
 
266
}
 
267
 
 
268
 
 
269
/** Wrapper around MYSQL_LOG::write() for slow log. */
 
270
 
 
271
bool Log_to_file_event_handler::
 
272
  log_slow(THD *thd, time_t current_time, time_t query_start_arg,
 
273
           const char *user_host, uint user_host_len,
 
274
           ulonglong query_utime, ulonglong lock_utime, bool is_command,
 
275
           const char *sql_text, uint sql_text_len)
 
276
{
 
277
  return mysql_slow_log.write(thd, current_time, query_start_arg,
 
278
                              user_host, user_host_len,
 
279
                              query_utime, lock_utime, is_command,
 
280
                              sql_text, sql_text_len);
 
281
}
 
282
 
 
283
 
 
284
/**
 
285
   Wrapper around MYSQL_LOG::write() for general log. We need it since we
 
286
   want all log event handlers to have the same signature.
 
287
*/
 
288
 
 
289
bool Log_to_file_event_handler::
 
290
  log_general(THD *thd __attribute__((__unused__)),
 
291
              time_t event_time, const char *user_host,
 
292
              uint user_host_len, int thread_id,
 
293
              const char *command_type, uint command_type_len,
 
294
              const char *sql_text, uint sql_text_len,
 
295
              CHARSET_INFO *client_cs __attribute__((__unused__)))
 
296
{
 
297
  return mysql_log.write(event_time, user_host, user_host_len,
 
298
                         thread_id, command_type, command_type_len,
 
299
                         sql_text, sql_text_len);
 
300
}
 
301
 
 
302
 
 
303
bool Log_to_file_event_handler::init()
 
304
{
 
305
  if (!is_initialized)
 
306
  {
 
307
    if (opt_slow_log)
 
308
      mysql_slow_log.open_slow_log(sys_var_slow_log_path.value);
 
309
 
 
310
    if (opt_log)
 
311
      mysql_log.open_query_log(sys_var_general_log_path.value);
 
312
 
 
313
    is_initialized= TRUE;
 
314
  }
 
315
 
 
316
  return FALSE;
 
317
}
 
318
 
 
319
 
 
320
void Log_to_file_event_handler::cleanup()
 
321
{
 
322
  mysql_log.cleanup();
 
323
  mysql_slow_log.cleanup();
 
324
}
 
325
 
 
326
void Log_to_file_event_handler::flush()
 
327
{
 
328
  /* reopen log files */
 
329
  if (opt_log)
 
330
    mysql_log.reopen_file();
 
331
  if (opt_slow_log)
 
332
    mysql_slow_log.reopen_file();
 
333
}
 
334
 
211
335
/*
212
336
  Log error with all enabled log event handlers
213
337
 
227
351
bool LOGGER::error_log_print(enum loglevel level, const char *format,
228
352
                             va_list args)
229
353
{
230
 
  bool error= false;
 
354
  bool error= FALSE;
231
355
  Log_event_handler **current_handler;
232
356
 
233
357
  /* currently we don't need locking here as there is no error_log table */
240
364
 
241
365
void LOGGER::cleanup_base()
242
366
{
243
 
  assert(inited == 1);
 
367
  DBUG_ASSERT(inited == 1);
244
368
  rwlock_destroy(&LOCK_logger);
 
369
  if (file_log_handler)
 
370
    file_log_handler->cleanup();
245
371
}
246
372
 
247
373
 
248
374
void LOGGER::cleanup_end()
249
375
{
250
 
  assert(inited == 1);
 
376
  DBUG_ASSERT(inited == 1);
 
377
  if (file_log_handler)
 
378
    delete file_log_handler;
251
379
}
252
380
 
253
381
 
257
385
*/
258
386
void LOGGER::init_base()
259
387
{
260
 
  assert(inited == 0);
 
388
  DBUG_ASSERT(inited == 0);
261
389
  inited= 1;
262
390
 
 
391
  /*
 
392
    Here we create file log handler. We don't do it for the table log handler
 
393
    here as it cannot be created so early. The reason is THD initialization,
 
394
    which depends on the system variables (parsed later).
 
395
  */
 
396
  if (!file_log_handler)
 
397
    file_log_handler= new Log_to_file_event_handler;
 
398
 
263
399
  /* by default we use traditional error log */
264
400
  init_error_log(LOG_FILE);
265
401
 
 
402
  file_log_handler->init_pthread_objects();
266
403
  my_rwlock_init(&LOCK_logger, NULL);
267
404
}
268
405
 
269
406
 
270
 
bool LOGGER::flush_logs(Session *session __attribute__((unused)))
 
407
bool LOGGER::flush_logs(THD *thd __attribute__((__unused__)))
271
408
{
272
409
  int rc= 0;
273
410
 
277
414
  */
278
415
  logger.lock_exclusive();
279
416
 
 
417
  /* reopen log files */
 
418
  file_log_handler->flush();
 
419
 
280
420
  /* end of log flush */
281
421
  logger.unlock();
282
422
  return rc;
283
423
}
284
424
 
285
 
void LOGGER::init_error_log(uint32_t error_log_printer)
 
425
 
 
426
/*
 
427
  Log slow query with all enabled log event handlers
 
428
 
 
429
  SYNOPSIS
 
430
    slow_log_print()
 
431
 
 
432
    thd                 THD of the query being logged
 
433
    query               The query being logged
 
434
    query_length        The length of the query string
 
435
    current_utime       Current time in microseconds (from undefined start)
 
436
 
 
437
  RETURN
 
438
    FALSE   OK
 
439
    TRUE    error occured
 
440
*/
 
441
 
 
442
bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
 
443
                            ulonglong current_utime)
 
444
 
 
445
{
 
446
  bool error= FALSE;
 
447
  Log_event_handler **current_handler;
 
448
  bool is_command= FALSE;
 
449
  char user_host_buff[MAX_USER_HOST_SIZE];
 
450
  Security_context *sctx= thd->security_ctx;
 
451
  uint user_host_len= 0;
 
452
  ulonglong query_utime, lock_utime;
 
453
 
 
454
  /*
 
455
    Print the message to the buffer if we have slow log enabled
 
456
  */
 
457
 
 
458
  if (*slow_log_handler_list)
 
459
  {
 
460
    time_t current_time;
 
461
 
 
462
    /* do not log slow queries from replication threads */
 
463
    if (thd->slave_thread && !opt_log_slow_slave_statements)
 
464
      return 0;
 
465
 
 
466
    lock_shared();
 
467
    if (!opt_slow_log)
 
468
    {
 
469
      unlock();
 
470
      return 0;
 
471
    }
 
472
 
 
473
    /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
 
474
    user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
 
475
                             sctx->priv_user ? sctx->priv_user : "", "[",
 
476
                             sctx->user ? sctx->user : "", "] @ ",
 
477
                             sctx->host ? sctx->host : "", " [",
 
478
                             sctx->ip ? sctx->ip : "", "]", NullS) -
 
479
                    user_host_buff);
 
480
 
 
481
    current_time= my_time_possible_from_micro(current_utime);
 
482
    if (thd->start_utime)
 
483
    {
 
484
      query_utime= (current_utime - thd->start_utime);
 
485
      lock_utime=  (thd->utime_after_lock - thd->start_utime);
 
486
    }
 
487
    else
 
488
    {
 
489
      query_utime= lock_utime= 0;
 
490
    }
 
491
 
 
492
    if (!query)
 
493
    {
 
494
      is_command= TRUE;
 
495
      query= command_name[thd->command].str;
 
496
      query_length= command_name[thd->command].length;
 
497
    }
 
498
 
 
499
    for (current_handler= slow_log_handler_list; *current_handler ;)
 
500
      error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
 
501
                                            user_host_buff, user_host_len,
 
502
                                            query_utime, lock_utime, is_command,
 
503
                                            query, query_length) || error;
 
504
 
 
505
    unlock();
 
506
  }
 
507
  return error;
 
508
}
 
509
 
 
510
bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
 
511
                               const char *query, uint query_length)
 
512
{
 
513
  bool error= FALSE;
 
514
  Log_event_handler **current_handler= general_log_handler_list;
 
515
  char user_host_buff[MAX_USER_HOST_SIZE];
 
516
  Security_context *sctx= thd->security_ctx;
 
517
  ulong id;
 
518
  uint user_host_len= 0;
 
519
  time_t current_time;
 
520
 
 
521
  if (thd)
 
522
    id= thd->thread_id;                 /* Normal thread */
 
523
  else
 
524
    id= 0;                              /* Log from connect handler */
 
525
 
 
526
  lock_shared();
 
527
  if (!opt_log)
 
528
  {
 
529
    unlock();
 
530
    return 0;
 
531
  }
 
532
  user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
 
533
                          sctx->priv_user ? sctx->priv_user : "", "[",
 
534
                          sctx->user ? sctx->user : "", "] @ ",
 
535
                          sctx->host ? sctx->host : "", " [",
 
536
                          sctx->ip ? sctx->ip : "", "]", NullS) -
 
537
                                                          user_host_buff;
 
538
 
 
539
  current_time= my_time(0);
 
540
 
 
541
  while (*current_handler)
 
542
    error|= (*current_handler++)->
 
543
      log_general(thd, current_time, user_host_buff,
 
544
                  user_host_len, id,
 
545
                  command_name[(uint) command].str,
 
546
                  command_name[(uint) command].length,
 
547
                  query, query_length,
 
548
                  thd->variables.character_set_client) || error;
 
549
  unlock();
 
550
 
 
551
  return error;
 
552
}
 
553
 
 
554
bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
 
555
                               const char *format, va_list args)
 
556
{
 
557
  uint message_buff_len= 0;
 
558
  char message_buff[MAX_LOG_BUFFER_SIZE];
 
559
 
 
560
  /* prepare message */
 
561
  if (format)
 
562
    message_buff_len= vsnprintf(message_buff, sizeof(message_buff),
 
563
                                   format, args);
 
564
  else
 
565
    message_buff[0]= '\0';
 
566
 
 
567
  return general_log_write(thd, command, message_buff, message_buff_len);
 
568
}
 
569
 
 
570
void LOGGER::init_error_log(uint error_log_printer)
286
571
{
287
572
  if (error_log_printer & LOG_NONE)
288
573
  {
290
575
    return;
291
576
  }
292
577
 
293
 
}
294
 
 
295
 
int LOGGER::set_handlers(uint32_t error_log_printer)
 
578
  switch (error_log_printer) {
 
579
  case LOG_FILE:
 
580
    error_log_handler_list[0]= file_log_handler;
 
581
    error_log_handler_list[1]= 0;
 
582
    break;
 
583
    /* these two are disabled for now */
 
584
  case LOG_TABLE:
 
585
    DBUG_ASSERT(0);
 
586
    break;
 
587
  case LOG_TABLE|LOG_FILE:
 
588
    DBUG_ASSERT(0);
 
589
    break;
 
590
  }
 
591
}
 
592
 
 
593
void LOGGER::init_slow_log(uint slow_log_printer)
 
594
{
 
595
  if (slow_log_printer & LOG_NONE)
 
596
  {
 
597
    slow_log_handler_list[0]= 0;
 
598
    return;
 
599
  }
 
600
 
 
601
  slow_log_handler_list[0]= file_log_handler;
 
602
  slow_log_handler_list[1]= 0;
 
603
}
 
604
 
 
605
void LOGGER::init_general_log(uint general_log_printer)
 
606
{
 
607
  if (general_log_printer & LOG_NONE)
 
608
  {
 
609
    general_log_handler_list[0]= 0;
 
610
    return;
 
611
  }
 
612
 
 
613
  general_log_handler_list[0]= file_log_handler;
 
614
  general_log_handler_list[1]= 0;
 
615
}
 
616
 
 
617
 
 
618
bool LOGGER::activate_log_handler(THD* thd __attribute__((__unused__)),
 
619
                                  uint log_type)
 
620
{
 
621
  MYSQL_QUERY_LOG *file_log;
 
622
  bool res= FALSE;
 
623
  lock_exclusive();
 
624
  switch (log_type) {
 
625
  case QUERY_LOG_SLOW:
 
626
    if (!opt_slow_log)
 
627
    {
 
628
      file_log= file_log_handler->get_mysql_slow_log();
 
629
 
 
630
      file_log->open_slow_log(sys_var_slow_log_path.value);
 
631
      init_slow_log(log_output_options);
 
632
      opt_slow_log= TRUE;
 
633
    }
 
634
    break;
 
635
  case QUERY_LOG_GENERAL:
 
636
    if (!opt_log)
 
637
    {
 
638
      file_log= file_log_handler->get_mysql_log();
 
639
 
 
640
      file_log->open_query_log(sys_var_general_log_path.value);
 
641
      init_general_log(log_output_options);
 
642
      opt_log= TRUE;
 
643
    }
 
644
    break;
 
645
  default:
 
646
    DBUG_ASSERT(0);
 
647
  }
 
648
  unlock();
 
649
  return res;
 
650
}
 
651
 
 
652
 
 
653
void LOGGER::deactivate_log_handler(THD *thd __attribute__((__unused__)),
 
654
                                    uint log_type)
 
655
{
 
656
  my_bool *tmp_opt= 0;
 
657
  MYSQL_LOG *file_log;
 
658
 
 
659
  switch (log_type) {
 
660
  case QUERY_LOG_SLOW:
 
661
    tmp_opt= &opt_slow_log;
 
662
    file_log= file_log_handler->get_mysql_slow_log();
 
663
    break;
 
664
  case QUERY_LOG_GENERAL:
 
665
    tmp_opt= &opt_log;
 
666
    file_log= file_log_handler->get_mysql_log();
 
667
    break;
 
668
  default:
 
669
    assert(0);                                  // Impossible
 
670
  }
 
671
 
 
672
  if (!(*tmp_opt))
 
673
    return;
 
674
 
 
675
  lock_exclusive();
 
676
  file_log->close(0);
 
677
  *tmp_opt= FALSE;
 
678
  unlock();
 
679
}
 
680
 
 
681
int LOGGER::set_handlers(uint error_log_printer,
 
682
                         uint slow_log_printer,
 
683
                         uint general_log_printer)
296
684
{
297
685
  /* error log table is not supported yet */
 
686
  DBUG_ASSERT(error_log_printer < LOG_TABLE);
 
687
 
298
688
  lock_exclusive();
299
689
 
300
690
  init_error_log(error_log_printer);
 
691
  init_slow_log(slow_log_printer);
 
692
  init_general_log(general_log_printer);
 
693
 
301
694
  unlock();
302
695
 
303
696
  return 0;
310
703
  SYNPOSIS
311
704
    binlog_trans_log_savepos()
312
705
 
313
 
    session      The thread to take the binlog data from
 
706
    thd      The thread to take the binlog data from
314
707
    pos      Pointer to variable where the position will be stored
315
708
 
316
709
  DESCRIPTION
320
713
 */
321
714
 
322
715
static void
323
 
binlog_trans_log_savepos(Session *session, my_off_t *pos)
 
716
binlog_trans_log_savepos(THD *thd, my_off_t *pos)
324
717
{
325
 
  assert(pos != NULL);
326
 
  if (session_get_ha_data(session, binlog_hton) == NULL)
327
 
    session->binlog_setup_trx_data();
 
718
  DBUG_ENTER("binlog_trans_log_savepos");
 
719
  DBUG_ASSERT(pos != NULL);
 
720
  if (thd_get_ha_data(thd, binlog_hton) == NULL)
 
721
    thd->binlog_setup_trx_data();
328
722
  binlog_trx_data *const trx_data=
329
 
    (binlog_trx_data*) session_get_ha_data(session, binlog_hton);
330
 
  assert(mysql_bin_log.is_open());
 
723
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
 
724
  DBUG_ASSERT(mysql_bin_log.is_open());
331
725
  *pos= trx_data->position();
332
 
  return;
 
726
  DBUG_PRINT("return", ("*pos: %lu", (ulong) *pos));
 
727
  DBUG_VOID_RETURN;
333
728
}
334
729
 
335
730
 
339
734
  SYNPOSIS
340
735
    binlog_trans_log_truncate()
341
736
 
342
 
    session      The thread to take the binlog data from
 
737
    thd      The thread to take the binlog data from
343
738
    pos      Position to truncate to
344
739
 
345
740
  DESCRIPTION
349
744
 
350
745
 */
351
746
static void
352
 
binlog_trans_log_truncate(Session *session, my_off_t pos)
 
747
binlog_trans_log_truncate(THD *thd, my_off_t pos)
353
748
{
354
 
  assert(session_get_ha_data(session, binlog_hton) != NULL);
 
749
  DBUG_ENTER("binlog_trans_log_truncate");
 
750
  DBUG_PRINT("enter", ("pos: %lu", (ulong) pos));
 
751
 
 
752
  DBUG_ASSERT(thd_get_ha_data(thd, binlog_hton) != NULL);
355
753
  /* Only true if binlog_trans_log_savepos() wasn't called before */
356
 
  assert(pos != ~(my_off_t) 0);
 
754
  DBUG_ASSERT(pos != ~(my_off_t) 0);
357
755
 
358
756
  binlog_trx_data *const trx_data=
359
 
    (binlog_trx_data*) session_get_ha_data(session, binlog_hton);
 
757
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
360
758
  trx_data->truncate(pos);
361
 
  return;
 
759
  DBUG_VOID_RETURN;
362
760
}
363
761
 
364
762
 
365
763
/*
366
764
  this function is mostly a placeholder.
367
 
  conceptually, binlog initialization (now mostly done in DRIZZLE_BIN_LOG::open)
 
765
  conceptually, binlog initialization (now mostly done in MYSQL_BIN_LOG::open)
368
766
  should be moved here.
369
767
*/
370
768
 
372
770
{
373
771
  binlog_hton= (handlerton *)p;
374
772
  binlog_hton->state=opt_bin_log ? SHOW_OPTION_YES : SHOW_OPTION_NO;
 
773
  binlog_hton->db_type=DB_TYPE_BINLOG;
375
774
  binlog_hton->savepoint_offset= sizeof(my_off_t);
376
775
  binlog_hton->close_connection= binlog_close_connection;
377
776
  binlog_hton->savepoint_set= binlog_savepoint_set;
380
779
  binlog_hton->rollback= binlog_rollback;
381
780
  binlog_hton->prepare= binlog_prepare;
382
781
  binlog_hton->flags= HTON_NOT_USER_SELECTABLE | HTON_HIDDEN;
383
 
 
384
782
  return 0;
385
783
}
386
784
 
387
 
static int binlog_close_connection(handlerton *hton __attribute__((unused)),
388
 
                                   Session *session)
 
785
static int binlog_close_connection(handlerton *hton __attribute__((__unused__)),
 
786
                                   THD *thd)
389
787
{
390
788
  binlog_trx_data *const trx_data=
391
 
    (binlog_trx_data*) session_get_ha_data(session, binlog_hton);
392
 
  assert(trx_data->empty());
393
 
  session_set_ha_data(session, binlog_hton, NULL);
 
789
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
 
790
  DBUG_ASSERT(trx_data->empty());
 
791
  thd_set_ha_data(thd, binlog_hton, NULL);
394
792
  trx_data->~binlog_trx_data();
395
 
  free((unsigned char*)trx_data);
 
793
  my_free((uchar*)trx_data, MYF(0));
396
794
  return 0;
397
795
}
398
796
 
402
800
  SYNOPSIS
403
801
    binlog_end_trans()
404
802
 
405
 
    session      The thread whose transaction should be ended
 
803
    thd      The thread whose transaction should be ended
406
804
    trx_data Pointer to the transaction data to use
407
805
    end_ev   The end event to use, or NULL
408
806
    all      True if the entire transaction should be ended, false if
420
818
    'all' is false), or reset completely (if 'all' is true).
421
819
 */
422
820
static int
423
 
binlog_end_trans(Session *session, binlog_trx_data *trx_data,
 
821
binlog_end_trans(THD *thd, binlog_trx_data *trx_data,
424
822
                 Log_event *end_ev, bool all)
425
823
{
 
824
  DBUG_ENTER("binlog_end_trans");
426
825
  int error=0;
427
826
  IO_CACHE *trans_log= &trx_data->trans_log;
 
827
  DBUG_PRINT("enter", ("transaction: %s  end_ev: 0x%lx",
 
828
                       all ? "all" : "stmt", (long) end_ev));
 
829
  DBUG_PRINT("info", ("thd->options={ %s%s}",
 
830
                      FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
 
831
                      FLAGSTR(thd->options, OPTION_BEGIN)));
428
832
 
429
833
  /*
430
834
    NULL denotes ROLLBACK with nothing to replicate: i.e., rollback of
444
848
      were, we would have to ensure that we're not ending a statement
445
849
      inside a stored function.
446
850
     */
447
 
    session->binlog_flush_pending_rows_event(true);
 
851
    thd->binlog_flush_pending_rows_event(TRUE);
448
852
 
449
 
    error= mysql_bin_log.write(session, &trx_data->trans_log, end_ev);
 
853
    error= mysql_bin_log.write(thd, &trx_data->trans_log, end_ev);
450
854
    trx_data->reset();
451
855
 
452
856
    /*
470
874
      If rolling back a statement in a transaction, we truncate the
471
875
      transaction cache to remove the statement.
472
876
     */
473
 
    if (all || !(session->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
 
877
    if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
474
878
    {
475
879
      trx_data->reset();
476
880
 
477
 
      assert(!session->binlog_get_pending_rows_event());
478
 
      session->clear_binlog_table_maps();
 
881
      DBUG_ASSERT(!thd->binlog_get_pending_rows_event());
 
882
      thd->clear_binlog_table_maps();
479
883
    }
480
884
    else                                        // ...statement
481
885
      trx_data->truncate(trx_data->before_stmt_pos);
488
892
    mysql_bin_log.update_table_map_version();
489
893
  }
490
894
 
491
 
  return(error);
 
895
  DBUG_RETURN(error);
492
896
}
493
897
 
494
 
static int binlog_prepare(handlerton *hton __attribute__((unused)),
495
 
                          Session *session __attribute__((unused)),
496
 
                          bool all __attribute__((unused)))
 
898
static int binlog_prepare(handlerton *hton __attribute__((__unused__)),
 
899
                          THD *thd __attribute__((__unused__)),
 
900
                          bool all __attribute__((__unused__)))
497
901
{
498
902
  /*
499
903
    do nothing.
500
904
    just pretend we can do 2pc, so that MySQL won't
501
905
    switch to 1pc.
502
 
    real work will be done in DRIZZLE_BIN_LOG::log_xid()
 
906
    real work will be done in MYSQL_BIN_LOG::log_xid()
503
907
  */
504
908
  return 0;
505
909
}
506
910
 
 
911
#define YESNO(X) ((X) ? "yes" : "no")
 
912
 
507
913
/**
508
914
  This function is called once after each statement.
509
915
 
511
917
  binlog file on commits.
512
918
 
513
919
  @param hton  The binlog handlerton.
514
 
  @param session   The client thread that executes the transaction.
 
920
  @param thd   The client thread that executes the transaction.
515
921
  @param all   This is @c true if this is a real transaction commit, and
516
922
               @false otherwise.
517
923
 
518
924
  @see handlerton::commit
519
925
*/
520
 
static int binlog_commit(handlerton *hton __attribute__((unused)),
521
 
                         Session *session, bool all)
 
926
static int binlog_commit(handlerton *hton __attribute__((__unused__)),
 
927
                         THD *thd, bool all)
522
928
{
 
929
  DBUG_ENTER("binlog_commit");
523
930
  binlog_trx_data *const trx_data=
524
 
    (binlog_trx_data*) session_get_ha_data(session, binlog_hton);
 
931
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
525
932
 
526
933
  if (trx_data->empty())
527
934
  {
528
 
    // we're here because trans_log was flushed in DRIZZLE_BIN_LOG::log_xid()
 
935
    // we're here because trans_log was flushed in MYSQL_BIN_LOG::log_xid()
529
936
    trx_data->reset();
530
 
    return(0);
 
937
    DBUG_RETURN(0);
531
938
  }
532
939
 
533
940
  /*
588
995
 
589
996
    Otherwise, we accumulate the statement
590
997
  */
591
 
  uint64_t const in_transaction=
592
 
    session->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
593
 
  if ((in_transaction && (all || (!trx_data->at_least_one_stmt && session->transaction.stmt.modified_non_trans_table))) || (!in_transaction && !all))
 
998
  ulonglong const in_transaction=
 
999
    thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
 
1000
  DBUG_PRINT("debug",
 
1001
             ("all: %d, empty: %s, in_transaction: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
 
1002
              all,
 
1003
              YESNO(trx_data->empty()),
 
1004
              YESNO(in_transaction),
 
1005
              YESNO(thd->transaction.all.modified_non_trans_table),
 
1006
              YESNO(thd->transaction.stmt.modified_non_trans_table)));
 
1007
  if ((in_transaction && (all || (!trx_data->at_least_one_stmt && thd->transaction.stmt.modified_non_trans_table))) || (!in_transaction && !all))
594
1008
  {
595
 
    Query_log_event qev(session, STRING_WITH_LEN("COMMIT"), true, false);
596
 
    qev.error_code= 0; // see comment in DRIZZLE_LOG::write(Session, IO_CACHE)
597
 
    int error= binlog_end_trans(session, trx_data, &qev, all);
598
 
    return(error);
 
1009
    Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
 
1010
    qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
 
1011
    int error= binlog_end_trans(thd, trx_data, &qev, all);
 
1012
    DBUG_RETURN(error);
599
1013
  }
600
 
  return(0);
 
1014
  DBUG_RETURN(0);
601
1015
}
602
1016
 
603
1017
/**
609
1023
  non-transactional tables, nothing needs to be logged.
610
1024
 
611
1025
  @param hton  The binlog handlerton.
612
 
  @param session   The client thread that executes the transaction.
 
1026
  @param thd   The client thread that executes the transaction.
613
1027
  @param all   This is @c true if this is a real transaction rollback, and
614
1028
               @false otherwise.
615
1029
 
616
1030
  @see handlerton::rollback
617
1031
*/
618
 
static int binlog_rollback(handlerton *hton __attribute__((unused)),
619
 
                           Session *session, bool all)
 
1032
static int binlog_rollback(handlerton *hton __attribute__((__unused__)),
 
1033
                           THD *thd, bool all)
620
1034
{
 
1035
  DBUG_ENTER("binlog_rollback");
621
1036
  int error=0;
622
1037
  binlog_trx_data *const trx_data=
623
 
    (binlog_trx_data*) session_get_ha_data(session, binlog_hton);
 
1038
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
624
1039
 
625
1040
  if (trx_data->empty()) {
626
1041
    trx_data->reset();
627
 
    return(0);
 
1042
    DBUG_RETURN(0);
628
1043
  }
629
1044
 
630
 
  if ((all && session->transaction.all.modified_non_trans_table) ||
631
 
      (!all && session->transaction.stmt.modified_non_trans_table) ||
632
 
      (session->options & OPTION_KEEP_LOG))
 
1045
  DBUG_PRINT("debug", ("all: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
 
1046
                       YESNO(all),
 
1047
                       YESNO(thd->transaction.all.modified_non_trans_table),
 
1048
                       YESNO(thd->transaction.stmt.modified_non_trans_table)));
 
1049
  if ((all && thd->transaction.all.modified_non_trans_table) ||
 
1050
      (!all && thd->transaction.stmt.modified_non_trans_table) ||
 
1051
      (thd->options & OPTION_KEEP_LOG))
633
1052
  {
634
1053
    /*
635
1054
      We write the transaction cache with a rollback last if we have
639
1058
      transactional table in that statement as well, which needs to be
640
1059
      rolled back on the slave.
641
1060
    */
642
 
    Query_log_event qev(session, STRING_WITH_LEN("ROLLBACK"), true, false);
643
 
    qev.error_code= 0; // see comment in DRIZZLE_LOG::write(Session, IO_CACHE)
644
 
    error= binlog_end_trans(session, trx_data, &qev, all);
 
1061
    Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
 
1062
    qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
 
1063
    error= binlog_end_trans(thd, trx_data, &qev, all);
645
1064
  }
646
 
  else if ((all && !session->transaction.all.modified_non_trans_table) ||
647
 
           (!all && !session->transaction.stmt.modified_non_trans_table))
 
1065
  else if ((all && !thd->transaction.all.modified_non_trans_table) ||
 
1066
           (!all && !thd->transaction.stmt.modified_non_trans_table))
648
1067
  {
649
1068
    /*
650
1069
      If we have modified only transactional tables, we can truncate
651
1070
      the transaction cache without writing anything to the binary
652
1071
      log.
653
1072
     */
654
 
    error= binlog_end_trans(session, trx_data, 0, all);
 
1073
    error= binlog_end_trans(thd, trx_data, 0, all);
655
1074
  }
656
 
  return(error);
 
1075
  DBUG_RETURN(error);
657
1076
}
658
1077
 
659
1078
/**
680
1099
  that case there is no need to have it in the binlog).
681
1100
*/
682
1101
 
683
 
static int binlog_savepoint_set(handlerton *hton __attribute__((unused)),
684
 
                                Session *session, void *sv)
 
1102
static int binlog_savepoint_set(handlerton *hton __attribute__((__unused__)),
 
1103
                                THD *thd, void *sv)
685
1104
{
686
 
  binlog_trans_log_savepos(session, (my_off_t*) sv);
 
1105
  DBUG_ENTER("binlog_savepoint_set");
 
1106
 
 
1107
  binlog_trans_log_savepos(thd, (my_off_t*) sv);
687
1108
  /* Write it to the binary log */
688
1109
  
689
1110
  int const error=
690
 
    session->binlog_query(Session::STMT_QUERY_TYPE,
691
 
                      session->query, session->query_length, true, false);
692
 
  return(error);
 
1111
    thd->binlog_query(THD::STMT_QUERY_TYPE,
 
1112
                      thd->query, thd->query_length, TRUE, FALSE);
 
1113
  DBUG_RETURN(error);
693
1114
}
694
1115
 
695
 
static int binlog_savepoint_rollback(handlerton *hton __attribute__((unused)),
696
 
                                     Session *session, void *sv)
 
1116
static int binlog_savepoint_rollback(handlerton *hton __attribute__((__unused__)),
 
1117
                                     THD *thd, void *sv)
697
1118
{
 
1119
  DBUG_ENTER("binlog_savepoint_rollback");
 
1120
 
698
1121
  /*
699
1122
    Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
700
1123
    non-transactional table. Otherwise, truncate the binlog cache starting
701
1124
    from the SAVEPOINT command.
702
1125
  */
703
 
  if (unlikely(session->transaction.all.modified_non_trans_table || 
704
 
               (session->options & OPTION_KEEP_LOG)))
 
1126
  if (unlikely(thd->transaction.all.modified_non_trans_table || 
 
1127
               (thd->options & OPTION_KEEP_LOG)))
705
1128
  {
706
1129
    int error=
707
 
      session->binlog_query(Session::STMT_QUERY_TYPE,
708
 
                        session->query, session->query_length, true, false);
709
 
    return(error);
 
1130
      thd->binlog_query(THD::STMT_QUERY_TYPE,
 
1131
                        thd->query, thd->query_length, TRUE, FALSE);
 
1132
    DBUG_RETURN(error);
710
1133
  }
711
 
  binlog_trans_log_truncate(session, *(my_off_t*)sv);
712
 
  return(0);
 
1134
  binlog_trans_log_truncate(thd, *(my_off_t*)sv);
 
1135
  DBUG_RETURN(0);
713
1136
}
714
1137
 
715
1138
 
716
1139
int check_binlog_magic(IO_CACHE* log, const char** errmsg)
717
1140
{
718
1141
  char magic[4];
719
 
  assert(my_b_tell(log) == 0);
 
1142
  DBUG_ASSERT(my_b_tell(log) == 0);
720
1143
 
721
 
  if (my_b_read(log, (unsigned char*) magic, sizeof(magic)))
 
1144
  if (my_b_read(log, (uchar*) magic, sizeof(magic)))
722
1145
  {
723
 
    *errmsg = _("I/O error reading the header from the binary log");
 
1146
    *errmsg = "I/O error reading the header from the binary log";
724
1147
    sql_print_error("%s, errno=%d, io cache code=%d", *errmsg, my_errno,
725
1148
                    log->error);
726
1149
    return 1;
727
1150
  }
728
1151
  if (memcmp(magic, BINLOG_MAGIC, sizeof(magic)))
729
1152
  {
730
 
    *errmsg = _("Binlog has bad magic number;  It's not a binary log file "
731
 
                "that can be used by this version of Drizzle");
 
1153
    *errmsg = "Binlog has bad magic number;  It's not a binary log file that can be used by this version of MySQL";
732
1154
    return 1;
733
1155
  }
734
1156
  return 0;
738
1160
File open_binlog(IO_CACHE *log, const char *log_file_name, const char **errmsg)
739
1161
{
740
1162
  File file;
 
1163
  DBUG_ENTER("open_binlog");
741
1164
 
742
 
  if ((file = my_open(log_file_name, O_RDONLY, 
 
1165
  if ((file = my_open(log_file_name, O_RDONLY | O_BINARY | O_SHARE, 
743
1166
                      MYF(MY_WME))) < 0)
744
1167
  {
745
 
    sql_print_error(_("Failed to open log (file '%s', errno %d)"),
 
1168
    sql_print_error("Failed to open log (file '%s', errno %d)",
746
1169
                    log_file_name, my_errno);
747
 
    *errmsg = _("Could not open log file");
 
1170
    *errmsg = "Could not open log file";
748
1171
    goto err;
749
1172
  }
750
1173
  if (init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0,
751
1174
                    MYF(MY_WME|MY_DONT_CHECK_FILESIZE)))
752
1175
  {
753
 
    sql_print_error(_("Failed to create a cache on log (file '%s')"),
 
1176
    sql_print_error("Failed to create a cache on log (file '%s')",
754
1177
                    log_file_name);
755
 
    *errmsg = _("Could not open log file");
 
1178
    *errmsg = "Could not open log file";
756
1179
    goto err;
757
1180
  }
758
1181
  if (check_binlog_magic(log,errmsg))
759
1182
    goto err;
760
 
  return(file);
 
1183
  DBUG_RETURN(file);
761
1184
 
762
1185
err:
763
1186
  if (file >= 0)
765
1188
    my_close(file,MYF(0));
766
1189
    end_io_cache(log);
767
1190
  }
768
 
  return(-1);
 
1191
  DBUG_RETURN(-1);
769
1192
}
770
1193
 
771
1194
 
781
1204
static int find_uniq_filename(char *name)
782
1205
{
783
1206
  long                  number;
784
 
  uint32_t                  i;
 
1207
  uint                  i;
785
1208
  char                  buff[FN_REFLEN];
786
1209
  struct st_my_dir     *dir_info;
787
1210
  register struct fileinfo *file_info;
788
1211
  ulong                 max_found=0;
789
1212
  size_t                buf_length, length;
790
1213
  char                  *start, *end;
 
1214
  DBUG_ENTER("find_uniq_filename");
791
1215
 
792
1216
  length= dirname_part(buff, name, &buf_length);
793
1217
  start=  name + length;
794
 
  end= strchr(start, '\0');
 
1218
  end=    strend(start);
795
1219
 
796
1220
  *end='.';
797
1221
  length= (size_t) (end-start+1);
798
1222
 
799
1223
  if (!(dir_info = my_dir(buff,MYF(MY_DONT_SORT))))
800
1224
  {                                             // This shouldn't happen
801
 
    my_stpcpy(end,".1");                                // use name+1
802
 
    return(0);
 
1225
    strmov(end,".1");                           // use name+1
 
1226
    DBUG_RETURN(0);
803
1227
  }
804
1228
  file_info= dir_info->dir_entry;
805
1229
  for (i=dir_info->number_off_files ; i-- ; file_info++)
806
1230
  {
807
 
    if (memcmp(file_info->name, start, length) == 0 &&
 
1231
    if (bcmp((uchar*) file_info->name, (uchar*) start, length) == 0 &&
808
1232
        test_if_number(file_info->name+length, &number,0))
809
1233
    {
810
1234
      set_if_bigger(max_found,(ulong) number);
814
1238
 
815
1239
  *end++='.';
816
1240
  sprintf(end,"%06ld",max_found+1);
817
 
  return(0);
 
1241
  DBUG_RETURN(0);
818
1242
}
819
1243
 
820
1244
 
821
 
void DRIZZLE_LOG::init(enum_log_type log_type_arg,
 
1245
void MYSQL_LOG::init(enum_log_type log_type_arg,
822
1246
                     enum cache_type io_cache_type_arg)
823
1247
{
 
1248
  DBUG_ENTER("MYSQL_LOG::init");
824
1249
  log_type= log_type_arg;
825
1250
  io_cache_type= io_cache_type_arg;
826
 
  return;
 
1251
  DBUG_PRINT("info",("log_type: %d", log_type));
 
1252
  DBUG_VOID_RETURN;
827
1253
}
828
1254
 
829
1255
 
848
1274
    1   error
849
1275
*/
850
1276
 
851
 
bool DRIZZLE_LOG::open(const char *log_name, enum_log_type log_type_arg,
 
1277
bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
852
1278
                     const char *new_name, enum cache_type io_cache_type_arg)
853
1279
{
854
1280
  char buff[FN_REFLEN];
855
1281
  File file= -1;
856
 
  int open_flags= O_CREAT;
 
1282
  int open_flags= O_CREAT | O_BINARY;
 
1283
  DBUG_ENTER("MYSQL_LOG::open");
 
1284
  DBUG_PRINT("enter", ("log_type: %d", (int) log_type_arg));
857
1285
 
858
1286
  write_error= 0;
859
1287
 
866
1294
  }
867
1295
 
868
1296
  if (new_name)
869
 
    my_stpcpy(log_file_name, new_name);
 
1297
    strmov(log_file_name, new_name);
870
1298
  else if (generate_new_name(log_file_name, name))
871
1299
    goto err;
872
1300
 
890
1318
    char *end;
891
1319
    int len=snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
892
1320
                     "started with:\nTCP Port: %d, Named Pipe: %s\n",
893
 
                     my_progname, server_version, COMPILATION_COMMENT,
 
1321
                     my_progname, server_version, MYSQL_COMPILATION_COMMENT,
894
1322
                     mysqld_port, ""
895
1323
                     );
896
 
    end= my_stpncpy(buff + len, "Time                 Id Command    Argument\n",
 
1324
    end= strnmov(buff + len, "Time                 Id Command    Argument\n",
897
1325
                 sizeof(buff) - len);
898
 
    if (my_b_write(&log_file, (unsigned char*) buff, (uint) (end-buff)) ||
 
1326
    if (my_b_write(&log_file, (uchar*) buff, (uint) (end-buff)) ||
899
1327
        flush_io_cache(&log_file))
900
1328
      goto err;
901
1329
  }
902
1330
 
903
1331
  log_state= LOG_OPENED;
904
 
  return(0);
 
1332
  DBUG_RETURN(0);
905
1333
 
906
1334
err:
907
 
  sql_print_error(_("Could not use %s for logging (error %d). "
908
 
                    "Turning logging off for the whole duration of the "
909
 
                    "Drizzle server process. "
910
 
                    "To turn it on again: fix the cause, "
911
 
                    "shutdown the Drizzle server and restart it."),
912
 
                    name, errno);
 
1335
  sql_print_error("Could not use %s for logging (error %d). \
 
1336
Turning logging off for the whole duration of the MySQL server process. \
 
1337
To turn it on again: fix the cause, \
 
1338
shutdown the MySQL server and restart it.", name, errno);
913
1339
  if (file >= 0)
914
1340
    my_close(file, MYF(0));
915
1341
  end_io_cache(&log_file);
916
 
  if (name)
917
 
  {
918
 
    free(name);
919
 
    name= NULL;
920
 
  }
 
1342
  safeFree(name);
921
1343
  log_state= LOG_CLOSED;
922
 
  return(1);
 
1344
  DBUG_RETURN(1);
923
1345
}
924
1346
 
925
 
DRIZZLE_LOG::DRIZZLE_LOG()
926
 
  : name(0), write_error(false), inited(false), log_type(LOG_UNKNOWN),
 
1347
MYSQL_LOG::MYSQL_LOG()
 
1348
  : name(0), write_error(FALSE), inited(FALSE), log_type(LOG_UNKNOWN),
927
1349
    log_state(LOG_CLOSED)
928
1350
{
929
1351
  /*
932
1354
    called only in main(). Doing initialization here would make it happen
933
1355
    before main().
934
1356
  */
935
 
  memset(&log_file, 0, sizeof(log_file));
 
1357
  bzero((char*) &log_file, sizeof(log_file));
936
1358
}
937
1359
 
938
 
void DRIZZLE_LOG::init_pthread_objects()
 
1360
void MYSQL_LOG::init_pthread_objects()
939
1361
{
940
 
  assert(inited == 0);
 
1362
  DBUG_ASSERT(inited == 0);
941
1363
  inited= 1;
942
1364
  (void) pthread_mutex_init(&LOCK_log, MY_MUTEX_INIT_SLOW);
943
1365
}
956
1378
    The internal structures are not freed until cleanup() is called
957
1379
*/
958
1380
 
959
 
void DRIZZLE_LOG::close(uint32_t exiting)
 
1381
void MYSQL_LOG::close(uint exiting)
960
1382
{                                       // One can't set log_type here!
 
1383
  DBUG_ENTER("MYSQL_LOG::close");
 
1384
  DBUG_PRINT("enter",("exiting: %d", (int) exiting));
961
1385
  if (log_state == LOG_OPENED)
962
1386
  {
963
1387
    end_io_cache(&log_file);
976
1400
  }
977
1401
 
978
1402
  log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
979
 
  if (name)
980
 
  {
981
 
    free(name);
982
 
    name= NULL;
983
 
  }
984
 
  return;
 
1403
  safeFree(name);
 
1404
  DBUG_VOID_RETURN;
985
1405
}
986
1406
 
987
1407
/** This is called only once. */
988
1408
 
989
 
void DRIZZLE_LOG::cleanup()
 
1409
void MYSQL_LOG::cleanup()
990
1410
{
 
1411
  DBUG_ENTER("cleanup");
991
1412
  if (inited)
992
1413
  {
993
1414
    inited= 0;
994
1415
    (void) pthread_mutex_destroy(&LOCK_log);
995
1416
    close(0);
996
1417
  }
997
 
  return;
 
1418
  DBUG_VOID_RETURN;
998
1419
}
999
1420
 
1000
1421
 
1001
 
int DRIZZLE_LOG::generate_new_name(char *new_name, const char *log_name)
 
1422
int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
1002
1423
{
1003
1424
  fn_format(new_name, log_name, mysql_data_home, "", 4);
1004
1425
  if (log_type == LOG_BIN)
1016
1437
}
1017
1438
 
1018
1439
 
 
1440
/*
 
1441
  Reopen the log file
 
1442
 
 
1443
  SYNOPSIS
 
1444
    reopen_file()
 
1445
 
 
1446
  DESCRIPTION
 
1447
    Reopen the log file. The method is used during FLUSH LOGS
 
1448
    and locks LOCK_log mutex
 
1449
*/
 
1450
 
 
1451
 
 
1452
void MYSQL_QUERY_LOG::reopen_file()
 
1453
{
 
1454
  char *save_name;
 
1455
 
 
1456
  DBUG_ENTER("MYSQL_LOG::reopen_file");
 
1457
  if (!is_open())
 
1458
  {
 
1459
    DBUG_PRINT("info",("log is closed"));
 
1460
    DBUG_VOID_RETURN;
 
1461
  }
 
1462
 
 
1463
  pthread_mutex_lock(&LOCK_log);
 
1464
 
 
1465
  save_name= name;
 
1466
  name= 0;                              // Don't free name
 
1467
  close(LOG_CLOSE_TO_BE_OPENED);
 
1468
 
 
1469
  /*
 
1470
     Note that at this point, log_state != LOG_CLOSED (important for is_open()).
 
1471
  */
 
1472
 
 
1473
  open(save_name, log_type, 0, io_cache_type);
 
1474
  my_free(save_name, MYF(0));
 
1475
 
 
1476
  pthread_mutex_unlock(&LOCK_log);
 
1477
 
 
1478
  DBUG_VOID_RETURN;
 
1479
}
 
1480
 
 
1481
 
 
1482
/*
 
1483
  Write a command to traditional general log file
 
1484
 
 
1485
  SYNOPSIS
 
1486
    write()
 
1487
 
 
1488
    event_time        command start timestamp
 
1489
    user_host         the pointer to the string with user@host info
 
1490
    user_host_len     length of the user_host string. this is computed once
 
1491
                      and passed to all general log  event handlers
 
1492
    thread_id         Id of the thread, issued a query
 
1493
    command_type      the type of the command being logged
 
1494
    command_type_len  the length of the string above
 
1495
    sql_text          the very text of the query being executed
 
1496
    sql_text_len      the length of sql_text string
 
1497
 
 
1498
  DESCRIPTION
 
1499
 
 
1500
   Log given command to to normal (not rotable) log file
 
1501
 
 
1502
  RETURN
 
1503
    FASE - OK
 
1504
    TRUE - error occured
 
1505
*/
 
1506
 
 
1507
bool MYSQL_QUERY_LOG::write(time_t event_time,
 
1508
                            const char *user_host __attribute__((__unused__)),
 
1509
                            uint user_host_len __attribute__((__unused__)),
 
1510
                            int thread_id,
 
1511
                            const char *command_type, uint command_type_len,
 
1512
                            const char *sql_text, uint sql_text_len)
 
1513
{
 
1514
  char buff[32];
 
1515
  uint length= 0;
 
1516
  char local_time_buff[MAX_TIME_SIZE];
 
1517
  struct tm start;
 
1518
  uint time_buff_len= 0;
 
1519
 
 
1520
  (void) pthread_mutex_lock(&LOCK_log);
 
1521
 
 
1522
  /* Test if someone closed between the is_open test and lock */
 
1523
  if (is_open())
 
1524
  {
 
1525
    /* Note that my_b_write() assumes it knows the length for this */
 
1526
      if (event_time != last_time)
 
1527
      {
 
1528
        last_time= event_time;
 
1529
 
 
1530
        localtime_r(&event_time, &start);
 
1531
 
 
1532
        time_buff_len= snprintf(local_time_buff, MAX_TIME_SIZE,
 
1533
                                "%02d%02d%02d %2d:%02d:%02d",
 
1534
                                start.tm_year % 100, start.tm_mon + 1,
 
1535
                                start.tm_mday, start.tm_hour,
 
1536
                                start.tm_min, start.tm_sec);
 
1537
 
 
1538
        if (my_b_write(&log_file, (uchar*) local_time_buff, time_buff_len))
 
1539
          goto err;
 
1540
      }
 
1541
      else
 
1542
        if (my_b_write(&log_file, (uchar*) "\t\t" ,2) < 0)
 
1543
          goto err;
 
1544
 
 
1545
      /* command_type, thread_id */
 
1546
      length= snprintf(buff, 32, "%5ld ", (long) thread_id);
 
1547
 
 
1548
    if (my_b_write(&log_file, (uchar*) buff, length))
 
1549
      goto err;
 
1550
 
 
1551
    if (my_b_write(&log_file, (uchar*) command_type, command_type_len))
 
1552
      goto err;
 
1553
 
 
1554
    if (my_b_write(&log_file, (uchar*) "\t", 1))
 
1555
      goto err;
 
1556
 
 
1557
    /* sql_text */
 
1558
    if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len))
 
1559
      goto err;
 
1560
 
 
1561
    if (my_b_write(&log_file, (uchar*) "\n", 1) ||
 
1562
        flush_io_cache(&log_file))
 
1563
      goto err;
 
1564
  }
 
1565
 
 
1566
  (void) pthread_mutex_unlock(&LOCK_log);
 
1567
  return FALSE;
 
1568
err:
 
1569
 
 
1570
  if (!write_error)
 
1571
  {
 
1572
    write_error= 1;
 
1573
    sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
 
1574
  }
 
1575
  (void) pthread_mutex_unlock(&LOCK_log);
 
1576
  return TRUE;
 
1577
}
 
1578
 
 
1579
 
 
1580
/*
 
1581
  Log a query to the traditional slow log file
 
1582
 
 
1583
  SYNOPSIS
 
1584
    write()
 
1585
 
 
1586
    thd               THD of the query
 
1587
    current_time      current timestamp
 
1588
    query_start_arg   command start timestamp
 
1589
    user_host         the pointer to the string with user@host info
 
1590
    user_host_len     length of the user_host string. this is computed once
 
1591
                      and passed to all general log event handlers
 
1592
    query_utime       Amount of time the query took to execute (in microseconds)
 
1593
    lock_utime        Amount of time the query was locked (in microseconds)
 
1594
    is_command        The flag, which determines, whether the sql_text is a
 
1595
                      query or an administrator command.
 
1596
    sql_text          the very text of the query or administrator command
 
1597
                      processed
 
1598
    sql_text_len      the length of sql_text string
 
1599
 
 
1600
  DESCRIPTION
 
1601
 
 
1602
   Log a query to the slow log file.
 
1603
 
 
1604
  RETURN
 
1605
    FALSE - OK
 
1606
    TRUE - error occured
 
1607
*/
 
1608
 
 
1609
bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
 
1610
                            time_t query_start_arg __attribute__((__unused__)),
 
1611
                            const char *user_host,
 
1612
                            uint user_host_len, ulonglong query_utime,
 
1613
                            ulonglong lock_utime, bool is_command,
 
1614
                            const char *sql_text, uint sql_text_len)
 
1615
{
 
1616
  bool error= 0;
 
1617
  DBUG_ENTER("MYSQL_QUERY_LOG::write");
 
1618
 
 
1619
  (void) pthread_mutex_lock(&LOCK_log);
 
1620
 
 
1621
  if (!is_open())
 
1622
  {
 
1623
    (void) pthread_mutex_unlock(&LOCK_log);
 
1624
    DBUG_RETURN(0);
 
1625
  }
 
1626
 
 
1627
  if (is_open())
 
1628
  {                                             // Safety agains reopen
 
1629
    int tmp_errno= 0;
 
1630
    char buff[80], *end;
 
1631
    char query_time_buff[22+7], lock_time_buff[22+7];
 
1632
    uint buff_len;
 
1633
    end= buff;
 
1634
 
 
1635
    if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT))
 
1636
    {
 
1637
      if (current_time != last_time)
 
1638
      {
 
1639
        last_time= current_time;
 
1640
        struct tm start;
 
1641
        localtime_r(&current_time, &start);
 
1642
 
 
1643
        buff_len= snprintf(buff, sizeof buff,
 
1644
                           "# Time: %02d%02d%02d %2d:%02d:%02d\n",
 
1645
                           start.tm_year % 100, start.tm_mon + 1,
 
1646
                           start.tm_mday, start.tm_hour,
 
1647
                           start.tm_min, start.tm_sec);
 
1648
 
 
1649
        /* Note that my_b_write() assumes it knows the length for this */
 
1650
        if (my_b_write(&log_file, (uchar*) buff, buff_len))
 
1651
          tmp_errno= errno;
 
1652
      }
 
1653
      const uchar uh[]= "# User@Host: ";
 
1654
      if (my_b_write(&log_file, uh, sizeof(uh) - 1))
 
1655
        tmp_errno= errno;
 
1656
      if (my_b_write(&log_file, (uchar*) user_host, user_host_len))
 
1657
        tmp_errno= errno;
 
1658
      if (my_b_write(&log_file, (uchar*) "\n", 1))
 
1659
        tmp_errno= errno;
 
1660
    }
 
1661
    /* For slow query log */
 
1662
    sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
 
1663
    sprintf(lock_time_buff,  "%.6f", ulonglong2double(lock_utime)/1000000.0);
 
1664
    if (my_b_printf(&log_file,
 
1665
                    "# Query_time: %s  Lock_time: %s"
 
1666
                    " Rows_sent: %lu  Rows_examined: %lu\n",
 
1667
                    query_time_buff, lock_time_buff,
 
1668
                    (ulong) thd->sent_row_count,
 
1669
                    (ulong) thd->examined_row_count) == (uint) -1)
 
1670
      tmp_errno= errno;
 
1671
    if (thd->db && strcmp(thd->db, db))
 
1672
    {                                           // Database changed
 
1673
      if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1)
 
1674
        tmp_errno= errno;
 
1675
      strmov(db,thd->db);
 
1676
    }
 
1677
    if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
 
1678
    {
 
1679
      end=strmov(end, ",last_insert_id=");
 
1680
      end=longlong10_to_str((longlong)
 
1681
                            thd->first_successful_insert_id_in_prev_stmt_for_binlog,
 
1682
                            end, -10);
 
1683
    }
 
1684
    // Save value if we do an insert.
 
1685
    if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
 
1686
    {
 
1687
      if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT))
 
1688
      {
 
1689
        end=strmov(end,",insert_id=");
 
1690
        end=longlong10_to_str((longlong)
 
1691
                              thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum(),
 
1692
                              end, -10);
 
1693
      }
 
1694
    }
 
1695
 
 
1696
    /*
 
1697
      This info used to show up randomly, depending on whether the query
 
1698
      checked the query start time or not. now we always write current
 
1699
      timestamp to the slow log
 
1700
    */
 
1701
    end= strmov(end, ",timestamp=");
 
1702
    end= int10_to_str((long) current_time, end, 10);
 
1703
 
 
1704
    if (end != buff)
 
1705
    {
 
1706
      *end++=';';
 
1707
      *end='\n';
 
1708
      if (my_b_write(&log_file, (uchar*) "SET ", 4) ||
 
1709
          my_b_write(&log_file, (uchar*) buff + 1, (uint) (end-buff)))
 
1710
        tmp_errno= errno;
 
1711
    }
 
1712
    if (is_command)
 
1713
    {
 
1714
      end= strxmov(buff, "# administrator command: ", NullS);
 
1715
      buff_len= (ulong) (end - buff);
 
1716
      my_b_write(&log_file, (uchar*) buff, buff_len);
 
1717
    }
 
1718
    if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len) ||
 
1719
        my_b_write(&log_file, (uchar*) ";\n",2) ||
 
1720
        flush_io_cache(&log_file))
 
1721
      tmp_errno= errno;
 
1722
    if (tmp_errno)
 
1723
    {
 
1724
      error= 1;
 
1725
      if (! write_error)
 
1726
      {
 
1727
        write_error= 1;
 
1728
        sql_print_error(ER(ER_ERROR_ON_WRITE), name, error);
 
1729
      }
 
1730
    }
 
1731
  }
 
1732
  (void) pthread_mutex_unlock(&LOCK_log);
 
1733
  DBUG_RETURN(error);
 
1734
}
 
1735
 
 
1736
 
1019
1737
/**
1020
1738
  @todo
1021
1739
  The following should be using fn_format();  We just need to
1022
1740
  first change fn_format() to cut the file name if it's too long.
1023
1741
*/
1024
 
const char *DRIZZLE_LOG::generate_name(const char *log_name,
 
1742
const char *MYSQL_LOG::generate_name(const char *log_name,
1025
1743
                                      const char *suffix,
1026
1744
                                      bool strip_ext, char *buff)
1027
1745
{
1035
1753
  if (strip_ext)
1036
1754
  {
1037
1755
    char *p= fn_ext(log_name);
1038
 
    uint32_t length= (uint) (p - log_name);
1039
 
    strmake(buff, log_name, cmin(length, (uint)FN_REFLEN));
 
1756
    uint length= (uint) (p - log_name);
 
1757
    strmake(buff, log_name, min(length, FN_REFLEN));
1040
1758
    return (const char*)buff;
1041
1759
  }
1042
1760
  return log_name;
1044
1762
 
1045
1763
 
1046
1764
 
1047
 
DRIZZLE_BIN_LOG::DRIZZLE_BIN_LOG()
 
1765
MYSQL_BIN_LOG::MYSQL_BIN_LOG()
1048
1766
  :bytes_written(0), prepared_xids(0), file_id(1), open_count(1),
1049
 
   need_start_event(true), m_table_map_version(0),
 
1767
   need_start_event(TRUE), m_table_map_version(0),
1050
1768
   description_event_for_exec(0), description_event_for_queue(0)
1051
1769
{
1052
1770
  /*
1056
1774
    before main().
1057
1775
  */
1058
1776
  index_file_name[0] = 0;
1059
 
  memset(&index_file, 0, sizeof(index_file));
 
1777
  bzero((char*) &index_file, sizeof(index_file));
1060
1778
}
1061
1779
 
1062
1780
/* this is called only once */
1063
1781
 
1064
 
void DRIZZLE_BIN_LOG::cleanup()
 
1782
void MYSQL_BIN_LOG::cleanup()
1065
1783
{
 
1784
  DBUG_ENTER("cleanup");
1066
1785
  if (inited)
1067
1786
  {
1068
1787
    inited= 0;
1073
1792
    (void) pthread_mutex_destroy(&LOCK_index);
1074
1793
    (void) pthread_cond_destroy(&update_cond);
1075
1794
  }
1076
 
  return;
 
1795
  DBUG_VOID_RETURN;
1077
1796
}
1078
1797
 
1079
1798
 
1080
1799
/* Init binlog-specific vars */
1081
 
void DRIZZLE_BIN_LOG::init(bool no_auto_events_arg, ulong max_size_arg)
 
1800
void MYSQL_BIN_LOG::init(bool no_auto_events_arg, ulong max_size_arg)
1082
1801
{
 
1802
  DBUG_ENTER("MYSQL_BIN_LOG::init");
1083
1803
  no_auto_events= no_auto_events_arg;
1084
1804
  max_size= max_size_arg;
1085
 
  return;
 
1805
  DBUG_PRINT("info",("max_size: %lu", max_size));
 
1806
  DBUG_VOID_RETURN;
1086
1807
}
1087
1808
 
1088
1809
 
1089
 
void DRIZZLE_BIN_LOG::init_pthread_objects()
 
1810
void MYSQL_BIN_LOG::init_pthread_objects()
1090
1811
{
1091
 
  assert(inited == 0);
 
1812
  DBUG_ASSERT(inited == 0);
1092
1813
  inited= 1;
1093
1814
  (void) pthread_mutex_init(&LOCK_log, MY_MUTEX_INIT_SLOW);
1094
1815
  (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
1096
1817
}
1097
1818
 
1098
1819
 
1099
 
bool DRIZZLE_BIN_LOG::open_index_file(const char *index_file_name_arg,
 
1820
bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
1100
1821
                                const char *log_name)
1101
1822
{
1102
1823
  File index_file_nr= -1;
1103
 
  assert(!my_b_inited(&index_file));
 
1824
  DBUG_ASSERT(!my_b_inited(&index_file));
1104
1825
 
1105
1826
  /*
1106
1827
    First open of this class instance
1116
1837
  fn_format(index_file_name, index_file_name_arg, mysql_data_home,
1117
1838
            ".index", opt);
1118
1839
  if ((index_file_nr= my_open(index_file_name,
1119
 
                              O_RDWR | O_CREAT,
 
1840
                              O_RDWR | O_CREAT | O_BINARY ,
1120
1841
                              MYF(MY_WME))) < 0 ||
1121
1842
       my_sync(index_file_nr, MYF(MY_WME)) ||
1122
1843
       init_io_cache(&index_file, index_file_nr,
1131
1852
    */
1132
1853
    if (index_file_nr >= 0)
1133
1854
      my_close(index_file_nr,MYF(0));
1134
 
    return true;
 
1855
    return TRUE;
1135
1856
  }
1136
 
  return false;
 
1857
  return FALSE;
1137
1858
}
1138
1859
 
1139
1860
 
1151
1872
    1   error
1152
1873
*/
1153
1874
 
1154
 
bool DRIZZLE_BIN_LOG::open(const char *log_name,
 
1875
bool MYSQL_BIN_LOG::open(const char *log_name,
1155
1876
                         enum_log_type log_type_arg,
1156
1877
                         const char *new_name,
1157
1878
                         enum cache_type io_cache_type_arg,
1160
1881
                         bool null_created_arg)
1161
1882
{
1162
1883
  File file= -1;
 
1884
  DBUG_ENTER("MYSQL_BIN_LOG::open");
 
1885
  DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
1163
1886
 
1164
1887
  write_error=0;
1165
1888
 
1166
1889
  /* open the main log file */
1167
 
  if (DRIZZLE_LOG::open(log_name, log_type_arg, new_name, io_cache_type_arg))
1168
 
    return(1);                            /* all warnings issued */
 
1890
  if (MYSQL_LOG::open(log_name, log_type_arg, new_name, io_cache_type_arg))
 
1891
    DBUG_RETURN(1);                            /* all warnings issued */
1169
1892
 
1170
1893
  init(no_auto_events_arg, max_size_arg);
1171
1894
 
1172
1895
  open_count++;
1173
1896
 
1174
 
  assert(log_type == LOG_BIN);
 
1897
  DBUG_ASSERT(log_type == LOG_BIN);
1175
1898
 
1176
1899
  {
1177
1900
    bool write_file_name_to_index_file=0;
1184
1907
        an extension for the binary log files.
1185
1908
        In this case we write a standard header to it.
1186
1909
      */
1187
 
      if (my_b_safe_write(&log_file, (unsigned char*) BINLOG_MAGIC,
 
1910
      if (my_b_safe_write(&log_file, (uchar*) BINLOG_MAGIC,
1188
1911
                          BIN_LOG_HEADER_SIZE))
1189
1912
        goto err;
1190
1913
      bytes_written+= BIN_LOG_HEADER_SIZE;
1191
1914
      write_file_name_to_index_file= 1;
1192
1915
    }
1193
1916
 
1194
 
    assert(my_b_inited(&index_file) != 0);
 
1917
    DBUG_ASSERT(my_b_inited(&index_file) != 0);
1195
1918
    reinit_io_cache(&index_file, WRITE_CACHE,
1196
1919
                    my_b_filelength(&index_file), 0, 0);
1197
1920
    if (need_start_event && !no_auto_events)
1255
1978
        As this is a new log file, we write the file name to the index
1256
1979
        file. As every time we write to the index file, we sync it.
1257
1980
      */
1258
 
      if (my_b_write(&index_file, (unsigned char*) log_file_name,
 
1981
      if (my_b_write(&index_file, (uchar*) log_file_name,
1259
1982
                     strlen(log_file_name)) ||
1260
 
          my_b_write(&index_file, (unsigned char*) "\n", 1) ||
 
1983
          my_b_write(&index_file, (uchar*) "\n", 1) ||
1261
1984
          flush_io_cache(&index_file) ||
1262
1985
          my_sync(index_file.file, MYF(MY_WME)))
1263
1986
        goto err;
1265
1988
  }
1266
1989
  log_state= LOG_OPENED;
1267
1990
 
1268
 
  return(0);
 
1991
  DBUG_RETURN(0);
1269
1992
 
1270
1993
err:
1271
 
  sql_print_error(_("Could not use %s for logging (error %d). "
1272
 
                    "Turning logging off for the whole duration of the "
1273
 
                    "Drizzle server process. "
1274
 
                    "To turn it on again: fix the cause, "
1275
 
                    "shutdown the Drizzle server and restart it."),
1276
 
                    name, errno);
 
1994
  sql_print_error("Could not use %s for logging (error %d). \
 
1995
Turning logging off for the whole duration of the MySQL server process. \
 
1996
To turn it on again: fix the cause, \
 
1997
shutdown the MySQL server and restart it.", name, errno);
1277
1998
  if (file >= 0)
1278
1999
    my_close(file,MYF(0));
1279
2000
  end_io_cache(&log_file);
1280
2001
  end_io_cache(&index_file);
1281
 
  if (name)
1282
 
  {
1283
 
    free(name);
1284
 
    name= NULL;
1285
 
  }
 
2002
  safeFree(name);
1286
2003
  log_state= LOG_CLOSED;
1287
 
  return(1);
 
2004
  DBUG_RETURN(1);
1288
2005
}
1289
2006
 
1290
2007
 
1291
 
int DRIZZLE_BIN_LOG::get_current_log(LOG_INFO* linfo)
 
2008
int MYSQL_BIN_LOG::get_current_log(LOG_INFO* linfo)
1292
2009
{
1293
2010
  pthread_mutex_lock(&LOCK_log);
1294
2011
  int ret = raw_get_current_log(linfo);
1296
2013
  return ret;
1297
2014
}
1298
2015
 
1299
 
int DRIZZLE_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
 
2016
int MYSQL_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
1300
2017
{
1301
2018
  strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name)-1);
1302
2019
  linfo->pos = my_b_tell(&log_file);
1320
2037
    0   ok
1321
2038
*/
1322
2039
 
 
2040
#ifdef HAVE_REPLICATION
 
2041
 
1323
2042
static bool copy_up_file_and_fill(IO_CACHE *index_file, my_off_t offset)
1324
2043
{
1325
2044
  int bytes_read;
1326
2045
  my_off_t init_offset= offset;
1327
2046
  File file= index_file->file;
1328
 
  unsigned char io_buf[IO_SIZE*2];
 
2047
  uchar io_buf[IO_SIZE*2];
 
2048
  DBUG_ENTER("copy_up_file_and_fill");
1329
2049
 
1330
2050
  for (;; offset+= bytes_read)
1331
2051
  {
1345
2065
 
1346
2066
  /* Reset data in old index cache */
1347
2067
  reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 1);
1348
 
  return(0);
 
2068
  DBUG_RETURN(0);
1349
2069
 
1350
2070
err:
1351
 
  return(1);
 
2071
  DBUG_RETURN(1);
1352
2072
}
1353
2073
 
 
2074
#endif /* HAVE_REPLICATION */
 
2075
 
1354
2076
/**
1355
2077
  Find the position in the log-index-file for the given log name.
1356
2078
 
1373
2095
    LOG_INFO_IO         Got IO error while reading file
1374
2096
*/
1375
2097
 
1376
 
int DRIZZLE_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
 
2098
int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
1377
2099
                            bool need_lock)
1378
2100
{
1379
2101
  int error= 0;
1380
2102
  char *fname= linfo->log_file_name;
1381
 
  uint32_t log_name_len= log_name ? (uint) strlen(log_name) : 0;
 
2103
  uint log_name_len= log_name ? (uint) strlen(log_name) : 0;
 
2104
  DBUG_ENTER("find_log_pos");
 
2105
  DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));
1382
2106
 
1383
2107
  /*
1384
2108
    Mutex needed because we need to make sure the file pointer does not
1393
2117
 
1394
2118
  for (;;)
1395
2119
  {
1396
 
    uint32_t length;
 
2120
    uint length;
1397
2121
    my_off_t offset= my_b_tell(&index_file);
1398
2122
    /* If we get 0 or 1 characters, this is the end of the file */
1399
2123
 
1409
2133
        (log_name_len == length-1 && fname[log_name_len] == '\n' &&
1410
2134
         !memcmp(fname, log_name, log_name_len)))
1411
2135
    {
 
2136
      DBUG_PRINT("info",("Found log file entry"));
1412
2137
      fname[length-1]=0;                        // remove last \n
1413
2138
      linfo->index_file_start_offset= offset;
1414
2139
      linfo->index_file_offset = my_b_tell(&index_file);
1418
2143
 
1419
2144
  if (need_lock)
1420
2145
    pthread_mutex_unlock(&LOCK_index);
1421
 
  return(error);
 
2146
  DBUG_RETURN(error);
1422
2147
}
1423
2148
 
1424
2149
 
1446
2171
    LOG_INFO_IO         Got IO error while reading file
1447
2172
*/
1448
2173
 
1449
 
int DRIZZLE_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
 
2174
int MYSQL_BIN_LOG::find_next_log(LOG_INFO* linfo, bool need_lock)
1450
2175
{
1451
2176
  int error= 0;
1452
 
  uint32_t length;
 
2177
  uint length;
1453
2178
  char *fname= linfo->log_file_name;
1454
2179
 
1455
2180
  if (need_lock)
1482
2207
 
1483
2208
  The new index file will only contain this file.
1484
2209
 
1485
 
  @param session                Thread
 
2210
  @param thd            Thread
1486
2211
 
1487
2212
  @note
1488
2213
    If not called from slave thread, write start event to new log
1493
2218
    1   error
1494
2219
*/
1495
2220
 
1496
 
bool DRIZZLE_BIN_LOG::reset_logs(Session* session)
 
2221
bool MYSQL_BIN_LOG::reset_logs(THD* thd)
1497
2222
{
1498
2223
  LOG_INFO linfo;
1499
2224
  bool error=0;
1500
2225
  const char* save_name;
 
2226
  DBUG_ENTER("reset_logs");
1501
2227
 
 
2228
  ha_reset_logs(thd);
1502
2229
  /*
1503
2230
    We need to get both locks to be sure that no one is trying to
1504
2231
    write to the index log file.
1508
2235
 
1509
2236
  /*
1510
2237
    The following mutex is needed to ensure that no threads call
1511
 
    'delete session' as we would then risk missing a 'rollback' from this
 
2238
    'delete thd' as we would then risk missing a 'rollback' from this
1512
2239
    thread. If the transaction involved MyISAM tables, it should go
1513
2240
    into binlog even on rollback.
1514
2241
  */
1515
 
  pthread_mutex_lock(&LOCK_thread_count);
 
2242
  VOID(pthread_mutex_lock(&LOCK_thread_count));
1516
2243
 
1517
2244
  /* Save variables so that we can reopen the log */
1518
2245
  save_name=name;
1521
2248
 
1522
2249
  /* First delete all old log files */
1523
2250
 
1524
 
  if (find_log_pos(&linfo, NULL, 0))
 
2251
  if (find_log_pos(&linfo, NullS, 0))
1525
2252
  {
1526
2253
    error=1;
1527
2254
    goto err;
1533
2260
    {
1534
2261
      if (my_errno == ENOENT) 
1535
2262
      {
1536
 
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2263
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1537
2264
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1538
2265
                            linfo.log_file_name);
1539
 
        sql_print_information(_("Failed to delete file '%s'"),
 
2266
        sql_print_information("Failed to delete file '%s'",
1540
2267
                              linfo.log_file_name);
1541
2268
        my_errno= 0;
1542
2269
        error= 0;
1543
2270
      }
1544
2271
      else
1545
2272
      {
1546
 
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2273
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1547
2274
                            ER_BINLOG_PURGE_FATAL_ERR,
1548
 
                            _("a problem with deleting %s; "
 
2275
                            "a problem with deleting %s; "
1549
2276
                            "consider examining correspondence "
1550
2277
                            "of your binlog index file "
1551
 
                            "to the actual binlog files"),
 
2278
                            "to the actual binlog files",
1552
2279
                            linfo.log_file_name);
1553
2280
        error= 1;
1554
2281
        goto err;
1564
2291
  {
1565
2292
    if (my_errno == ENOENT) 
1566
2293
    {
1567
 
      push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2294
      push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1568
2295
                          ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1569
2296
                          index_file_name);
1570
 
      sql_print_information(_("Failed to delete file '%s'"),
 
2297
      sql_print_information("Failed to delete file '%s'",
1571
2298
                            index_file_name);
1572
2299
      my_errno= 0;
1573
2300
      error= 0;
1574
2301
    }
1575
2302
    else
1576
2303
    {
1577
 
      push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2304
      push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1578
2305
                          ER_BINLOG_PURGE_FATAL_ERR,
1579
2306
                          "a problem with deleting %s; "
1580
2307
                          "consider examining correspondence "
1585
2312
      goto err;
1586
2313
    }
1587
2314
  }
1588
 
  if (!session->slave_thread)
 
2315
  if (!thd->slave_thread)
1589
2316
    need_start_event=1;
1590
2317
  if (!open_index_file(index_file_name, 0))
1591
2318
    open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0);
1592
 
  free((unsigned char*) save_name);
 
2319
  my_free((uchar*) save_name, MYF(0));
1593
2320
 
1594
2321
err:
1595
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
2322
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
1596
2323
  pthread_mutex_unlock(&LOCK_index);
1597
2324
  pthread_mutex_unlock(&LOCK_log);
1598
 
  return(error);
 
2325
  DBUG_RETURN(error);
1599
2326
}
1600
2327
 
1601
2328
 
1636
2363
    LOG_INFO_IO         Got IO error while reading file
1637
2364
*/
1638
2365
 
 
2366
#ifdef HAVE_REPLICATION
1639
2367
 
1640
 
int DRIZZLE_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
 
2368
int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
1641
2369
{
1642
2370
  int error;
 
2371
  DBUG_ENTER("purge_first_log");
1643
2372
 
1644
 
  assert(is_open());
1645
 
  assert(rli->slave_running == 1);
1646
 
  assert(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name.c_str()));
 
2373
  DBUG_ASSERT(is_open());
 
2374
  DBUG_ASSERT(rli->slave_running == 1);
 
2375
  DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->event_relay_log_name));
1647
2376
 
1648
2377
  pthread_mutex_lock(&LOCK_index);
1649
2378
  pthread_mutex_lock(&rli->log_space_lock);
1650
 
  rli->relay_log.purge_logs(rli->group_relay_log_name.c_str(), included,
 
2379
  rli->relay_log.purge_logs(rli->group_relay_log_name, included,
1651
2380
                            0, 0, &rli->log_space_total);
1652
2381
  // Tell the I/O thread to take the relay_log_space_limit into account
1653
2382
  rli->ignore_log_space_limit= 0;
1666
2395
    If included is true, we want the first relay log;
1667
2396
    otherwise we want the one after event_relay_log_name.
1668
2397
  */
1669
 
  if ((included && (error=find_log_pos(&rli->linfo, NULL, 0))) ||
 
2398
  if ((included && (error=find_log_pos(&rli->linfo, NullS, 0))) ||
1670
2399
      (!included &&
1671
 
       ((error=find_log_pos(&rli->linfo, rli->event_relay_log_name.c_str(), 0)) ||
 
2400
       ((error=find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)) ||
1672
2401
        (error=find_next_log(&rli->linfo, 0)))))
1673
2402
  {
1674
2403
    char buff[22];
1675
 
    sql_print_error(_("next log error: %d  offset: %s  log: %s included: %d"),
 
2404
    sql_print_error("next log error: %d  offset: %s  log: %s included: %d",
1676
2405
                    error,
1677
2406
                    llstr(rli->linfo.index_file_offset,buff),
1678
 
                    rli->group_relay_log_name.c_str(),
 
2407
                    rli->group_relay_log_name,
1679
2408
                    included);
1680
2409
    goto err;
1681
2410
  }
1684
2413
    Reset rli's coordinates to the current log.
1685
2414
  */
1686
2415
  rli->event_relay_log_pos= BIN_LOG_HEADER_SIZE;
1687
 
  rli->event_relay_log_name.assign(rli->linfo.log_file_name);
 
2416
  strmake(rli->event_relay_log_name,rli->linfo.log_file_name,
 
2417
          sizeof(rli->event_relay_log_name)-1);
1688
2418
 
1689
2419
  /*
1690
2420
    If we removed the rli->group_relay_log_name file,
1694
2424
  if (included)
1695
2425
  {
1696
2426
    rli->group_relay_log_pos = BIN_LOG_HEADER_SIZE;
1697
 
    rli->group_relay_log_name.assign(rli->linfo.log_file_name);
 
2427
    strmake(rli->group_relay_log_name,rli->linfo.log_file_name,
 
2428
            sizeof(rli->group_relay_log_name)-1);
1698
2429
    rli->notify_group_relay_log_name_update();
1699
2430
  }
1700
2431
 
1703
2434
 
1704
2435
err:
1705
2436
  pthread_mutex_unlock(&LOCK_index);
1706
 
  return(error);
 
2437
  DBUG_RETURN(error);
1707
2438
}
1708
2439
 
1709
2440
/**
1710
2441
  Update log index_file.
1711
2442
*/
1712
2443
 
1713
 
int DRIZZLE_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
 
2444
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
1714
2445
{
1715
2446
  if (copy_up_file_and_fill(&index_file, log_info->index_file_start_offset))
1716
2447
    return LOG_INFO_IO;
1745
2476
                                stat() or my_delete()
1746
2477
*/
1747
2478
 
1748
 
int DRIZZLE_BIN_LOG::purge_logs(const char *to_log, 
 
2479
int MYSQL_BIN_LOG::purge_logs(const char *to_log, 
1749
2480
                          bool included,
1750
2481
                          bool need_mutex, 
1751
2482
                          bool need_update_threads, 
1752
 
                          uint64_t *decrease_log_space)
 
2483
                          ulonglong *decrease_log_space)
1753
2484
{
1754
2485
  int error;
1755
2486
  int ret = 0;
1756
2487
  bool exit_loop= 0;
1757
2488
  LOG_INFO log_info;
 
2489
  DBUG_ENTER("purge_logs");
 
2490
  DBUG_PRINT("info",("to_log= %s",to_log));
1758
2491
 
1759
2492
  if (need_mutex)
1760
2493
    pthread_mutex_lock(&LOCK_index);
1765
2498
    File name exists in index file; delete until we find this file
1766
2499
    or a file that is used.
1767
2500
  */
1768
 
  if ((error=find_log_pos(&log_info, NULL, 0 /*no mutex*/)))
 
2501
  if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
1769
2502
    goto err;
1770
2503
  while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&
1771
2504
         !log_in_use(log_info.log_file_name))
1779
2512
          It's not fatal if we can't stat a log file that does not exist;
1780
2513
          If we could not stat, we won't delete.
1781
2514
        */     
1782
 
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2515
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1783
2516
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1784
2517
                            log_info.log_file_name);
1785
 
        sql_print_information(_("Failed to execute stat() on file '%s'"),
 
2518
        sql_print_information("Failed to execute stat on file '%s'",
1786
2519
                              log_info.log_file_name);
1787
2520
        my_errno= 0;
1788
2521
      }
1791
2524
        /*
1792
2525
          Other than ENOENT are fatal
1793
2526
        */
1794
 
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2527
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1795
2528
                            ER_BINLOG_PURGE_FATAL_ERR,
1796
 
                            _("a problem with getting info on being purged %s; "
 
2529
                            "a problem with getting info on being purged %s; "
1797
2530
                            "consider examining correspondence "
1798
2531
                            "of your binlog index file "
1799
 
                            "to the actual binlog files"),
 
2532
                            "to the actual binlog files",
1800
2533
                            log_info.log_file_name);
1801
2534
        error= LOG_INFO_FATAL;
1802
2535
        goto err;
1804
2537
    }
1805
2538
    else
1806
2539
    {
 
2540
      DBUG_PRINT("info",("purging %s",log_info.log_file_name));
1807
2541
      if (!my_delete(log_info.log_file_name, MYF(0)))
1808
2542
      {
1809
2543
        if (decrease_log_space)
1813
2547
      {
1814
2548
        if (my_errno == ENOENT) 
1815
2549
        {
1816
 
          push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2550
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1817
2551
                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1818
2552
                              log_info.log_file_name);
1819
 
          sql_print_information(_("Failed to delete file '%s'"),
 
2553
          sql_print_information("Failed to delete file '%s'",
1820
2554
                                log_info.log_file_name);
1821
2555
          my_errno= 0;
1822
2556
        }
1823
2557
        else
1824
2558
        {
1825
 
          push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2559
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1826
2560
                              ER_BINLOG_PURGE_FATAL_ERR,
1827
 
                              _("a problem with deleting %s; "
 
2561
                              "a problem with deleting %s; "
1828
2562
                              "consider examining correspondence "
1829
2563
                              "of your binlog index file "
1830
 
                              "to the actual binlog files"),
 
2564
                              "to the actual binlog files",
1831
2565
                              log_info.log_file_name);
1832
2566
          if (my_errno == EMFILE)
1833
2567
          {
 
2568
            DBUG_PRINT("info",
 
2569
                       ("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno));
1834
2570
            error= LOG_INFO_EMFILE;
1835
2571
          }
1836
2572
          error= LOG_INFO_FATAL;
1839
2575
      }
1840
2576
    }
1841
2577
 
 
2578
    ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
 
2579
 
1842
2580
    if (find_next_log(&log_info, 0) || exit_loop)
1843
2581
      break;
1844
2582
  }
1855
2593
err:
1856
2594
  if (need_mutex)
1857
2595
    pthread_mutex_unlock(&LOCK_index);
1858
 
  return(error);
 
2596
  DBUG_RETURN(error);
1859
2597
}
1860
2598
 
1861
2599
/**
1862
2600
  Remove all logs before the given file date from disk and from the
1863
2601
  index file.
1864
2602
 
1865
 
  @param session                Thread pointer
 
2603
  @param thd            Thread pointer
1866
2604
  @param before_date    Delete all log files before given date.
1867
2605
 
1868
2606
  @note
1877
2615
                                stat() or my_delete()
1878
2616
*/
1879
2617
 
1880
 
int DRIZZLE_BIN_LOG::purge_logs_before_date(time_t purge_time)
 
2618
int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time)
1881
2619
{
1882
2620
  int error;
1883
2621
  LOG_INFO log_info;
1884
2622
  struct stat stat_area;
1885
2623
 
 
2624
  DBUG_ENTER("purge_logs_before_date");
 
2625
 
1886
2626
  pthread_mutex_lock(&LOCK_index);
1887
2627
 
1888
2628
  /*
1890
2630
    or a file that is used or a file
1891
2631
    that is older than purge_time.
1892
2632
  */
1893
 
  if ((error=find_log_pos(&log_info, NULL, 0 /*no mutex*/)))
 
2633
  if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))
1894
2634
    goto err;
1895
2635
 
1896
2636
  while (strcmp(log_file_name, log_info.log_file_name) &&
1903
2643
        /*
1904
2644
          It's not fatal if we can't stat a log file that does not exist.
1905
2645
        */     
1906
 
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2646
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1907
2647
                            ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1908
2648
                            log_info.log_file_name);
1909
 
        sql_print_information(_("Failed to execute stat() on file '%s'"),
 
2649
        sql_print_information("Failed to execute stat on file '%s'",
1910
2650
                              log_info.log_file_name);
1911
2651
        my_errno= 0;
1912
2652
      }
1915
2655
        /*
1916
2656
          Other than ENOENT are fatal
1917
2657
        */
1918
 
        push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2658
        push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1919
2659
                            ER_BINLOG_PURGE_FATAL_ERR,
1920
 
                            _("a problem with getting info on being purged %s; "
 
2660
                            "a problem with getting info on being purged %s; "
1921
2661
                            "consider examining correspondence "
1922
2662
                            "of your binlog index file "
1923
 
                            "to the actual binlog files"),
 
2663
                            "to the actual binlog files",
1924
2664
                            log_info.log_file_name);
1925
2665
        error= LOG_INFO_FATAL;
1926
2666
        goto err;
1935
2675
        if (my_errno == ENOENT) 
1936
2676
        {
1937
2677
          /* It's not fatal even if we can't delete a log file */
1938
 
          push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
2678
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1939
2679
                              ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE),
1940
2680
                              log_info.log_file_name);
1941
 
          sql_print_information(_("Failed to delete file '%s'"),
 
2681
          sql_print_information("Failed to delete file '%s'",
1942
2682
                                log_info.log_file_name);
1943
2683
          my_errno= 0;
1944
2684
        }
1945
2685
        else
1946
2686
        {
1947
 
          push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
 
2687
          push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
1948
2688
                              ER_BINLOG_PURGE_FATAL_ERR,
1949
 
                              _("a problem with deleting %s; "
 
2689
                              "a problem with deleting %s; "
1950
2690
                              "consider examining correspondence "
1951
2691
                              "of your binlog index file "
1952
 
                              "to the actual binlog files"),
 
2692
                              "to the actual binlog files",
1953
2693
                              log_info.log_file_name);
1954
2694
          error= LOG_INFO_FATAL;
1955
2695
          goto err;
1956
2696
        }
1957
2697
      }
 
2698
      ha_binlog_index_purge_file(current_thd, log_info.log_file_name);
1958
2699
    }
1959
2700
    if (find_next_log(&log_info, 0))
1960
2701
      break;
1968
2709
 
1969
2710
err:
1970
2711
  pthread_mutex_unlock(&LOCK_index);
1971
 
  return(error);
 
2712
  DBUG_RETURN(error);
1972
2713
}
 
2714
#endif /* HAVE_REPLICATION */
1973
2715
 
1974
2716
 
1975
2717
/**
1981
2723
    If file name will be longer then FN_REFLEN it will be truncated
1982
2724
*/
1983
2725
 
1984
 
void DRIZZLE_BIN_LOG::make_log_name(char* buf, const char* log_ident)
 
2726
void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
1985
2727
{
1986
 
  uint32_t dir_len = dirname_length(log_file_name); 
 
2728
  uint dir_len = dirname_length(log_file_name); 
1987
2729
  if (dir_len >= FN_REFLEN)
1988
2730
    dir_len=FN_REFLEN-1;
1989
 
  my_stpncpy(buf, log_file_name, dir_len);
 
2731
  strnmov(buf, log_file_name, dir_len);
1990
2732
  strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len -1);
1991
2733
}
1992
2734
 
1995
2737
  Check if we are writing/reading to the given log file.
1996
2738
*/
1997
2739
 
1998
 
bool DRIZZLE_BIN_LOG::is_active(const char *log_file_name_arg)
 
2740
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
1999
2741
{
2000
2742
  return !strcmp(log_file_name, log_file_name_arg);
2001
2743
}
2009
2751
  method).
2010
2752
*/
2011
2753
 
2012
 
void DRIZZLE_BIN_LOG::new_file()
 
2754
void MYSQL_BIN_LOG::new_file()
2013
2755
{
2014
2756
  new_file_impl(1);
2015
2757
}
2016
2758
 
2017
2759
 
2018
 
void DRIZZLE_BIN_LOG::new_file_without_locking()
 
2760
void MYSQL_BIN_LOG::new_file_without_locking()
2019
2761
{
2020
2762
  new_file_impl(0);
2021
2763
}
2030
2772
    The new file name is stored last in the index file
2031
2773
*/
2032
2774
 
2033
 
void DRIZZLE_BIN_LOG::new_file_impl(bool need_lock)
 
2775
void MYSQL_BIN_LOG::new_file_impl(bool need_lock)
2034
2776
{
2035
2777
  char new_name[FN_REFLEN], *new_name_ptr, *old_name;
2036
2778
 
 
2779
  DBUG_ENTER("MYSQL_BIN_LOG::new_file_impl");
2037
2780
  if (!is_open())
2038
2781
  {
2039
 
    return;
 
2782
    DBUG_PRINT("info",("log is closed"));
 
2783
    DBUG_VOID_RETURN;
2040
2784
  }
2041
2785
 
2042
2786
  if (need_lock)
2060
2804
    tc_log_page_waits++;
2061
2805
    pthread_mutex_lock(&LOCK_prep_xids);
2062
2806
    while (prepared_xids) {
 
2807
      DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
2063
2808
      pthread_cond_wait(&COND_prep_xids, &LOCK_prep_xids);
2064
2809
    }
2065
2810
    pthread_mutex_unlock(&LOCK_prep_xids);
2116
2861
 
2117
2862
  open(old_name, log_type, new_name_ptr,
2118
2863
       io_cache_type, no_auto_events, max_size, 1);
2119
 
  free(old_name);
 
2864
  my_free(old_name,MYF(0));
2120
2865
 
2121
2866
end:
2122
2867
  if (need_lock)
2123
2868
    pthread_mutex_unlock(&LOCK_log);
2124
2869
  pthread_mutex_unlock(&LOCK_index);
2125
2870
 
2126
 
  return;
 
2871
  DBUG_VOID_RETURN;
2127
2872
}
2128
2873
 
2129
2874
 
2130
 
bool DRIZZLE_BIN_LOG::append(Log_event* ev)
 
2875
bool MYSQL_BIN_LOG::append(Log_event* ev)
2131
2876
{
2132
2877
  bool error = 0;
2133
2878
  pthread_mutex_lock(&LOCK_log);
 
2879
  DBUG_ENTER("MYSQL_BIN_LOG::append");
2134
2880
 
2135
 
  assert(log_file.type == SEQ_READ_APPEND);
 
2881
  DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
2136
2882
  /*
2137
2883
    Log_event::write() is smart enough to use my_b_write() or
2138
2884
    my_b_append() depending on the kind of cache we have.
2143
2889
    goto err;
2144
2890
  }
2145
2891
  bytes_written+= ev->data_written;
 
2892
  DBUG_PRINT("info",("max_size: %lu",max_size));
2146
2893
  if ((uint) my_b_append_tell(&log_file) > max_size)
2147
2894
    new_file_without_locking();
2148
2895
 
2149
2896
err:
2150
2897
  pthread_mutex_unlock(&LOCK_log);
2151
2898
  signal_update();                              // Safe as we don't call close
2152
 
  return(error);
 
2899
  DBUG_RETURN(error);
2153
2900
}
2154
2901
 
2155
2902
 
2156
 
bool DRIZZLE_BIN_LOG::appendv(const char* buf, uint32_t len,...)
 
2903
bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...)
2157
2904
{
2158
2905
  bool error= 0;
 
2906
  DBUG_ENTER("MYSQL_BIN_LOG::appendv");
2159
2907
  va_list(args);
2160
2908
  va_start(args,len);
2161
2909
 
2162
 
  assert(log_file.type == SEQ_READ_APPEND);
 
2910
  DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
2163
2911
 
2164
2912
  safe_mutex_assert_owner(&LOCK_log);
2165
2913
  do
2166
2914
  {
2167
 
    if (my_b_append(&log_file,(unsigned char*) buf,len))
 
2915
    if (my_b_append(&log_file,(uchar*) buf,len))
2168
2916
    {
2169
2917
      error= 1;
2170
2918
      goto err;
2171
2919
    }
2172
2920
    bytes_written += len;
2173
2921
  } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint)));
 
2922
  DBUG_PRINT("info",("max_size: %lu",max_size));
2174
2923
  if ((uint) my_b_append_tell(&log_file) > max_size)
2175
2924
    new_file_without_locking();
2176
2925
 
2177
2926
err:
2178
2927
  if (!error)
2179
2928
    signal_update();
2180
 
  return(error);
 
2929
  DBUG_RETURN(error);
2181
2930
}
2182
2931
 
2183
2932
 
2184
 
bool DRIZZLE_BIN_LOG::flush_and_sync()
 
2933
bool MYSQL_BIN_LOG::flush_and_sync()
2185
2934
{
2186
2935
  int err=0, fd=log_file.file;
2187
2936
  safe_mutex_assert_owner(&LOCK_log);
2195
2944
  return err;
2196
2945
}
2197
2946
 
2198
 
void DRIZZLE_BIN_LOG::start_union_events(Session *session, query_id_t query_id_param)
2199
 
{
2200
 
  assert(!session->binlog_evt_union.do_union);
2201
 
  session->binlog_evt_union.do_union= true;
2202
 
  session->binlog_evt_union.unioned_events= false;
2203
 
  session->binlog_evt_union.unioned_events_trans= false;
2204
 
  session->binlog_evt_union.first_query_id= query_id_param;
2205
 
}
2206
 
 
2207
 
void DRIZZLE_BIN_LOG::stop_union_events(Session *session)
2208
 
{
2209
 
  assert(session->binlog_evt_union.do_union);
2210
 
  session->binlog_evt_union.do_union= false;
2211
 
}
2212
 
 
2213
 
bool DRIZZLE_BIN_LOG::is_query_in_union(Session *session, query_id_t query_id_param)
2214
 
{
2215
 
  return (session->binlog_evt_union.do_union && 
2216
 
          query_id_param >= session->binlog_evt_union.first_query_id);
 
2947
void MYSQL_BIN_LOG::start_union_events(THD *thd, query_id_t query_id_param)
 
2948
{
 
2949
  DBUG_ASSERT(!thd->binlog_evt_union.do_union);
 
2950
  thd->binlog_evt_union.do_union= TRUE;
 
2951
  thd->binlog_evt_union.unioned_events= FALSE;
 
2952
  thd->binlog_evt_union.unioned_events_trans= FALSE;
 
2953
  thd->binlog_evt_union.first_query_id= query_id_param;
 
2954
}
 
2955
 
 
2956
void MYSQL_BIN_LOG::stop_union_events(THD *thd)
 
2957
{
 
2958
  DBUG_ASSERT(thd->binlog_evt_union.do_union);
 
2959
  thd->binlog_evt_union.do_union= FALSE;
 
2960
}
 
2961
 
 
2962
bool MYSQL_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
 
2963
{
 
2964
  return (thd->binlog_evt_union.do_union && 
 
2965
          query_id_param >= thd->binlog_evt_union.first_query_id);
2217
2966
}
2218
2967
 
2219
2968
 
2222
2971
  binlog_hton, which has internal linkage.
2223
2972
*/
2224
2973
 
2225
 
int Session::binlog_setup_trx_data()
 
2974
int THD::binlog_setup_trx_data()
2226
2975
{
 
2976
  DBUG_ENTER("THD::binlog_setup_trx_data");
2227
2977
  binlog_trx_data *trx_data=
2228
 
    (binlog_trx_data*) session_get_ha_data(this, binlog_hton);
 
2978
    (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2229
2979
 
2230
2980
  if (trx_data)
2231
 
    return(0);                             // Already set up
 
2981
    DBUG_RETURN(0);                             // Already set up
2232
2982
 
2233
2983
  trx_data= (binlog_trx_data*) my_malloc(sizeof(binlog_trx_data), MYF(MY_ZEROFILL));
2234
2984
  if (!trx_data ||
2235
2985
      open_cached_file(&trx_data->trans_log, mysql_tmpdir,
2236
2986
                       LOG_PREFIX, binlog_cache_size, MYF(MY_WME)))
2237
2987
  {
2238
 
    free((unsigned char*)trx_data);
2239
 
    return(1);                      // Didn't manage to set it up
 
2988
    my_free((uchar*)trx_data, MYF(MY_ALLOW_ZERO_PTR));
 
2989
    DBUG_RETURN(1);                      // Didn't manage to set it up
2240
2990
  }
2241
 
  session_set_ha_data(this, binlog_hton, trx_data);
2242
 
 
2243
 
  trx_data= new (session_get_ha_data(this, binlog_hton)) binlog_trx_data;
2244
 
 
2245
 
  return(0);
 
2991
  thd_set_ha_data(this, binlog_hton, trx_data);
 
2992
 
 
2993
  trx_data= new (thd_get_ha_data(this, binlog_hton)) binlog_trx_data;
 
2994
 
 
2995
  DBUG_RETURN(0);
2246
2996
}
2247
2997
 
2248
2998
/*
2267
3017
      We only update the saved position if the old one was undefined,
2268
3018
      the reason is that there are some cases (e.g., for CREATE-SELECT)
2269
3019
      where the position is saved twice (e.g., both in
2270
 
      select_create::prepare() and Session::binlog_write_table_map()) , but
 
3020
      select_create::prepare() and THD::binlog_write_table_map()) , but
2271
3021
      we should use the first. This means that calls to this function
2272
3022
      can be used to start the statement before the first table map
2273
3023
      event, to include some extra events.
2274
3024
 */
2275
3025
 
2276
3026
void
2277
 
Session::binlog_start_trans_and_stmt()
 
3027
THD::binlog_start_trans_and_stmt()
2278
3028
{
2279
 
  binlog_trx_data *trx_data= (binlog_trx_data*) session_get_ha_data(this, binlog_hton);
 
3029
  binlog_trx_data *trx_data= (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
 
3030
  DBUG_ENTER("binlog_start_trans_and_stmt");
 
3031
  DBUG_PRINT("enter", ("trx_data: 0x%lx  trx_data->before_stmt_pos: %lu",
 
3032
                       (long) trx_data,
 
3033
                       (trx_data ? (ulong) trx_data->before_stmt_pos :
 
3034
                        (ulong) 0)));
2280
3035
 
2281
3036
  if (trx_data == NULL ||
2282
3037
      trx_data->before_stmt_pos == MY_OFF_T_UNDEF)
2283
3038
  {
2284
3039
    this->binlog_set_stmt_begin();
2285
3040
    if (options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
2286
 
      trans_register_ha(this, true, binlog_hton);
2287
 
    trans_register_ha(this, false, binlog_hton);
 
3041
      trans_register_ha(this, TRUE, binlog_hton);
 
3042
    trans_register_ha(this, FALSE, binlog_hton);
2288
3043
    /*
2289
3044
      Mark statement transaction as read/write. We never start
2290
3045
      a binary log transaction and keep it read-only,
2296
3051
    */
2297
3052
    ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
2298
3053
  }
2299
 
  return;
 
3054
  DBUG_VOID_RETURN;
2300
3055
}
2301
3056
 
2302
 
void Session::binlog_set_stmt_begin() {
 
3057
void THD::binlog_set_stmt_begin() {
2303
3058
  binlog_trx_data *trx_data=
2304
 
    (binlog_trx_data*) session_get_ha_data(this, binlog_hton);
 
3059
    (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2305
3060
 
2306
3061
  /*
2307
3062
    The call to binlog_trans_log_savepos() might create the trx_data
2311
3066
  */
2312
3067
  my_off_t pos= 0;
2313
3068
  binlog_trans_log_savepos(this, &pos);
2314
 
  trx_data= (binlog_trx_data*) session_get_ha_data(this, binlog_hton);
 
3069
  trx_data= (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2315
3070
  trx_data->before_stmt_pos= pos;
2316
3071
}
2317
3072
 
2320
3075
  Write a table map to the binary log.
2321
3076
 */
2322
3077
 
2323
 
int Session::binlog_write_table_map(Table *table, bool is_trans)
 
3078
int THD::binlog_write_table_map(TABLE *table, bool is_trans)
2324
3079
{
2325
3080
  int error;
 
3081
  DBUG_ENTER("THD::binlog_write_table_map");
 
3082
  DBUG_PRINT("enter", ("table: 0x%lx  (%s: #%lu)",
 
3083
                       (long) table, table->s->table_name.str,
 
3084
                       table->s->table_map_id));
2326
3085
 
2327
3086
  /* Pre-conditions */
2328
 
  assert(current_stmt_binlog_row_based && mysql_bin_log.is_open());
2329
 
  assert(table->s->table_map_id != UINT32_MAX);
 
3087
  DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
 
3088
  DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
2330
3089
 
2331
3090
  Table_map_log_event::flag_set const
2332
3091
    flags= Table_map_log_event::TM_NO_FLAGS;
2338
3097
    binlog_start_trans_and_stmt();
2339
3098
 
2340
3099
  if ((error= mysql_bin_log.write(&the_event)))
2341
 
    return(error);
 
3100
    DBUG_RETURN(error);
2342
3101
 
2343
3102
  binlog_table_maps++;
2344
3103
  table->s->table_map_version= mysql_bin_log.table_map_version();
2345
 
  return(0);
 
3104
  DBUG_RETURN(0);
2346
3105
}
2347
3106
 
2348
3107
Rows_log_event*
2349
 
Session::binlog_get_pending_rows_event() const
 
3108
THD::binlog_get_pending_rows_event() const
2350
3109
{
2351
3110
  binlog_trx_data *const trx_data=
2352
 
    (binlog_trx_data*) session_get_ha_data(this, binlog_hton);
 
3111
    (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2353
3112
  /*
2354
3113
    This is less than ideal, but here's the story: If there is no
2355
3114
    trx_data, prepare_pending_rows_event() has never been called
2360
3119
}
2361
3120
 
2362
3121
void
2363
 
Session::binlog_set_pending_rows_event(Rows_log_event* ev)
 
3122
THD::binlog_set_pending_rows_event(Rows_log_event* ev)
2364
3123
{
2365
 
  if (session_get_ha_data(this, binlog_hton) == NULL)
 
3124
  if (thd_get_ha_data(this, binlog_hton) == NULL)
2366
3125
    binlog_setup_trx_data();
2367
3126
 
2368
3127
  binlog_trx_data *const trx_data=
2369
 
    (binlog_trx_data*) session_get_ha_data(this, binlog_hton);
 
3128
    (binlog_trx_data*) thd_get_ha_data(this, binlog_hton);
2370
3129
 
2371
 
  assert(trx_data);
 
3130
  DBUG_ASSERT(trx_data);
2372
3131
  trx_data->set_pending(ev);
2373
3132
}
2374
3133
 
2379
3138
  event.
2380
3139
*/
2381
3140
int
2382
 
DRIZZLE_BIN_LOG::flush_and_set_pending_rows_event(Session *session,
 
3141
MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
2383
3142
                                                Rows_log_event* event)
2384
3143
{
2385
 
  assert(mysql_bin_log.is_open());
 
3144
  DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)");
 
3145
  DBUG_ASSERT(mysql_bin_log.is_open());
 
3146
  DBUG_PRINT("enter", ("event: 0x%lx", (long) event));
2386
3147
 
2387
3148
  int error= 0;
2388
3149
 
2389
3150
  binlog_trx_data *const trx_data=
2390
 
    (binlog_trx_data*) session_get_ha_data(session, binlog_hton);
2391
 
 
2392
 
  assert(trx_data);
 
3151
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
 
3152
 
 
3153
  DBUG_ASSERT(trx_data);
 
3154
 
 
3155
  DBUG_PRINT("info", ("trx_data->pending(): 0x%lx", (long) trx_data->pending()));
2393
3156
 
2394
3157
  if (Rows_log_event* pending= trx_data->pending())
2395
3158
  {
2416
3179
    if (pending->write(file))
2417
3180
    {
2418
3181
      pthread_mutex_unlock(&LOCK_log);
2419
 
      return(1);
 
3182
      DBUG_RETURN(1);
2420
3183
    }
2421
3184
 
2422
3185
    /*
2452
3215
    pthread_mutex_unlock(&LOCK_log);
2453
3216
  }
2454
3217
 
2455
 
  session->binlog_set_pending_rows_event(event);
 
3218
  thd->binlog_set_pending_rows_event(event);
2456
3219
 
2457
 
  return(error);
 
3220
  DBUG_RETURN(error);
2458
3221
}
2459
3222
 
2460
3223
/**
2461
3224
  Write an event to the binary log.
2462
3225
*/
2463
3226
 
2464
 
bool DRIZZLE_BIN_LOG::write(Log_event *event_info)
 
3227
bool MYSQL_BIN_LOG::write(Log_event *event_info)
2465
3228
{
2466
 
  Session *session= event_info->session;
 
3229
  THD *thd= event_info->thd;
2467
3230
  bool error= 1;
 
3231
  DBUG_ENTER("MYSQL_BIN_LOG::write(Log_event *)");
2468
3232
 
2469
 
  if (session->binlog_evt_union.do_union)
 
3233
  if (thd->binlog_evt_union.do_union)
2470
3234
  {
2471
3235
    /*
2472
3236
      In Stored function; Remember that function call caused an update.
2473
3237
      We will log the function call to the binary log on function exit
2474
3238
    */
2475
 
    session->binlog_evt_union.unioned_events= true;
2476
 
    session->binlog_evt_union.unioned_events_trans |= event_info->cache_stmt;
2477
 
    return(0);
 
3239
    thd->binlog_evt_union.unioned_events= TRUE;
 
3240
    thd->binlog_evt_union.unioned_events_trans |= event_info->cache_stmt;
 
3241
    DBUG_RETURN(0);
2478
3242
  }
2479
3243
 
2480
3244
  /*
2488
3252
    this will close all tables on the slave.
2489
3253
  */
2490
3254
  bool const end_stmt= false;
2491
 
  session->binlog_flush_pending_rows_event(end_stmt);
 
3255
  thd->binlog_flush_pending_rows_event(end_stmt);
2492
3256
 
2493
3257
  pthread_mutex_lock(&LOCK_log);
2494
3258
 
2506
3270
      binlog_[wild_]{do|ignore}_table?" (WL#1049)"
2507
3271
    */
2508
3272
    const char *local_db= event_info->get_db();
2509
 
    if ((session && !(session->options & OPTION_BIN_LOG)) ||
 
3273
    if ((thd && !(thd->options & OPTION_BIN_LOG)) ||
2510
3274
        (!binlog_filter->db_ok(local_db)))
2511
3275
    {
2512
 
      pthread_mutex_unlock(&LOCK_log);
2513
 
      return(0);
 
3276
      VOID(pthread_mutex_unlock(&LOCK_log));
 
3277
      DBUG_RETURN(0);
2514
3278
    }
2515
3279
 
2516
3280
    /*
2522
3286
     trans/non-trans table types the best possible in binlogging)
2523
3287
      - or if the event asks for it (cache_stmt == TRUE).
2524
3288
    */
2525
 
    if (opt_using_transactions && session)
 
3289
    if (opt_using_transactions && thd)
2526
3290
    {
2527
 
      if (session->binlog_setup_trx_data())
 
3291
      if (thd->binlog_setup_trx_data())
2528
3292
        goto err;
2529
3293
 
2530
3294
      binlog_trx_data *const trx_data=
2531
 
        (binlog_trx_data*) session_get_ha_data(session, binlog_hton);
 
3295
        (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
2532
3296
      IO_CACHE *trans_log= &trx_data->trans_log;
2533
3297
      my_off_t trans_log_pos= my_b_tell(trans_log);
2534
3298
      if (event_info->get_cache_stmt() || trans_log_pos != 0)
2535
3299
      {
 
3300
        DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu",
 
3301
                            event_info->get_cache_stmt(),
 
3302
                            (ulong) trans_log_pos));
2536
3303
        if (trans_log_pos == 0)
2537
 
          session->binlog_start_trans_and_stmt();
 
3304
          thd->binlog_start_trans_and_stmt();
2538
3305
        file= trans_log;
2539
3306
      }
2540
3307
      /*
2544
3311
        LOCK_log.
2545
3312
      */
2546
3313
    }
 
3314
    DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
2547
3315
 
2548
3316
    /*
2549
3317
      No check for auto events flag here - this write method should
2559
3327
      If row-based binlogging, Insert_id, Rand and other kind of "setting
2560
3328
      context" events are not needed.
2561
3329
    */
2562
 
    if (session)
 
3330
    if (thd)
2563
3331
    {
2564
 
      if (!session->current_stmt_binlog_row_based)
 
3332
      if (!thd->current_stmt_binlog_row_based)
2565
3333
      {
2566
 
        if (session->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
 
3334
        if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
2567
3335
        {
2568
 
          Intvar_log_event e(session,(unsigned char) LAST_INSERT_ID_EVENT,
2569
 
                             session->first_successful_insert_id_in_prev_stmt_for_binlog);
 
3336
          Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
 
3337
                             thd->first_successful_insert_id_in_prev_stmt_for_binlog);
2570
3338
          if (e.write(file))
2571
3339
            goto err;
2572
3340
        }
2573
 
        if (session->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
 
3341
        if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
2574
3342
        {
 
3343
          DBUG_PRINT("info",("number of auto_inc intervals: %u",
 
3344
                             thd->auto_inc_intervals_in_cur_stmt_for_binlog.
 
3345
                             nb_elements()));
2575
3346
          /*
2576
3347
            If the auto_increment was second in a table's index (possible with
2577
3348
            MyISAM or BDB) (table->next_number_keypart != 0), such event is
2578
3349
            in fact not necessary. We could avoid logging it.
2579
3350
          */
2580
 
          Intvar_log_event e(session, (unsigned char) INSERT_ID_EVENT,
2581
 
                             session->auto_inc_intervals_in_cur_stmt_for_binlog.
 
3351
          Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT,
 
3352
                             thd->auto_inc_intervals_in_cur_stmt_for_binlog.
2582
3353
                             minimum());
2583
3354
          if (e.write(file))
2584
3355
            goto err;
2585
3356
        }
2586
 
        if (session->rand_used)
 
3357
        if (thd->rand_used)
2587
3358
        {
2588
 
          Rand_log_event e(session,session->rand_saved_seed1,session->rand_saved_seed2);
 
3359
          Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
2589
3360
          if (e.write(file))
2590
3361
            goto err;
2591
3362
        }
2592
 
        if (session->user_var_events.elements)
 
3363
        if (thd->user_var_events.elements)
2593
3364
        {
2594
 
          for (uint32_t i= 0; i < session->user_var_events.elements; i++)
 
3365
          for (uint i= 0; i < thd->user_var_events.elements; i++)
2595
3366
          {
2596
3367
            BINLOG_USER_VAR_EVENT *user_var_event;
2597
 
            get_dynamic(&session->user_var_events,(unsigned char*) &user_var_event, i);
2598
 
            User_var_log_event e(session, user_var_event->user_var_event->name.str,
 
3368
            get_dynamic(&thd->user_var_events,(uchar*) &user_var_event, i);
 
3369
            User_var_log_event e(thd, user_var_event->user_var_event->name.str,
2599
3370
                                 user_var_event->user_var_event->name.length,
2600
3371
                                 user_var_event->value,
2601
3372
                                 user_var_event->length,
2639
3410
    ++m_table_map_version;
2640
3411
 
2641
3412
  pthread_mutex_unlock(&LOCK_log);
2642
 
  return(error);
 
3413
  DBUG_RETURN(error);
2643
3414
}
2644
3415
 
2645
3416
 
2649
3420
  return logger.error_log_print(level, format, args);
2650
3421
}
2651
3422
 
2652
 
void DRIZZLE_BIN_LOG::rotate_and_purge(uint32_t flags)
 
3423
 
 
3424
bool slow_log_print(THD *thd, const char *query, uint query_length,
 
3425
                    ulonglong current_utime)
 
3426
{
 
3427
  return logger.slow_log_print(thd, query, query_length, current_utime);
 
3428
}
 
3429
 
 
3430
 
 
3431
bool LOGGER::log_command(THD *thd, enum enum_server_command command)
 
3432
{
 
3433
  /*
 
3434
    Log command if we have at least one log event handler enabled and want
 
3435
    to log this king of commands
 
3436
  */
 
3437
  if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
 
3438
  {
 
3439
    if (thd->options & OPTION_LOG_OFF)
 
3440
    {
 
3441
      /* No logging */
 
3442
      return FALSE;
 
3443
    }
 
3444
 
 
3445
    return TRUE;
 
3446
  }
 
3447
 
 
3448
  return FALSE;
 
3449
}
 
3450
 
 
3451
 
 
3452
bool general_log_print(THD *thd, enum enum_server_command command,
 
3453
                       const char *format, ...)
 
3454
{
 
3455
  va_list args;
 
3456
  uint error= 0;
 
3457
 
 
3458
  /* Print the message to the buffer if we want to log this king of commands */
 
3459
  if (! logger.log_command(thd, command))
 
3460
    return FALSE;
 
3461
 
 
3462
  va_start(args, format);
 
3463
  error= logger.general_log_print(thd, command, format, args);
 
3464
  va_end(args);
 
3465
 
 
3466
  return error;
 
3467
}
 
3468
 
 
3469
bool general_log_write(THD *thd, enum enum_server_command command,
 
3470
                       const char *query, uint query_length)
 
3471
{
 
3472
  /* Write the message to the log if we want to log this king of commands */
 
3473
  if (logger.log_command(thd, command))
 
3474
    return logger.general_log_write(thd, command, query, query_length);
 
3475
 
 
3476
  return FALSE;
 
3477
}
 
3478
 
 
3479
void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
2653
3480
{
2654
3481
  if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
2655
3482
    pthread_mutex_lock(&LOCK_log);
2657
3484
      (my_b_tell(&log_file) >= (my_off_t) max_size))
2658
3485
  {
2659
3486
    new_file_without_locking();
 
3487
#ifdef HAVE_REPLICATION
2660
3488
    if (expire_logs_days)
2661
3489
    {
2662
3490
      time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
2663
3491
      if (purge_time >= 0)
2664
3492
        purge_logs_before_date(purge_time);
2665
3493
    }
 
3494
#endif
2666
3495
  }
2667
3496
  if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
2668
3497
    pthread_mutex_unlock(&LOCK_log);
2669
3498
}
2670
3499
 
2671
 
uint32_t DRIZZLE_BIN_LOG::next_file_id()
 
3500
uint MYSQL_BIN_LOG::next_file_id()
2672
3501
{
2673
 
  uint32_t res;
 
3502
  uint res;
2674
3503
  pthread_mutex_lock(&LOCK_log);
2675
3504
  res = file_id++;
2676
3505
  pthread_mutex_unlock(&LOCK_log);
2692
3521
    be reset as a READ_CACHE to be able to read the contents from it.
2693
3522
 */
2694
3523
 
2695
 
int DRIZZLE_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
 
3524
int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
2696
3525
{
2697
3526
  Mutex_sentry sentry(lock_log ? &LOCK_log : NULL);
2698
3527
 
2699
3528
  if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
2700
3529
    return ER_ERROR_ON_WRITE;
2701
 
  uint32_t length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
 
3530
  uint length= my_b_bytes_in_cache(cache), group, carry, hdr_offs;
2702
3531
  long val;
2703
 
  unsigned char header[LOG_EVENT_HEADER_LEN];
 
3532
  uchar header[LOG_EVENT_HEADER_LEN];
2704
3533
 
2705
3534
  /*
2706
3535
    The events in the buffer have incorrect end_log_pos data
2728
3557
    */
2729
3558
    if (unlikely(carry > 0))
2730
3559
    {
2731
 
      assert(carry < LOG_EVENT_HEADER_LEN);
 
3560
      DBUG_ASSERT(carry < LOG_EVENT_HEADER_LEN);
2732
3561
 
2733
3562
      /* assemble both halves */
2734
 
      memcpy(&header[carry], cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
 
3563
      memcpy(&header[carry], (char *)cache->read_pos, LOG_EVENT_HEADER_LEN - carry);
2735
3564
 
2736
3565
      /* fix end_log_pos */
2737
3566
      val= uint4korr(&header[LOG_POS_OFFSET]) + group;
2745
3574
        copy fixed second half of header to cache so the correct
2746
3575
        version will be written later.
2747
3576
      */
2748
 
      memcpy(cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
 
3577
      memcpy((char *)cache->read_pos, &header[carry], LOG_EVENT_HEADER_LEN - carry);
2749
3578
 
2750
3579
      /* next event header at ... */
2751
3580
      hdr_offs = uint4korr(&header[EVENT_LEN_OFFSET]) - carry;
2774
3603
        if (hdr_offs + LOG_EVENT_HEADER_LEN > length)
2775
3604
        {
2776
3605
          carry= length - hdr_offs;
2777
 
          memcpy(header, cache->read_pos + hdr_offs, carry);
 
3606
          memcpy(header, (char *)cache->read_pos + hdr_offs, carry);
2778
3607
          length= hdr_offs;
2779
3608
        }
2780
3609
        else
2781
3610
        {
2782
3611
          /* we've got a full event-header, and it came in one piece */
2783
3612
 
2784
 
          unsigned char *log_pos= (unsigned char *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
 
3613
          uchar *log_pos= (uchar *)cache->read_pos + hdr_offs + LOG_POS_OFFSET;
2785
3614
 
2786
3615
          /* fix end_log_pos */
2787
3616
          val= uint4korr(log_pos) + group;
2788
3617
          int4store(log_pos, val);
2789
3618
 
2790
3619
          /* next event header at ... */
2791
 
          log_pos= (unsigned char *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
 
3620
          log_pos= (uchar *)cache->read_pos + hdr_offs + EVENT_LEN_OFFSET;
2792
3621
          hdr_offs += uint4korr(log_pos);
2793
3622
 
2794
3623
        }
2811
3640
    cache->read_pos=cache->read_end;            // Mark buffer used up
2812
3641
  } while ((length= my_b_fill(cache)));
2813
3642
 
2814
 
  assert(carry == 0);
 
3643
  DBUG_ASSERT(carry == 0);
2815
3644
 
2816
3645
  if (sync_log)
2817
3646
    flush_and_sync();
2827
3656
  was updated in a transaction which was rolled back. This is to ensure
2828
3657
  that the same updates are run on the slave.
2829
3658
 
2830
 
  @param session
 
3659
  @param thd
2831
3660
  @param cache          The cache to copy to the binlog
2832
3661
  @param commit_event   The commit event to print after writing the
2833
3662
                        contents of the cache.
2840
3669
    'cache' needs to be reinitialized after this functions returns.
2841
3670
*/
2842
3671
 
2843
 
bool DRIZZLE_BIN_LOG::write(Session *session, IO_CACHE *cache, Log_event *commit_event)
 
3672
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
2844
3673
{
2845
 
  pthread_mutex_lock(&LOCK_log);
 
3674
  DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)");
 
3675
  VOID(pthread_mutex_lock(&LOCK_log));
2846
3676
 
2847
3677
  /* NULL would represent nothing to replicate after ROLLBACK */
2848
 
  assert(commit_event != NULL);
 
3678
  DBUG_ASSERT(commit_event != NULL);
2849
3679
 
2850
 
  assert(is_open());
 
3680
  DBUG_ASSERT(is_open());
2851
3681
  if (likely(is_open()))                       // Should always be true
2852
3682
  {
2853
3683
    /*
2861
3691
        transaction is either a BEGIN..COMMIT block or a single
2862
3692
        statement in autocommit mode.
2863
3693
      */
2864
 
      Query_log_event qinfo(session, STRING_WITH_LEN("BEGIN"), true, false);
 
3694
      Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
2865
3695
      /*
2866
3696
        Imagine this is rollback due to net timeout, after all
2867
3697
        statements of the transaction succeeded. Then we want a
2871
3701
        generated event, and as this event is generated late it would
2872
3702
        lead to false alarms.
2873
3703
 
2874
 
        This is safer than session->clear_error() against kills at shutdown.
 
3704
        This is safer than thd->clear_error() against kills at shutdown.
2875
3705
      */
2876
3706
      qinfo.error_code= 0;
2877
3707
      /*
2885
3715
      if (qinfo.write(&log_file))
2886
3716
        goto err;
2887
3717
 
 
3718
      DBUG_EXECUTE_IF("crash_before_writing_xid",
 
3719
                      {
 
3720
                        if ((write_error= write_cache(cache, false, true)))
 
3721
                          DBUG_PRINT("info", ("error writing binlog cache: %d",
 
3722
                                               write_error));
 
3723
                        DBUG_PRINT("info", ("crashing before writing xid"));
 
3724
                        abort();
 
3725
                      });
 
3726
 
2888
3727
      if ((write_error= write_cache(cache, false, false)))
2889
3728
        goto err;
2890
3729
 
2892
3731
        goto err;
2893
3732
      if (flush_and_sync())
2894
3733
        goto err;
 
3734
      DBUG_EXECUTE_IF("half_binlogged_transaction", abort(););
2895
3735
      if (cache->error)                         // Error on read
2896
3736
      {
2897
3737
        sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno);
2918
3758
    else
2919
3759
      rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
2920
3760
  }
2921
 
  pthread_mutex_unlock(&LOCK_log);
 
3761
  VOID(pthread_mutex_unlock(&LOCK_log));
2922
3762
 
2923
 
  return(0);
 
3763
  DBUG_RETURN(0);
2924
3764
 
2925
3765
err:
2926
3766
  if (!write_error)
2928
3768
    write_error= 1;
2929
3769
    sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
2930
3770
  }
2931
 
  pthread_mutex_unlock(&LOCK_log);
2932
 
  return(1);
 
3771
  VOID(pthread_mutex_unlock(&LOCK_log));
 
3772
  DBUG_RETURN(1);
2933
3773
}
2934
3774
 
2935
3775
 
2936
3776
/**
2937
3777
  Wait until we get a signal that the relay log has been updated
2938
3778
 
2939
 
  @param[in] session   a Session struct
 
3779
  @param[in] thd   a THD struct
2940
3780
  @note
2941
3781
    LOCK_log must be taken before calling this function.
2942
3782
    It will be released at the end of the function.
2943
3783
*/
2944
3784
 
2945
 
void DRIZZLE_BIN_LOG::wait_for_update_relay_log(Session* session)
 
3785
void MYSQL_BIN_LOG::wait_for_update_relay_log(THD* thd)
2946
3786
{
2947
3787
  const char *old_msg;
2948
 
  old_msg= session->enter_cond(&update_cond, &LOCK_log,
 
3788
  DBUG_ENTER("wait_for_update_relay_log");
 
3789
  old_msg= thd->enter_cond(&update_cond, &LOCK_log,
2949
3790
                           "Slave has read all relay log; " 
2950
3791
                           "waiting for the slave I/O "
2951
3792
                           "thread to update it" );
2952
3793
  pthread_cond_wait(&update_cond, &LOCK_log);
2953
 
  session->exit_cond(old_msg);
2954
 
  return;
 
3794
  thd->exit_cond(old_msg);
 
3795
  DBUG_VOID_RETURN;
2955
3796
}
2956
3797
 
2957
3798
 
2960
3801
  Applies to master only.
2961
3802
     
2962
3803
  NOTES
2963
 
  @param[in] session        a Session struct
 
3804
  @param[in] thd        a THD struct
2964
3805
  @param[in] timeout    a pointer to a timespec;
2965
3806
                        NULL means to wait w/o timeout.
2966
3807
  @retval    0          if got signalled on update
2971
3812
    LOCK_log is released by the caller.
2972
3813
*/
2973
3814
 
2974
 
int DRIZZLE_BIN_LOG::wait_for_update_bin_log(Session* session,
 
3815
int MYSQL_BIN_LOG::wait_for_update_bin_log(THD* thd,
2975
3816
                                           const struct timespec *timeout)
2976
3817
{
2977
3818
  int ret= 0;
2978
 
  const char* old_msg = session->get_proc_info();
2979
 
  old_msg= session->enter_cond(&update_cond, &LOCK_log,
 
3819
  const char* old_msg = thd->proc_info;
 
3820
  DBUG_ENTER("wait_for_update_bin_log");
 
3821
  old_msg= thd->enter_cond(&update_cond, &LOCK_log,
2980
3822
                           "Master has sent all binlog to slave; "
2981
3823
                           "waiting for binlog to be updated");
2982
3824
  if (!timeout)
2984
3826
  else
2985
3827
    ret= pthread_cond_timedwait(&update_cond, &LOCK_log,
2986
3828
                                const_cast<struct timespec *>(timeout));
2987
 
  return(ret);
 
3829
  DBUG_RETURN(ret);
2988
3830
}
2989
3831
 
2990
3832
 
3002
3844
    The internal structures are not freed until cleanup() is called
3003
3845
*/
3004
3846
 
3005
 
void DRIZZLE_BIN_LOG::close(uint32_t exiting)
 
3847
void MYSQL_BIN_LOG::close(uint exiting)
3006
3848
{                                       // One can't set log_type here!
 
3849
  DBUG_ENTER("MYSQL_BIN_LOG::close");
 
3850
  DBUG_PRINT("enter",("exiting: %d", (int) exiting));
3007
3851
  if (log_state == LOG_OPENED)
3008
3852
  {
 
3853
#ifdef HAVE_REPLICATION
3009
3854
    if (log_type == LOG_BIN && !no_auto_events &&
3010
3855
        (exiting & LOG_CLOSE_STOP_EVENT))
3011
3856
    {
3014
3859
      bytes_written+= s.data_written;
3015
3860
      signal_update();
3016
3861
    }
 
3862
#endif /* HAVE_REPLICATION */
3017
3863
 
3018
3864
    /* don't pwrite in a file opened with O_APPEND - it doesn't work */
3019
3865
    if (log_file.type == WRITE_CACHE && log_type == LOG_BIN)
3020
3866
    {
3021
3867
      my_off_t offset= BIN_LOG_HEADER_SIZE + FLAGS_OFFSET;
3022
 
      unsigned char flags= 0;            // clearing LOG_EVENT_BINLOG_IN_USE_F
3023
 
      assert(pwrite(log_file.file, &flags, 1, offset)==1);
 
3868
      uchar flags= 0;            // clearing LOG_EVENT_BINLOG_IN_USE_F
 
3869
      pwrite(log_file.file, &flags, 1, offset);
3024
3870
    }
3025
3871
 
3026
3872
    /* this will cleanup IO_CACHE, sync and close the file */
3027
 
    DRIZZLE_LOG::close(exiting);
 
3873
    MYSQL_LOG::close(exiting);
3028
3874
  }
3029
3875
 
3030
3876
  /*
3042
3888
    }
3043
3889
  }
3044
3890
  log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
3045
 
  if (name)
3046
 
  {
3047
 
    free(name);
3048
 
    name= NULL;
3049
 
  }
3050
 
  return;
 
3891
  safeFree(name);
 
3892
  DBUG_VOID_RETURN;
3051
3893
}
3052
3894
 
3053
3895
 
3054
 
void DRIZZLE_BIN_LOG::set_max_size(ulong max_size_arg)
 
3896
void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg)
3055
3897
{
3056
3898
  /*
3057
3899
    We need to take locks, otherwise this may happen:
3060
3902
    uses the old_max_size argument, so max_size_arg has been overwritten and
3061
3903
    it's like if the SET command was never run.
3062
3904
  */
 
3905
  DBUG_ENTER("MYSQL_BIN_LOG::set_max_size");
3063
3906
  pthread_mutex_lock(&LOCK_log);
3064
3907
  if (is_open())
3065
3908
    max_size= max_size_arg;
3066
3909
  pthread_mutex_unlock(&LOCK_log);
3067
 
  return;
 
3910
  DBUG_VOID_RETURN;
3068
3911
}
3069
3912
 
3070
3913
 
3090
3933
{
3091
3934
  register int flag;
3092
3935
  const char *start;
 
3936
  DBUG_ENTER("test_if_number");
3093
3937
 
3094
3938
  flag= 0; 
3095
3939
  start= str;
3110
3954
         str++, flag=1) ;
3111
3955
  }
3112
3956
  if (*str != 0 || flag == 0)
3113
 
    return(0);
 
3957
    DBUG_RETURN(0);
3114
3958
  if (res)
3115
3959
    *res=atol(start);
3116
 
  return(1);                    /* Number ok */
 
3960
  DBUG_RETURN(1);                       /* Number ok */
3117
3961
} /* test_if_number */
3118
3962
 
3119
3963
 
3120
3964
void sql_perror(const char *message)
3121
3965
{
 
3966
#ifdef HAVE_STRERROR
3122
3967
  sql_print_error("%s: %s",message, strerror(errno));
 
3968
#else
 
3969
  perror(message);
 
3970
#endif
3123
3971
}
3124
3972
 
3125
3973
 
3130
3978
  {
3131
3979
    char err_renamed[FN_REFLEN], *end;
3132
3980
    end= strmake(err_renamed,log_error_file,FN_REFLEN-4);
3133
 
    my_stpcpy(end, "-old");
3134
 
    pthread_mutex_lock(&LOCK_error_log);
 
3981
    strmov(end, "-old");
 
3982
    VOID(pthread_mutex_lock(&LOCK_error_log));
3135
3983
    char err_temp[FN_REFLEN+4];
3136
3984
    /*
3137
3985
     On Windows is necessary a temporary file for to rename
3138
3986
     the current error file.
3139
3987
    */
3140
 
    strxmov(err_temp, err_renamed,"-tmp",NULL);
 
3988
    strxmov(err_temp, err_renamed,"-tmp",NullS);
3141
3989
    (void) my_delete(err_temp, MYF(0)); 
3142
3990
    if (freopen(err_temp,"a+",stdout))
3143
3991
    {
3144
3992
      int fd;
3145
3993
      size_t bytes;
3146
 
      unsigned char buf[IO_SIZE];
 
3994
      uchar buf[IO_SIZE];
3147
3995
 
3148
 
      if(freopen(err_temp,"a+",stderr)==NULL)
3149
 
        return 1;
 
3996
      freopen(err_temp,"a+",stderr);
3150
3997
      (void) my_delete(err_renamed, MYF(0));
3151
3998
      my_rename(log_error_file,err_renamed,MYF(0));
3152
 
      if (freopen(log_error_file,"a+",stdout)==NULL)
3153
 
        return 1;
3154
 
      else
3155
 
        if(freopen(log_error_file,"a+",stderr)==NULL)
3156
 
          return 1;
 
3999
      if (freopen(log_error_file,"a+",stdout))
 
4000
        freopen(log_error_file,"a+",stderr);
3157
4001
 
3158
4002
      if ((fd = my_open(err_temp, O_RDONLY, MYF(0))) >= 0)
3159
4003
      {
3166
4010
    }
3167
4011
    else
3168
4012
     result= 1;
3169
 
    pthread_mutex_unlock(&LOCK_error_log);
 
4013
    VOID(pthread_mutex_unlock(&LOCK_error_log));
3170
4014
  }
3171
4015
   return result;
3172
4016
}
3173
4017
 
3174
 
void DRIZZLE_BIN_LOG::signal_update()
 
4018
void MYSQL_BIN_LOG::signal_update()
3175
4019
{
 
4020
  DBUG_ENTER("MYSQL_BIN_LOG::signal_update");
3176
4021
  pthread_cond_broadcast(&update_cond);
3177
 
  return;
 
4022
  DBUG_VOID_RETURN;
3178
4023
}
3179
4024
 
3180
4025
/**
3194
4039
    return an error (e.g. logging to the log tables)
3195
4040
*/
3196
4041
static void print_buffer_to_file(enum loglevel level,
3197
 
                                 int error_code __attribute__((unused)),
 
4042
                                 int error_code __attribute__((__unused__)),
3198
4043
                                 const char *buffer,
3199
 
                                 size_t buffer_length __attribute__((unused)))
 
4044
                                 size_t buffer_length __attribute__((__unused__)))
3200
4045
{
3201
4046
  time_t skr;
3202
4047
  struct tm tm_tmp;
3203
4048
  struct tm *start;
 
4049
  DBUG_ENTER("print_buffer_to_file");
 
4050
  DBUG_PRINT("enter",("buffer: %s", buffer));
3204
4051
 
3205
 
  pthread_mutex_lock(&LOCK_error_log);
 
4052
  VOID(pthread_mutex_lock(&LOCK_error_log));
3206
4053
 
3207
4054
  skr= my_time(0);
3208
4055
  localtime_r(&skr, &tm_tmp);
3221
4068
 
3222
4069
  fflush(stderr);
3223
4070
 
3224
 
  pthread_mutex_unlock(&LOCK_error_log);
3225
 
  return;
 
4071
  VOID(pthread_mutex_unlock(&LOCK_error_log));
 
4072
  DBUG_VOID_RETURN;
3226
4073
}
3227
4074
 
3228
4075
 
3231
4078
  char   buff[1024];
3232
4079
  size_t length;
3233
4080
  int error_code= errno;
 
4081
  DBUG_ENTER("vprint_msg_to_log");
3234
4082
 
3235
4083
  length= vsnprintf(buff, sizeof(buff), format, args);
3236
4084
 
3237
4085
  print_buffer_to_file(level, error_code, buff, length);
3238
4086
 
3239
 
  return(0);
 
4087
  DBUG_RETURN(0);
3240
4088
}
3241
4089
 
3242
4090
 
3243
4091
void sql_print_error(const char *format, ...) 
3244
4092
{
3245
4093
  va_list args;
 
4094
  DBUG_ENTER("sql_print_error");
3246
4095
 
3247
4096
  va_start(args, format);
3248
4097
  error_log_print(ERROR_LEVEL, format, args);
3249
4098
  va_end(args);
3250
4099
 
3251
 
  return;
 
4100
  DBUG_VOID_RETURN;
3252
4101
}
3253
4102
 
3254
4103
 
3255
4104
void sql_print_warning(const char *format, ...) 
3256
4105
{
3257
4106
  va_list args;
 
4107
  DBUG_ENTER("sql_print_warning");
3258
4108
 
3259
4109
  va_start(args, format);
3260
4110
  error_log_print(WARNING_LEVEL, format, args);
3261
4111
  va_end(args);
3262
4112
 
3263
 
  return;
 
4113
  DBUG_VOID_RETURN;
3264
4114
}
3265
4115
 
3266
4116
 
3267
4117
void sql_print_information(const char *format, ...) 
3268
4118
{
3269
4119
  va_list args;
 
4120
  DBUG_ENTER("sql_print_information");
3270
4121
 
3271
4122
  va_start(args, format);
3272
4123
  error_log_print(INFORMATION_LEVEL, format, args);
3273
4124
  va_end(args);
3274
4125
 
3275
 
  return;
 
4126
  DBUG_VOID_RETURN;
3276
4127
}
3277
4128
 
3278
4129
 
3327
4178
 
3328
4179
int TC_LOG_MMAP::open(const char *opt_name)
3329
4180
{
3330
 
  uint32_t i;
3331
 
  bool crashed= false;
 
4181
  uint i;
 
4182
  bool crashed=FALSE;
3332
4183
  PAGE *pg;
3333
4184
 
3334
 
  assert(total_ha_2pc > 1);
3335
 
  assert(opt_name && opt_name[0]);
 
4185
  DBUG_ASSERT(total_ha_2pc > 1);
 
4186
  DBUG_ASSERT(opt_name && opt_name[0]);
3336
4187
 
3337
 
  tc_log_page_size= getpagesize();
3338
 
  assert(TC_LOG_PAGE_SIZE % tc_log_page_size == 0);
 
4188
  tc_log_page_size= my_getpagesize();
 
4189
  DBUG_ASSERT(TC_LOG_PAGE_SIZE % tc_log_page_size == 0);
3339
4190
 
3340
4191
  fn_format(logname,opt_name,mysql_data_home,"",MY_UNPACK_FILENAME);
3341
4192
  if ((fd= my_open(logname, O_RDWR, MYF(0))) < 0)
3354
4205
  else
3355
4206
  {
3356
4207
    inited= 1;
3357
 
    crashed= true;
3358
 
    sql_print_information(_("Recovering after a crash using %s"), opt_name);
 
4208
    crashed= TRUE;
 
4209
    sql_print_information("Recovering after a crash using %s", opt_name);
3359
4210
    if (tc_heuristic_recover)
3360
4211
    {
3361
 
      sql_print_error(_("Cannot perform automatic crash recovery when "
3362
 
                      "--tc-heuristic-recover is used"));
 
4212
      sql_print_error("Cannot perform automatic crash recovery when "
 
4213
                      "--tc-heuristic-recover is used");
3363
4214
      goto err;
3364
4215
    }
3365
4216
    file_length= my_seek(fd, 0L, MY_SEEK_END, MYF(MY_WME+MY_FAE));
3367
4218
      goto err;
3368
4219
  }
3369
4220
 
3370
 
  data= (unsigned char *)my_mmap(0, (size_t)file_length, PROT_READ|PROT_WRITE,
 
4221
  data= (uchar *)my_mmap(0, (size_t)file_length, PROT_READ|PROT_WRITE,
3371
4222
                        MAP_NOSYNC|MAP_SHARED, fd, 0);
3372
4223
  if (data == MAP_FAILED)
3373
4224
  {
3377
4228
  inited=2;
3378
4229
 
3379
4230
  npages=(uint)file_length/tc_log_page_size;
3380
 
  assert(npages >= 3);             // to guarantee non-empty pool
 
4231
  DBUG_ASSERT(npages >= 3);             // to guarantee non-empty pool
3381
4232
  if (!(pages=(PAGE *)my_malloc(npages*sizeof(PAGE), MYF(MY_WME|MY_ZEROFILL))))
3382
4233
    goto err;
3383
4234
  inited=3;
3403
4254
      goto err;
3404
4255
 
3405
4256
  memcpy(data, tc_log_magic, sizeof(tc_log_magic));
3406
 
  data[sizeof(tc_log_magic)]= (unsigned char)total_ha_2pc;
 
4257
  data[sizeof(tc_log_magic)]= (uchar)total_ha_2pc;
3407
4258
  msync(data, tc_log_page_size, MS_SYNC);
3408
4259
  my_sync(fd, MYF(0));
3409
4260
  inited=5;
3511
4362
    threads waiting for a page, but then all these threads will be waiting
3512
4363
    for a fsync() anyway
3513
4364
 
3514
 
   If tc_log == DRIZZLE_LOG then tc_log writes transaction to binlog and
 
4365
   If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
3515
4366
   records XID in a special Xid_log_event.
3516
4367
   If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
3517
4368
   log.
3525
4376
    to the position in memory where xid was logged to.
3526
4377
*/
3527
4378
 
3528
 
int TC_LOG_MMAP::log_xid(Session *session __attribute__((unused)), my_xid xid)
 
4379
int TC_LOG_MMAP::log_xid(THD *thd __attribute__((__unused__)), my_xid xid)
3529
4380
{
3530
4381
  int err;
3531
4382
  PAGE *p;
3554
4405
  while (*p->ptr)
3555
4406
  {
3556
4407
    p->ptr++;
3557
 
    assert(p->ptr < p->end);               // because p->free > 0
 
4408
    DBUG_ASSERT(p->ptr < p->end);               // because p->free > 0
3558
4409
  }
3559
4410
 
3560
4411
  /* found! store xid there and mark the page dirty */
3561
 
  cookie= (ulong)((unsigned char *)p->ptr - data);      // can never be zero
 
4412
  cookie= (ulong)((uchar *)p->ptr - data);      // can never be zero
3562
4413
  *p->ptr++= xid;
3563
4414
  p->free--;
3564
4415
  p->state= DIRTY;
3587
4438
      goto done;                             // we're done
3588
4439
    }
3589
4440
  }                                          // page was not synced! do it now
3590
 
  assert(active == p && syncing == 0);
 
4441
  DBUG_ASSERT(active == p && syncing == 0);
3591
4442
  pthread_mutex_lock(&LOCK_active);
3592
4443
  syncing=p;                                 // place is vacant - take it
3593
4444
  active=0;                                  // page is not active anymore
3604
4455
{
3605
4456
  int err;
3606
4457
 
3607
 
  assert(syncing != active);
 
4458
  DBUG_ASSERT(syncing != active);
3608
4459
 
3609
4460
  /*
3610
4461
    sit down and relax - this can take a while...
3637
4488
  cookie points directly to the memory where xid was logged.
3638
4489
*/
3639
4490
 
3640
 
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid __attribute__((unused)))
 
4491
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid __attribute__((__unused__)))
3641
4492
{
3642
4493
  PAGE *p=pages+(cookie/tc_log_page_size);
3643
4494
  my_xid *x=(my_xid *)(data+cookie);
3644
4495
 
3645
 
  assert(*x == xid);
3646
 
  assert(x >= p->start && x < p->end);
 
4496
  DBUG_ASSERT(*x == xid);
 
4497
  DBUG_ASSERT(x >= p->start && x < p->end);
3647
4498
  *x=0;
3648
4499
 
3649
4500
  pthread_mutex_lock(&p->lock);
3650
4501
  p->free++;
3651
 
  assert(p->free <= p->size);
 
4502
  DBUG_ASSERT(p->free <= p->size);
3652
4503
  set_if_smaller(p->ptr, x);
3653
4504
  if (p->free == p->size)               // the page is completely empty
3654
4505
    statistic_decrement(tc_log_cur_pages_used, &LOCK_status);
3659
4510
 
3660
4511
void TC_LOG_MMAP::close()
3661
4512
{
3662
 
  uint32_t i;
 
4513
  uint i;
3663
4514
  switch (inited) {
3664
4515
  case 6:
3665
4516
    pthread_mutex_destroy(&LOCK_sync);
3677
4528
      pthread_cond_destroy(&pages[i].cond);
3678
4529
    }
3679
4530
  case 3:
3680
 
    free((unsigned char*)pages);
 
4531
    my_free((uchar*)pages, MYF(0));
3681
4532
  case 2:
3682
4533
    my_munmap((char*)data, (size_t)file_length);
3683
4534
  case 1:
3695
4546
 
3696
4547
  if (memcmp(data, tc_log_magic, sizeof(tc_log_magic)))
3697
4548
  {
3698
 
    sql_print_error(_("Bad magic header in tc log"));
 
4549
    sql_print_error("Bad magic header in tc log");
3699
4550
    goto err1;
3700
4551
  }
3701
4552
 
3705
4556
  */
3706
4557
  if (data[sizeof(tc_log_magic)] != total_ha_2pc)
3707
4558
  {
3708
 
    sql_print_error(_("Recovery failed! You must enable "
 
4559
    sql_print_error("Recovery failed! You must enable "
3709
4560
                    "exactly %d storage engines that support "
3710
 
                    "two-phase commit protocol"),
 
4561
                    "two-phase commit protocol",
3711
4562
                    data[sizeof(tc_log_magic)]);
3712
4563
    goto err1;
3713
4564
  }
3719
4570
  for ( ; p < end_p ; p++)
3720
4571
  {
3721
4572
    for (my_xid *x=p->start; x < p->end; x++)
3722
 
      if (*x && my_hash_insert(&xids, (unsigned char *)x))
 
4573
      if (*x && my_hash_insert(&xids, (uchar *)x))
3723
4574
        goto err2; // OOM
3724
4575
  }
3725
4576
 
3727
4578
    goto err2;
3728
4579
 
3729
4580
  hash_free(&xids);
3730
 
  memset(data, 0, (size_t)file_length);
 
4581
  bzero(data, (size_t)file_length);
3731
4582
  return 0;
3732
4583
 
3733
4584
err2:
3734
4585
  hash_free(&xids);
3735
4586
err1:
3736
 
  sql_print_error(_("Crash recovery failed. Either correct the problem "
 
4587
  sql_print_error("Crash recovery failed. Either correct the problem "
3737
4588
                  "(if it's, for example, out of memory error) and restart, "
3738
 
                  "or delete tc log and start drizzled with "
3739
 
                  "--tc-heuristic-recover={commit|rollback}"));
 
4589
                  "or delete tc log and start mysqld with "
 
4590
                  "--tc-heuristic-recover={commit|rollback}");
3740
4591
  return 1;
3741
4592
}
3742
4593
#endif
3763
4614
  if (!tc_heuristic_recover)
3764
4615
    return 0;
3765
4616
 
3766
 
  sql_print_information(_("Heuristic crash recovery mode"));
 
4617
  sql_print_information("Heuristic crash recovery mode");
3767
4618
  if (ha_recover(0))
3768
 
    sql_print_error(_("Heuristic crash recovery failed"));
3769
 
  sql_print_information(_("Please restart mysqld without --tc-heuristic-recover"));
 
4619
    sql_print_error("Heuristic crash recovery failed");
 
4620
  sql_print_information("Please restart mysqld without --tc-heuristic-recover");
3770
4621
  return 1;
3771
4622
}
3772
4623
 
3773
4624
/****** transaction coordinator log for 2pc - binlog() based solution ******/
3774
 
#define TC_LOG_BINLOG DRIZZLE_BIN_LOG
 
4625
#define TC_LOG_BINLOG MYSQL_BIN_LOG
3775
4626
 
3776
4627
/**
3777
4628
  @todo
3786
4637
  LOG_INFO log_info;
3787
4638
  int      error= 1;
3788
4639
 
3789
 
  assert(total_ha_2pc > 1);
3790
 
  assert(opt_name && opt_name[0]);
 
4640
  DBUG_ASSERT(total_ha_2pc > 1);
 
4641
  DBUG_ASSERT(opt_name && opt_name[0]);
3791
4642
 
3792
4643
  pthread_mutex_init(&LOCK_prep_xids, MY_MUTEX_INIT_FAST);
3793
4644
  pthread_cond_init (&COND_prep_xids, 0);
3807
4658
    return 1;
3808
4659
  }
3809
4660
 
3810
 
  if ((error= find_log_pos(&log_info, NULL, 1)))
 
4661
  if ((error= find_log_pos(&log_info, NullS, 1)))
3811
4662
  {
3812
4663
    if (error != LOG_INFO_EOF)
3813
 
      sql_print_error(_("find_log_pos() failed (error: %d)"), error);
 
4664
      sql_print_error("find_log_pos() failed (error: %d)", error);
3814
4665
    else
3815
4666
      error= 0;
3816
4667
    goto err;
3834
4685
 
3835
4686
    if (error !=  LOG_INFO_EOF)
3836
4687
    {
3837
 
      sql_print_error(_("find_log_pos() failed (error: %d)"), error);
 
4688
      sql_print_error("find_log_pos() failed (error: %d)", error);
3838
4689
      goto err;
3839
4690
    }
3840
4691
 
3848
4699
        ev->get_type_code() == FORMAT_DESCRIPTION_EVENT &&
3849
4700
        ev->flags & LOG_EVENT_BINLOG_IN_USE_F)
3850
4701
    {
3851
 
      sql_print_information(_("Recovering after a crash using %s"), opt_name);
 
4702
      sql_print_information("Recovering after a crash using %s", opt_name);
3852
4703
      error= recover(&log, (Format_description_log_event *)ev);
3853
4704
    }
3854
4705
    else
3869
4720
/** This is called on shutdown, after ha_panic. */
3870
4721
void TC_LOG_BINLOG::close()
3871
4722
{
3872
 
  assert(prepared_xids==0);
 
4723
  DBUG_ASSERT(prepared_xids==0);
3873
4724
  pthread_mutex_destroy(&LOCK_prep_xids);
3874
4725
  pthread_cond_destroy (&COND_prep_xids);
3875
4726
}
3883
4734
  @retval
3884
4735
    1    success
3885
4736
*/
3886
 
int TC_LOG_BINLOG::log_xid(Session *session, my_xid xid)
 
4737
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
3887
4738
{
3888
 
  Xid_log_event xle(session, xid);
 
4739
  DBUG_ENTER("TC_LOG_BINLOG::log");
 
4740
  Xid_log_event xle(thd, xid);
3889
4741
  binlog_trx_data *trx_data=
3890
 
    (binlog_trx_data*) session_get_ha_data(session, binlog_hton);
 
4742
    (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
3891
4743
  /*
3892
4744
    We always commit the entire transaction when writing an XID. Also
3893
4745
    note that the return value is inverted.
3894
4746
   */
3895
 
  return(!binlog_end_trans(session, trx_data, &xle, true));
 
4747
  DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle, TRUE));
3896
4748
}
3897
4749
 
3898
 
void TC_LOG_BINLOG::unlog(ulong cookie __attribute__((unused)),
3899
 
                          my_xid xid __attribute__((unused)))
 
4750
void TC_LOG_BINLOG::unlog(ulong cookie __attribute__((__unused__)),
 
4751
                          my_xid xid __attribute__((__unused__)))
3900
4752
{
3901
4753
  pthread_mutex_lock(&LOCK_prep_xids);
3902
 
  assert(prepared_xids > 0);
 
4754
  DBUG_ASSERT(prepared_xids > 0);
3903
4755
  if (--prepared_xids == 0) {
 
4756
    DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
3904
4757
    pthread_cond_signal(&COND_prep_xids);
3905
4758
  }
3906
4759
  pthread_mutex_unlock(&LOCK_prep_xids);
3927
4780
    if (ev->get_type_code() == XID_EVENT)
3928
4781
    {
3929
4782
      Xid_log_event *xev=(Xid_log_event *)ev;
3930
 
      unsigned char *x= (unsigned char *) memdup_root(&mem_root, (unsigned char*) &xev->xid,
 
4783
      uchar *x= (uchar *) memdup_root(&mem_root, (uchar*) &xev->xid,
3931
4784
                                      sizeof(xev->xid));
3932
4785
      if (! x)
3933
4786
        goto err2;
3947
4800
  free_root(&mem_root, MYF(0));
3948
4801
  hash_free(&xids);
3949
4802
err1:
3950
 
  sql_print_error(_("Crash recovery failed. Either correct the problem "
 
4803
  sql_print_error("Crash recovery failed. Either correct the problem "
3951
4804
                  "(if it's, for example, out of memory error) and restart, "
3952
4805
                  "or delete (or rename) binary log and start mysqld with "
3953
 
                  "--tc-heuristic-recover={commit|rollback}"));
 
4806
                  "--tc-heuristic-recover={commit|rollback}");
3954
4807
  return 1;
3955
4808
}
3956
4809
 
3970
4823
  @return byte offset from the beginning of the binlog
3971
4824
*/
3972
4825
extern "C"
3973
 
uint64_t mysql_bin_log_file_pos(void)
 
4826
ulonglong mysql_bin_log_file_pos(void)
3974
4827
{
3975
 
  return (uint64_t) mysql_bin_log.get_log_file()->pos_in_file;
 
4828
  return (ulonglong) mysql_bin_log.get_log_file()->pos_in_file;
3976
4829
}
3977
4830
#endif /* INNODB_COMPATIBILITY_HOOKS */
3978
4831
 
3979
4832
 
 
4833
struct st_mysql_storage_engine binlog_storage_engine=
 
4834
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
 
4835
 
3980
4836
mysql_declare_plugin(binlog)
3981
4837
{
3982
 
  DRIZZLE_STORAGE_ENGINE_PLUGIN,
 
4838
  MYSQL_STORAGE_ENGINE_PLUGIN,
 
4839
  &binlog_storage_engine,
3983
4840
  "binlog",
3984
 
  "1.0",
3985
4841
  "MySQL AB",
3986
4842
  "This is a pseudo storage engine to represent the binlog in a transaction",
3987
4843
  PLUGIN_LICENSE_GPL,
3988
4844
  binlog_init, /* Plugin Init */
3989
4845
  NULL, /* Plugin Deinit */
 
4846
  0x0100 /* 1.0 */,
3990
4847
  NULL,                       /* status variables                */
3991
4848
  NULL,                       /* system variables                */
3992
4849
  NULL                        /* config options                  */