Commit e3e2b4e1 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-15 Log SQL errors.

        mysys/my_logger.c was moved to sql/sql_logger.c
        Logger service was rewritten with file functions instead of stream, so it
        can handle huge files.
parent 620d62ac
...@@ -84,7 +84,7 @@ const char *set_thd_proc_info(void*, const char * info, const char *func, ...@@ -84,7 +84,7 @@ const char *set_thd_proc_info(void*, const char * info, const char *func,
typedef struct logger_handle_st LOGGER_HANDLE; typedef struct logger_handle_st LOGGER_HANDLE;
extern struct logger_service_st { extern struct logger_service_st {
LOGGER_HANDLE* (*open)(const char *path, LOGGER_HANDLE* (*open)(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations); unsigned int rotations);
int (*close)(LOGGER_HANDLE *log); int (*close)(LOGGER_HANDLE *log);
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
...@@ -92,7 +92,7 @@ extern struct logger_service_st { ...@@ -92,7 +92,7 @@ extern struct logger_service_st {
int (*rotate)(LOGGER_HANDLE *log); int (*rotate)(LOGGER_HANDLE *log);
} *logger_service; } *logger_service;
LOGGER_HANDLE *logger_open(const char *path, LOGGER_HANDLE *logger_open(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations); unsigned int rotations);
int logger_close(LOGGER_HANDLE *log); int logger_close(LOGGER_HANDLE *log);
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
......
...@@ -84,7 +84,7 @@ const char *set_thd_proc_info(void*, const char * info, const char *func, ...@@ -84,7 +84,7 @@ const char *set_thd_proc_info(void*, const char * info, const char *func,
typedef struct logger_handle_st LOGGER_HANDLE; typedef struct logger_handle_st LOGGER_HANDLE;
extern struct logger_service_st { extern struct logger_service_st {
LOGGER_HANDLE* (*open)(const char *path, LOGGER_HANDLE* (*open)(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations); unsigned int rotations);
int (*close)(LOGGER_HANDLE *log); int (*close)(LOGGER_HANDLE *log);
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
...@@ -92,7 +92,7 @@ extern struct logger_service_st { ...@@ -92,7 +92,7 @@ extern struct logger_service_st {
int (*rotate)(LOGGER_HANDLE *log); int (*rotate)(LOGGER_HANDLE *log);
} *logger_service; } *logger_service;
LOGGER_HANDLE *logger_open(const char *path, LOGGER_HANDLE *logger_open(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations); unsigned int rotations);
int logger_close(LOGGER_HANDLE *log); int logger_close(LOGGER_HANDLE *log);
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
......
...@@ -84,7 +84,7 @@ const char *set_thd_proc_info(void*, const char * info, const char *func, ...@@ -84,7 +84,7 @@ const char *set_thd_proc_info(void*, const char * info, const char *func,
typedef struct logger_handle_st LOGGER_HANDLE; typedef struct logger_handle_st LOGGER_HANDLE;
extern struct logger_service_st { extern struct logger_service_st {
LOGGER_HANDLE* (*open)(const char *path, LOGGER_HANDLE* (*open)(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations); unsigned int rotations);
int (*close)(LOGGER_HANDLE *log); int (*close)(LOGGER_HANDLE *log);
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
...@@ -92,7 +92,7 @@ extern struct logger_service_st { ...@@ -92,7 +92,7 @@ extern struct logger_service_st {
int (*rotate)(LOGGER_HANDLE *log); int (*rotate)(LOGGER_HANDLE *log);
} *logger_service; } *logger_service;
LOGGER_HANDLE *logger_open(const char *path, LOGGER_HANDLE *logger_open(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations); unsigned int rotations);
int logger_close(LOGGER_HANDLE *log); int logger_close(LOGGER_HANDLE *log);
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
......
...@@ -61,7 +61,7 @@ typedef struct logger_handle_st LOGGER_HANDLE; ...@@ -61,7 +61,7 @@ typedef struct logger_handle_st LOGGER_HANDLE;
extern struct logger_service_st { extern struct logger_service_st {
LOGGER_HANDLE* (*open)(const char *path, LOGGER_HANDLE* (*open)(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations); unsigned int rotations);
int (*close)(LOGGER_HANDLE *log); int (*close)(LOGGER_HANDLE *log);
int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
...@@ -81,7 +81,7 @@ extern struct logger_service_st { ...@@ -81,7 +81,7 @@ extern struct logger_service_st {
#else #else
LOGGER_HANDLE *logger_open(const char *path, LOGGER_HANDLE *logger_open(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations); unsigned int rotations);
int logger_close(LOGGER_HANDLE *log); int logger_close(LOGGER_HANDLE *log);
int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr);
......
...@@ -95,6 +95,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ...@@ -95,6 +95,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/create_options.cc ../sql/rpl_utility.cc ../sql/create_options.cc ../sql/rpl_utility.cc
../sql/rpl_reporting.cc ../sql/rpl_reporting.cc
../sql/sql_expression_cache.cc ../sql/sql_expression_cache.cc
../sql/sql_logger.c
${GEN_SOURCES} ${GEN_SOURCES}
${MYSYS_LIBWRAP_SOURCE} ${MYSYS_LIBWRAP_SOURCE}
) )
......
...@@ -37,7 +37,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c ...@@ -37,7 +37,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c
safemalloc.c my_new.cc safemalloc.c my_new.cc
my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c
my_rdtsc.c my_context.c my_logger.c) my_rdtsc.c my_context.c)
IF (WIN32) IF (WIN32)
SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_winthread.c my_wincond.c my_winerr.c my_winfile.c my_windac.c my_conio.c) SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_winthread.c my_wincond.c my_winerr.c my_winfile.c my_windac.c my_conio.c)
......
...@@ -17,13 +17,24 @@ ...@@ -17,13 +17,24 @@
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
/*
Disable __attribute__() on non-gcc compilers.
*/
#if !defined(__attribute__) && !defined(__GNUC__)
#define __attribute__(A)
#endif
#ifdef _WIN32
#define localtime_r(a, b) localtime_s(b, a)
#endif /*WIN32*/
/* /*
rate 0 means the logging was disabled. rate 0 means the logging was disabled.
*/ */
static char *filename; static char *filename;
static unsigned int rate; static unsigned int rate;
static unsigned int size_limit; static unsigned long long size_limit;
static unsigned int rotations; static unsigned int rotations;
static char rotate; static char rotate;
...@@ -37,9 +48,9 @@ static MYSQL_SYSVAR_UINT(rate, rate, PLUGIN_VAR_RQCMDARG, ...@@ -37,9 +48,9 @@ static MYSQL_SYSVAR_UINT(rate, rate, PLUGIN_VAR_RQCMDARG,
"Sampling rate. If set to 0(zero), the logging is disabled.", NULL, NULL, "Sampling rate. If set to 0(zero), the logging is disabled.", NULL, NULL,
1, 0, 1000000, 1); 1, 0, 1000000, 1);
static MYSQL_SYSVAR_UINT(size_limit, size_limit, static MYSQL_SYSVAR_ULONGLONG(size_limit, size_limit,
PLUGIN_VAR_READONLY, "Log file size limit", NULL, NULL, PLUGIN_VAR_READONLY, "Log file size limit", NULL, NULL,
1000000, 100, 1024*1024L*1024L, 1); 1000000, 100, 0, 1);
static MYSQL_SYSVAR_UINT(rotations, rotations, static MYSQL_SYSVAR_UINT(rotations, rotations,
PLUGIN_VAR_READONLY, "Number of rotations before log is removed.", PLUGIN_VAR_READONLY, "Number of rotations before log is removed.",
...@@ -79,7 +90,7 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)), ...@@ -79,7 +90,7 @@ static void log_sql_errors(MYSQL_THD thd __attribute__((unused)),
time_t event_time = event->general_time; time_t event_time = event->general_time;
count = 0; count = 0;
localtime_r(&event_time, &t); (void) localtime_r(&event_time, &t);
logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d " logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d "
"%s ERROR %d: %s : %s\n", "%s ERROR %d: %s : %s\n",
t.tm_year + 1900, t.tm_mon + 1, t.tm_year + 1900, t.tm_mon + 1,
......
...@@ -85,6 +85,7 @@ SET (SQL_SOURCE ...@@ -85,6 +85,7 @@ SET (SQL_SOURCE
gcalc_slicescan.cc gcalc_tools.cc gcalc_slicescan.cc gcalc_tools.cc
threadpool_common.cc threadpool_common.cc
../sql-common/mysql_async.c ../sql-common/mysql_async.c
sql_logger.c
${GEN_SOURCES} ${GEN_SOURCES}
${MYSYS_LIBWRAP_SOURCE} ${MYSYS_LIBWRAP_SOURCE}
) )
......
...@@ -22,15 +22,17 @@ extern char *mysql_data_home; ...@@ -22,15 +22,17 @@ extern char *mysql_data_home;
extern PSI_mutex_key key_LOCK_logger_service; extern PSI_mutex_key key_LOCK_logger_service;
typedef struct logger_handle_st { typedef struct logger_handle_st {
FILE *file; File file;
char path[FN_REFLEN]; char path[FN_REFLEN];
long size_limit; unsigned long long size_limit;
unsigned int rotations; unsigned int rotations;
size_t path_len; size_t path_len;
mysql_mutex_t lock; mysql_mutex_t lock;
} LSFS; } LSFS;
#define LOG_FLAGS (O_APPEND | O_CREAT | O_WRONLY)
static unsigned int n_dig(unsigned int i) static unsigned int n_dig(unsigned int i)
{ {
return (i == 0) ? 0 : ((i < 10) ? 1 : ((i < 100) ? 2 : 3)); return (i == 0) ? 0 : ((i < 10) ? 1 : ((i < 100) ? 2 : 3));
...@@ -38,7 +40,7 @@ static unsigned int n_dig(unsigned int i) ...@@ -38,7 +40,7 @@ static unsigned int n_dig(unsigned int i)
LOGGER_HANDLE *logger_open(const char *path, LOGGER_HANDLE *logger_open(const char *path,
unsigned long size_limit, unsigned long long size_limit,
unsigned int rotations) unsigned int rotations)
{ {
LOGGER_HANDLE new_log, *l_perm; LOGGER_HANDLE new_log, *l_perm;
...@@ -61,19 +63,17 @@ LOGGER_HANDLE *logger_open(const char *path, ...@@ -61,19 +63,17 @@ LOGGER_HANDLE *logger_open(const char *path,
/* File path too long */ /* File path too long */
return 0; return 0;
} }
if (!(new_log.file= fopen(new_log.path, "a+"))) if ((new_log.file= my_open(new_log.path, LOG_FLAGS, MYF(0))) < 0)
{ {
errno= my_errno;
/* Check errno for the cause */ /* Check errno for the cause */
return 0; return 0;
} }
setbuf(new_log.file, 0); if (!(l_perm= (LOGGER_HANDLE *) my_malloc(sizeof(LOGGER_HANDLE), MYF(0))))
fseek(new_log.file, 0, SEEK_END);
if (!(l_perm= (LOGGER_HANDLE *)
my_malloc(sizeof(LOGGER_HANDLE), MYF(0))))
{ {
fclose(new_log.file); my_close(new_log.file, MYF(0));
new_log.file= NULL; new_log.file= -1;
return 0; /* End of memory */ return 0; /* End of memory */
} }
*l_perm= new_log; *l_perm= new_log;
...@@ -84,9 +84,11 @@ LOGGER_HANDLE *logger_open(const char *path, ...@@ -84,9 +84,11 @@ LOGGER_HANDLE *logger_open(const char *path,
int logger_close(LOGGER_HANDLE *log) int logger_close(LOGGER_HANDLE *log)
{ {
int result; int result;
File file= log->file;
mysql_mutex_destroy(&log->lock); mysql_mutex_destroy(&log->lock);
result= fclose(log->file);
my_free(log); my_free(log);
if ((result= my_close(file, MYF(0))))
errno= my_errno;
return result; return result;
} }
...@@ -114,32 +116,45 @@ static int do_rotate(LOGGER_HANDLE *log) ...@@ -114,32 +116,45 @@ static int do_rotate(LOGGER_HANDLE *log)
logname(log, buf_old, i); logname(log, buf_old, i);
if (!access(buf_old, F_OK) && if (!access(buf_old, F_OK) &&
(result= my_rename(buf_old, buf_new, MYF(0)))) (result= my_rename(buf_old, buf_new, MYF(0))))
return result; goto exit;
tmp= buf_old; tmp= buf_old;
buf_old= buf_new; buf_old= buf_new;
buf_new= tmp; buf_new= tmp;
} }
if ((result= fclose(log->file))) if ((result= my_close(log->file, MYF(0))))
return result; goto exit;
namebuf[log->path_len]= 0; namebuf[log->path_len]= 0;
result= my_rename(namebuf, logname(log, log->path, 1), MYF(0)); result= my_rename(namebuf, logname(log, log->path, 1), MYF(0));
log->file= fopen(namebuf, "a+"); log->file= my_open(namebuf, LOG_FLAGS, MYF(0));
return log->file==NULL || result; exit:
errno= my_errno;
return log->file < 0 || result;
} }
int logger_vprintf(LOGGER_HANDLE *log, const char* fmt, va_list ap) int logger_vprintf(LOGGER_HANDLE *log, const char* fmt, va_list ap)
{ {
int result; int result;
my_off_t filesize;
char cvtbuf[1024];
size_t n_bytes;
mysql_mutex_lock(&log->lock); mysql_mutex_lock(&log->lock);
if (ftell(log->file) >= log->size_limit && if ((filesize= my_tell(log->file, MYF(0))) == (my_off_t) -1 ||
do_rotate(log)) ((unsigned long long)filesize >= log->size_limit &&
do_rotate(log)))
{ {
result= -1; result= -1;
errno= my_errno;
goto exit; /* Log rotation needed but failed */ goto exit; /* Log rotation needed but failed */
} }
result= my_vfprintf(log->file, fmt, ap); n_bytes= my_vsnprintf(cvtbuf, sizeof(cvtbuf), fmt, ap);
if (n_bytes >= sizeof(cvtbuf))
n_bytes= sizeof(cvtbuf) - 1;
result= my_write(log->file, (uchar *) cvtbuf, n_bytes, MYF(0));
exit: exit:
mysql_mutex_unlock(&log->lock); mysql_mutex_unlock(&log->lock);
return result; return result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment