Commit be255d65 authored by unknown's avatar unknown
Browse files

open binlog index file *before* tc_log->open() and binlog itself *after*


sql/mysql_priv.h:
  checkpoint: open_log() removed
sql/sql_yacc.yy:
  checkpoint: open_log() removed
sql/log.cc:
  split the opening of the .index file and binlog itself - now they are done by separate functions
sql/slave.cc:
  init_relay_log_info() made static
  split the opening of the .index file and binlog itself - now they are done by separate functions
sql/slave.h:
  init_relay_log_info() made static
sql/sql_class.h:
  split the opening of the .index file and binlog itself - now they are done by separate functions
parent 24e1d1c8
Loading
Loading
Loading
Loading
+129 −90
Original line number Diff line number Diff line
@@ -421,6 +421,67 @@ void MYSQL_LOG::init_pthread_objects()
  (void) pthread_cond_init(&update_cond, 0);
}

const char *MYSQL_LOG::generate_name(const char *log_name,
                                     const char *suffix,
                                     bool strip_ext, char *buff)
{
  DBUG_ASSERT(!strip_ext || (log_name && log_name[0]));
  if (!log_name || !log_name[0])
  {
    /*
      TODO: The following should be using fn_format();  We just need to
      first change fn_format() to cut the file name if it's too long.
    */
    strmake(buff,glob_hostname,FN_REFLEN-5);
    strmov(fn_ext(buff),suffix);
    return (const char *)buff;
  }
  // get rid of extension if the log is binary to avoid problems
  if (strip_ext)
  {
    char *p = fn_ext(log_name);
    uint length=(uint) (p-log_name);
    strmake(buff,log_name,min(length,FN_REFLEN));
    return (const char*)buff;
  }
  return log_name;
}

bool MYSQL_LOG::open_index_file(const char *index_file_name_arg,
                                const char *log_name)
{
  File index_file_nr= -1;
  DBUG_ASSERT(!my_b_inited(&index_file));

  /*
    First open of this class instance
    Create an index file that will hold all file names uses for logging.
    Add new entries to the end of it.
  */
  myf opt= MY_UNPACK_FILENAME;
  if (!index_file_name_arg)
  {
    index_file_name_arg= log_name;    // Use same basename for index file
    opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT;
  }
  fn_format(index_file_name, index_file_name_arg, mysql_data_home,
            ".index", opt);
  if ((index_file_nr= my_open(index_file_name,
                              O_RDWR | O_CREAT | O_BINARY ,
                              MYF(MY_WME))) < 0 ||
       my_sync(index_file_nr, MYF(MY_WME)) ||
       init_io_cache(&index_file, index_file_nr,
                     IO_SIZE, WRITE_CACHE,
                     my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
                     0, MYF(MY_WME)))
  {
    if (index_file_nr >= 0)
      my_close(index_file_nr,MYF(0));
    return TRUE;
  }
  return FALSE;
}


/*
  Open a (new) log file.
@@ -436,18 +497,19 @@ void MYSQL_LOG::init_pthread_objects()
    1	error
*/

bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
		     const char *new_name, const char *index_file_name_arg,
bool MYSQL_LOG::open(const char *log_name,
                     enum_log_type log_type_arg,
                     const char *new_name,
                     enum cache_type io_cache_type_arg,
                     bool no_auto_events_arg,
                     ulong max_size_arg,
                     bool null_created_arg)
{
  char buff[512];
  File file= -1, index_file_nr= -1;
  char buff[FN_REFLEN];
  File file= -1;
  int open_flags = O_CREAT | O_BINARY;
  DBUG_ENTER("MYSQL_LOG::open");
  DBUG_PRINT("enter",("log_type: %d",(int) log_type));
  DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));

  last_time=query_start=0;
  write_error=0;
@@ -455,7 +517,10 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
  init(log_type_arg,io_cache_type_arg,no_auto_events_arg,max_size_arg);

  if (!(name=my_strdup(log_name,MYF(MY_WME))))
  {
    name= (char *)log_name; // for the error message
    goto err;
  }
  if (new_name)
    strmov(log_file_name,new_name);
  else if (generate_new_name(log_file_name, name))
@@ -521,13 +586,6 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
  {
    bool write_file_name_to_index_file=0;

    myf opt= MY_UNPACK_FILENAME;
    if (!index_file_name_arg)
    {
      index_file_name_arg= name;	// Use same basename for index file
      opt= MY_UNPACK_FILENAME | MY_REPLACE_EXT;
    }

    if (!my_b_filelength(&log_file))
    {
      /*
@@ -543,31 +601,9 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
      write_file_name_to_index_file= 1;
    }

    if (!my_b_inited(&index_file))
    {
      /*
	First open of this class instance
	Create an index file that will hold all file names uses for logging.
	Add new entries to the end of it.
      */
      fn_format(index_file_name, index_file_name_arg, mysql_data_home,
		".index", opt);
      if ((index_file_nr= my_open(index_file_name,
				  O_RDWR | O_CREAT | O_BINARY ,
				  MYF(MY_WME))) < 0 ||
          my_sync(index_file_nr, MYF(MY_WME)) ||
	  init_io_cache(&index_file, index_file_nr,
			IO_SIZE, WRITE_CACHE,
			my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)),
			0, MYF(MY_WME)))
	goto err;
    }
    else
    {
      safe_mutex_assert_owner(&LOCK_index);
      reinit_io_cache(&index_file, WRITE_CACHE, my_b_filelength(&index_file),
		      0, 0);
    }
    DBUG_ASSERT(my_b_inited(&index_file));
    reinit_io_cache(&index_file, WRITE_CACHE,
                    my_b_filelength(&index_file), 0, 0);
    if (need_start_event && !no_auto_events)
    {
      /*
@@ -644,11 +680,9 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
  sql_print_error("Could not use %s for logging (error %d). \
Turning logging off for the whole duration of the MySQL server process. \
To turn it on again: fix the cause, \
shutdown the MySQL server and restart it.", log_name, errno);
shutdown the MySQL server and restart it.", name, errno);
  if (file >= 0)
    my_close(file,MYF(0));
  if (index_file_nr >= 0)
    my_close(index_file_nr,MYF(0));
  end_io_cache(&log_file);
  end_io_cache(&index_file);
  safeFree(name);
@@ -754,8 +788,8 @@ int MYSQL_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
  DBUG_PRINT("enter",("log_name: %s", log_name ? log_name : "NULL"));

  /*
    Mutex needed because we need to make sure the file pointer does not move
    from under our feet
    Mutex needed because we need to make sure the file pointer does not
    move from under our feet
  */
  if (need_lock)
    pthread_mutex_lock(&LOCK_index);
@@ -907,7 +941,8 @@ bool MYSQL_LOG::reset_logs(THD* thd)
  my_delete(index_file_name, MYF(MY_WME));	// Reset (open will update)
  if (!thd->slave_thread)
    need_start_event=1;
  open(save_name, save_log_type, 0, index_file_name,
  open_index_file(index_file_name, 0);
  open(save_name, save_log_type, 0,
       io_cache_type, no_auto_events, max_size, 0);
  my_free((gptr) save_name, MYF(0));

@@ -1320,8 +1355,8 @@ void MYSQL_LOG::new_file(bool need_lock)
     trigger temp tables deletion on slaves.
  */

  open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type,
       no_auto_events, max_size, 1);
  open(old_name, save_log_type, new_name_ptr,
       io_cache_type, no_auto_events, max_size, 1);
  my_free(old_name,MYF(0));

end:
@@ -2433,7 +2468,7 @@ int TC_LOG_MMAP::open(const char *opt_name)
  bool crashed=FALSE;
  PAGE *pg;

  DBUG_ASSERT(total_ha_2pc);
  DBUG_ASSERT(total_ha_2pc > 1);
  DBUG_ASSERT(opt_name && opt_name[0]);

#ifdef HAVE_GETPAGESIZE
@@ -2824,6 +2859,18 @@ int TC_LOG_MMAP::recover()
  return 1;
}

/*
  Perform heuristic recovery, if --tc-heuristic-recover was used

  RETURN VALUE
    0	no heuristic recovery was requested
    1   heuristic recovery was performed

  NOTE
    no matter whether heuristic recovery was successful or not
    mysqld must exit. So, return value is the same in both cases.
*/

int TC_LOG::using_heuristic_recover()
{
  if (!tc_heuristic_recover)
@@ -2848,10 +2895,11 @@ int TC_LOG::using_heuristic_recover()

int TC_LOG_BINLOG::open(const char *opt_name)
{
  LOG_INFO log_info, new_log_info;
  int      error;
  LOG_INFO log_info;
  int      error= 1;

  DBUG_ASSERT(total_ha_2pc > 1);
  DBUG_ASSERT(opt_name && opt_name[0]);

  pthread_mutex_init(&LOCK_prep_xids, MY_MUTEX_INIT_FAST);
  pthread_cond_init (&COND_prep_xids, 0);
@@ -2859,21 +2907,15 @@ int TC_LOG_BINLOG::open(const char *opt_name)
  if (using_heuristic_recover())
    return 1;

  /*
    read index file to get a last but one binlog filename
    note - there's no need to lock any mutex, mysqld is only starting
    up, no other threads are running yet.
    still, there's safe_mutex_assert_owner() in binlog code, so
    let's keep it happy.
  */

  if ((error= find_log_pos(&new_log_info, NullS, 1)))
  if ((error= find_log_pos(&log_info, NullS, 1)))
  {
    if (error != LOG_INFO_EOF)
      sql_print_error("find_log_pos() failed (error: %d)", error);
    goto err;                           // er ? where's the current entry ?
    else
      error= 0;
    goto err;
  }

  if (strcmp(log_file_name, new_log_info.log_file_name))
  {
    const char *errmsg;
    char        last_event_type=UNKNOWN_EVENT;
@@ -2881,23 +2923,22 @@ int TC_LOG_BINLOG::open(const char *opt_name)
    File        file;
    Log_event  *ev=0;
    Format_description_log_event fdle(BINLOG_VERSION);
    char        log_name[FN_REFLEN];

    if (! fdle.is_valid())
      goto err;

    do
    for (error= 0; !error ;)
    {
      log_info.index_file_offset=new_log_info.index_file_offset;
      log_info.index_file_start_offset=new_log_info.index_file_offset;
      strcpy(log_info.log_file_name, new_log_info.log_file_name);
      if ((error= find_next_log(&new_log_info, 1)))
      strnmov(log_name, log_info.log_file_name, sizeof(log_name));
      if ((error= find_next_log(&log_info, 1)) != LOG_INFO_EOF)
      {
        sql_print_error("find_log_pos() failed (error: %d)", error);
        goto err;                  // er ? where's the current entry ?
        goto err;
      }
    }
    } while (strcmp(log_file_name, new_log_info.log_file_name));

    if ((file= open_binlog(&log, log_info.log_file_name, &errmsg)) < 0)
    if ((file= open_binlog(&log, log_name, &errmsg)) < 0)
    {
      sql_print_error("%s", errmsg);
      goto err;
@@ -2921,10 +2962,8 @@ int TC_LOG_BINLOG::open(const char *opt_name)
      goto err;
  }

  return 0;

err:
  return 1;
  return error;
}

/* this is called on shutdown, after ha_panic */
+0 −5
Original line number Diff line number Diff line
@@ -930,11 +930,6 @@ void sql_print_information(const char *format, ...);

bool fn_format_relative_to_data_home(my_string to, const char *name,
				     const char *dir, const char *extension);
bool open_log(MYSQL_LOG *log, const char *hostname,
	      const char *opt_name, const char *extension,
	      const char *index_file_name,
	      enum_log_type type, bool read_append,
	      bool no_auto_events, ulong max_size);
File open_binlog(IO_CACHE *log, const char *log_file_name,
                 const char **errmsg);
handlerton *binlog_init();
+25 −47
Original line number Diff line number Diff line
@@ -2297,37 +2297,6 @@ const char *load_default_groups[]= {
static const int load_default_groups_sz=
sizeof(load_default_groups)/sizeof(load_default_groups[0]);

bool open_log(MYSQL_LOG *log, const char *hostname,
	      const char *opt_name, const char *extension,
	      const char *index_file_name,
	      enum_log_type type, bool read_append,
	      bool no_auto_events, ulong max_size)
{
  char tmp[FN_REFLEN];
  if (!opt_name || !opt_name[0])
  {
    /*
      TODO: The following should be using fn_format();  We just need to
      first change fn_format() to cut the file name if it's too long.
    */
    strmake(tmp,hostname,FN_REFLEN-5);
    strmov(fn_ext(tmp),extension);
    opt_name=tmp;
  }
  // get rid of extension if the log is binary to avoid problems
  if (type == LOG_BIN)
  {
    char *p = fn_ext(opt_name);
    uint length=(uint) (p-opt_name);
    strmake(tmp,opt_name,min(length,FN_REFLEN));
    opt_name=tmp;
  }
  return log->open(opt_name, type, 0, index_file_name,
		   (read_append) ? SEQ_READ_APPEND : WRITE_CACHE,
		   no_auto_events, max_size, 0);
}


/*
  Initialize one of the global date/time format variables

@@ -2617,8 +2586,7 @@ static int init_server_components()
#endif
  /* Setup log files */
  if (opt_log)
    open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS,
	     LOG_NORMAL, 0, 0, 0);
    mysql_log.open_query_log(opt_logname);
  if (opt_update_log)
  {
    /*
@@ -2671,20 +2639,13 @@ version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
with --log-bin instead.");
    }
  }
  if (opt_bin_log)
  {
    open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin",
	     opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size);
    using_update_log=1;
  }
  else if (opt_log_slave_updates)
  if (opt_log_slave_updates && !opt_bin_log)
      sql_print_warning("\
you need to use --log-bin to make --log-slave-updates work. \
You need to use --log-bin to make --log-slave-updates work. \
Now disabling --log-slave-updates.");

  if (opt_slow_log)
    open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log",
             NullS, LOG_NORMAL, 0, 0, 0);
    mysql_slow_log.open_slow_log(opt_slow_logname);

#ifdef HAVE_REPLICATION
  if (opt_log_slave_updates && replicate_same_server_id)
@@ -2716,12 +2677,25 @@ server.");
    }
  }

  if (opt_bin_log)
  {
    char buf[FN_REFLEN];
    const char *ln;
    ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
    if (ln == buf)
    {
      my_free(opt_bin_logname, MYF(0));
      opt_bin_logname=my_strdup(buf, MYF(0));
    }
    mysql_bin_log.open_index_file(opt_binlog_index_name, ln);
    using_update_log=1;
  }

  if (ha_init())
    {
    sql_print_error("Can't init databases");
    unireg_abort(1);
  }

  tc_log= total_ha_2pc > 1 ? opt_bin_log  ?
                 (TC_LOG *)&mysql_bin_log :
                 (TC_LOG *)&tc_log_mmap   :
@@ -2733,6 +2707,10 @@ server.");
    unireg_abort(1);
  }

  if (opt_bin_log)
    mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
                       WRITE_CACHE, 0, max_binlog_size, 0);

#ifdef HAVE_REPLICATION
  if (opt_bin_log && expire_logs_days)
  {
+66 −69
Original line number Diff line number Diff line
@@ -1655,7 +1655,8 @@ void end_master_info(MASTER_INFO* mi)
}


int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
static int init_relay_log_info(RELAY_LOG_INFO* rli,
                               const char* info_fname)
{
  char fname[FN_REFLEN+128];
  int info_fd;
@@ -1674,23 +1675,10 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
  rli->log_space_limit= relay_log_space_limit;
  rli->log_space_total= 0;

  // TODO: make this work with multi-master
  if (!opt_relay_logname)
  {
    char tmp[FN_REFLEN];
    /*
      TODO: The following should be using fn_format();  We just need to
      first change fn_format() to cut the file name if it's too long.
    */
    strmake(tmp,glob_hostname,FN_REFLEN-5);
    strmov(strcend(tmp,'.'),"-relay-bin");
    opt_relay_logname=my_strdup(tmp,MYF(MY_WME));
  }

  /*
    The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE.
    Note that the I/O thread flushes it to disk after writing every event, in
    flush_master_info(mi, 1).
    Note that the I/O thread flushes it to disk after writing every
    event, in flush_master_info(mi, 1).
  */

  /*
@@ -1702,17 +1690,26 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname)
    switch to using max_binlog_size for the relay log) and update
    rli->relay_log.max_size (and mysql_bin_log.max_size).
  */
  {
    char buf[FN_REFLEN];
    const char *ln;
    ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
                                     1, buf);

  if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname,
	       "-relay-bin", opt_relaylog_index_name,
	       LOG_BIN, 1 /* read_append cache */,
	       0 /* starting from 5.0 we want relay logs to have auto events */,
               max_relay_log_size ? max_relay_log_size : max_binlog_size))
    /*
      note, that if open() fails, we'll still have index file open
      but a destructor will take care of that
    */
    if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln) ||
        rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0,
                            (max_relay_log_size ? max_relay_log_size :
                            max_binlog_size), 0))
    {
      pthread_mutex_unlock(&rli->data_lock);
      sql_print_error("Failed in open_log() called from init_relay_log_info()");
      DBUG_RETURN(1);
    }
  }

  /* if file does not exist */
  if (access(fname,F_OK))
+9 −10
Original line number Diff line number Diff line
@@ -523,7 +523,6 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
		     bool abort_if_no_master_info_file,
		     int thread_mask);
void end_master_info(MASTER_INFO* mi);
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
void end_relay_log_info(RELAY_LOG_INFO* rli);
void lock_slave_threads(MASTER_INFO* mi);
void unlock_slave_threads(MASTER_INFO* mi);
Loading