Below is the list of changes that have just been committed into a local
5.1 repository of antony. When antony does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-03-08 02:46:56-08:00, acurtis@stripped +15 -0
Temporary commit for work in progress.
Will be collapsed at a later date.
libmysqld/Makefile.am@stripped, 2007-03-08 02:46:30-08:00, acurtis@stripped +1 -1
remove log_file.cc and log_table.cc from the makefile as it is now built by the
plugin framework.
plugin/log_file/Makefile.am@stripped, 2007-03-08 02:46:32-08:00, acurtis@stripped +43 -0
New BitKeeper file ``plugin/log_file/Makefile.am''
plugin/log_file/Makefile.am@stripped, 2007-03-08 02:46:32-08:00, acurtis@stripped +0 -0
plugin/log_file/log_file.cc@stripped, 2007-03-07 23:04:41-08:00, acurtis@stripped +0 -0
Rename: sql/log_file.cc -> plugin/log_file/log_file.cc
plugin/log_file/plug.in@stripped, 2007-03-08 02:46:32-08:00, acurtis@stripped +5 -0
New BitKeeper file ``plugin/log_file/plug.in''
plugin/log_file/plug.in@stripped, 2007-03-08 02:46:32-08:00, acurtis@stripped +0 -0
plugin/log_null/Makefile.am@stripped, 2007-03-08 02:46:33-08:00, acurtis@stripped +45 -0
New BitKeeper file ``plugin/log_null/Makefile.am''
plugin/log_null/Makefile.am@stripped, 2007-03-08 02:46:33-08:00, acurtis@stripped +0 -0
plugin/log_null/log_null.cc@stripped, 2007-03-08 02:46:33-08:00, acurtis@stripped +165 -0
New BitKeeper file ``plugin/log_null/log_null.cc''
plugin/log_null/log_null.cc@stripped, 2007-03-08 02:46:33-08:00, acurtis@stripped +0 -0
plugin/log_null/plug.in@stripped, 2007-03-08 02:46:34-08:00, acurtis@stripped +5 -0
New BitKeeper file ``plugin/log_null/plug.in''
plugin/log_null/plug.in@stripped, 2007-03-08 02:46:34-08:00, acurtis@stripped +0 -0
plugin/log_syslog/Makefile.am@stripped, 2007-03-08 02:46:35-08:00, acurtis@stripped +45 -0
New BitKeeper file ``plugin/log_syslog/Makefile.am''
plugin/log_syslog/Makefile.am@stripped, 2007-03-08 02:46:34-08:00, acurtis@stripped +0 -0
plugin/log_syslog/log_syslog.cc@stripped, 2007-03-08 02:46:35-08:00, acurtis@stripped +177
-0
New BitKeeper file ``plugin/log_syslog/log_syslog.cc''
plugin/log_syslog/log_syslog.cc@stripped, 2007-03-08 02:46:35-08:00, acurtis@stripped +0 -0
plugin/log_syslog/plug.in@stripped, 2007-03-08 02:46:35-08:00, acurtis@stripped +5 -0
New BitKeeper file ``plugin/log_syslog/plug.in''
plugin/log_syslog/plug.in@stripped, 2007-03-08 02:46:35-08:00, acurtis@stripped +0 -0
plugin/log_table/Makefile.am@stripped, 2007-03-08 02:46:31-08:00, acurtis@stripped +45 -0
New BitKeeper file ``plugin/log_table/Makefile.am''
plugin/log_table/Makefile.am@stripped, 2007-03-08 02:46:31-08:00, acurtis@stripped +0 -0
plugin/log_table/log_table.cc@stripped, 2007-03-08 02:46:30-08:00, acurtis@stripped +379
-156
remove tab characters.
make it actually work.
plugin/log_table/log_table.cc@stripped, 2007-03-08 01:19:52-08:00, acurtis@stripped +0 -0
Rename: sql/log_table.cc -> plugin/log_table/log_table.cc
plugin/log_table/plug.in@stripped, 2007-03-08 02:46:32-08:00, acurtis@stripped +5 -0
New BitKeeper file ``plugin/log_table/plug.in''
plugin/log_table/plug.in@stripped, 2007-03-08 02:46:32-08:00, acurtis@stripped +0 -0
sql/Makefile.am@stripped, 2007-03-08 02:46:30-08:00, acurtis@stripped +0 -1
remove log_file.cc and log_table.cc from the makefile as it is now built by the
plugin framework.
sql/sql_logger.cc@stripped, 2007-03-08 02:46:31-08:00, acurtis@stripped +0 -1
remove unused variable.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: acurtis
# Host: ltamd64.xiphis.org
# Root: /home/antony/work2/mysql-5.1-logging.2
--- 1.176/sql/Makefile.am 2007-03-08 02:47:49 -08:00
+++ 1.177/sql/Makefile.am 2007-03-08 02:47:49 -08:00
@@ -111,7 +111,6 @@
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_logger.cc \
- log_file.cc log_table.cc \
sql_servers.cc
--- New file ---
+++ plugin/log_file/Makefile.am 07/03/08 02:46:32
# Copyright (C) 2007 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#called from the top level Makefile
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
MYSQLLIBdir= $(pkglibdir)
INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
-I$(top_srcdir)/regex \
-I$(top_srcdir)/sql \
-I$(srcdir)
WRAPLIBS=
LDADD =
DEFS = @DEFS@ -DMYSQL_SERVER
noinst_HEADERS =
EXTRA_LIBRARIES = liblogfile.a
noinst_LIBRARIES = @plugin_logfile_static_target@
liblogfile_a_CXXFLAGS= $(AM_CFLAGS)
liblogfile_a_CFLAGS = $(AM_CFLAGS)
liblogfile_a_SOURCES= log_file.cc
EXTRA_DIST = CMakeLists.txt plug.in
# Don't update the files from bitkeeper
%::SCCS/s.%
--- New file ---
+++ plugin/log_file/plug.in 07/03/08 02:46:32
MYSQL_PLUGIN(logfile, [Text File Log Plugin],
[This plugin writes the general log and the slow query log as a text file.])
MYSQL_PLUGIN_STATIC(logfile, [liblogfile.a])
MYSQL_PLUGIN_MANDATORY(logfile) dnl Default
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(logfile, [log_file.cc])
--- New file ---
+++ plugin/log_null/Makefile.am 07/03/08 02:46:33
# Copyright (C) 2007 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#called from the top level Makefile
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
MYSQLLIBdir= $(pkglibdir)
INCLUDES = -I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/regex \
-I$(top_srcdir)/sql \
-I$(srcdir)
LDADD =
DEFS = @DEFS@ -DMYSQL_SERVER
noinst_HEADERS =
EXTRA_LTLIBRARIES = log_null.la
pkglib_LTLIBRARIES = @plugin_lognull_shared_target@
log_null_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
log_null_la_CXXFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
log_null_la_SOURCES = log_null.cc
EXTRA_LIBRARIES = liblognull.a
noinst_LIBRARIES = @plugin_lognull_static_target@
liblognull_a_CXXFLAGS = $(AM_CFLAGS)
liblognull_a_SOURCES = log_null.cc
EXTRA_DIST = CMakeLists.txt plug.in
# Don't update the files from bitkeeper
%::SCCS/s.%
--- New file ---
+++ plugin/log_null/log_null.cc 07/03/08 02:46:33
/* Copyright (C) 2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
#include <stdarg.h>
#include <mysql/plugin.h>
struct log_data
{
int err_count;
int pre_count;
int suf_count;
int flush_count;
};
static int null_prefix_log(THD *thd, void *data, time_t start_time,
enum loglevel log_level,
enum enum_server_command command,
const char *format, va_list args)
{
log_data *log= (log_data*) data;
/*
This is called before a statement has been executed.
*/
log->pre_count++;
return 0;
}
static int null_suffix_log(THD *thd, void *data, time_t start_time,
enum loglevel log_level,
enum enum_server_command command,
const char *format, va_list args)
{
log_data *log= (log_data*) data;
/*
This is called after a statement has been executed.
*/
log->suf_count++;
return 0;
}
static int null_error_log(THD *thd, void *data, time_t start_time,
enum loglevel log_level,
enum enum_server_command command,
const char *format, va_list args)
{
log_data *log= (log_data*) data;
/*
When an error message is emitted by mysqld, it will
be seen here.
*/
log->err_count++;
return 0;
}
static my_bool null_flush_logs(THD *thd, void *data)
{
log_data *log= (log_data*) data;
/*
Called when FLUSH is encountered.
This is where if you have any open file handles,
you may want to close and reopen them.
*/
log->flush_count++;
return 0;
}
static int logger_init(void *p)
{
mysql_logger *logger= (mysql_logger *) p;
log_data *data;
int error= ENOMEM;
if (!(data= (log_data *) my_malloc(sizeof(log_data),
MYF(MY_WME | MY_ZEROFILL))))
goto fail;
/*
Set up your data structures.
Install whatever interests you.
*/
logger->prefix_log= null_prefix_log;
logger->suffix_log= null_suffix_log;
logger->error_log= null_error_log;
logger->flush_logs= null_flush_logs;
logger->data= data;
error= 0;
fail:
if (error && data)
{
my_free((gptr) data, MYF(MY_WME));
}
return error;
}
static int logger_fini(void *p)
{
mysql_logger *logger= (mysql_logger *) p;
log_data *data= (log_data *) logger->data;
if (data)
{
my_free((gptr) data, MYF(MY_WME));
}
return 0;
}
struct st_mysql_logging log_null=
{ MYSQL_LOGGING_INTERFACE_VERSION };
mysql_declare_plugin(lognull)
{
MYSQL_LOGGING_PLUGIN,
&log_null,
"LogNull",
"MySQL AB",
"Logging to nowhere",
PLUGIN_LICENSE_GPL,
logger_init, /* Plugin Init */
logger_fini, /* Plugin Deinit */
0x0100 /* 1.0 */,
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
--- New file ---
+++ plugin/log_null/plug.in 07/03/08 02:46:34
MYSQL_PLUGIN(lognull, [Null Log Plugin],
[This Log plugin does not do anything useful.])
MYSQL_PLUGIN_DYNAMIC(lognull, [log_null.la])
MYSQL_PLUGIN_STATIC(lognull, [liblognull.a])
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(lognull, [log_null.cc])
--- New file ---
+++ plugin/log_syslog/Makefile.am 07/03/08 02:46:34
# Copyright (C) 2007 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#called from the top level Makefile
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
MYSQLLIBdir= $(pkglibdir)
INCLUDES = -I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/regex \
-I$(top_srcdir)/sql \
-I$(srcdir)
LDADD =
DEFS = @DEFS@ -DMYSQL_SERVER
noinst_HEADERS =
EXTRA_LTLIBRARIES = log_syslog.la
pkglib_LTLIBRARIES = @plugin_logsyslog_shared_target@
log_syslog_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
log_syslog_la_CXXFLAGS =$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
log_syslog_la_SOURCES = log_syslog.cc
EXTRA_LIBRARIES = liblogsyslog.a
noinst_LIBRARIES = @plugin_logsyslog_static_target@
liblogsyslog_a_CXXFLAGS =$(AM_CFLAGS)
liblogsyslog_a_SOURCES =log_syslog.cc
EXTRA_DIST = CMakeLists.txt plug.in
# Don't update the files from bitkeeper
%::SCCS/s.%
--- New file ---
+++ plugin/log_syslog/log_syslog.cc 07/03/08 02:46:35
/* Copyright (C) 2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
#include <stdarg.h>
#ifndef __NT__
#include <syslog.h>
#endif
#include <mysql/plugin.h>
/*
Experimental Syslog Error Log Plugin - may harm kittens.
*/
struct log_data
{
const char *ident;
int option;
int facility;
#ifdef __NT__
HANDLE event;
#endif /*__NT__*/
};
static int error_log(THD *thd, void *data, time_t start_time,
enum loglevel log_level, enum enum_server_command command,
const char *format, va_list args)
{
log_data *log= (log_data*) data;
#ifdef __NT__
HANDLE event;
LPCSTR *buffmsgptr;
WORD wType;
switch (log_level) {
case ERROR_LEVEL:
wType= EVENTLOG_ERROR_TYPE;
break;
case WARNING_LEVEL:
wType= EVENTLOG_WARNING_TYPE;
break;
case INFORMATION_LEVEL:
default:
wType= EVENTLOG_INFORMATION_TYPE;
break;
}
if (data->event)
{
char *fmt= (char *) my_alloca(strlen(format) + 5);
char buff[STRING_BUFFER_USUAL_SIZE];
String str(buff, sizeof(buff), system_charset_info);
strxmov(fmt, format, "\r\n\r\n", NullS);
str.length(0);
my_vstrprintf(&str, fmt, args);
my_afree(fmt);
buffmsgptr= (LPCSTR*) str.c_ptr_quick(); // Keep windows happy
ReportEvent(event, wType, 0, MSG_DEFAULT, NULL, 1, 0,
buffmsgptr, NULL);
}
#else
int priority;
switch (log_level) {
case ERROR_LEVEL:
priority= log->facility | LOG_ERR;
break;
case WARNING_LEVEL:
priority= log->facility | LOG_WARNING;
break;
case INFORMATION_LEVEL:
default:
priority= log->facility | LOG_INFO;
break;
}
vsyslog(priority, format, args);
#endif /*__NT__*/
return 0;
}
static int logger_init(void *p)
{
mysql_logger *logger= (mysql_logger *) p;
log_data *data;
int error= ENOMEM;
LEX_STRING d= { C_STRING_WITH_LEN("mysql") };
if (!(data= (log_data *) my_malloc(sizeof(log_data), MYF(MY_WME))) ||
!(data->ident= (char *) my_memdup(d.str, d.length, MYF(MY_WME))))
goto fail;
data->option= LOG_PERROR | LOG_PID;
data->facility= LOG_LOCAL0;
#ifdef __NT__
data->event= RegisterEventSource(NULL, data->ident)
#else
openlog(data->ident, data->option, data->facility);
#endif /*__NT__*/
logger->error_log= error_log;
logger->data= data;
error= 0;
fail:
if (error && data)
{
my_free((gptr) data->ident, MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) data, MYF(MY_WME));
}
return error;
}
static int logger_fini(void *p)
{
mysql_logger *logger= (mysql_logger *) p;
log_data *data= (log_data *) logger->data;
if (data)
{
#ifdef __NT__
DeregisterEventSource(data->event);
#else
closelog();
#endif /*__NT__*/
my_free((gptr) data->ident, MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) data, MYF(MY_WME));
}
return 0;
}
struct st_mysql_logging log_syslog=
{ MYSQL_LOGGING_INTERFACE_VERSION };
mysql_declare_plugin(logsyslog)
{
MYSQL_LOGGING_PLUGIN,
&log_syslog,
"LogSyslog",
"MySQL AB",
"Logs errors to the system logger facility",
PLUGIN_LICENSE_GPL,
logger_init, /* Plugin Init */
logger_fini, /* Plugin Deinit */
0x0100 /* 1.0 */,
NULL, /* status variables */
NULL, /* system variables */
NULL /* config options */
}
mysql_declare_plugin_end;
--- New file ---
+++ plugin/log_syslog/plug.in 07/03/08 02:46:35
MYSQL_PLUGIN(logsyslog, [Syslog Log Plugin],
[This plugin writes the error log to the system logging facility.])
MYSQL_PLUGIN_DYNAMIC(logsyslog, [log_syslog.la])
MYSQL_PLUGIN_STATIC(logsyslog, [liblogsyslog.a])
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(logsyslog, [log_syslog.cc])
--- New file ---
+++ plugin/log_table/Makefile.am 07/03/08 02:46:31
# Copyright (C) 2007 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#called from the top level Makefile
MYSQLDATAdir = $(localstatedir)
MYSQLSHAREdir = $(pkgdatadir)
MYSQLBASEdir= $(prefix)
MYSQLLIBdir= $(pkglibdir)
INCLUDES = -I$(top_builddir)/include \
-I$(top_srcdir)/include \
-I$(top_srcdir)/regex \
-I$(top_srcdir)/sql \
-I$(srcdir)
LDADD =
DEFS = @DEFS@ -DMYSQL_SERVER
noinst_HEADERS =
EXTRA_LTLIBRARIES = log_table.la
pkglib_LTLIBRARIES = @plugin_logtable_shared_target@
log_table_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
log_table_la_CXXFLAGS = $(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
log_table_la_SOURCES = log_table.cc
EXTRA_LIBRARIES = liblogtable.a
noinst_LIBRARIES = @plugin_logtable_static_target@
liblogtable_a_CXXFLAGS =$(AM_CFLAGS)
liblogtable_a_SOURCES = log_table.cc
EXTRA_DIST = CMakeLists.txt plug.in
# Don't update the files from bitkeeper
%::SCCS/s.%
--- New file ---
+++ plugin/log_table/plug.in 07/03/08 02:46:32
MYSQL_PLUGIN(logtable, [Table Log Plugin],
[This plugin writes the general log and the slow query log into a table.])
MYSQL_PLUGIN_DYNAMIC(logtable, [log_table.la])
MYSQL_PLUGIN_STATIC(logtable, [liblogtable.a])
MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(logtable, [log_table.cc])
--- 1.1/sql/log_table.cc 2007-03-08 02:47:49 -08:00
+++ 1.3/plugin/log_table/log_table.cc 2007-03-08 02:47:49 -08:00
@@ -17,24 +17,35 @@
#include <stdarg.h>
#include <mysql/plugin.h>
+/*
+ Logs to tables: mysql.general_log and mysql.slow_log
+
+ It should be flexible enough to handle any storage engine
+ and does not require columns to be in a specific order,
+ as long as all the expected columns are present.
+
+ LIMITATIONS:
+ When LOCK TABLES is in effect, this plugin will not
+ log anything. Logging to transactional tables make
+ the logging tables a party to the current transaction
+ so log rows may be 'rolled back'.
+
+ Some future solution such as logging to a temporary
+ in-memory table or structure and then spooling the
+ logs out when safe, perhaps from an alternate thread.
+
+*/
+
+
struct log_data
{
bool gen_bad, slo_bad;
+ bool gen_warn_trans, slo_warn_trans;
LEX_STRING gen_db, gen_table;
LEX_STRING slo_db, slo_table;
};
-static void setup_table(TABLE_LIST *tables, LEX_STRING *db, LEX_STRING *name)
-{
- bzero(tables, sizeof(TABLE_LIST));
- tables->db= db->str;
- tables->table_name= tables->alias= name->str;
- tables->lock_type= TL_WRITE_CONCURRENT_INSERT;
- tables->updating= TRUE;
-}
-
-
static String *my_print_user_host_info(THD *thd, String *str)
{
Security_context *sctx= thd->security_ctx;
@@ -48,92 +59,243 @@
}
+/*
+ A utility class to make inserting into tables quick and easy.
+*/
+class QuickInsert
+{
+ Name_resolution_context *ctx;
+ my_bool save_report_error;
+ my_bool save_nosend_error;
+ bool save_isfatal_error;
+ TABLE_LIST table_list[1], *leaves;
+ TABLE *table;
+ COPY_INFO info;
+ List<Item> fields;
+ Field *field;
+ LEX lex, *oldlex;
+ THD *thd;
+ int error;
+public:
+ QuickInsert(THD *athd, LEX_STRING *db, LEX_STRING *table_name)
+ : save_report_error(athd->net.report_error),
+ save_nosend_error(athd->net.no_send_error),
+ save_isfatal_error(athd->is_fatal_error),
+ thd(athd), oldlex(athd->lex), leaves(0),
+ table(NULL), ctx(NULL), error(1), lex()
+ {
+ bzero((char*)&info, sizeof(info));
+ bzero((char*)&table_list, sizeof(table_list));
+
+ info.ignore= 1;
+ info.handle_duplicates= DUP_ERROR;
+
+ table_list[0].db= db->str;
+ table_list[0].db_length= db->length;
+ table_list[0].table_name= table_name->str;
+ table_list[0].table_name_length= table_name->length;
+ table_list[0].lock_type= TL_WRITE_CONCURRENT_INSERT;
+ table_list[0].alias= table_list[0].table_name;
+ }
+
+ ~QuickInsert()
+ {
+ if (table && (error || thd->net.report_error))
+ table->file->ha_release_auto_increment();
+ close_thread_tables(thd);
+
+ thd->net.report_error= save_report_error;
+ thd->net.no_send_error= save_nosend_error;
+ thd->is_fatal_error= save_isfatal_error;
+ thd->lex= oldlex;
+ }
+
+ bool open_table()
+ {
+ thd->lex= &lex;
+
+ mysql_init_query(thd, (uchar*) "", 0);
+
+ thd->net.report_error= 0;
+ thd->net.no_send_error= 1;
+ thd->is_fatal_error= 0;
+
+ if (open_and_lock_tables(thd, table_list) || thd->is_fatal_error)
+ return true;
+
+ thd->lex->select_lex.context.table_list=
+ thd->lex->select_lex.context.first_name_resolution_table= &table_list[0];
+
+ if (setup_tables(thd, &thd->lex->select_lex.context,
+ &thd->lex->select_lex.top_join_list,
+ table_list, &leaves, FALSE))
+ return true;
+
+ ctx= &thd->lex->select_lex.context;
+ return false;
+ }
+
+ bool is_transactional()
+ {
+ return table_list->table->file->has_transactions();
+ }
+
+ Item_field *push_field(const char *field_name)
+ {
+ Item_field *item;
+ DBUG_ASSERT(ctx);
+ fields.push_back(item= new Item_field(ctx, NullS, NullS, field_name));
+ return item;
+ }
+
+ bool check_fields()
+ {
+ TABLE *t= table_list->table;
+
+ if (setup_fields(thd, 0, fields, MARK_COLUMNS_WRITE, 0, 0) ||
+ check_that_all_fields_are_given_values(thd, t, table_list))
+ return true;
+
+ table= t;
+ table->mark_columns_needed_for_insert();
+ return false;
+ }
+
+ void reset_record()
+ {
+ DBUG_ASSERT(table);
+ restore_record(table, s->default_values);
+ error= 0;
+ }
+
+ int write()
+ {
+ DBUG_ASSERT(table && !error);
+ return error= write_record(thd, table, &info);
+ }
+};
+
+
static int table_prefix_log(THD *thd, void *data, time_t start_time,
- enum loglevel log_level,
- enum enum_server_command command,
- const char *format, va_list args)
+ enum loglevel log_level,
+ enum enum_server_command command,
+ const char *format, va_list args)
{
log_data *log= (log_data*) data;
+ CHARSET_INFO *client_cs= thd->variables.character_set_client;
const LEX_STRING *cmdstr= &command_name[(uint) command];
- int error= 0;
+ char user_buff[STRING_BUFFER_USUAL_SIZE];
+ char arg_buff[STRING_BUFFER_USUAL_SIZE];
+ String user(user_buff, sizeof(user_buff), client_cs);
+ String arg(arg_buff, sizeof(arg_buff), client_cs);
+ TIME ltime;
/* If LOCK TABLES is in effect, we log nothing */
if (!thd || thd->locked_tables || log->gen_bad)
return 0;
- CHARSET_INFO *client_cs= thd->variables.character_set_client;
- Name_resolution_context ctx;
- List<Item> fields, dummy_fields, dummy_values;
- List_item *values= new List_item;
- List<List_item> values_list;
- TABLE_LIST tables[0];
- char user_buff[64];
- String user(user_buff, sizeof(user_buff), client_cs);
-
- ctx.init();
- bzero(tables, sizeof(tables));
-
+ /* build the required values to emit */
user.length(0);
my_print_user_host_info(thd, &user);
- setup_table(tables, &log->gen_db, &log->gen_table);
+ arg.length(0);
+ my_vstrprintf(&arg, format, args);
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "event_time"));
- values->push_back(new Item_func_from_unixtime(
- new Item_int((longlong)start_time)));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "user_host"));
- values->push_back(new Item_string(user.c_ptr_quick(),
- user.length(), client_cs));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "thread_id"));
- values->push_back(new Item_int(thd->thread_id));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "server_id"));
- values->push_back(new Item_int(server_id));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "command_type"));
- values->push_back(new Item_string(cmdstr->str, cmdstr->length, client_cs));
+ if (!start_time)
+ start_time= time(NULL);
+ thd->variables.time_zone->gmt_sec_to_TIME(<ime, (my_time_t) start_time);
+
+ /* prepare to insert into the general log table */
+ QuickInsert quick(thd, &log->gen_db, &log->gen_table);
+ Item_field *item[6];
+ Field *field[6];
+ int i, error= 1;
+
+ if (quick.open_table())
+ goto fail;
+ if (!log->gen_warn_trans && quick.is_transactional())
{
- char buff[STRING_BUFFER_USUAL_SIZE];
- String arg(buff, sizeof(buff), client_cs);
-
- arg.length(0);
- my_vstrprintf(&arg, format, args);
-
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "argument"));
- values->push_back(new Item_string(arg.c_ptr_quick(), arg.length(),
- client_cs));
+ log->gen_warn_trans= TRUE;
+ sql_print_warning("Logging general log to transactional table '%s.%s' "
+ "may have unexpected behaviour",
+ log->gen_db.str, log->gen_table.str);
}
- values_list.push_back(values);
+ item[0]= quick.push_field("event_time");
+ item[1]= quick.push_field("user_host");
+ item[2]= quick.push_field("thread_id");
+ item[3]= quick.push_field("server_id");
+ item[4]= quick.push_field("command_type");
+ item[5]= quick.push_field("argument");
- DBUG_ASSERT(fields.elements == values->elements);
+ if (quick.check_fields())
+ goto fail;
- thd->in_lock_tables=1;
- thd->options|= OPTION_TABLE_LOCK;
+ for (i= 0; i < 6; i++)
+ field[i]= item[i]->field;
- error= mysql_insert(thd, tables, fields, values_list,
- dummy_fields, dummy_values,
- DUP_ERROR, 1);
+ quick.reset_record();
+
+ field[0]->set_notnull();
+ field[0]->store_time(<ime, MYSQL_TIMESTAMP_DATETIME);
+
+ field[1]->set_notnull();
+ field[1]->store(user.c_ptr_quick(), user.length(), client_cs);
+
+ field[2]->set_notnull();
+ field[2]->store((longlong) thd->thread_id, TRUE);
+
+ field[3]->set_notnull();
+ field[3]->store((longlong) server_id, TRUE);
+
+ field[4]->set_notnull();
+ field[4]->store(cmdstr->str, cmdstr->length, client_cs);
+
+ field[5]->set_notnull();
+ field[5]->store(arg.c_ptr_quick(), arg.length(), client_cs);
+
+ error= quick.write();
+
+fail:
+ if (error || thd->net.report_error)
+ {
+ log->gen_bad= 1;
+ sql_print_warning("failed to insert to general log table");
+ }
return error;
}
static int table_suffix_log(THD *thd, void *data, time_t start_time,
- enum loglevel log_level,
- enum enum_server_command command,
- const char *format, va_list args)
+ enum loglevel log_level,
+ enum enum_server_command command,
+ const char *format, va_list args)
{
log_data *log= (log_data*) data;
+ CHARSET_INFO *client_cs= thd->variables.character_set_client;
ulong long_query_time;
- int error= 0;
bool slow_query= FALSE;
+ longlong sent_row_count, examined_row_count;
+ longlong last_insert_id, insert_id;
+ bool have_last_insert_id, have_insert_id;
+ char user_buff[STRING_BUFFER_USUAL_SIZE];
+ char query_buff[STRING_BUFFER_USUAL_SIZE];
+ String user(user_buff, sizeof(user_buff), client_cs);
+ String qstr(query_buff, sizeof(query_buff), client_cs);
time_t now= time(NULL);
+ char *query;
+ uint query_length;
+ TIME ltime;
/* If LOCK TABLES is in effect, we log nothing */
if (!thd || thd->locked_tables || log->slo_bad)
return 0;
+ /* we need to test if this is a slow query */
+
long_query_time= thd->variables.long_query_time;
if (long_query_time < (ulong) (now - thd->time_after_lock))
@@ -141,102 +303,157 @@
if ((specialflag & SPECIAL_LOG_QUERIES_NOT_USING_INDEXES) &&
(thd->server_status &
- (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)))
+ (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)))
slow_query= TRUE;
if (!thd->enable_slow_log || thd->user_time)
slow_query= FALSE;
- if (slow_query)
+ if (!slow_query)
+ return 0;
+
+ /* increment the long_query_count, we found one */
+ thd->status_var.long_query_count++;
+
+ /* prepare the values which we will emit */
+ sent_row_count= thd->sent_row_count;
+ examined_row_count= thd->examined_row_count;
+ have_last_insert_id=
+ thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
+ last_insert_id= (longlong)
+ thd->first_successful_insert_id_in_prev_stmt_for_binlog;
+ insert_id= (have_insert_id=
+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
+ ? (longlong) thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum()
+ : 0;
+
+ user.length(0);
+ my_print_user_host_info(thd, &user);
+
+ if (!format)
+ {
+ query= command_name[thd->command].str;
+ query_length= command_name[thd->command].length;
+ }
+ else
+ {
+ qstr.length(0);
+ my_vstrprintf(&qstr, format, args);
+ query= qstr.c_ptr_quick();
+ query_length= qstr.length();
+ }
+
+ if (!start_time)
+ thd->variables.time_zone->gmt_sec_to_TIME(<ime, (my_time_t) time(NULL));
+ else
+ thd->variables.time_zone->gmt_sec_to_TIME(<ime, (my_time_t) start_time);
+
+ /* prepare to insert into the slow query table */
+ QuickInsert quick(thd, &log->slo_db, &log->slo_table);
+ Item_field *item[11];
+ Field *field[11];
+ int i, error= 1;
+
+ if (quick.open_table())
+ goto fail;
+
+ if (!log->slo_warn_trans && quick.is_transactional())
{
- CHARSET_INFO *client_cs= thd->variables.character_set_client;
- Name_resolution_context ctx;
- List<Item> fields, dummy_fields, dummy_values;
- List<List_item> values_list;
- List_item values;
- TABLE_LIST tables[0];
- char qstr_buff[STRING_BUFFER_USUAL_SIZE];
- char user_buff[64];
- String user(user_buff, sizeof(user_buff), client_cs);
- String qstr(qstr_buff, sizeof(qstr_buff), client_cs);
- const char *query;
- uint query_length;
-
- thd->status_var.long_query_count++;
-
- ctx.init();
-
- user.length(0);
- my_print_user_host_info(thd, &user);
-
- if (!format)
- {
- query= command_name[thd->command].str;
- query_length= command_name[thd->command].length;
- }
- else
- {
- qstr.length(0);
- my_vstrprintf(&qstr, format, args);
- query= qstr.c_ptr_quick();
- query_length= qstr.length();
- }
-
- setup_table(tables, &log->slo_db, &log->slo_table);
-
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "start_time"));
- values.push_back(new Item_func_from_unixtime(
- new Item_int((longlong)start_time)));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "user_host"));
- values.push_back(new Item_string(user.c_ptr_quick(),
- user.length(), client_cs));
- if (start_time)
- {
- longlong query_time, lock_time;
-
- query_time= (longlong) (now - start_time);
- lock_time= (longlong) (thd->time_after_lock - start_time);
-
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "query_time"));
- values.push_back(new Item_int(query_time));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "lock_time"));
- values.push_back(new Item_int(lock_time));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "rows_sent"));
- values.push_back(new Item_int((longlong) thd->sent_row_count));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "rows_examined"));
- values.push_back(new Item_int((longlong) thd->examined_row_count));
- }
- if (thd->db)
- {
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "db"));
- values.push_back(new Item_string(thd->db, thd->db_length, client_cs));
- }
- if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
- {
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "last_insert_id"));
- values.push_back(new Item_int((longlong)
- thd->first_successful_insert_id_in_prev_stmt_for_binlog));
- }
- if (thd->auto_inc_intervals_in_cur_stmt_for_binlog.nb_elements() > 0)
- {
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "insert_id"));
- values.push_back(new Item_int((longlong)
- thd->auto_inc_intervals_in_cur_stmt_for_binlog.minimum()));
- }
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "server_id"));
- values.push_back(new Item_int(server_id));
- fields.push_back(new Item_ref(&ctx, NullS, NullS, "sql_text"));
- values.push_back(new Item_string(query, query_length, client_cs));
-
- values_list.push_back(&values);
-
- DBUG_ASSERT(fields.elements == values.elements);
-
- error= mysql_insert(thd, tables, fields, values_list,
- dummy_fields, dummy_values,
- DUP_ERROR, 1);
+ log->gen_warn_trans= TRUE;
+ sql_print_warning("Logging slow queries to transactional table '%s.%s' "
+ "may have unexpected behaviour",
+ log->slo_db.str, log->slo_table.str);
}
+ item[0]= quick.push_field("start_time");
+ item[1]= quick.push_field("user_host");
+ item[2]= quick.push_field("query_time");
+ item[3]= quick.push_field("lock_time");
+ item[4]= quick.push_field("rows_sent");
+ item[5]= quick.push_field("rows_examined");
+ item[6]= quick.push_field("db");
+ item[7]= quick.push_field("last_insert_id");
+ item[8]= quick.push_field("insert_id");
+ item[9]= quick.push_field("server_id");
+ item[10]= quick.push_field("sql_text");
+
+ if (quick.check_fields())
+ goto fail;
+
+ for (i= 0; i < 11; i++)
+ field[i]= item[i]->field;
+
+ quick.reset_record();
+
+ field[0]->set_notnull();
+ field[0]->store_time(<ime, MYSQL_TIMESTAMP_DATETIME);
+
+ field[1]->set_notnull();
+ field[1]->store(user.c_ptr_quick(), user.length(), client_cs);
+
+ if (start_time)
+ {
+ longlong query_time, lock_time;
+
+ query_time= (longlong) (now - start_time);
+ lock_time= (longlong) (thd->time_after_lock - start_time);
+
+ field[2]->set_notnull();
+ field[2]->store(query_time, TRUE);
+ field[3]->set_notnull();
+ field[3]->store(lock_time, TRUE);
+ field[4]->set_notnull();
+ field[4]->store(sent_row_count, TRUE);
+ field[5]->set_notnull();
+ field[5]->store(examined_row_count, TRUE);
+ }
+ else
+ {
+ field[2]->set_null();
+ field[3]->set_null();
+ field[4]->set_null();
+ field[5]->set_null();
+ }
+
+ if (thd->db)
+ {
+ field[6]->set_notnull();
+ field[6]->store(thd->db, thd->db_length, client_cs);
+ }
+ else
+ field[6]->set_null();
+
+ if (have_last_insert_id)
+ {
+ field[7]->set_notnull();
+ field[7]->store(last_insert_id);
+ }
+ else
+ field[7]->set_null();
+
+ if (have_insert_id)
+ {
+ field[8]->set_notnull();
+ field[8]->store(insert_id);
+ }
+ else
+ field[8]->set_null();
+
+ field[9]->set_notnull();
+ field[9]->store((longlong) server_id);
+
+ field[10]->set_notnull();
+ field[10]->store(query, query_length, client_cs);
+
+ error= quick.write();
+
+fail:
+ if (error || thd->net.report_error)
+ {
+ log->slo_bad= 1;
+ sql_print_warning("failed to insert to slow query log table");
+ }
+
return error;
}
@@ -246,26 +463,32 @@
mysql_logger *logger= (mysql_logger *) p;
log_data *data;
int error= ENOMEM;
+
+ /* For now, these values are hard coded */
LEX_STRING db= { C_STRING_WITH_LEN("mysql") };
LEX_STRING gen= { C_STRING_WITH_LEN("general_log") };
LEX_STRING slo= { C_STRING_WITH_LEN("slow_log") };
if (!(data= (log_data *) my_malloc(sizeof(log_data),
- MYF(MY_WME | MY_ZEROFILL))))
- goto fail;
+ MYF(MY_WME | MY_ZEROFILL))))
+ goto fail;
- if ((data->gen_db.str= my_strdup(db.str, MYF(MY_WME))))
+ if (opt_log && (data->gen_db.str= my_strdup(db.str, MYF(MY_WME))))
+ {
data->gen_db.length= db.length;
- if ((data->gen_table.str= my_strdup(gen.str, MYF(MY_WME))))
- data->gen_table.length= gen.length;
+ if ((data->gen_table.str= my_strdup(gen.str, MYF(MY_WME))))
+ data->gen_table.length= gen.length;
+ }
- if ((data->slo_db.str= my_strdup(db.str, MYF(MY_WME))))
+ if (opt_slow_log && (data->slo_db.str= my_strdup(db.str, MYF(MY_WME))))
+ {
data->slo_db.length= db.length;
- if ((data->slo_table.str= my_strdup(slo.str, MYF(MY_WME))))
- data->slo_table.length= slo.length;
+ if ((data->slo_table.str= my_strdup(slo.str, MYF(MY_WME))))
+ data->slo_table.length= slo.length;
+ }
if (data->gen_db.str && data->gen_table.str)
logger->prefix_log= table_prefix_log;
@@ -284,7 +507,7 @@
my_free((gptr) data->slo_table.str, MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr) data, MYF(MY_WME));
}
-
+
return error;
}
--- 1.2/sql/sql_logger.cc 2007-03-08 02:47:49 -08:00
+++ 1.3/sql/sql_logger.cc 2007-03-08 02:47:49 -08:00
@@ -69,7 +69,6 @@
static my_bool flush_log(THD *thd, st_plugin_int *plugin, void *data)
{
mysql_logger *logger= (mysql_logger *) plugin->data;
- my_bool result;
DBUG_ENTER("flush_log");
if (logger->flush_logs)
--- 1.110/libmysqld/Makefile.am 2007-03-08 02:47:49 -08:00
+++ 1.111/libmysqld/Makefile.am 2007-03-08 02:47:49 -08:00
@@ -74,7 +74,7 @@
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
sql_tablespace.cc \
rpl_injector.cc my_user.c partition_info.cc \
- sql_logger.cc log_file.cc log_table.cc \
+ sql_logger.cc \
sql_servers.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)
| Thread |
|---|
| • bk commit into 5.1 tree (acurtis:1.2468) | antony | 8 Mar |