diff options
author | unknown <davi@moksha.com.br> | 2007-10-18 15:45:07 -0300 |
---|---|---|
committer | unknown <davi@moksha.com.br> | 2007-10-18 15:45:07 -0300 |
commit | b9b481ec70c2475abb6303ae08c6b73592bf0c03 (patch) | |
tree | 540546209ad541756aaa56853f9a69fbf859a671 /sql | |
parent | 73458352133ac1d2660e60e84b96d3659cff399a (diff) | |
download | mariadb-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.cc | 154 | ||||
-rw-r--r-- | sql/log.h | 4 | ||||
-rw-r--r-- | sql/log_event.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/sp_head.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 7 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 13 |
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; |