#At file:///mnt/raid/alik/MySQL/bzr/00/bug27863/mysql-next-mr-bf-bug27863.2/ based on revid:alik@stripped
3144 Alexander Nozdrin 2010-04-07
A patch for Bug#27863 (excessive memory usage for many small queries
in a multiquery packet).
This patch fixes issue #1 described in the bug report:
1) Lex_input_stream allocates more memory on its construction than it is
ever going to need
The fix is to allocate a buffer (cpp_buffer) once for a multiquery packet.
modified:
sql/event_data_objects.cc
sql/ha_ndbcluster_binlog.cc
sql/log_event.cc
sql/mysql_priv.h
sql/sp.cc
sql/sql_lex.cc
sql/sql_lex.h
sql/sql_parse.cc
sql/sql_partition.cc
sql/sql_prepare.cc
sql/sql_trigger.cc
sql/sql_view.cc
=== modified file 'sql/event_data_objects.cc'
--- a/sql/event_data_objects.cc 2010-01-30 19:37:52 +0000
+++ b/sql/event_data_objects.cc 2010-04-07 16:27:10 +0000
@@ -1435,7 +1435,7 @@ Event_job_data::execute(THD *thd, bool d
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
{
- Parser_state parser_state(thd, thd->query(), thd->query_length());
+ Parser_state parser_state(thd, thd->query(), thd->query_length(), NULL);
lex_start(thd);
if (parse_sql(thd, & parser_state, creation_ctx))
=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc 2010-03-13 10:58:27 +0000
+++ b/sql/ha_ndbcluster_binlog.cc 2010-04-07 16:27:10 +0000
@@ -268,7 +268,7 @@ static void run_query(THD *thd, char *bu
DBUG_ASSERT(!thd->in_sub_stmt);
DBUG_ASSERT(!thd->locked_tables_mode);
- mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
+ mysql_parse(thd, thd->query(), thd->query_length(), NULL, &found_semicolon);
if (no_print_error && thd->is_slave_error)
{
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc 2010-03-20 09:35:40 +0000
+++ b/sql/log_event.cc 2010-04-07 16:27:10 +0000
@@ -3274,7 +3274,7 @@ int Query_log_event::do_apply_event(Rela
/* Execute the query (note that we bypass dispatch_command()) */
const char* found_semicolon= NULL;
- mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
+ mysql_parse(thd, thd->query(), thd->query_length(), NULL, &found_semicolon);
log_slow_statement(thd);
/*
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2010-03-22 10:36:23 +0000
+++ b/sql/mysql_priv.h 2010-04-07 16:27:10 +0000
@@ -1088,9 +1088,10 @@ bool mysql_opt_change_db(THD *thd,
bool *cur_db_changed);
void mysql_parse(THD *thd, const char *inBuf, uint length,
+ char *cpp_buffer,
const char ** semicolon);
-bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
+bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length);
bool is_update_query(enum enum_sql_command command);
bool is_log_table_write_query(enum enum_sql_command command);
bool alloc_query(THD *thd, const char *packet, uint packet_length);
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2010-03-20 09:35:40 +0000
+++ b/sql/sp.cc 2010-04-07 16:27:10 +0000
@@ -713,7 +713,7 @@ static sp_head *sp_compile(THD *thd, Str
thd->variables.sql_mode= sql_mode;
thd->variables.select_limit= HA_POS_ERROR;
- Parser_state parser_state(thd, defstr->c_ptr(), defstr->length());
+ Parser_state parser_state(thd, defstr->c_ptr(), defstr->length(), NULL);
lex_start(thd);
thd->push_internal_handler(&warning_handler);
thd->spcont= 0;
=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc 2010-03-22 10:36:23 +0000
+++ b/sql/sql_lex.cc 2010-04-07 16:27:10 +0000
@@ -138,7 +138,8 @@ st_parsing_options::reset()
Lex_input_stream::Lex_input_stream(THD *thd,
const char* buffer,
- unsigned int length)
+ unsigned int length,
+ char *cpp_buffer)
: m_thd(thd),
yylineno(1),
yytoklen(0),
@@ -166,7 +167,11 @@ Lex_input_stream::Lex_input_stream(THD *
in_comment(NO_COMMENT),
m_underscore_cs(NULL)
{
- m_cpp_buf= (char*) thd->alloc(length + 1);
+ if (cpp_buffer)
+ m_cpp_buf= cpp_buffer;
+ else
+ m_cpp_buf= (char*) thd->alloc(length + 1);
+
m_cpp_ptr= m_cpp_buf;
}
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2010-03-22 10:36:23 +0000
+++ b/sql/sql_lex.h 2010-04-07 16:27:10 +0000
@@ -1345,7 +1345,8 @@ enum enum_comment_state
class Lex_input_stream
{
public:
- Lex_input_stream(THD *thd, const char* buff, unsigned int length);
+ Lex_input_stream(THD *thd, const char* buff, unsigned int length,
+ char *cpp_buffer);
~Lex_input_stream();
/**
@@ -2245,8 +2246,9 @@ public:
class Parser_state
{
public:
- Parser_state(THD *thd, const char* buff, unsigned int length)
- : m_lip(thd, buff, length), m_yacc()
+ Parser_state(THD *thd, const char* buff, unsigned int length,
+ char *cpp_buffer)
+ : m_lip(thd, buff, length, cpp_buffer), m_yacc()
{}
~Parser_state()
=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc 2010-03-20 09:35:40 +0000
+++ b/sql/sql_parse.cc 2010-04-07 16:27:10 +0000
@@ -470,7 +470,8 @@ static void handle_bootstrap_impl(THD *t
mode we have only one thread.
*/
thd->set_time();
- mysql_parse(thd, thd->query(), length, & found_semicolon);
+ char *cpp_buffer= (char *) thd->alloc(thd->query_length());
+ mysql_parse(thd, thd->query(), length, cpp_buffer, & found_semicolon);
close_thread_tables(thd); // Free tables
bootstrap_error= thd->is_error();
@@ -1021,7 +1022,8 @@ bool dispatch_command(enum enum_server_c
thd->profiling.set_query_source(thd->query(), thd->query_length());
#endif
- mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
+ char *cpp_buffer= (char *) thd->alloc(thd->query_length());
+ mysql_parse(thd, thd->query(), thd->query_length(), cpp_buffer, &end_of_stmt);
while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
{
@@ -1067,7 +1069,7 @@ bool dispatch_command(enum enum_server_c
statistic_increment(thd->status_var.questions, &LOCK_status);
thd->set_time(); /* Reset the query start time. */
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
- mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
+ mysql_parse(thd, beginning_of_next_stmt, length, cpp_buffer, &end_of_stmt);
}
DBUG_PRINT("info",("query ready"));
@@ -5656,6 +5658,7 @@ void mysql_init_multi_delete(LEX *lex)
*/
void mysql_parse(THD *thd, const char *inBuf, uint length,
+ char *cpp_buffer,
const char ** found_semicolon)
{
int error;
@@ -5686,7 +5689,7 @@ void mysql_parse(THD *thd, const char *i
{
LEX *lex= thd->lex;
- Parser_state parser_state(thd, inBuf, length);
+ Parser_state parser_state(thd, inBuf, length, cpp_buffer);
bool err= parse_sql(thd, & parser_state, NULL);
*found_semicolon= parser_state.m_lip.found_semicolon;
@@ -5783,7 +5786,7 @@ bool mysql_test_parse_for_slave(THD *thd
bool error= 0;
DBUG_ENTER("mysql_test_parse_for_slave");
- Parser_state parser_state(thd, inBuf, length);
+ Parser_state parser_state(thd, inBuf, length, NULL);
lex_start(thd);
mysql_reset_thd_for_next_command(thd);
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2010-03-22 10:36:23 +0000
+++ b/sql/sql_partition.cc 2010-04-07 16:27:10 +0000
@@ -4179,7 +4179,7 @@ bool mysql_unpack_partition(THD *thd,
thd->variables.character_set_client= system_charset_info;
- Parser_state parser_state(thd, part_buf, part_info_len);
+ Parser_state parser_state(thd, part_buf, part_info_len, NULL);
if (init_lex_with_single_table(thd, table, &lex))
goto end;
=== modified file 'sql/sql_prepare.cc'
--- a/sql/sql_prepare.cc 2010-03-11 13:47:34 +0000
+++ b/sql/sql_prepare.cc 2010-04-07 16:27:10 +0000
@@ -2930,7 +2930,7 @@ Execute_sql_statement::execute_server_co
if (alloc_query(thd, m_sql_text.str, m_sql_text.length))
return TRUE;
- Parser_state parser_state(thd, thd->query(), thd->query_length());
+ Parser_state parser_state(thd, thd->query(), thd->query_length(), NULL);
parser_state.m_lip.multi_statements= FALSE;
lex_start(thd);
@@ -3170,7 +3170,7 @@ bool Prepared_statement::prepare(const c
old_stmt_arena= thd->stmt_arena;
thd->stmt_arena= this;
- Parser_state parser_state(thd, thd->query(), thd->query_length());
+ Parser_state parser_state(thd, thd->query(), thd->query_length(), NULL);
parser_state.m_lip.stmt_prepare_mode= TRUE;
parser_state.m_lip.multi_statements= FALSE;
lex_start(thd);
=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc 2010-02-24 13:52:27 +0000
+++ b/sql/sql_trigger.cc 2010-04-07 16:27:10 +0000
@@ -1310,7 +1310,8 @@ bool Table_triggers_list::check_n_load(T
Parser_state parser_state(thd,
trg_create_str->str,
- trg_create_str->length);
+ trg_create_str->length,
+ NULL);
Trigger_creation_ctx *creation_ctx=
Trigger_creation_ctx::create(thd,
=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc 2010-03-20 09:35:40 +0000
+++ b/sql/sql_view.cc 2010-04-07 16:27:10 +0000
@@ -1175,7 +1175,8 @@ bool mysql_make_view(THD *thd, File_pars
bool dbchanged;
Parser_state parser_state(thd,
table->select_stmt.str,
- table->select_stmt.length);
+ table->select_stmt.length,
+ NULL);
/*
Use view db name as thread default database, in order to ensure
Attachment: [text/bzr-bundle] bzr/alik@sun.com-20100407162710-t9yo3bf7z1bak4fx.bundle
| Thread |
|---|
| • bzr commit into mysql-next-mr-bugfixing branch (alik:3144) Bug#27863 | Alexander Nozdrin | 7 Apr |