1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-34775 Wrong reopen of already open routine due to auto-create in SP

MDEV-34171 denied removing indirect routines/tables after
recover_from_failed_open() for auto-create partition case. Now we are
going further and keep them for any failed table reopen.

MDEV-34171 did not handle correctly open_and_process_routine() after
that skip of sp_remove_not_own_routines(). Now it is fixed by
sroutine_to_open correct usage.
This commit is contained in:
Aleksey Midenkov
2025-03-24 09:01:07 +03:00
parent f813c8541a
commit 4c695c85bd
4 changed files with 57 additions and 26 deletions

View File

@@ -3470,4 +3470,25 @@ drop table t;
#
# End of 10.9 tests
#
#
# MDEV-34775 Wrong reopen of already open routine due to auto-create in SP
#
create table t (a int) with system versioning
partition by system_time
interval 1 minute auto;
create function f()
returns int
begin
replace into t select * from t;
return 0;
end $
set timestamp= @@timestamp + 61;
select f();
f()
0
drop table t;
drop function f;
#
# End of 10.11 tests
#
set global innodb_stats_persistent= @save_persistent;

View File

@@ -2717,5 +2717,32 @@ drop table t;
--echo # End of 10.9 tests
--echo #
--echo #
--echo # MDEV-34775 Wrong reopen of already open routine due to auto-create in SP
--echo #
create table t (a int) with system versioning
partition by system_time
interval 1 minute auto;
--delimiter $
create function f()
returns int
begin
replace into t select * from t;
return 0;
end $
--delimiter ;
set timestamp= @@timestamp + 61;
select f();
drop table t;
drop function f;
--echo #
--echo # End of 10.11 tests
--echo #
set global innodb_stats_persistent= @save_persistent;
--source suite/versioning/common_finish.inc

View File

@@ -4561,6 +4561,7 @@ bool open_tables(THD *thd, const DDL_options_st &options,
}
thd->current_tablenr= 0;
sroutine_to_open= &thd->lex->sroutines_list.first;
restart:
/*
@@ -4576,7 +4577,6 @@ restart:
has_prelocking_list= thd->lex->requires_prelocking();
table_to_open= start;
sroutine_to_open= &thd->lex->sroutines_list.first;
*counter= 0;
THD_STAGE_INFO(thd, stage_opening_tables);
prelocking_strategy->reset(thd);
@@ -4673,7 +4673,7 @@ restart:
elements from the table list (if MERGE tables are involved),
*/
close_tables_for_reopen(thd, start, ot_ctx.start_of_statement_svp(),
ot_ctx.remove_implicitly_used_deps());
false);
/*
Here we rely on the fact that 'tables' still points to the valid
@@ -4741,10 +4741,9 @@ restart:
/* F.ex. deadlock happened */
if (ot_ctx.can_recover_from_failed_open())
{
DBUG_ASSERT(ot_ctx.remove_implicitly_used_deps());
close_tables_for_reopen(thd, start,
ot_ctx.start_of_statement_svp(),
ot_ctx.remove_implicitly_used_deps());
true);
if (ot_ctx.recover_from_failed_open())
goto error;
@@ -4753,6 +4752,7 @@ restart:
goto error;
error= FALSE;
sroutine_to_open= &thd->lex->sroutines_list.first;
goto restart;
}
/*
@@ -6034,19 +6034,19 @@ bool restart_trans_for_tables(THD *thd, TABLE_LIST *table)
trying to reopen tables. NULL if no metadata locks
were held and thus all metadata locks should be
released.
@param[in] remove_implicit_deps True in case routines and tables implicitly
@param[in] remove_indirect True in case routines and tables implicitly
used by a statement should be removed.
*/
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
const MDL_savepoint &start_of_statement_svp,
bool remove_implicit_deps)
bool remove_indirect)
{
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
TABLE_LIST *tmp;
if (remove_implicit_deps)
if (remove_indirect)
{
TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
/*
If table list consists only from tables from prelocking set, table list
for new attempt should be empty, so we have to update list's root pointer.

View File

@@ -157,7 +157,7 @@ thr_lock_type read_lock_type_for_table(THD *thd,
my_bool mysql_rm_tmp_tables(void);
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
const MDL_savepoint &start_of_statement_svp,
bool remove_implicit_dependencies);
bool remove_indirect);
bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db,
LEX_CSTRING *table, thr_lock_type lock_type);
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
@@ -568,23 +568,6 @@ public:
return m_timeout;
}
/**
Return true in case tables and routines the statement implicilty
dependent on should be removed, else return false.
@note The use case when routines and tables the statement implicitly
dependent on shouldn't be removed is the one when a new partition be
created on handling the INSERT statement against a versioning partitioned
table. For this case re-opening a versioning table would result in adding
implicitly dependent routines (e.g. table's triggers) that lead to
allocation of memory on PS mem_root and so leaking a memory until the PS
statement be deallocated.
*/
bool remove_implicitly_used_deps() const
{
return m_action != OT_ADD_HISTORY_PARTITION;
}
uint get_flags() const { return m_flags; }
/**