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#6613 | Jon Olav Hauglid | 15 Nov |