List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:November 14 2012 10:15am
Subject:bzr push into mysql-trunk-wl6613 branch (jon.hauglid:4987 to 4988) WL#6613
View as plain text  
 4988 Jon Olav Hauglid	2012-11-14
      WL#6613: Refactor logging code - split logging and binlogging code
      
      Remove MYSQL_LOG and move implementation to MYSQL_QUERY_LOG
      and MYSQL_BINARY_LOG.
      
      Move replication code out of log.h and log.cc.
      
      Remove dead code.
      
      Update log.h/log.cc according to current code standard.

    modified:
      sql/binlog.cc
      sql/binlog.h
      sql/log.cc
      sql/log.h
      sql/mysqld.cc
      sql/rpl_rli.cc
      sql/rpl_tblmap.h
      sql/sql_alter.cc
      sql/sql_class.h
      sql/sql_table.cc
      sql/sys_vars.cc
 4987 Jon Olav Hauglid	2012-11-14
      Change tree name

    modified:
      .bzr-mysql/default.conf
=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2012-11-13 18:27:55 +0000
+++ b/sql/binlog.cc	2012-11-14 10:15:19 +0000
@@ -31,6 +31,7 @@
 #include "rpl_mi.h"
 #include <list>
 #include <string>
+#include <m_ctype.h>				// For test_if_number
 
 using std::max;
 using std::min;
@@ -64,7 +65,7 @@ bool opt_binlog_order_commits= true;
 const char *log_bin_index= 0;
 const char *log_bin_basename= 0;
 
-MYSQL_BIN_LOG mysql_bin_log(&sync_binlog_period);
+MYSQL_BIN_LOG mysql_bin_log(&sync_binlog_period, WRITE_CACHE);
 
 static int binlog_init(void *p);
 static int binlog_start_trans_and_stmt(THD *thd, Log_event *start_event);
@@ -1629,6 +1630,35 @@ static int binlog_savepoint_rollback(han
   DBUG_RETURN(0);
 }
 
+/**
+   purge logs, master and slave sides both, related error code
+   convertor.
+   Called from @c purge_error_message(), @c MYSQL_BIN_LOG::reset_logs()
+
+   @param  res  an internal to purging routines error code 
+
+   @return the user level error code ER_*
+*/
+static uint purge_log_get_error_code(int res)
+{
+  uint errcode= 0;
+
+  switch (res)  {
+  case 0: break;
+  case LOG_INFO_EOF:	errcode= ER_UNKNOWN_TARGET_BINLOG; break;
+  case LOG_INFO_IO:	errcode= ER_IO_ERR_LOG_INDEX_READ; break;
+  case LOG_INFO_INVALID:errcode= ER_BINLOG_PURGE_PROHIBITED; break;
+  case LOG_INFO_SEEK:	errcode= ER_FSEEK_FAIL; break;
+  case LOG_INFO_MEM:	errcode= ER_OUT_OF_RESOURCES; break;
+  case LOG_INFO_FATAL:	errcode= ER_BINLOG_PURGE_FATAL_ERR; break;
+  case LOG_INFO_IN_USE: errcode= ER_LOG_IN_USE; break;
+  case LOG_INFO_EMFILE: errcode= ER_BINLOG_PURGE_EMFILE; break;
+  default:		errcode= ER_LOG_PURGE_UNKNOWN_ERR; break;
+  }
+
+  return errcode;
+}
+
 #ifdef HAVE_REPLICATION
 
 /*
@@ -2235,8 +2265,14 @@ bool mysql_show_binlog_events(THD* thd)
 #endif /* HAVE_REPLICATION */
 
 
-MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period)
-  :bytes_written(0), file_id(1), open_count(1),
+MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period,
+                             enum cache_type io_cache_type_arg)
+  :name(NULL), write_error(false), inited(false),
+   log_state(LOG_CLOSED), io_cache_type(io_cache_type_arg)
+#ifdef HAVE_PSI_INTERFACE
+   ,m_key_LOCK_log(key_LOG_LOCK_log),
+#endif
+   bytes_written(0), file_id(1), open_count(1),
    sync_period_ptr(sync_period), sync_counter(0),
    m_prep_xids(0),
    is_relay_log(0), signal_cnt(0),
@@ -2250,6 +2286,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_
     called only in main(). Doing initialization here would make it happen
     before main().
   */
+  memset(&log_file, 0, sizeof(log_file));
   index_file_name[0] = 0;
   memset(&index_file, 0, sizeof(index_file));
   memset(&purge_index_file, 0, sizeof(purge_index_file));
@@ -2280,7 +2317,9 @@ void MYSQL_BIN_LOG::cleanup()
 
 void MYSQL_BIN_LOG::init_pthread_objects()
 {
-  MYSQL_LOG::init_pthread_objects();
+  DBUG_ASSERT(inited == 0);
+  inited= 1;
+  mysql_mutex_init(m_key_LOCK_log, &LOCK_log, MY_MUTEX_INIT_SLOW);
   mysql_mutex_init(m_key_LOCK_index, &LOCK_index, MY_MUTEX_INIT_SLOW);
   mysql_mutex_init(m_key_LOCK_commit, &LOCK_commit, MY_MUTEX_INIT_FAST);
   mysql_mutex_init(m_key_LOCK_sync, &LOCK_sync, MY_MUTEX_INIT_FAST);
@@ -2297,6 +2336,310 @@ void MYSQL_BIN_LOG::init_pthread_objects
                    );
 }
 
+
+/**
+  Check if a string is a valid number.
+
+  @param str			String to test
+  @param res			Store value here
+  @param allow_wildcards	Set to 1 if we should ignore '%' and '_'
+
+  @note
+    For the moment the allow_wildcards argument is not used
+    Should be move to some other file.
+
+  @retval
+    1	String is a number
+  @retval
+    0	String is not a number
+*/
+
+static bool test_if_number(register const char *str,
+			   ulong *res, bool allow_wildcards)
+{
+  reg2 int flag;
+  const char *start;
+  DBUG_ENTER("test_if_number");
+
+  flag=0; start=str;
+  while (*str++ == ' ') ;
+  if (*--str == '-' || *str == '+')
+    str++;
+  while (my_isdigit(files_charset_info,*str) ||
+	 (allow_wildcards && (*str == wild_many || *str == wild_one)))
+  {
+    flag=1;
+    str++;
+  }
+  if (*str == '.')
+  {
+    for (str++ ;
+	 my_isdigit(files_charset_info,*str) ||
+	   (allow_wildcards && (*str == wild_many || *str == wild_one)) ;
+	 str++, flag=1) ;
+  }
+  if (*str != 0 || flag == 0)
+    DBUG_RETURN(0);
+  if (res)
+    *res=atol(start);
+  DBUG_RETURN(1);			/* Number ok */
+} /* test_if_number */
+
+
+/*
+  Maximum unique log filename extension.
+  Note: setting to 0x7FFFFFFF due to atol windows
+        overflow/truncate.
+ */
+#define MAX_LOG_UNIQUE_FN_EXT 0x7FFFFFFF
+
+/*
+   Number of warnings that will be printed to error log
+   before extension number is exhausted.
+*/
+#define LOG_WARN_UNIQUE_FN_EXT_LEFT 1000
+
+/**
+  Find a unique filename for 'filename.#'.
+
+  Set '#' to the number next to the maximum found in the most
+  recent log file extension.
+
+  This function will return nonzero if: (i) the generated name
+  exceeds FN_REFLEN; (ii) if the number of extensions is exhausted;
+  or (iii) some other error happened while examining the filesystem.
+
+  @return
+    nonzero if not possible to get unique filename.
+*/
+
+static int find_uniq_filename(char *name)
+{
+  uint                  i;
+  char                  buff[FN_REFLEN], ext_buf[FN_REFLEN];
+  struct st_my_dir     *dir_info;
+  reg1 struct fileinfo *file_info;
+  ulong                 max_found= 0, next= 0, number= 0;
+  size_t		buf_length, length;
+  char			*start, *end;
+  int                   error= 0;
+  DBUG_ENTER("find_uniq_filename");
+
+  length= dirname_part(buff, name, &buf_length);
+  start=  name + length;
+  end=    strend(start);
+
+  *end='.';
+  length= (size_t) (end - start + 1);
+
+  if ((DBUG_EVALUATE_IF("error_unique_log_filename", 1, 
+      !(dir_info= my_dir(buff,MYF(MY_DONT_SORT))))))
+  {						// This shouldn't happen
+    strmov(end,".1");				// use name+1
+    DBUG_RETURN(1);
+  }
+  file_info= dir_info->dir_entry;
+  for (i= dir_info->number_off_files ; i-- ; file_info++)
+  {
+    if (memcmp(file_info->name, start, length) == 0 &&
+	test_if_number(file_info->name+length, &number,0))
+    {
+      set_if_bigger(max_found,(ulong) number);
+    }
+  }
+  my_dirend(dir_info);
+
+  /* check if reached the maximum possible extension number */
+  if (max_found == MAX_LOG_UNIQUE_FN_EXT)
+  {
+    sql_print_error("Log filename extension number exhausted: %06lu. \
+Please fix this by archiving old logs and \
+updating the index files.", max_found);
+    error= 1;
+    goto end;
+  }
+
+  next= max_found + 1;
+  if (sprintf(ext_buf, "%06lu", next)<0)
+  {
+    error= 1;
+    goto end;
+  }
+  *end++='.';
+
+  /* 
+    Check if the generated extension size + the file name exceeds the
+    buffer size used. If one did not check this, then the filename might be
+    truncated, resulting in error.
+   */
+  if (((strlen(ext_buf) + (end - name)) >= FN_REFLEN))
+  {
+    sql_print_error("Log filename too large: %s%s (%zu). \
+Please fix this by archiving old logs and updating the \
+index files.", name, ext_buf, (strlen(ext_buf) + (end - name)));
+    error= 1;
+    goto end;
+  }
+
+  if (sprintf(end, "%06lu", next)<0)
+  {
+    error= 1;
+    goto end;
+  }
+
+  /* print warning if reaching the end of available extensions. */
+  if ((next > (MAX_LOG_UNIQUE_FN_EXT - LOG_WARN_UNIQUE_FN_EXT_LEFT)))
+    sql_print_warning("Next log extension: %lu. \
+Remaining log filename extensions: %lu. \
+Please consider archiving some logs.", next, (MAX_LOG_UNIQUE_FN_EXT - next));
+
+end:
+  DBUG_RETURN(error);
+}
+
+
+int MYSQL_BIN_LOG::generate_new_name(char *new_name, const char *log_name)
+{
+  fn_format(new_name, log_name, mysql_data_home, "", 4);
+  if (!fn_ext(log_name)[0])
+  {
+    if (find_uniq_filename(new_name))
+    {
+      my_printf_error(ER_NO_UNIQUE_LOGFILE, ER(ER_NO_UNIQUE_LOGFILE),
+                      MYF(ME_FATALERROR), log_name);
+      sql_print_error(ER(ER_NO_UNIQUE_LOGFILE), log_name);
+      return 1;
+    }
+  }
+  return 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.
+*/
+const char *MYSQL_BIN_LOG::generate_name(const char *log_name,
+                                         const char *suffix,
+                                         char *buff)
+{
+  if (!log_name || !log_name[0])
+  {
+    strmake(buff, pidfile_name, FN_REFLEN - strlen(suffix) - 1);
+    return (const char *)
+      fn_format(buff, buff, "", suffix, MYF(MY_REPLACE_EXT|MY_REPLACE_DIR));
+  }
+  // get rid of extension to avoid problems
+
+  char *p= fn_ext(log_name);
+  uint length= (uint) (p - log_name);
+  strmake(buff, log_name, min<size_t>(length, FN_REFLEN-1));
+  return (const char*)buff;
+}
+
+
+bool MYSQL_BIN_LOG::init_and_set_log_file_name(const char *log_name,
+                                               const char *new_name)
+{
+  if (new_name && !strmov(log_file_name, new_name))
+    return TRUE;
+  else if (!new_name && generate_new_name(log_file_name, log_name))
+    return TRUE;
+
+  return FALSE;
+}
+
+
+/*
+  Open a (new) log file.
+
+  SYNOPSIS
+    open()
+
+    log_name            The name of the log to open
+    new_name            The new name for the logfile. This is only needed
+                        when the method is used to open the binlog file.
+
+  DESCRIPTION
+    Open the logfile, init IO_CACHE and write startup messages
+    (in case of general and slow query logs).
+
+  RETURN VALUES
+    0   ok
+    1   error
+*/
+
+bool MYSQL_BIN_LOG::open(
+#ifdef HAVE_PSI_INTERFACE
+                     PSI_file_key log_file_key,
+#endif
+                     const char *log_name,
+                     const char *new_name)
+{
+  File file= -1;
+  my_off_t pos= 0;
+  int open_flags= O_CREAT | O_BINARY;
+  DBUG_ENTER("MYSQL_BIN_LOG::open");
+
+  write_error= 0;
+
+  if (!(name= my_strdup(log_name, MYF(MY_WME))))
+  {
+    name= (char *)log_name; // for the error message
+    goto err;
+  }
+
+  if (init_and_set_log_file_name(name, new_name))
+    goto err;
+
+  if (io_cache_type == SEQ_READ_APPEND)
+    open_flags |= O_RDWR | O_APPEND;
+  else
+    open_flags |= O_WRONLY;
+
+  db[0]= 0;
+
+#ifdef HAVE_PSI_INTERFACE
+  /* Keep the key for reopen */
+  m_log_file_key= log_file_key;
+#endif
+
+  if ((file= mysql_file_open(log_file_key,
+                             log_file_name, open_flags,
+                             MYF(MY_WME | ME_WAITTANG))) < 0)
+    goto err;
+
+  if ((pos= mysql_file_tell(file, MYF(MY_WME))) == MY_FILEPOS_ERROR)
+  {
+    if (my_errno == ESPIPE)
+      pos= 0;
+    else
+      goto err;
+  }
+
+  if (init_io_cache(&log_file, file, IO_SIZE, io_cache_type, pos, 0,
+                    MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)))
+    goto err;
+
+  log_state= LOG_OPENED;
+  DBUG_RETURN(0);
+
+err:
+  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.", name, errno);
+  if (file >= 0)
+    mysql_file_close(file, MYF(0));
+  end_io_cache(&log_file);
+  my_free(name);
+  name= NULL;
+  log_state= LOG_CLOSED;
+  DBUG_RETURN(1);
+}
+
+
 bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
                                     const char *log_name, bool need_lock_index)
 {
@@ -2691,7 +3034,6 @@ end:
 
 bool MYSQL_BIN_LOG::open_binlog(const char *log_name,
                                 const char *new_name,
-                                enum cache_type io_cache_type_arg,
                                 ulong max_size_arg,
                                 bool null_created_arg,
                                 bool need_lock_index,
@@ -2705,8 +3047,7 @@ bool MYSQL_BIN_LOG::open_binlog(const ch
   DBUG_ENTER("MYSQL_BIN_LOG::open_binlog(const char *, ...)");
   DBUG_PRINT("enter",("name: %s", log_name));
 
-  if (init_and_set_log_file_name(log_name, new_name, LOG_BIN,
-                                 io_cache_type_arg))
+  if (init_and_set_log_file_name(log_name, new_name))
   {
     sql_print_error("MYSQL_BIN_LOG::open failed to generate new file name.");
     DBUG_RETURN(1);
@@ -2724,7 +3065,7 @@ bool MYSQL_BIN_LOG::open_binlog(const ch
       it may be good to consider what actually happens when
       open_purge_index_file succeeds but register or sync fails.
 
-      Perhaps we might need the code below in MYSQL_LOG_BIN::cleanup
+      Perhaps we might need the code below in MYSQL_BIN_LOG::cleanup
       for "real life" purposes as well? 
     */
     DBUG_EXECUTE_IF("fault_injection_registering_index", {
@@ -2744,11 +3085,11 @@ bool MYSQL_BIN_LOG::open_binlog(const ch
   write_error= 0;
 
   /* open the main log file */
-  if (MYSQL_LOG::open(
+  if (open(
 #ifdef HAVE_PSI_INTERFACE
                       m_key_file_log,
 #endif
-                      log_name, LOG_BIN, new_name, io_cache_type_arg))
+                      log_name, new_name))
   {
 #ifdef HAVE_REPLICATION
     close_purge_index_file();
@@ -3414,7 +3755,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
 #endif
 
   if (!open_index_file(index_file_name, 0, false/*need_lock_index=false*/))
-    if ((error= open_binlog(save_name, 0, io_cache_type,
+    if ((error= open_binlog(save_name, 0,
                             max_size, false,
                             false/*need_lock_index=false*/,
                             false/*need_sid_lock=false*/,
@@ -4395,7 +4736,7 @@ int MYSQL_BIN_LOG::new_file_impl(bool ne
   {
     /* reopen the binary log file. */
     file_to_open= new_name_ptr;
-    error= open_binlog(old_name, new_name_ptr, io_cache_type,
+    error= open_binlog(old_name, new_name_ptr,
                        max_size, true,
                        false/*need_lock_index=false*/,
                        true/*need_sid_lock=true*/,
@@ -5463,7 +5804,30 @@ void MYSQL_BIN_LOG::close(uint exiting)
     }
 
     /* this will cleanup IO_CACHE, sync and close the file */
-    MYSQL_LOG::close(exiting);
+    if (log_state == LOG_OPENED)
+    {
+      end_io_cache(&log_file);
+
+      if (mysql_file_sync(log_file.file, MYF(MY_WME)) && ! write_error)
+      {
+        char errbuf[MYSYS_STRERROR_SIZE];
+        write_error= 1;
+        sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno,
+                        my_strerror(errbuf, sizeof(errbuf), errno));
+      }
+
+      if (mysql_file_close(log_file.file, MYF(MY_WME)) && ! write_error)
+      {
+        char errbuf[MYSYS_STRERROR_SIZE];
+        write_error= 1;
+        sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno,
+                        my_strerror(errbuf, sizeof(errbuf), errno));
+      }
+    }
+
+    log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
+    my_free(name);
+    name= NULL;
   }
 
   /*
@@ -5548,7 +5912,7 @@ int MYSQL_BIN_LOG::open_binlog(const cha
   if (using_heuristic_recover())
   {
     /* generate a new binlog to mask a corrupted one */
-    open_binlog(opt_name, 0, WRITE_CACHE, max_binlog_size, false,
+    open_binlog(opt_name, 0, max_binlog_size, false,
                 true/*need_lock_index=true*/,
                 true/*need_sid_lock=true*/,
                 NULL);
@@ -8227,7 +8591,7 @@ int THD::binlog_query(THD::enum_binlog_q
     */
   case THD::STMT_QUERY_TYPE:
     /*
-      The MYSQL_LOG::write() function will set the STMT_END_F flag and
+      The MYSQL_BIN_LOG::write() function will set the STMT_END_F flag and
       flush the pending rows event if necessary.
     */
     {

=== modified file 'sql/binlog.h'
--- a/sql/binlog.h	2012-09-18 12:32:43 +0000
+++ b/sql/binlog.h	2012-11-14 10:15:19 +0000
@@ -208,11 +208,70 @@ private:
   mysql_mutex_t m_lock_done;
 };
 
+/* log info errors */
+#define LOG_INFO_EOF -1
+#define LOG_INFO_IO  -2
+#define LOG_INFO_INVALID -3
+#define LOG_INFO_SEEK -4
+#define LOG_INFO_MEM -6
+#define LOG_INFO_FATAL -7
+#define LOG_INFO_IN_USE -8
+#define LOG_INFO_EMFILE -9
+
+/* bitmap to MYSQL_BIN_LOG::close() */
+#define LOG_CLOSE_INDEX		1
+#define LOG_CLOSE_TO_BE_OPENED	2
+#define LOG_CLOSE_STOP_EVENT	4
 
-class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG
+#ifdef HAVE_PSI_INTERFACE
+extern PSI_mutex_key key_LOG_INFO_lock;
+#endif
+
+/*
+  Note that we destroy the lock mutex in the desctructor here.
+  This means that object instances cannot be destroyed/go out of scope,
+  until we have reset thd->current_linfo to NULL;
+ */
+typedef struct st_log_info
+{
+  char log_file_name[FN_REFLEN];
+  my_off_t index_file_offset, index_file_start_offset;
+  my_off_t pos;
+  bool fatal; // if the purge happens to give us a negative offset
+  mysql_mutex_t lock;
+  st_log_info()
+    : index_file_offset(0), index_file_start_offset(0),
+      pos(0), fatal(0)
+    {
+      log_file_name[0] = '\0';
+      mysql_mutex_init(key_LOG_INFO_lock, &lock, MY_MUTEX_INIT_FAST);
+    }
+  ~st_log_info() { mysql_mutex_destroy(&lock);}
+} LOG_INFO;
+
+/*
+  TODO use mmap instead of IO_CACHE for binlog
+  (mmap+fsync is two times faster than write+fsync)
+*/
+
+class MYSQL_BIN_LOG: public TC_LOG
 {
- private:
+  enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
+
+  /* LOCK_log is inited by init_pthread_objects() */
+  mysql_mutex_t LOCK_log;
+  char *name;
+  char log_file_name[FN_REFLEN];
+  char db[NAME_LEN + 1];
+  bool write_error, inited;
+  IO_CACHE log_file;
+  volatile enum_log_state log_state;
+  const enum cache_type io_cache_type;
 #ifdef HAVE_PSI_INTERFACE
+  /** Instrumentation key to use for file io in @c log_file */
+  PSI_file_key m_log_file_key;
+  /** The instrumentation key to use for @ LOCK_log. */
+  PSI_mutex_key m_key_LOCK_log;
   /** The instrumentation key to use for @ LOCK_index. */
   PSI_mutex_key m_key_LOCK_index;
 
@@ -343,9 +402,20 @@ class MYSQL_BIN_LOG: public TC_LOG, priv
   Stage_manager stage_manager;
   void do_flush(THD *thd);
 
+  bool open(
+#ifdef HAVE_PSI_INTERFACE
+            PSI_file_key log_file_key,
+#endif
+            const char *log_name,
+            const char *new_name);
+  bool init_and_set_log_file_name(const char *log_name,
+                                  const char *new_name);
+  int generate_new_name(char *new_name, const char *log_name);
+
 public:
-  using MYSQL_LOG::generate_name;
-  using MYSQL_LOG::is_open;
+  const char *generate_name(const char *log_name, const char *suffix,
+                            char *buff);
+  bool is_open() const { return log_state != LOG_CLOSED; }
 
   /* This is relay log */
   bool is_relay_log;
@@ -386,7 +456,8 @@ public:
   */
   uint8 relay_log_checksum_alg;
 
-  MYSQL_BIN_LOG(uint *sync_period);
+  MYSQL_BIN_LOG(uint *sync_period,
+                enum cache_type io_cache_type_arg);
   /*
     note that there's no destructor ~MYSQL_BIN_LOG() !
     The reason is that we don't want it to be automatically called
@@ -510,8 +581,6 @@ public:
     @param log_name Name of binlog
     @param new_name Name of binlog, too. todo: what's the difference
     between new_name and log_name?
-    @param io_cache_type_arg Specifies how the IO cache is opened:
-    read-only or read-write.
     @param max_size The size at which this binlog will be rotated.
     @param null_created If false, and a Format_description_log_event
     is written, then the Format_description_log_event will have the
@@ -525,7 +594,6 @@ public:
   */
   bool open_binlog(const char *log_name,
                    const char *new_name,
-                   enum cache_type io_cache_type_arg,
                    ulong max_size,
                    bool null_created,
                    bool need_lock_index, bool need_sid_lock,
@@ -656,6 +724,7 @@ void check_binlog_stmt_cache_size(THD *t
 bool binlog_enabled();
 void register_binlog_handler(THD *thd, bool trx);
 int gtid_empty_group_log_and_cleanup(THD *thd);
+int query_error_code(THD *thd, bool not_killed);
 
 extern const char *log_bin_index;
 extern const char *log_bin_basename;

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2012-11-06 14:16:49 +0000
+++ b/sql/log.cc	2012-11-14 10:15:19 +0000
@@ -38,7 +38,6 @@
 
 #include <my_dir.h>
 #include <stdarg.h>
-#include <m_ctype.h>				// For test_if_number
 
 #ifdef _WIN32
 #include "message.h"
@@ -47,12 +46,24 @@
 using std::min;
 using std::max;
 
-/* max size of the log message */
-#define MAX_LOG_BUFFER_SIZE 1024
-#define MAX_TIME_SIZE 32
+enum enum_slow_query_log_table_field
+{
+  SQLT_FIELD_START_TIME = 0,
+  SQLT_FIELD_USER_HOST,
+  SQLT_FIELD_QUERY_TIME,
+  SQLT_FIELD_LOCK_TIME,
+  SQLT_FIELD_ROWS_SENT,
+  SQLT_FIELD_ROWS_EXAMINED,
+  SQLT_FIELD_DATABASE,
+  SQLT_FIELD_LAST_INSERT_ID,
+  SQLT_FIELD_INSERT_ID,
+  SQLT_FIELD_SERVER_ID,
+  SQLT_FIELD_SQL_TEXT,
+  SQLT_FIELD_THREAD_ID,
+  SQLT_FIELD_COUNT
+};
 
-static
-const TABLE_FIELD_TYPE slow_query_log_table_fields[SQLT_FIELD_COUNT] =
+static const TABLE_FIELD_TYPE slow_query_log_table_fields[SQLT_FIELD_COUNT] =
 {
   {
     { C_STRING_WITH_LEN("start_time") },
@@ -117,25 +128,21 @@ const TABLE_FIELD_TYPE slow_query_log_ta
 };
 
 static const TABLE_FIELD_DEF
-  slow_query_log_table_def= {SQLT_FIELD_COUNT, slow_query_log_table_fields};
+slow_query_log_table_def= {SQLT_FIELD_COUNT, slow_query_log_table_fields};
+
 
-class Slow_query_log_table_intact : public Table_check_intact
+enum enum_general_log_table_field
 {
-protected:
-  void report_error(uint, const char *fmt, ...)
-  {
-    va_list args;
-    va_start(args, fmt);
-    error_log_print(ERROR_LEVEL, fmt, args);
-    va_end(args);
-  }
+  GLT_FIELD_EVENT_TIME = 0,
+  GLT_FIELD_USER_HOST,
+  GLT_FIELD_THREAD_ID,
+  GLT_FIELD_SERVER_ID,
+  GLT_FIELD_COMMAND_TYPE,
+  GLT_FIELD_ARGUMENT,
+  GLT_FIELD_COUNT
 };
 
-/** In case of an error, a message is printed to the error log. */
-static Slow_query_log_table_intact sqlt_intact;
-
-static
-const TABLE_FIELD_TYPE general_log_table_fields[GLT_FIELD_COUNT] =
+static const TABLE_FIELD_TYPE general_log_table_fields[GLT_FIELD_COUNT] =
 {
   {
     { C_STRING_WITH_LEN("event_time") },
@@ -172,7 +179,8 @@ const TABLE_FIELD_TYPE general_log_table
 static const TABLE_FIELD_DEF
   general_log_table_def= {GLT_FIELD_COUNT, general_log_table_fields};
 
-class General_log_table_intact : public Table_check_intact
+
+class Query_log_table_intact : public Table_check_intact
 {
 protected:
   void report_error(uint, const char *fmt, ...)
@@ -185,41 +193,11 @@ protected:
 };
 
 /** In case of an error, a message is printed to the error log. */
-static General_log_table_intact glt_intact;
-
-LOGGER logger;
-
-static bool test_if_number(const char *str,
-			   ulong *res, bool allow_wildcards);
+static Query_log_table_intact log_table_intact;
 
-/**
-   purge logs, master and slave sides both, related error code
-   convertor.
-   Called from @c purge_error_message(), @c MYSQL_BIN_LOG::reset_logs()
-
-   @param  res  an internal to purging routines error code 
-
-   @return the user level error code ER_*
-*/
-uint purge_log_get_error_code(int res)
-{
-  uint errcode= 0;
 
-  switch (res)  {
-  case 0: break;
-  case LOG_INFO_EOF:	errcode= ER_UNKNOWN_TARGET_BINLOG; break;
-  case LOG_INFO_IO:	errcode= ER_IO_ERR_LOG_INDEX_READ; break;
-  case LOG_INFO_INVALID:errcode= ER_BINLOG_PURGE_PROHIBITED; break;
-  case LOG_INFO_SEEK:	errcode= ER_FSEEK_FAIL; break;
-  case LOG_INFO_MEM:	errcode= ER_OUT_OF_RESOURCES; break;
-  case LOG_INFO_FATAL:	errcode= ER_BINLOG_PURGE_FATAL_ERR; break;
-  case LOG_INFO_IN_USE: errcode= ER_LOG_IN_USE; break;
-  case LOG_INFO_EMFILE: errcode= ER_BINLOG_PURGE_EMFILE; break;
-  default:		errcode= ER_LOG_PURGE_UNKNOWN_ERR; break;
-  }
+LOGGER logger;
 
-  return errcode;
-}
 
 /**
   Silence all errors and warnings reported when performing a write
@@ -228,6 +206,7 @@ uint purge_log_get_error_code(int res)
   handlers, so that the presence of logging does not interfere and affect
   the logic of an application.
 */
+
 class Silence_log_table_errors : public Internal_error_handler
 {
   char m_message[MYSQL_ERRMSG_SIZE];
@@ -244,22 +223,15 @@ public:
                                 const char* sql_state,
                                 Sql_condition::enum_severity_level level,
                                 const char* msg,
-                                Sql_condition ** cond_hdl);
+                                Sql_condition ** cond_hdl)
+  {
+    *cond_hdl= NULL;
+    strmake(m_message, msg, sizeof(m_message)-1);
+    return true;
+  }
   const char *message() const { return m_message; }
 };
 
-bool
-Silence_log_table_errors::handle_condition(THD *,
-                                           uint,
-                                           const char*,
-                                           Sql_condition::enum_severity_level,
-                                           const char* msg,
-                                           Sql_condition ** cond_hdl)
-{
-  *cond_hdl= NULL;
-  strmake(m_message, msg, sizeof(m_message)-1);
-  return TRUE;
-}
 
 sql_print_message_func sql_print_message_handlers[3] =
 {
@@ -268,6 +240,7 @@ sql_print_message_func sql_print_message
   sql_print_error
 };
 
+
 /**
   Create the name of the log specified.
 
@@ -280,6 +253,7 @@ sql_print_message_func sql_print_message
 
   @returns Pointer to new string containing the name.
 */
+
 char *make_log_name(char *buff, const char *name, const char* log_ext)
 {
   strmake(buff, name, FN_REFLEN-5);
@@ -287,7 +261,8 @@ char *make_log_name(char *buff, const ch
                    MYF(MY_UNPACK_FILENAME|MY_REPLACE_EXT));
 }
 
-bool LOGGER::is_log_table_enabled(uint log_table_type)
+
+bool LOGGER::is_log_table_enabled(enum_log_table_type log_table_type)
 {
   switch (log_table_type) {
   case QUERY_LOG_SLOW:
@@ -298,14 +273,17 @@ bool LOGGER::is_log_table_enabled(uint l
             && (log_output_options & LOG_TABLE));
   default:
     DBUG_ASSERT(0);
-    return FALSE;                             /* make compiler happy */
+    return false;                             /* make compiler happy */
   }
 }
 
 
 /* Check if a given table is opened log table */
-int check_if_log_table(size_t db_len, const char *db, size_t table_name_len,
-                       const char *table_name, bool check_if_opened)
+
+enum_log_table_type check_if_log_table(size_t db_len, const char *db,
+                                       size_t table_name_len,
+                                       const char *table_name,
+                                       bool check_if_opened)
 {
   if (db_len == 5 &&
       !(lower_case_table_names ?
@@ -319,7 +297,7 @@ int check_if_log_table(size_t db_len, co
     {
       if (!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_GENERAL))
         return QUERY_LOG_GENERAL;
-      return 0;
+      return NO_LOG_TABLE;
     }
 
     if (table_name_len == 8 && !(lower_case_table_names ?
@@ -328,20 +306,10 @@ int check_if_log_table(size_t db_len, co
     {
       if (!check_if_opened || logger.is_log_table_enabled(QUERY_LOG_SLOW))
         return QUERY_LOG_SLOW;
-      return 0;
+      return NO_LOG_TABLE;
     }
   }
-  return 0;
-}
-
-
-Log_to_csv_event_handler::Log_to_csv_event_handler()
-{
-}
-
-
-Log_to_csv_event_handler::~Log_to_csv_event_handler()
-{
+  return NO_LOG_TABLE;
 }
 
 
@@ -350,7 +318,6 @@ void Log_to_csv_event_handler::cleanup()
   logger.is_log_tables_initialized= FALSE;
 }
 
-/* log event handlers */
 
 /**
   Log command to the general log table
@@ -382,12 +349,15 @@ void Log_to_csv_event_handler::cleanup()
   @retval  TRUE    error occured
 */
 
-bool Log_to_csv_event_handler::
-  log_general(THD *thd, time_t event_time, const char *user_host,
-              uint user_host_len, my_thread_id thread_id,
-              const char *command_type, uint command_type_len,
-              const char *sql_text, uint sql_text_len,
-              const CHARSET_INFO *client_cs)
+bool Log_to_csv_event_handler::log_general(THD *thd, time_t event_time,
+                                           const char *user_host,
+                                           uint user_host_len,
+                                           my_thread_id thread_id,
+                                           const char *command_type,
+                                           uint command_type_len,
+                                           const char *sql_text,
+                                           uint sql_text_len,
+                                           const CHARSET_INFO *client_cs)
 {
   TABLE_LIST table_list;
   TABLE *table;
@@ -434,7 +404,7 @@ bool Log_to_csv_event_handler::
 
   need_close= TRUE;
 
-  if (glt_intact.check(table_list.table, &general_log_table_def))
+  if (log_table_intact.check(table_list.table, &general_log_table_def))
     goto err;
 
   if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) ||
@@ -552,11 +522,13 @@ err:
     TRUE - error occured
 */
 
-bool Log_to_csv_event_handler::
-  log_slow(THD *thd, time_t current_time, time_t query_start_arg,
-           const char *user_host, uint user_host_len,
-           ulonglong query_utime, ulonglong lock_utime, bool is_command,
-           const char *sql_text, uint sql_text_len)
+bool Log_to_csv_event_handler::log_slow(THD *thd, time_t current_time,
+                                        time_t query_start_arg,
+                                        const char *user_host,
+                                        uint user_host_len,
+                                        ulonglong query_utime,
+                                        ulonglong lock_utime, bool is_command,
+                                        const char *sql_text, uint sql_text_len)
 {
   TABLE_LIST table_list;
   TABLE *table;
@@ -586,7 +558,7 @@ bool Log_to_csv_event_handler::
 
   need_close= TRUE;
 
-  if (sqlt_intact.check(table_list.table, &slow_query_log_table_def))
+  if (log_table_intact.check(table_list.table, &slow_query_log_table_def))
     goto err;
 
   if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) ||
@@ -716,8 +688,9 @@ err:
   DBUG_RETURN(result);
 }
 
-int Log_to_csv_event_handler::
-  activate_log(THD *thd, uint log_table_type)
+
+int Log_to_csv_event_handler::activate_log(THD *thd,
+                                           enum_log_table_type log_table_type)
 {
   TABLE_LIST table_list;
   TABLE *table;
@@ -753,35 +726,18 @@ int Log_to_csv_event_handler::
   DBUG_RETURN(result);
 }
 
-bool Log_to_csv_event_handler::
-  log_error(enum loglevel level, const char *format, va_list args)
-{
-  /* No log table is implemented */
-  DBUG_ASSERT(0);
-  return FALSE;
-}
-
-bool Log_to_file_event_handler::
-  log_error(enum loglevel level, const char *format,
-            va_list args)
-{
-  return vprint_msg_to_log(level, format, args);
-}
-
-void Log_to_file_event_handler::init_pthread_objects()
-{
-  mysql_log.init_pthread_objects();
-  mysql_slow_log.init_pthread_objects();
-}
-
 
-/** Wrapper around MYSQL_LOG::write() for slow log. */
+/** Wrapper around MYSQL_QUERY_LOG::write() for slow log. */
 
-bool Log_to_file_event_handler::
-  log_slow(THD *thd, time_t current_time, time_t query_start_arg,
-           const char *user_host, uint user_host_len,
-           ulonglong query_utime, ulonglong lock_utime, bool is_command,
-           const char *sql_text, uint sql_text_len)
+bool Log_to_file_event_handler::log_slow(THD *thd, time_t current_time,
+                                         time_t query_start_arg,
+                                         const char *user_host,
+                                         uint user_host_len,
+                                         ulonglong query_utime,
+                                         ulonglong lock_utime,
+                                         bool is_command,
+                                         const char *sql_text,
+                                         uint sql_text_len)
 {
   Silence_log_table_errors error_handler;
   thd->push_internal_handler(&error_handler);
@@ -795,16 +751,19 @@ bool Log_to_file_event_handler::
 
 
 /**
-   Wrapper around MYSQL_LOG::write() for general log. We need it since we
+   Wrapper around MYSQL_QUERY_LOG::write() for general log. We need it since we
    want all log event handlers to have the same signature.
 */
 
-bool Log_to_file_event_handler::
-  log_general(THD *thd, time_t event_time, const char *user_host,
-              uint user_host_len, my_thread_id thread_id,
-              const char *command_type, uint command_type_len,
-              const char *sql_text, uint sql_text_len,
-              const CHARSET_INFO *client_cs)
+bool Log_to_file_event_handler::log_general(THD *thd, time_t event_time,
+                                            const char *user_host,
+                                            uint user_host_len,
+                                            my_thread_id thread_id,
+                                            const char *command_type,
+                                            uint command_type_len,
+                                            const char *sql_text,
+                                            uint sql_text_len,
+                                            const CHARSET_INFO *client_cs)
 {
   Silence_log_table_errors error_handler;
   thd->push_internal_handler(&error_handler);
@@ -826,19 +785,13 @@ bool Log_to_file_event_handler::init()
     if (opt_log)
       mysql_log.open_query_log(opt_logname);
 
-    is_initialized= TRUE;
+    is_initialized= true;
   }
 
-  return FALSE;
+  return false;
 }
 
 
-void Log_to_file_event_handler::cleanup()
-{
-  mysql_log.cleanup();
-  mysql_slow_log.cleanup();
-}
-
 void Log_to_file_event_handler::flush()
 {
   /* reopen log files */
@@ -848,6 +801,7 @@ void Log_to_file_event_handler::flush()
     mysql_slow_log.reopen_file();
 }
 
+
 /*
   Log error with all enabled log event handlers
 
@@ -867,7 +821,7 @@ void Log_to_file_event_handler::flush()
 bool LOGGER::error_log_print(enum loglevel level, const char *format,
                              va_list args)
 {
-  bool error= FALSE;
+  bool error= false;
   Log_event_handler **current_handler;
 
   /* currently we don't need locking here as there is no error_log table */
@@ -909,6 +863,7 @@ void LOGGER::cleanup_end()
   Perform basic log initialization: create file-based log handler and
   init error log.
 */
+
 void LOGGER::init_base()
 {
   DBUG_ASSERT(inited == 0);
@@ -962,7 +917,7 @@ bool LOGGER::flush_logs(THD *thd)
 
 /**
   Close and reopen the slow log (with locks).
-  
+
   @returns FALSE.
 */
 bool LOGGER::flush_slow_log()
@@ -1024,7 +979,6 @@ bool LOGGER::flush_general_log()
 */
 
 bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length)
-
 {
   bool error= FALSE;
   Log_event_handler **current_handler;
@@ -1093,6 +1047,7 @@ bool LOGGER::slow_log_print(THD *thd, co
   return error;
 }
 
+
 bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
                                const char *query, uint query_length)
 {
@@ -1119,7 +1074,7 @@ bool LOGGER::general_log_write(THD *thd,
                           command_name[(uint) command].str,
                           command_name[(uint) command].length,
                           query, query_length);
-                        
+
   while (*current_handler)
     error|= (*current_handler++)->
       log_general(thd, current_time, user_host_buff,
@@ -1133,6 +1088,7 @@ bool LOGGER::general_log_write(THD *thd,
   return error;
 }
 
+
 bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
                                const char *format, va_list args)
 {
@@ -1149,6 +1105,7 @@ bool LOGGER::general_log_print(THD *thd,
   return general_log_write(thd, command, message_buff, message_buff_len);
 }
 
+
 void LOGGER::init_error_log(uint error_log_printer)
 {
   if (error_log_printer & LOG_NONE)
@@ -1172,6 +1129,7 @@ void LOGGER::init_error_log(uint error_l
   }
 }
 
+
 void LOGGER::init_slow_log(uint slow_log_printer)
 {
   if (slow_log_printer & LOG_NONE)
@@ -1197,6 +1155,7 @@ void LOGGER::init_slow_log(uint slow_log
   }
 }
 
+
 void LOGGER::init_general_log(uint general_log_printer)
 {
   if (general_log_printer & LOG_NONE)
@@ -1223,7 +1182,7 @@ void LOGGER::init_general_log(uint gener
 }
 
 
-bool LOGGER::activate_log_handler(THD* thd, uint log_type)
+bool LOGGER::activate_log_handler(THD* thd, enum_log_table_type log_type)
 {
   MYSQL_QUERY_LOG *file_log;
   bool res= FALSE;
@@ -1239,7 +1198,7 @@ bool LOGGER::activate_log_handler(THD* t
       {
         /* Error printed by open table in activate_log() */
         res= TRUE;
-        file_log->close(0);
+        file_log->close(false);
       }
       else
       {
@@ -1258,7 +1217,7 @@ bool LOGGER::activate_log_handler(THD* t
       {
         /* Error printed by open table in activate_log() */
         res= TRUE;
-        file_log->close(0);
+        file_log->close(false);
       }
       else
       {
@@ -1275,10 +1234,10 @@ bool LOGGER::activate_log_handler(THD* t
 }
 
 
-void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
+void LOGGER::deactivate_log_handler(THD *thd, enum_log_table_type log_type)
 {
   my_bool *tmp_opt= 0;
-  MYSQL_LOG *file_log= NULL;
+  MYSQL_QUERY_LOG *file_log= NULL;
 
   switch (log_type) {
   case QUERY_LOG_SLOW:
@@ -1297,18 +1256,12 @@ void LOGGER::deactivate_log_handler(THD
     return;
 
   lock_exclusive();
-  file_log->close(0);
+  file_log->close(false);
   *tmp_opt= FALSE;
   unlock();
 }
 
 
-/* the parameters are unused for the log tables */
-bool Log_to_csv_event_handler::init()
-{
-  return 0;
-}
-
 int LOGGER::set_handlers(uint error_log_printer,
                          uint slow_log_printer,
                          uint general_log_printer)
@@ -1337,6 +1290,7 @@ int LOGGER::set_handlers(uint error_log_
   return 0;
 }
 
+
 #ifdef _WIN32
 static int eventSource = 0;
 
@@ -1374,131 +1328,6 @@ static void setup_windows_event_source()
 
 #endif /* _WIN32 */
 
-/**
-  Find a unique filename for 'filename.#'.
-
-  Set '#' to the number next to the maximum found in the most
-  recent log file extension.
-
-  This function will return nonzero if: (i) the generated name
-  exceeds FN_REFLEN; (ii) if the number of extensions is exhausted;
-  or (iii) some other error happened while examining the filesystem.
-
-  @return
-    nonzero if not possible to get unique filename.
-*/
-
-static int find_uniq_filename(char *name)
-{
-  uint                  i;
-  char                  buff[FN_REFLEN], ext_buf[FN_REFLEN];
-  struct st_my_dir     *dir_info;
-  reg1 struct fileinfo *file_info;
-  ulong                 max_found= 0, next= 0, number= 0;
-  size_t		buf_length, length;
-  char			*start, *end;
-  int                   error= 0;
-  DBUG_ENTER("find_uniq_filename");
-
-  length= dirname_part(buff, name, &buf_length);
-  start=  name + length;
-  end=    strend(start);
-
-  *end='.';
-  length= (size_t) (end - start + 1);
-
-  if ((DBUG_EVALUATE_IF("error_unique_log_filename", 1, 
-      !(dir_info= my_dir(buff,MYF(MY_DONT_SORT))))))
-  {						// This shouldn't happen
-    strmov(end,".1");				// use name+1
-    DBUG_RETURN(1);
-  }
-  file_info= dir_info->dir_entry;
-  for (i= dir_info->number_off_files ; i-- ; file_info++)
-  {
-    if (memcmp(file_info->name, start, length) == 0 &&
-	test_if_number(file_info->name+length, &number,0))
-    {
-      set_if_bigger(max_found,(ulong) number);
-    }
-  }
-  my_dirend(dir_info);
-
-  /* check if reached the maximum possible extension number */
-  if (max_found == MAX_LOG_UNIQUE_FN_EXT)
-  {
-    sql_print_error("Log filename extension number exhausted: %06lu. \
-Please fix this by archiving old logs and \
-updating the index files.", max_found);
-    error= 1;
-    goto end;
-  }
-
-  next= max_found + 1;
-  if (sprintf(ext_buf, "%06lu", next)<0)
-  {
-    error= 1;
-    goto end;
-  }
-  *end++='.';
-
-  /* 
-    Check if the generated extension size + the file name exceeds the
-    buffer size used. If one did not check this, then the filename might be
-    truncated, resulting in error.
-   */
-  if (((strlen(ext_buf) + (end - name)) >= FN_REFLEN))
-  {
-    sql_print_error("Log filename too large: %s%s (%zu). \
-Please fix this by archiving old logs and updating the \
-index files.", name, ext_buf, (strlen(ext_buf) + (end - name)));
-    error= 1;
-    goto end;
-  }
-
-  if (sprintf(end, "%06lu", next)<0)
-  {
-    error= 1;
-    goto end;
-  }
-
-  /* print warning if reaching the end of available extensions. */
-  if ((next > (MAX_LOG_UNIQUE_FN_EXT - LOG_WARN_UNIQUE_FN_EXT_LEFT)))
-    sql_print_warning("Next log extension: %lu. \
-Remaining log filename extensions: %lu. \
-Please consider archiving some logs.", next, (MAX_LOG_UNIQUE_FN_EXT - next));
-
-end:
-  DBUG_RETURN(error);
-}
-
-
-void MYSQL_LOG::init(enum_log_type log_type_arg,
-                     enum cache_type io_cache_type_arg)
-{
-  DBUG_ENTER("MYSQL_LOG::init");
-  log_type= log_type_arg;
-  io_cache_type= io_cache_type_arg;
-  DBUG_PRINT("info",("log_type: %d", log_type));
-  DBUG_VOID_RETURN;
-}
-
-
-bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name,
-                                           const char *new_name,
-                                           enum_log_type log_type_arg,
-                                           enum cache_type io_cache_type_arg)
-{
-  init(log_type_arg, io_cache_type_arg);
-
-  if (new_name && !strmov(log_file_name, new_name))
-    return TRUE;
-  else if (!new_name && generate_new_name(log_file_name, log_name))
-    return TRUE;
-
-  return FALSE;
-}
-
 
 /*
   Open a (new) log file.
@@ -1507,10 +1336,6 @@ bool MYSQL_LOG::init_and_set_log_file_na
     open()
 
     log_name            The name of the log to open
-    log_type_arg        The type of the log. E.g. LOG_NORMAL
-    new_name            The new name for the logfile. This is only needed
-                        when the method is used to open the binlog file.
-    io_cache_type_arg   The type of the IO_CACHE to use for this log file
 
   DESCRIPTION
     Open the logfile, init IO_CACHE and write startup messages
@@ -1521,21 +1346,18 @@ bool MYSQL_LOG::init_and_set_log_file_na
     1   error
 */
 
-bool MYSQL_LOG::open(
+bool MYSQL_QUERY_LOG::open(
 #ifdef HAVE_PSI_INTERFACE
                      PSI_file_key log_file_key,
 #endif
-                     const char *log_name, enum_log_type log_type_arg,
-                     const char *new_name, enum cache_type io_cache_type_arg)
+                     const char *log_name)
 {
   char buff[FN_REFLEN];
   File file= -1;
   my_off_t pos= 0;
-  int open_flags= O_CREAT | O_BINARY;
-  DBUG_ENTER("MYSQL_LOG::open");
-  DBUG_PRINT("enter", ("log_type: %d", (int) log_type_arg));
+  DBUG_ENTER("MYSQL_QUERY_LOG::open");
 
-  write_error= 0;
+  write_error= false;
 
   if (!(name= my_strdup(log_name, MYF(MY_WME))))
   {
@@ -1543,14 +1365,7 @@ bool MYSQL_LOG::open(
     goto err;
   }
 
-  if (init_and_set_log_file_name(name, new_name,
-                                 log_type_arg, io_cache_type_arg))
-    goto err;
-
-  if (io_cache_type == SEQ_READ_APPEND)
-    open_flags |= O_RDWR | O_APPEND;
-  else
-    open_flags |= O_WRONLY | (log_type == LOG_BIN ? 0 : O_APPEND);
+  fn_format(log_file_name, name, mysql_data_home, "", 4);
 
   db[0]= 0;
 
@@ -1560,7 +1375,8 @@ bool MYSQL_LOG::open(
 #endif
 
   if ((file= mysql_file_open(log_file_key,
-                             log_file_name, open_flags,
+                             log_file_name,
+                             O_CREAT | O_BINARY | O_WRONLY | O_APPEND,
                              MYF(MY_WME | ME_WAITTANG))) < 0)
     goto err;
 
@@ -1572,12 +1388,10 @@ bool MYSQL_LOG::open(
       goto err;
   }
 
-  if (init_io_cache(&log_file, file, IO_SIZE, io_cache_type, pos, 0,
-                    MYF(MY_WME | MY_NABP |
-                        ((log_type == LOG_BIN) ? MY_WAIT_IF_FULL : 0))))
+  if (init_io_cache(&log_file, file, IO_SIZE, WRITE_CACHE, pos, 0,
+                    MYF(MY_WME | MY_NABP)))
     goto err;
 
-  if (log_type == LOG_NORMAL)
   {
     char *end;
     int len=my_snprintf(buff, sizeof(buff), "%s, Version: %s (%s). "
@@ -1585,24 +1399,24 @@ bool MYSQL_LOG::open(
                         "embedded library\n",
                         my_progname, server_version, MYSQL_COMPILATION_COMMENT
 #elif _WIN32
-			"started with:\nTCP Port: %d, Named Pipe: %s\n",
+                        "started with:\nTCP Port: %d, Named Pipe: %s\n",
                         my_progname, server_version, MYSQL_COMPILATION_COMMENT,
                         mysqld_port, mysqld_unix_port
 #else
-			"started with:\nTcp port: %d  Unix socket: %s\n",
+                        "started with:\nTcp port: %d  Unix socket: %s\n",
                         my_progname, server_version, MYSQL_COMPILATION_COMMENT,
                         mysqld_port, mysqld_unix_port
 #endif
-                       );
+                        );
     end= strnmov(buff + len, "Time                 Id Command    Argument\n",
                  sizeof(buff) - len);
     if (my_b_write(&log_file, (uchar*) buff, (uint) (end-buff)) ||
-	flush_io_cache(&log_file))
+        flush_io_cache(&log_file))
       goto err;
   }
 
   log_state= LOG_OPENED;
-  DBUG_RETURN(0);
+  DBUG_RETURN(false);
 
 err:
   sql_print_error("Could not use %s for logging (error %d). \
@@ -1615,50 +1429,26 @@ shutdown the MySQL server and restart it
   my_free(name);
   name= NULL;
   log_state= LOG_CLOSED;
-  DBUG_RETURN(1);
+  DBUG_RETURN(true);
 }
 
-MYSQL_LOG::MYSQL_LOG()
-  : name(0), write_error(FALSE), inited(FALSE), log_type(LOG_UNKNOWN),
-    log_state(LOG_CLOSED)
-#ifdef HAVE_PSI_INTERFACE
-  , m_key_LOCK_log(key_LOG_LOCK_log)
-#endif
-{
-  /*
-    We don't want to initialize LOCK_Log here as such initialization depends on
-    safe_mutex (when using safe_mutex) which depends on MY_INIT(), which is
-    called only in main(). Doing initialization here would make it happen
-    before main().
-  */
-  memset(&log_file, 0, sizeof(log_file));
-}
-
-void MYSQL_LOG::init_pthread_objects()
-{
-  DBUG_ASSERT(inited == 0);
-  inited= 1;
-  mysql_mutex_init(m_key_LOCK_log, &LOCK_log, MY_MUTEX_INIT_SLOW);
-}
 
 /*
   Close the log file
 
   SYNOPSIS
     close()
-    exiting     Bitmask. For the slow and general logs the only used bit is
-                LOG_CLOSE_TO_BE_OPENED. This is used if we intend to call
-                open at once after close.
+    to_be_reopened  This is used if we intend to call
+                    open at once after close.
 
   NOTES
     One can do an open on the object at once after doing a close.
     The internal structures are not freed until cleanup() is called
 */
 
-void MYSQL_LOG::close(uint exiting)
+void MYSQL_QUERY_LOG::close(bool to_be_reopened)
 {					// One can't set log_type here!
-  DBUG_ENTER("MYSQL_LOG::close");
-  DBUG_PRINT("enter",("exiting: %d", (int) exiting));
+  DBUG_ENTER("MYSQL_QUERY_LOG::close");
   if (log_state == LOG_OPENED)
   {
     end_io_cache(&log_file);
@@ -1666,7 +1456,7 @@ void MYSQL_LOG::close(uint exiting)
     if (mysql_file_sync(log_file.file, MYF(MY_WME)) && ! write_error)
     {
       char errbuf[MYSYS_STRERROR_SIZE];
-      write_error= 1;
+      write_error= true;
       sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno,
                       my_strerror(errbuf, sizeof(errbuf), errno));
     }
@@ -1674,53 +1464,34 @@ void MYSQL_LOG::close(uint exiting)
     if (mysql_file_close(log_file.file, MYF(MY_WME)) && ! write_error)
     {
       char errbuf[MYSYS_STRERROR_SIZE];
-      write_error= 1;
+      write_error= true;
       sql_print_error(ER_DEFAULT(ER_ERROR_ON_WRITE), name, errno,
                       my_strerror(errbuf, sizeof(errbuf), errno));
     }
   }
 
-  log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED;
+  log_state= to_be_reopened ? LOG_TO_BE_OPENED : LOG_CLOSED;
   my_free(name);
   name= NULL;
   DBUG_VOID_RETURN;
 }
 
+
 /** This is called only once. */
 
-void MYSQL_LOG::cleanup()
+void MYSQL_QUERY_LOG::cleanup()
 {
-  DBUG_ENTER("cleanup");
+  DBUG_ENTER("MYSQL_QUERY_LOG::cleanup");
   if (inited)
   {
-    inited= 0;
+    inited= false;
     mysql_mutex_destroy(&LOCK_log);
-    close(0);
+    close(false);
   }
   DBUG_VOID_RETURN;
 }
 
 
-int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name)
-{
-  fn_format(new_name, log_name, mysql_data_home, "", 4);
-  if (log_type == LOG_BIN)
-  {
-    if (!fn_ext(log_name)[0])
-    {
-      if (find_uniq_filename(new_name))
-      {
-        my_printf_error(ER_NO_UNIQUE_LOGFILE, ER(ER_NO_UNIQUE_LOGFILE),
-                        MYF(ME_FATALERROR), log_name);
-	sql_print_error(ER(ER_NO_UNIQUE_LOGFILE), log_name);
-	return 1;
-      }
-    }
-  }
-  return 0;
-}
-
-
 /*
   Reopen the log file
 
@@ -1732,12 +1503,11 @@ int MYSQL_LOG::generate_new_name(char *n
     and locks LOCK_log mutex
 */
 
-
 void MYSQL_QUERY_LOG::reopen_file()
 {
   char *save_name;
 
-  DBUG_ENTER("MYSQL_LOG::reopen_file");
+  DBUG_ENTER("MYSQL_QUERY_LOG::reopen_file");
   if (!is_open())
   {
     DBUG_PRINT("info",("log is closed"));
@@ -1747,8 +1517,8 @@ void MYSQL_QUERY_LOG::reopen_file()
   mysql_mutex_lock(&LOCK_log);
 
   save_name= name;
-  name= 0;				// Don't free name
-  close(LOG_CLOSE_TO_BE_OPENED);
+  name= NULL;				// Don't free name
+  close(true);
 
   /*
      Note that at this point, log_state != LOG_CLOSED (important for is_open()).
@@ -1758,7 +1528,7 @@ void MYSQL_QUERY_LOG::reopen_file()
 #ifdef HAVE_PSI_INTERFACE
        m_log_file_key,
 #endif
-       save_name, log_type, 0, io_cache_type);
+       save_name);
   my_free(save_name);
 
   mysql_mutex_unlock(&LOCK_log);
@@ -1852,18 +1622,18 @@ bool MYSQL_QUERY_LOG::write(time_t event
   }
 
   mysql_mutex_unlock(&LOCK_log);
-  return FALSE;
+  return false;
 err:
 
   if (!write_error)
   {
     char errbuf[MYSYS_STRERROR_SIZE];
-    write_error= 1;
+    write_error= true;
     sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno,
                     my_strerror(errbuf, sizeof(errbuf), errno));
   }
   mysql_mutex_unlock(&LOCK_log);
-  return TRUE;
+  return true;
 }
 
 
@@ -1902,7 +1672,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, ti
                             ulonglong lock_utime, bool is_command,
                             const char *sql_text, uint sql_text_len)
 {
-  bool error= 0;
+  bool error= false;
   DBUG_ENTER("MYSQL_QUERY_LOG::write");
 
   mysql_mutex_lock(&LOCK_log);
@@ -2010,11 +1780,11 @@ bool MYSQL_QUERY_LOG::write(THD *thd, ti
       tmp_errno= errno;
     if (tmp_errno)
     {
-      error= 1;
+      error= true;
       if (! write_error)
       {
         char errbuf[MYSYS_STRERROR_SIZE];
-        write_error= 1;
+        write_error= true;
         sql_print_error(ER(ER_ERROR_ON_WRITE), name, error,
                         my_strerror(errbuf, sizeof(errbuf), errno));
       }
@@ -2030,9 +1800,9 @@ bool MYSQL_QUERY_LOG::write(THD *thd, ti
   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.
 */
-const char *MYSQL_LOG::generate_name(const char *log_name,
-                                      const char *suffix,
-                                      bool strip_ext, char *buff)
+const char *MYSQL_QUERY_LOG::generate_name(const char *log_name,
+                                           const char *suffix,
+                                           char *buff)
 {
   if (!log_name || !log_name[0])
   {
@@ -2040,14 +1810,6 @@ const char *MYSQL_LOG::generate_name(con
     return (const char *)
       fn_format(buff, buff, "", suffix, MYF(MY_REPLACE_EXT|MY_REPLACE_DIR));
   }
-  // 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<size_t>(length, FN_REFLEN-1));
-    return (const char*)buff;
-  }
   return log_name;
 }
 
@@ -2110,6 +1872,7 @@ bool general_log_print(THD *thd, enum en
   return error;
 }
 
+
 bool general_log_write(THD *thd, enum enum_server_command command,
                        const char *query, uint query_length)
 {
@@ -2120,54 +1883,6 @@ bool general_log_write(THD *thd, enum en
   return FALSE;
 }
 
-/**
-  Check if a string is a valid number.
-
-  @param str			String to test
-  @param res			Store value here
-  @param allow_wildcards	Set to 1 if we should ignore '%' and '_'
-
-  @note
-    For the moment the allow_wildcards argument is not used
-    Should be move to some other file.
-
-  @retval
-    1	String is a number
-  @retval
-    0	String is not a number
-*/
-
-static bool test_if_number(register const char *str,
-			   ulong *res, bool allow_wildcards)
-{
-  reg2 int flag;
-  const char *start;
-  DBUG_ENTER("test_if_number");
-
-  flag=0; start=str;
-  while (*str++ == ' ') ;
-  if (*--str == '-' || *str == '+')
-    str++;
-  while (my_isdigit(files_charset_info,*str) ||
-	 (allow_wildcards && (*str == wild_many || *str == wild_one)))
-  {
-    flag=1;
-    str++;
-  }
-  if (*str == '.')
-  {
-    for (str++ ;
-	 my_isdigit(files_charset_info,*str) ||
-	   (allow_wildcards && (*str == wild_many || *str == wild_one)) ;
-	 str++, flag=1) ;
-  }
-  if (*str != 0 || flag == 0)
-    DBUG_RETURN(0);
-  if (res)
-    *res=atol(start);
-  DBUG_RETURN(1);			/* Number ok */
-} /* test_if_number */
-
 
 void sql_perror(const char *message)
 {
@@ -2228,6 +1943,7 @@ bool flush_error_log()
   return result;
 }
 
+
 #ifdef _WIN32
 static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
                                         size_t length, size_t buffLen)
@@ -2298,6 +2014,7 @@ static void print_buffer_to_file(enum lo
   DBUG_VOID_RETURN;
 }
 
+
 /**
   Prints a printf style message to the error log and, under NT, to the
   Windows event log.
@@ -2314,6 +2031,7 @@ static void print_buffer_to_file(enum lo
     signature to be compatible with other logging routines, which could
     return an error (e.g. logging to the log tables)
 */
+
 int vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
 {
   char   buff[1024];
@@ -2332,7 +2050,7 @@ int vprint_msg_to_log(enum loglevel leve
 #endif /* EMBEDDED_LIBRARY */
 
 
-void sql_print_error(const char *format, ...) 
+void sql_print_error(const char *format, ...)
 {
   va_list args;
   DBUG_ENTER("sql_print_error");
@@ -2345,7 +2063,7 @@ void sql_print_error(const char *format,
 }
 
 
-void sql_print_warning(const char *format, ...) 
+void sql_print_warning(const char *format, ...)
 {
   va_list args;
   DBUG_ENTER("sql_print_warning");
@@ -2358,7 +2076,7 @@ void sql_print_warning(const char *forma
 }
 
 
-void sql_print_information(const char *format, ...) 
+void sql_print_information(const char *format, ...)
 {
   va_list args;
   DBUG_ENTER("sql_print_information");
@@ -2662,7 +2380,7 @@ TC_LOG::enum_result TC_LOG_MMAP::commit(
     threads waiting for a page, but then all these threads will be waiting
     for a fsync() anyway
 
-   If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
+   If tc_log == MYSQL_BIN_LOG then tc_log writes transaction to binlog and
    records XID in a special Xid_log_event.
    If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
    log.

=== modified file 'sql/log.h'
--- a/sql/log.h	2012-11-06 14:16:49 +0000
+++ b/sql/log.h	2012-11-14 10:15:19 +0000
@@ -20,21 +20,6 @@
 #include "handler.h"                            /* my_xid */
 
 /**
-  the struct aggregates two paramenters that identify an event
-  uniquely in scope of communication of a particular master and slave couple.
-  I.e there can not be 2 events from the same staying connected master which
-  have the same coordinates.
-  @note
-  Such identifier is not yet unique generally as the event originating master
-  is resetable. Also the crashed master can be replaced with some other.
-*/
-typedef struct event_coordinates
-{
-  char * file_name; // binlog file name (directories stripped)
-  my_off_t  pos;       // event's position in the binlog file
-} LOG_POS_COORD;
-
-/**
   Transaction Coordinator Log.
 
   A base abstract class for three different implementations of the
@@ -183,160 +168,43 @@ extern TC_LOG *tc_log;
 extern TC_LOG_MMAP tc_log_mmap;
 extern TC_LOG_DUMMY tc_log_dummy;
 
-/* log info errors */
-#define LOG_INFO_EOF -1
-#define LOG_INFO_IO  -2
-#define LOG_INFO_INVALID -3
-#define LOG_INFO_SEEK -4
-#define LOG_INFO_MEM -6
-#define LOG_INFO_FATAL -7
-#define LOG_INFO_IN_USE -8
-#define LOG_INFO_EMFILE -9
-
-
-/* bitmap to SQL_LOG::close() */
-#define LOG_CLOSE_INDEX		1
-#define LOG_CLOSE_TO_BE_OPENED	2
-#define LOG_CLOSE_STOP_EVENT	4
-
-/* 
-  Maximum unique log filename extension.
-  Note: setting to 0x7FFFFFFF due to atol windows 
-        overflow/truncate.
- */
-#define MAX_LOG_UNIQUE_FN_EXT 0x7FFFFFFF
-
-/* 
-   Number of warnings that will be printed to error log
-   before extension number is exhausted.
-*/
-#define LOG_WARN_UNIQUE_FN_EXT_LEFT 1000
-
-#ifdef HAVE_PSI_INTERFACE
-extern PSI_mutex_key key_LOG_INFO_lock;
-#endif
-
-/*
-  Note that we destroy the lock mutex in the desctructor here.
-  This means that object instances cannot be destroyed/go out of scope,
-  until we have reset thd->current_linfo to NULL;
- */
-typedef struct st_log_info
+/* type of the log table */
+enum enum_log_table_type
 {
-  char log_file_name[FN_REFLEN];
-  my_off_t index_file_offset, index_file_start_offset;
-  my_off_t pos;
-  bool fatal; // if the purge happens to give us a negative offset
-  mysql_mutex_t lock;
-  st_log_info()
-    : index_file_offset(0), index_file_start_offset(0),
-      pos(0), fatal(0)
-    {
-      log_file_name[0] = '\0';
-      mysql_mutex_init(key_LOG_INFO_lock, &lock, MY_MUTEX_INIT_FAST);
-    }
-  ~st_log_info() { mysql_mutex_destroy(&lock);}
-} LOG_INFO;
-
-/*
-  Currently we have only 3 kinds of logging functions: old-fashioned
-  logs, stdout and csv logging routines.
-*/
-#define MAX_LOG_HANDLERS_NUM 3
-
-/* log event handler flags */
-#define LOG_NONE       1
-#define LOG_FILE       2
-#define LOG_TABLE      4
-
-enum enum_log_type { LOG_UNKNOWN, LOG_NORMAL, LOG_BIN };
-enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
-
-/*
-  TODO use mmap instead of IO_CACHE for binlog
-  (mmap+fsync is two times faster than write+fsync)
-*/
+  NO_LOG_TABLE = 0,
+  QUERY_LOG_SLOW = 1,
+  QUERY_LOG_GENERAL = 2
+};
 
-class MYSQL_LOG
+class MYSQL_QUERY_LOG
 {
+private:
+  static const uint MAX_TIME_SIZE= 32;
 public:
-  MYSQL_LOG();
-  void init_pthread_objects();
-  void cleanup();
-  bool open(
+  MYSQL_QUERY_LOG()
+  : name(NULL), write_error(false), inited(false),
+    log_state(LOG_CLOSED), last_time(0)
 #ifdef HAVE_PSI_INTERFACE
-            PSI_file_key log_file_key,
+    ,m_key_LOCK_log(key_LOG_LOCK_log)
 #endif
-            const char *log_name,
-            enum_log_type log_type,
-            const char *new_name,
-            enum cache_type io_cache_type_arg);
-  bool init_and_set_log_file_name(const char *log_name,
-                                  const char *new_name,
-                                  enum_log_type log_type_arg,
-                                  enum cache_type io_cache_type_arg);
-  void init(enum_log_type log_type_arg,
-            enum cache_type io_cache_type_arg);
-  void close(uint exiting);
-  inline bool is_open() { return log_state != LOG_CLOSED; }
-  const char *generate_name(const char *log_name, const char *suffix,
-                            bool strip_ext, char *buff);
-  int generate_new_name(char *new_name, const char *log_name);
- protected:
-  /* LOCK_log is inited by init_pthread_objects() */
-  mysql_mutex_t LOCK_log;
-  char *name;
-  char log_file_name[FN_REFLEN];
-  char time_buff[20], db[NAME_LEN + 1];
-  bool write_error, inited;
-  IO_CACHE log_file;
-  enum_log_type log_type;
-  volatile enum_log_state log_state;
-  enum cache_type io_cache_type;
-  friend class Log_event;
-#ifdef HAVE_PSI_INTERFACE
-  /** Instrumentation key to use for file io in @c log_file */
-  PSI_file_key m_log_file_key;
-  /** The instrumentation key to use for @ LOCK_log. */
-  PSI_mutex_key m_key_LOCK_log;
-#endif
-};
-
-
-enum enum_general_log_table_field
-{
-  GLT_FIELD_EVENT_TIME = 0,
-  GLT_FIELD_USER_HOST,
-  GLT_FIELD_THREAD_ID,
-  GLT_FIELD_SERVER_ID,
-  GLT_FIELD_COMMAND_TYPE,
-  GLT_FIELD_ARGUMENT,
-  GLT_FIELD_COUNT
-};
-
-
-enum enum_slow_query_log_table_field
-{
-  SQLT_FIELD_START_TIME = 0,
-  SQLT_FIELD_USER_HOST,
-  SQLT_FIELD_QUERY_TIME,
-  SQLT_FIELD_LOCK_TIME,
-  SQLT_FIELD_ROWS_SENT,
-  SQLT_FIELD_ROWS_EXAMINED,
-  SQLT_FIELD_DATABASE,
-  SQLT_FIELD_LAST_INSERT_ID,
-  SQLT_FIELD_INSERT_ID,
-  SQLT_FIELD_SERVER_ID,
-  SQLT_FIELD_SQL_TEXT,
-  SQLT_FIELD_THREAD_ID,
-  SQLT_FIELD_COUNT
-};
-
-
-class MYSQL_QUERY_LOG: public MYSQL_LOG
-{
-public:
-  MYSQL_QUERY_LOG() : last_time(0) {}
+  {
+    /*
+      We don't want to initialize LOCK_Log here as such initialization depends on
+      safe_mutex (when using safe_mutex) which depends on MY_INIT(), which is
+      called only in main(). Doing initialization here would make it happen
+      before main().
+    */
+    memset(&log_file, 0, sizeof(log_file));
+  }
+  bool is_open() const { return log_state != LOG_CLOSED; }
+  void close(bool to_be_reopened);
+  void cleanup();
+  void init_pthread_objects()
+  {
+    DBUG_ASSERT(inited == false);
+    inited= true;
+    mysql_mutex_init(m_key_LOCK_log, &LOCK_log, MY_MUTEX_INIT_SLOW);
+  }
   void reopen_file();
   bool write(time_t event_time, const char *user_host,
              uint user_host_len, my_thread_id thread_id,
@@ -353,8 +221,7 @@ public:
 #ifdef HAVE_PSI_INTERFACE
                 key_file_slow_log,
 #endif
-                generate_name(log_name, "-slow.log", 0, buf),
-                LOG_NORMAL, 0, WRITE_CACHE);
+                generate_name(log_name, "-slow.log", buf));
   }
   bool open_query_log(const char *log_name)
   {
@@ -363,12 +230,36 @@ public:
 #ifdef HAVE_PSI_INTERFACE
                 key_file_query_log,
 #endif
-                generate_name(log_name, ".log", 0, buf),
-                LOG_NORMAL, 0, WRITE_CACHE);
+                generate_name(log_name, ".log", buf));
   }
 
 private:
+  bool open(
+#ifdef HAVE_PSI_INTERFACE
+            PSI_file_key log_file_key,
+#endif
+            const char *log_name);
+  const char *generate_name(const char *log_name, const char *suffix,
+                            char *buff);
+
+  enum enum_log_state { LOG_OPENED, LOG_CLOSED, LOG_TO_BE_OPENED };
+
+private:
+  /* LOCK_log is inited by init_pthread_objects() */
+  mysql_mutex_t LOCK_log;
+  char *name;
+  char log_file_name[FN_REFLEN];
+  char db[NAME_LEN + 1];
+  bool write_error, inited;
+  IO_CACHE log_file;
+  volatile enum_log_state log_state;
   time_t last_time;
+#ifdef HAVE_PSI_INTERFACE
+  /** Instrumentation key to use for file io in @c log_file */
+  PSI_file_key m_log_file_key;
+  /** The instrumentation key to use for @ LOCK_log. */
+  PSI_mutex_key m_key_LOCK_log;
+#endif
 };
 
 class Log_event_handler
@@ -393,16 +284,10 @@ public:
   virtual ~Log_event_handler() {}
 };
 
-
-int check_if_log_table(size_t db_len, const char *db, size_t table_name_len,
-                       const char *table_name, bool check_if_opened);
-
 class Log_to_csv_event_handler: public Log_event_handler
 {
 public:
-  Log_to_csv_event_handler();
-  ~Log_to_csv_event_handler();
-  virtual bool init();
+  virtual bool init() { return false; }
   virtual void cleanup();
 
   virtual bool log_slow(THD *thd, time_t current_time,
@@ -411,20 +296,22 @@ public:
                         ulonglong lock_utime, bool is_command,
                         const char *sql_text, uint sql_text_len);
   virtual bool log_error(enum loglevel level, const char *format,
-                         va_list args);
+                         va_list args)
+  {
+    /* No log table is implemented */
+    DBUG_ASSERT(0);
+    return false;
+  }
   virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
                            uint user_host_len, my_thread_id thread_id,
                            const char *command_type, uint command_type_len,
                            const char *sql_text, uint sql_text_len,
                            const CHARSET_INFO *client_cs);
 
-  int activate_log(THD *thd, uint log_type);
+  int activate_log(THD *thd, enum_log_table_type log_type);
 };
 
-
-/* type of the log table */
-#define QUERY_LOG_SLOW 1
-#define QUERY_LOG_GENERAL 2
+int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
 
 class Log_to_file_event_handler: public Log_event_handler
 {
@@ -435,7 +322,11 @@ public:
   Log_to_file_event_handler(): is_initialized(FALSE)
   {}
   virtual bool init();
-  virtual void cleanup();
+  virtual void cleanup()
+  {
+    mysql_log.cleanup();
+    mysql_slow_log.cleanup();
+  }
 
   virtual bool log_slow(THD *thd, time_t current_time,
                         time_t query_start_arg, const char *user_host,
@@ -443,22 +334,43 @@ public:
                         ulonglong lock_utime, bool is_command,
                         const char *sql_text, uint sql_text_len);
   virtual bool log_error(enum loglevel level, const char *format,
-                         va_list args);
+                         va_list args)
+  {
+    return vprint_msg_to_log(level, format, args);
+  }
   virtual bool log_general(THD *thd, time_t event_time, const char *user_host,
                            uint user_host_len, my_thread_id thread_id,
                            const char *command_type, uint command_type_len,
                            const char *sql_text, uint sql_text_len,
                            const CHARSET_INFO *client_cs);
   void flush();
-  void init_pthread_objects();
+  void init_pthread_objects()
+  {
+    mysql_log.init_pthread_objects();
+    mysql_slow_log.init_pthread_objects();
+  }
   MYSQL_QUERY_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
   MYSQL_QUERY_LOG *get_mysql_log() { return &mysql_log; }
 };
 
 
+/* log event handler flags */
+static const uint LOG_NONE= 1;
+static const uint LOG_FILE= 2;
+static const uint LOG_TABLE= 4;
+
+
 /* Class which manages slow, general and error log event handlers */
 class LOGGER
 {
+  /*
+    Currently we have only 3 kinds of logging functions: old-fashioned
+    logs, stdout and csv logging routines.
+  */
+  static const uint MAX_LOG_HANDLERS_NUM= 3;
+  /* max size of the log message */
+  static const uint MAX_LOG_BUFFER_SIZE= 1024;
+
   mysql_rwlock_t LOCK_logger;
   /* flag to check whether logger mutex is initialized */
   uint inited;
@@ -471,18 +383,22 @@ class LOGGER
   Log_event_handler *error_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
   Log_event_handler *slow_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
   Log_event_handler *general_log_handler_list[MAX_LOG_HANDLERS_NUM + 1];
-
 public:
-
   bool is_log_tables_initialized;
 
+private:
+  void init_error_log(uint error_log_printer);
+  void init_slow_log(uint slow_log_printer);
+  void init_general_log(uint general_log_printer);
+
+public:
   LOGGER() : inited(0), table_log_handler(NULL),
              file_log_handler(NULL), is_log_tables_initialized(FALSE)
   {}
   void lock_shared() { mysql_rwlock_rdlock(&LOCK_logger); }
   void lock_exclusive() { mysql_rwlock_wrlock(&LOCK_logger); }
   void unlock() { mysql_rwlock_unlock(&LOCK_logger); }
-  bool is_log_table_enabled(uint log_table_type);
+  bool is_log_table_enabled(enum_log_table_type log_table_type);
   bool log_command(THD *thd, enum enum_server_command command);
 
   /*
@@ -512,45 +428,34 @@ public:
   int set_handlers(uint error_log_printer,
                    uint slow_log_printer,
                    uint general_log_printer);
-  void init_error_log(uint error_log_printer);
-  void init_slow_log(uint slow_log_printer);
-  void init_general_log(uint general_log_printer);
-  void deactivate_log_handler(THD* thd, uint log_type);
-  bool activate_log_handler(THD* thd, uint log_type);
+  void deactivate_log_handler(THD* thd, enum_log_table_type log_type);
+  bool activate_log_handler(THD* thd, enum_log_table_type log_type);
   MYSQL_QUERY_LOG *get_slow_log_file_handler() const
-  { 
+  {
     if (file_log_handler)
       return file_log_handler->get_mysql_slow_log();
     return NULL;
   }
   MYSQL_QUERY_LOG *get_log_file_handler() const
-  { 
+  {
     if (file_log_handler)
       return file_log_handler->get_mysql_log();
     return NULL;
   }
+  void set_log_output(uint log_printer)
+  {
+    lock_exclusive();
+    init_slow_log(log_printer);
+    init_general_log(log_printer);
+    unlock();
+  }
 };
 
-enum enum_binlog_row_image {
-  /** PKE in the before image and changed columns in the after image */
-  BINLOG_ROW_IMAGE_MINIMAL= 0,
-  /** Whenever possible, before and after image contain all columns except blobs. */
-  BINLOG_ROW_IMAGE_NOBLOB= 1,
-  /** All columns in both before and after image. */
-  BINLOG_ROW_IMAGE_FULL= 2
-};
-
-enum enum_binlog_format {
-  BINLOG_FORMAT_MIXED= 0, ///< statement if safe, otherwise row - autodetected
-  BINLOG_FORMAT_STMT=  1, ///< statement-based
-  BINLOG_FORMAT_ROW=   2, ///< row-based
-  BINLOG_FORMAT_UNSPEC=3  ///< thd_binlog_format() returns it when binlog is closed
-};
-
-int query_error_code(THD *thd, bool not_killed);
-uint purge_log_get_error_code(int res);
+enum_log_table_type check_if_log_table(size_t db_len, const char *db,
+                                       size_t table_name_len,
+                                       const char *table_name,
+                                       bool check_if_opened);
 
-int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
 void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
 void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
 void sql_print_information(const char *format, ...)

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2012-11-08 10:05:03 +0000
+++ b/sql/mysqld.cc	2012-11-14 10:15:19 +0000
@@ -4669,7 +4669,7 @@ a file name for --log-bin-index option",
 
     char buf[FN_REFLEN];
     const char *ln;
-    ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
+    ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", buf);
     if (!opt_bin_logname && !opt_binlog_index_name)
     {
       /*
@@ -4903,7 +4903,7 @@ a file name for --log-bin-index option",
     mysql_bin_log.set_previous_gtid_set(
       const_cast<Gtid_set*>(gtid_state->get_logged_gtids()));
     if (mysql_bin_log.open_binlog(opt_bin_logname, 0,
-                                  WRITE_CACHE, max_binlog_size, false,
+                                  max_binlog_size, false,
                                   true/*need_lock_index=true*/,
                                   true/*need_sid_lock=true*/,
                                   NULL))

=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc	2012-11-06 14:16:49 +0000
+++ b/sql/rpl_rli.cc	2012-11-14 10:15:19 +0000
@@ -75,7 +75,7 @@ Relay_log_info::Relay_log_info(bool is_s
              , param_id
             ),
    replicate_same_server_id(::replicate_same_server_id),
-   cur_log_fd(-1), relay_log(&sync_relaylog_period),
+   cur_log_fd(-1), relay_log(&sync_relaylog_period, SEQ_READ_APPEND),
    is_relay_log_recovery(is_slave_recovery),
    save_temporary_tables(0),
    cur_log_old_open_count(0), group_relay_log_pos(0), event_relay_log_pos(0),
@@ -1727,7 +1727,7 @@ a file name for --relay-log-index option
     const char *ln;
     static bool name_warning_sent= 0;
     ln= relay_log.generate_name(opt_relay_logname, "-relay-bin",
-                                1, buf);
+                                buf);
     /* We send the warning only at startup, not after every RESET SLAVE */
     if (!opt_relay_logname && !opt_relaylog_index_name && !name_warning_sent)
     {
@@ -1781,7 +1781,7 @@ a file name for --relay-log-index option
       note, that if open() fails, we'll still have index file open
       but a destructor will take care of that
     */
-    if (relay_log.open_binlog(ln, 0, SEQ_READ_APPEND,
+    if (relay_log.open_binlog(ln, 0,
                               (max_relay_log_size ? max_relay_log_size :
                                max_binlog_size), true,
                               true/*need_lock_index=true*/,

=== modified file 'sql/rpl_tblmap.h'
--- a/sql/rpl_tblmap.h	2011-09-07 10:08:09 +0000
+++ b/sql/rpl_tblmap.h	2012-11-14 10:15:19 +0000
@@ -26,6 +26,22 @@ void free_table_map_log_event(TABLE *tab
 #endif
 
 
+/**
+  the struct aggregates two paramenters that identify an event
+  uniquely in scope of communication of a particular master and slave couple.
+  I.e there can not be 2 events from the same staying connected master which
+  have the same coordinates.
+  @note
+  Such identifier is not yet unique generally as the event originating master
+  is resetable. Also the crashed master can be replaced with some other.
+*/
+typedef struct event_coordinates
+{
+  char * file_name; // binlog file name (directories stripped)
+  my_off_t  pos;       // event's position in the binlog file
+} LOG_POS_COORD;
+
+
 /*
   CLASS table_mapping
 

=== modified file 'sql/sql_alter.cc'
--- a/sql/sql_alter.cc	2012-10-25 13:34:04 +0000
+++ b/sql/sql_alter.cc	2012-11-14 10:15:19 +0000
@@ -340,11 +340,12 @@ bool Sql_cmd_discard_import_tablespace::
     it is the case.
     TODO: this design is obsolete and will be removed.
   */
-  int table_kind= check_if_log_table(table_list->db_length, table_list->db,
-                                     table_list->table_name_length,
-                                     table_list->table_name, false);
+  enum_log_table_type table_kind=
+    check_if_log_table(table_list->db_length, table_list->db,
+                       table_list->table_name_length,
+                       table_list->table_name, false);
 
-  if (table_kind)
+  if (table_kind != NO_LOG_TABLE)
   {
     /* Disable alter of enabled log tables */
     if (logger.is_log_table_enabled(table_kind))

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2012-11-08 23:03:17 +0000
+++ b/sql/sql_class.h	2012-11-14 10:15:19 +0000
@@ -81,6 +81,7 @@ class Rows_log_event;
 class Sroutine_hash_entry;
 class User_level_lock;
 class user_var_entry;
+typedef struct st_log_info LOG_INFO;
 
 enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
 
@@ -94,6 +95,20 @@ enum enum_slave_type_conversions { SLAVE
 enum enum_slave_rows_search_algorithms { SLAVE_ROWS_TABLE_SCAN = (1U << 0),
                                          SLAVE_ROWS_INDEX_SCAN = (1U << 1),
                                          SLAVE_ROWS_HASH_SCAN  = (1U << 2)};
+enum enum_binlog_row_image {
+  /** PKE in the before image and changed columns in the after image */
+  BINLOG_ROW_IMAGE_MINIMAL= 0,
+  /** Whenever possible, before and after image contain all columns except blobs. */
+  BINLOG_ROW_IMAGE_NOBLOB= 1,
+  /** All columns in both before and after image. */
+  BINLOG_ROW_IMAGE_FULL= 2
+};
+enum enum_binlog_format {
+  BINLOG_FORMAT_MIXED= 0, ///< statement if safe, otherwise row - autodetected
+  BINLOG_FORMAT_STMT=  1, ///< statement-based
+  BINLOG_FORMAT_ROW=   2, ///< row-based
+  BINLOG_FORMAT_UNSPEC=3  ///< thd_binlog_format() returns it when binlog is closed
+};
 
 enum enum_mark_columns
 { MARK_COLUMNS_NONE, MARK_COLUMNS_READ, MARK_COLUMNS_WRITE};

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2012-11-07 12:05:17 +0000
+++ b/sql/sql_table.cc	2012-11-14 10:15:19 +0000
@@ -7487,11 +7487,12 @@ bool mysql_alter_table(THD *thd,char *ne
     it is the case.
     TODO: this design is obsolete and will be removed.
   */
-  int table_kind= check_if_log_table(table_list->db_length, table_list->db,
-                                     table_list->table_name_length,
-                                     table_list->table_name, false);
+  enum_log_table_type table_kind=
+    check_if_log_table(table_list->db_length, table_list->db,
+                       table_list->table_name_length,
+                       table_list->table_name, false);
 
-  if (table_kind)
+  if (table_kind != NO_LOG_TABLE)
   {
     /* Disable alter of enabled log tables */
     if (logger.is_log_table_enabled(table_kind))

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2012-11-07 16:54:50 +0000
+++ b/sql/sys_vars.cc	2012-11-14 10:15:19 +0000
@@ -3764,7 +3764,7 @@ static bool fix_log_state(sys_var *self,
 {
   bool res;
   my_bool *UNINIT_VAR(newvalptr), newval, UNINIT_VAR(oldval);
-  uint UNINIT_VAR(log_type);
+  enum_log_table_type log_type= NO_LOG_TABLE;
 
   if (self == &Sys_general_log)
   {
@@ -3805,10 +3805,7 @@ static bool check_not_empty_set(sys_var
 }
 static bool fix_log_output(sys_var *self, THD *thd, enum_var_type type)
 {
-  logger.lock_exclusive();
-  logger.init_slow_log(log_output_options);
-  logger.init_general_log(log_output_options);
-  logger.unlock();
+  logger.set_log_output(log_output_options);
   return false;
 }
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-wl6613 branch (jon.hauglid:4987 to 4988) WL#6613Jon Olav Hauglid15 Nov