From: Dmitry Shulga Date: May 20 2011 7:07pm Subject: bzr push into mysql-5.1 branch (Dmitry.Shulga:3624 to 3625) Bug#38813 Bug#11749345 List-Archive: http://lists.mysql.com/commits/137814 X-Bug: 38813,11749345 Message-Id: <201105201907.p4KJ7rrh007978@acsmt358.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============9208726582621691686==" --===============9208726582621691686== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 3625 Dmitry Shulga 2011-05-20 Fixed bug#11749345 (formerly bug#38813) - increasing memory consumption when selecting from I_S and views exist, in SP. Symptoms: re-execution of prepared statement (or statement in a stored routine) which read from one of I_S tables and which in order to fill this I_S table had to open a view led to increasing memory consumption. What happened in this situation was that during the process of view opening for purpose of I_S filling view-related structures (like its LEX) were allocated on persistent MEM_ROOT of prepared statement (or stored routine). Since this MEM_ROOT is not freed until prepared statement deallocation (or expulsion of stored routine from the cache) and code responsible for filling I_S is not able to re-use results of view opening from previous executions this allocation ended up in memory hogging. This patch solves the problem by ensuring that when a view opened for the purpose of I_S filling all its structures are allocated on non-persistent runtime MEM_ROOT. This is achieved by activating a temporary Query_arena bound to this MEM_ROOT. Since this step makes impossible linking of view structures into LEX of our prepared statement (or stored routine statement) this patch also changes code filling I_S table to install a proxy LEX before trying to open a view or a table. Consequently some code which was responsible for backing-up/restoring parts of LEX when view/table was opened during filling of I_S table became redundant and was removed. This patch doesn't contain test case for this bug as it is hard to test memory hogging in our test suite. modified: sql/sql_show.cc 3624 Luis Soares 2011-05-19 [merge] BUG#11746302 Automerge mysql-5.1-gca into latest mysql-5.1. modified: mysql-test/suite/rpl/r/rpl_relayspace.result mysql-test/suite/rpl/t/rpl_relayspace.test === modified file 'sql/sql_show.cc' --- a/sql/sql_show.cc 2011-04-04 13:04:15 +0000 +++ b/sql/sql_show.cc 2011-05-20 16:52:52 +0000 @@ -2428,12 +2428,11 @@ bool schema_table_store_record(THD *thd, } -int make_table_list(THD *thd, SELECT_LEX *sel, - LEX_STRING *db_name, LEX_STRING *table_name) +static int make_table_list(THD *thd, SELECT_LEX *sel, + LEX_STRING *db_name, LEX_STRING *table_name) { Table_ident *table_ident; table_ident= new Table_ident(thd, *db_name, *table_name, 1); - sel->init_query(); if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ)) return 1; return 0; @@ -3003,79 +3002,179 @@ make_table_name_list(THD *thd, Listlex; - bool res; - LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name; - enum_sql_command save_sql_command= lex->sql_command; - TABLE_LIST *show_table_list= tables->schema_select_lex->table_list.first; - TABLE *table= tables->table; - int error= 1; - DBUG_ENTER("fill_schema_show"); +static bool +fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, + TABLE *table, ST_SCHEMA_TABLE *schema_table, + LEX_STRING *orig_db_name, + LEX_STRING *orig_table_name, + Open_tables_state *open_tables_state_backup) +{ + Query_arena i_s_arena(thd->mem_root, + Query_arena::CONVENTIONAL_EXECUTION), + backup_arena, *old_arena; + LEX *old_lex= thd->lex, temp_lex, *lex; + LEX_STRING db_name, table_name; + TABLE_LIST *table_list; + bool result= true; - lex->all_selects_list= tables->schema_select_lex; /* - Restore thd->temporary_tables to be able to process - temporary tables(only for 'show index' & 'show columns'). - This should be changed when processing of temporary tables for - I_S tables will be done. + When a view is opened its structures are allocated on a permanent + statement arena and linked into the LEX tree for the current statement + (this happens even in cases when view is handled through TEMPTABLE + algorithm). + + To prevent this process from unnecessary hogging of memory in the permanent + arena of our I_S query and to avoid damaging its LEX we use temporary + arena and LEX for table/view opening. + + Use temporary arena instead of statement permanent arena. Also make + it active arena and save original one for successive restoring. */ - thd->temporary_tables= open_tables_state_backup->temporary_tables; + old_arena= thd->stmt_arena; + thd->stmt_arena= &i_s_arena; + thd->set_n_backup_active_arena(&i_s_arena, &backup_arena); + + /* Prepare temporary LEX. */ + thd->lex= lex= &temp_lex; + lex_start(thd); + + /* Disable constant subquery evaluation as we won't be locking tables. */ + lex->context_analysis_only= CONTEXT_ANALYSIS_ONLY_VIEW; + + /* + Some of process_table() functions rely on wildcard being passed from + old LEX (or at least being initialized). + */ + lex->wild= old_lex->wild; + + /* + Since make_table_list() might change database and table name passed + to it we create copies of orig_db_name and orig_table_name here. + These copies are used for make_table_list() while unaltered values + are passed to process_table() functions. + */ + if (!thd->make_lex_string(&db_name, orig_db_name->str, + orig_db_name->length, FALSE) || + !thd->make_lex_string(&table_name, orig_table_name->str, + orig_table_name->length, FALSE)) + goto end; + + /* + Create table list element for table to be open. Link it with the + temporary LEX. The latter is required to correctly open views and + produce table describing their structure. + */ + if (make_table_list(thd, &lex->select_lex, &db_name, &table_name)) + goto end; + + table_list= lex->select_lex.table_list.first; + + if (is_show_fields_or_keys) + { + /* + Restore thd->temporary_tables to be able to process + temporary tables (only for 'show index' & 'show columns'). + This should be changed when processing of temporary tables for + I_S tables will be done. + */ + thd->temporary_tables= open_tables_state_backup->temporary_tables; + } + else + { + /* + Apply optimization flags for table opening which are relevant for + this I_S table. We can't do this for SHOW COLUMNS/KEYS because of + backward compatibility. + */ + table_list->i_s_requested_object= schema_table->i_s_requested_object; + } + /* Let us set fake sql_command so views won't try to merge themselves into main statement. If we don't do this, SELECT * from information_schema.xxxx will cause problems. - SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()' + SQLCOM_SHOW_FIELDS is used because it satisfies + 'only_view_structure()'. */ lex->sql_command= SQLCOM_SHOW_FIELDS; - res= open_normal_and_derived_tables(thd, show_table_list, - MYSQL_LOCK_IGNORE_FLUSH); - lex->sql_command= save_sql_command; + + result= open_normal_and_derived_tables(thd, table_list, + MYSQL_LOCK_IGNORE_FLUSH); + /* - get_all_tables() returns 1 on failure and 0 on success thus - return only these and not the result code of ::process_table() + Restore old value of sql_command back as it is being looked at in + process_table() function. + */ + lex->sql_command= old_lex->sql_command; + + /* + XXX: show_table_list has a flag i_is_requested, + and when it's set, open_normal_and_derived_tables() + can return an error without setting an error message + in THD, which is a hack. This is why we have to + check for res, then for thd->is_error() and only then + for thd->main_da.sql_errno(). - We should use show_table_list->alias instead of - show_table_list->table_name because table_name - could be changed during opening of I_S tables. It's safe - to use alias because alias contains original table name - in this case(this part of code is used only for - 'show columns' & 'show statistics' commands). + Again we don't do this for SHOW COLUMNS/KEYS because + of backward compatibility. + */ + if (!is_show_fields_or_keys && result && thd->is_error() && + thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) + { + /* + Hide error for a non-existing table. + For example, this error can occur when we use a where condition + with a db name and table, but the table does not exist. + */ + result= 0; + thd->clear_error(); + } + else + { + result= schema_table->process_table(thd, table_list, + table, result, + orig_db_name, + orig_table_name); + } + +end: + lex->unit.cleanup(); + + /* Restore original LEX value, statement's arena and THD arena values. */ + lex_end(thd->lex); + + if (i_s_arena.free_list) + i_s_arena.free_items(); + + /* + For safety reset list of open temporary tables before closing + all tables open within this Open_tables_state. */ - table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias, - strlen(show_table_list->alias), FALSE); - if (!show_table_list->view) - db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db, - show_table_list->db_length, FALSE); - else - db_name= &show_table_list->view_db; - - - error= test(schema_table->process_table(thd, show_table_list, - table, res, db_name, - table_name)); - thd->temporary_tables= 0; - close_tables_for_reopen(thd, &show_table_list); - DBUG_RETURN(error); + thd->temporary_tables= NULL; + close_thread_tables(thd); + thd->lex= old_lex; + + thd->stmt_arena= old_arena; + thd->restore_active_arena(&i_s_arena, &backup_arena); + + return result; } @@ -3300,11 +3399,8 @@ int get_all_tables(THD *thd, TABLE_LIST { LEX *lex= thd->lex; TABLE *table= tables->table; - SELECT_LEX *old_all_select_lex= lex->all_selects_list; - enum_sql_command save_sql_command= lex->sql_command; SELECT_LEX *lsel= tables->schema_select_lex; ST_SCHEMA_TABLE *schema_table= tables->schema_table; - SELECT_LEX sel; LOOKUP_FIELD_VALUES lookup_field_vals; LEX_STRING *db_name, *table_name; bool with_i_schema; @@ -3312,20 +3408,14 @@ int get_all_tables(THD *thd, TABLE_LIST List db_names; List_iterator_fast it(db_names); COND *partial_cond= 0; - uint derived_tables= lex->derived_tables; int error= 1; Open_tables_state open_tables_state_backup; - uint8 save_context_analysis_only= lex->context_analysis_only; - Query_tables_list query_tables_list_backup; #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *sctx= thd->security_ctx; #endif uint table_open_method; DBUG_ENTER("get_all_tables"); - lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW; - lex->reset_n_backup_query_tables_list(&query_tables_list_backup); - /* We should not introduce deadlocks even if we already have some tables open and locked, since we won't lock tables which we will @@ -3340,8 +3430,18 @@ int get_all_tables(THD *thd, TABLE_LIST */ if (lsel && lsel->table_list.first) { - error= fill_schema_show_cols_or_idxs(thd, tables, schema_table, - &open_tables_state_backup); + LEX_STRING db_name, table_name; + + db_name.str= lsel->table_list.first->db; + db_name.length= lsel->table_list.first->db_length; + + table_name.str= lsel->table_list.first->table_name; + table_name.length= lsel->table_list.first->table_name_length; + + error= fill_schema_table_by_open(thd, TRUE, + table, schema_table, + &db_name, &table_name, + &open_tables_state_backup); goto err; } @@ -3399,12 +3499,6 @@ int get_all_tables(THD *thd, TABLE_LIST it.rewind(); /* To get access to new elements in basis list */ while ((db_name= it++)) { - LEX_STRING orig_db_name; - - /* db_name can be changed in make_table_list() func */ - if (!thd->make_lex_string(&orig_db_name, db_name->str, - db_name->length, FALSE)) - goto err; #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(check_access(thd,SELECT_ACL, db_name->str, &thd->col_access, 0, 1, with_i_schema) || @@ -3466,64 +3560,14 @@ int get_all_tables(THD *thd, TABLE_LIST continue; } - int res; - LEX_STRING tmp_lex_string; - /* - Set the parent lex of 'sel' because it is needed by - sel.init_query() which is called inside make_table_list. - */ thd->no_warnings_for_error= 1; - sel.parent_lex= lex; - if (make_table_list(thd, &sel, db_name, table_name)) - goto err; - TABLE_LIST *show_table_list= sel.table_list.first; - lex->all_selects_list= &sel; - lex->derived_tables= 0; - lex->sql_command= SQLCOM_SHOW_FIELDS; - show_table_list->i_s_requested_object= - schema_table->i_s_requested_object; + DEBUG_SYNC(thd, "before_open_in_get_all_tables"); - res= open_normal_and_derived_tables(thd, show_table_list, - MYSQL_LOCK_IGNORE_FLUSH); - lex->sql_command= save_sql_command; - /* - XXX: show_table_list has a flag i_is_requested, - and when it's set, open_normal_and_derived_tables() - can return an error without setting an error message - in THD, which is a hack. This is why we have to - check for res, then for thd->is_error() only then - for thd->main_da.sql_errno(). - */ - if (res && thd->is_error() && - thd->main_da.sql_errno() == ER_NO_SUCH_TABLE) - { - /* - Hide error for not existing table. - This error can occur for example when we use - where condition with db name and table name and this - table does not exist. - */ - res= 0; - thd->clear_error(); - } - else - { - /* - We should use show_table_list->alias instead of - show_table_list->table_name because table_name - could be changed during opening of I_S tables. It's safe - to use alias because alias contains original table name - in this case. - */ - thd->make_lex_string(&tmp_lex_string, show_table_list->alias, - strlen(show_table_list->alias), FALSE); - res= schema_table->process_table(thd, show_table_list, table, - res, &orig_db_name, - &tmp_lex_string); - close_tables_for_reopen(thd, &show_table_list); - } - DBUG_ASSERT(!lex->query_tables_own_last); - if (res) + + if (fill_schema_table_by_open(thd, FALSE, + table, schema_table, + db_name, table_name, + &open_tables_state_backup)) goto err; } } @@ -3539,11 +3583,7 @@ int get_all_tables(THD *thd, TABLE_LIST error= 0; err: thd->restore_backup_open_tables_state(&open_tables_state_backup); - lex->restore_backup_query_tables_list(&query_tables_list_backup); - lex->derived_tables= derived_tables; - lex->all_selects_list= old_all_select_lex; - lex->context_analysis_only= save_context_analysis_only; - lex->sql_command= save_sql_command; + DBUG_RETURN(error); } --===============9208726582621691686== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/dmitry.shulga@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: dmitry.shulga@stripped\ # h0mpo732tesiohbm # target_branch: file:///Users/shulga/projects/mysql/mysql-5.1-\ # bug11749345/ # testament_sha1: c961d1baba63153496d0bf7106869bbda5da4e0e # timestamp: 2011-05-21 02:07:48 +0700 # base_revision_id: luis.soares@stripped\ # 4g8gpmg0ebg4jitd # # Begin bundle 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 --===============9208726582621691686==--