mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-14959: Fixed memory leak relating with view and IS
Fixed memory leak taken place on executing a prepared statement or a stored routine that querying a view and this view constructed on an information schema table. For example, Lets consider the following definition of the view 'v1' CREATE VIEW v1 AS SELECT table_name FROM information_schema.views ORDER BY table_name; Querying this view in PS mode result in hit of assert. PREPARE stmt FROM "SELECT * FROM v1"; EXECUTE stmt; EXECUTE stmt; (*) Running the statement marked with (*) leads to a crash in case server build with mode to control allocation of a memory from SP/PS memory root on the second and following executions of PS/SP. The reason of leaking the memory is that a memory allocated on processing of FRM file for the view requested from a PS/PS memory root meaning that this memory be released only when a stored routine be evicted from SP-cache or a prepared statement be deallocated that typically happens on termination of a user session. To fix the issue switch to a memory root specially created for allocation of short-lived objects that requested on parsing FRM.
This commit is contained in:
@ -4955,7 +4955,8 @@ try_acquire_high_prio_shared_mdl_lock(THD *thd, TABLE_LIST *table,
|
|||||||
open_tables function for this table
|
open_tables function for this table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int fill_schema_table_from_frm(THD *thd, TABLE *table,
|
static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root,
|
||||||
|
TABLE *table,
|
||||||
ST_SCHEMA_TABLE *schema_table,
|
ST_SCHEMA_TABLE *schema_table,
|
||||||
LEX_CSTRING *db_name,
|
LEX_CSTRING *db_name,
|
||||||
LEX_CSTRING *table_name,
|
LEX_CSTRING *table_name,
|
||||||
@ -4967,6 +4968,9 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
|
|||||||
TABLE_LIST table_list;
|
TABLE_LIST table_list;
|
||||||
uint res= 0;
|
uint res= 0;
|
||||||
char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1];
|
char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1];
|
||||||
|
Query_arena i_s_arena(mem_root, Query_arena::STMT_CONVENTIONAL_EXECUTION);
|
||||||
|
Query_arena backup_arena, *old_arena;
|
||||||
|
bool i_s_arena_active= false;
|
||||||
|
|
||||||
bzero((char*) &table_list, sizeof(TABLE_LIST));
|
bzero((char*) &table_list, sizeof(TABLE_LIST));
|
||||||
bzero((char*) &tbl, sizeof(TABLE));
|
bzero((char*) &tbl, sizeof(TABLE));
|
||||||
@ -5041,6 +5045,11 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
old_arena= thd->stmt_arena;
|
||||||
|
thd->stmt_arena= &i_s_arena;
|
||||||
|
thd->set_n_backup_active_arena(&i_s_arena, &backup_arena);
|
||||||
|
i_s_arena_active= true;
|
||||||
|
|
||||||
share= tdc_acquire_share(thd, &table_list, GTS_TABLE | GTS_VIEW);
|
share= tdc_acquire_share(thd, &table_list, GTS_TABLE | GTS_VIEW);
|
||||||
if (!share)
|
if (!share)
|
||||||
{
|
{
|
||||||
@ -5122,7 +5131,16 @@ end:
|
|||||||
savepoint is safe.
|
savepoint is safe.
|
||||||
*/
|
*/
|
||||||
DBUG_ASSERT(thd->open_tables == NULL);
|
DBUG_ASSERT(thd->open_tables == NULL);
|
||||||
|
|
||||||
thd->mdl_context.rollback_to_savepoint(open_tables_state_backup->mdl_system_tables_svp);
|
thd->mdl_context.rollback_to_savepoint(open_tables_state_backup->mdl_system_tables_svp);
|
||||||
|
|
||||||
|
if (i_s_arena_active)
|
||||||
|
{
|
||||||
|
thd->stmt_arena= old_arena;
|
||||||
|
thd->restore_active_arena(&i_s_arena, &backup_arena);
|
||||||
|
i_s_arena.free_items();
|
||||||
|
}
|
||||||
|
|
||||||
if (!thd->is_fatal_error)
|
if (!thd->is_fatal_error)
|
||||||
thd->clear_error();
|
thd->clear_error();
|
||||||
return res;
|
return res;
|
||||||
@ -5351,7 +5369,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
|
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
|
||||||
db_name != &INFORMATION_SCHEMA_NAME)
|
db_name != &INFORMATION_SCHEMA_NAME)
|
||||||
{
|
{
|
||||||
if (!fill_schema_table_from_frm(thd, table, schema_table,
|
if (!fill_schema_table_from_frm(thd, &tmp_mem_root,
|
||||||
|
table, schema_table,
|
||||||
db_name, table_name,
|
db_name, table_name,
|
||||||
&open_tables_state_backup,
|
&open_tables_state_backup,
|
||||||
can_deadlock))
|
can_deadlock))
|
||||||
|
Reference in New Issue
Block a user