mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -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 {
|
|||||||
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,
|
|||||||
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 {
|
|||||||
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,
|
|||||||
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 {
|
|||||||
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;
|
|||||||
|
|
||||||
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 {
|
|||||||
#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
|
|||||||
../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
|
|||||||
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 @@
|
|||||||
#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,
|
|||||||
"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)),
|
|||||||
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
|
|||||||
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;
|
|||||||
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)
|
|||||||
|
|
||||||
|
|
||||||
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,
|
|||||||
/* 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,
|
|||||||
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)
|
|||||||
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;
|
Reference in New Issue
Block a user