summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <davi@moksha.com.br>2007-10-18 15:45:07 -0300
committerunknown <davi@moksha.com.br>2007-10-18 15:45:07 -0300
commitb9b481ec70c2475abb6303ae08c6b73592bf0c03 (patch)
tree540546209ad541756aaa56853f9a69fbf859a671 /sql
parent73458352133ac1d2660e60e84b96d3659cff399a (diff)
downloadmariadb-git-b9b481ec70c2475abb6303ae08c6b73592bf0c03.tar.gz
Bug#21557 entries in the general query log truncated at 1000 characters.
The general log write function (general_log_print) uses printf style arguments which need to be pre-processed, meaning that the all arguments are copied to a single buffer and the problem is that the buffer size is constant (1022 characters) but queries can be much larger then this. The solution is to introduce a new log write function that accepts a buffer and it's length as arguments. The function is to be used when a formatted output is not required, which is the case for almost all query write-to-log calls. This is a incompatible change with respect to the log format of prepared statements. mysql-test/r/log_tables.result: Add test case result for Bug#21557 mysql-test/t/log_tables.test: Add test case for Bug#21557 sql/log.cc: Introduce the logger function general_log_write which is similar to general_log_print but accepts a single buffer and the buffer length. The function doesn't perform any formatting and sends the buffer directly to the underlying log handlers. sql/log.h: Introduce the logger function general_log_write. sql/log_event.cc: Pass the query buffer directly to the logger function, formatting is not required on this case. sql/mysql_priv.h: Prototype for the logger function general_log_write. sql/sp_head.cc: Pass the query buffer directly to the logger function, formatting is not required on this case. sql/sql_parse.cc: Pass the buffer directly to the logger function when formatting is not required. sql/sql_prepare.cc: Don't log the statement id, it avoids making a extra copy of the query and the query is not truncated anymore if it exceeds the limit.
Diffstat (limited to 'sql')
-rw-r--r--sql/log.cc154
-rw-r--r--sql/log.h4
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_parse.cc7
-rw-r--r--sql/sql_prepare.cc13
7 files changed, 108 insertions, 77 deletions
diff --git a/sql/log.cc b/sql/log.cc
index 9d6f6fa4c9b..e923418b23a 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -944,73 +944,65 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
return error;
}
-bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
- const char *format, va_list args)
+bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
+ const char *query, uint query_length)
{
bool error= FALSE;
Log_event_handler **current_handler= general_log_handler_list;
+ char user_host_buff[MAX_USER_HOST_SIZE];
+ Security_context *sctx= thd->security_ctx;
+ ulong id;
+ uint user_host_len= 0;
+ time_t current_time;
- /*
- Print the message to the buffer if we have at least one log event handler
- enabled and want to log this king of commands
- */
- if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
- {
- char message_buff[MAX_LOG_BUFFER_SIZE];
- char user_host_buff[MAX_USER_HOST_SIZE];
- Security_context *sctx= thd->security_ctx;
- ulong id;
- uint message_buff_len= 0, user_host_len= 0;
- time_t current_time;
- if (thd)
- { /* Normal thread */
- if ((thd->options & OPTION_LOG_OFF)
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- && (sctx->master_access & SUPER_ACL)
-#endif
- )
- {
- return 0; /* No logging */
- }
- id= thd->thread_id;
- }
- else
- id=0; /* Log from connect handler */
+ if (thd)
+ id= thd->thread_id; /* Normal thread */
+ else
+ id= 0; /* Log from connect handler */
- lock_shared();
- if (!opt_log)
- {
- unlock();
- return 0;
- }
- user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
- sctx->priv_user ? sctx->priv_user : "", "[",
- sctx->user ? sctx->user : "", "] @ ",
- sctx->host ? sctx->host : "", " [",
- sctx->ip ? sctx->ip : "", "]", NullS) -
- user_host_buff;
-
- /* prepare message */
- if (format)
- message_buff_len= my_vsnprintf(message_buff,
- sizeof(message_buff), format, args);
- else
- message_buff[0]= '\0';
-
- current_time= my_time(0);
- while (*current_handler)
- error+= (*current_handler++)->
- log_general(thd, current_time, user_host_buff,
- user_host_len, id,
- command_name[(uint) command].str,
- command_name[(uint) command].length,
- message_buff, message_buff_len,
- thd->variables.character_set_client) || error;
+ lock_shared();
+ if (!opt_log)
+ {
unlock();
+ return 0;
}
+ user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
+ sctx->priv_user ? sctx->priv_user : "", "[",
+ sctx->user ? sctx->user : "", "] @ ",
+ sctx->host ? sctx->host : "", " [",
+ sctx->ip ? sctx->ip : "", "]", NullS) -
+ user_host_buff;
+
+ current_time= my_time(0);
+ while (*current_handler)
+ error+= (*current_handler++)->
+ log_general(thd, current_time, user_host_buff,
+ user_host_len, id,
+ command_name[(uint) command].str,
+ command_name[(uint) command].length,
+ query, query_length,
+ thd->variables.character_set_client) || error;
+ unlock();
+
return error;
}
+bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
+ const char *format, va_list args)
+{
+ uint message_buff_len= 0;
+ char message_buff[MAX_LOG_BUFFER_SIZE];
+
+ /* prepare message */
+ if (format)
+ message_buff_len= my_vsnprintf(message_buff, sizeof(message_buff),
+ format, args);
+ else
+ message_buff[0]= '\0';
+
+ 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)
@@ -2075,10 +2067,10 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
if (my_b_write(&log_file, (uchar*) buff, buff_len))
tmp_errno= errno;
}
- if (my_b_printf(&log_file, "# User@Host: ", sizeof("# User@Host: ") - 1)
- != sizeof("# User@Host: ") - 1)
+ const uchar uh[]= "# User@Host: ";
+ if (my_b_write(&log_file, uh, sizeof(uh) - 1))
tmp_errno= errno;
- if (my_b_printf(&log_file, user_host, user_host_len) != user_host_len)
+ if (my_b_write(&log_file, (uchar*) user_host, user_host_len))
tmp_errno= errno;
if (my_b_write(&log_file, (uchar*) "\n", 1))
tmp_errno= errno;
@@ -3736,12 +3728,44 @@ bool slow_log_print(THD *thd, const char *query, uint query_length,
}
+bool LOGGER::log_command(THD *thd, enum enum_server_command command)
+{
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ Security_context *sctx= thd->security_ctx;
+#endif
+ /*
+ Log command if we have at least one log event handler enabled and want
+ to log this king of commands
+ */
+ if (*general_log_handler_list && (what_to_log & (1L << (uint) command)))
+ {
+ if ((thd->options & OPTION_LOG_OFF)
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ && (sctx->master_access & SUPER_ACL)
+#endif
+ )
+ {
+ /* No logging */
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
bool general_log_print(THD *thd, enum enum_server_command command,
const char *format, ...)
{
va_list args;
uint error= 0;
+ /* Print the message to the buffer if we want to log this king of commands */
+ if (! logger.log_command(thd, command))
+ return FALSE;
+
va_start(args, format);
error= logger.general_log_print(thd, command, format, args);
va_end(args);
@@ -3749,6 +3773,16 @@ bool general_log_print(THD *thd, enum enum_server_command command,
return error;
}
+bool general_log_write(THD *thd, enum enum_server_command command,
+ const char *query, uint query_length)
+{
+ /* Write the message to the log if we want to log this king of commands */
+ if (logger.log_command(thd, command))
+ return logger.general_log_write(thd, command, query, query_length);
+
+ return FALSE;
+}
+
void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
{
if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED))
diff --git a/sql/log.h b/sql/log.h
index e597c986794..bef0101c8b5 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -499,6 +499,8 @@ public:
void lock_exclusive() { rw_wrlock(&LOCK_logger); }
void unlock() { rw_unlock(&LOCK_logger); }
bool is_log_table_enabled(uint log_table_type);
+ bool log_command(THD *thd, enum enum_server_command command);
+
/*
We want to initialize all log mutexes as soon as possible,
but we cannot do it in constructor, as safe_mutex relies on
@@ -518,6 +520,8 @@ public:
ulonglong current_utime);
bool general_log_print(THD *thd,enum enum_server_command command,
const char *format, va_list args);
+ bool general_log_write(THD *thd, enum enum_server_command command,
+ const char *query, uint query_length);
/* we use this function to setup all enabled log event handlers */
int set_handlers(uint error_log_printer,
diff --git a/sql/log_event.cc b/sql/log_event.cc
index d8e22953fc2..a435894382b 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2113,7 +2113,7 @@ START SLAVE; . Query: '%s'", expected_error, thd->query);
/* If the query was not ignored, it is printed to the general log */
if (thd->net.last_errno != ER_SLAVE_IGNORED_TABLE)
- general_log_print(thd, COM_QUERY, "%s", thd->query);
+ general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
compare_errors:
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 79d4c16f9c1..08e535548e0 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -740,6 +740,9 @@ bool slow_log_print(THD *thd, const char *query, uint query_length,
bool general_log_print(THD *thd, enum enum_server_command command,
const char *format,...);
+bool general_log_write(THD *thd, enum enum_server_command command,
+ const char *query, uint query_length);
+
#include "sql_class.h"
#include "sql_acl.h"
#include "tztime.h"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 7de230bba78..6e0da982369 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -2707,7 +2707,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
queries with SP vars can't be cached)
*/
if (unlikely((thd->options & OPTION_LOG_OFF)==0))
- general_log_print(thd, COM_QUERY, "%s", thd->query);
+ general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
if (query_cache_send_result_to_client(thd,
thd->query, thd->query_length) <= 0)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 695e923e816..83ac2ee44dc 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -782,7 +782,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
packet, packet_length, thd->charset());
if (!mysql_change_db(thd, &tmp, FALSE))
{
- general_log_print(thd, command, "%s",thd->db);
+ general_log_write(thd, command, thd->db, thd->db_length);
send_ok(thd);
}
break;
@@ -980,10 +980,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; // fatal error is set
char *packet_end= thd->query + thd->query_length;
/* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
- const char *format= "%.*b";
const char* found_semicolon= NULL;
- general_log_print(thd, command, format, thd->query_length, thd->query);
+ general_log_write(thd, command, thd->query, thd->query_length);
DBUG_PRINT("query",("%-.4096s",thd->query));
if (!(specialflag & SPECIAL_NO_PRIOR))
@@ -1142,7 +1141,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
break;
}
- general_log_print(thd, command, db.str);
+ general_log_write(thd, command, db.str, db.length);
mysql_rm_db(thd, db.str, 0, 0);
break;
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 05743b6dfe3..a6cdcf14881 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2947,12 +2947,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
the general log.
*/
if (thd->spcont == NULL)
- {
- const char *format= "[%lu] %.*b";
- general_log_print(thd, COM_STMT_PREPARE, format, id,
- query_length, query);
-
- }
+ general_log_write(thd, COM_STMT_PREPARE, query, query_length);
}
DBUG_RETURN(error);
}
@@ -3150,11 +3145,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
the general log.
*/
if (error == 0 && thd->spcont == NULL)
- {
- const char *format= "[%lu] %.*b";
- general_log_print(thd, COM_STMT_EXECUTE, format, id,
- thd->query_length, thd->query);
- }
+ general_log_write(thd, COM_STMT_EXECUTE, thd->query, thd->query_length);
error:
flags&= ~ (uint) IS_IN_USE;