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 # 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; set global innodb_stats_persistent= @save_persistent;

View File

@@ -2717,5 +2717,32 @@ drop table t;
--echo # End of 10.9 tests --echo # End of 10.9 tests
--echo # --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; set global innodb_stats_persistent= @save_persistent;
--source suite/versioning/common_finish.inc --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; thd->current_tablenr= 0;
sroutine_to_open= &thd->lex->sroutines_list.first;
restart: restart:
/* /*
@@ -4576,7 +4577,6 @@ restart:
has_prelocking_list= thd->lex->requires_prelocking(); has_prelocking_list= thd->lex->requires_prelocking();
table_to_open= start; table_to_open= start;
sroutine_to_open= &thd->lex->sroutines_list.first;
*counter= 0; *counter= 0;
THD_STAGE_INFO(thd, stage_opening_tables); THD_STAGE_INFO(thd, stage_opening_tables);
prelocking_strategy->reset(thd); prelocking_strategy->reset(thd);
@@ -4673,7 +4673,7 @@ restart:
elements from the table list (if MERGE tables are involved), elements from the table list (if MERGE tables are involved),
*/ */
close_tables_for_reopen(thd, start, ot_ctx.start_of_statement_svp(), 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 Here we rely on the fact that 'tables' still points to the valid
@@ -4741,10 +4741,9 @@ restart:
/* F.ex. deadlock happened */ /* F.ex. deadlock happened */
if (ot_ctx.can_recover_from_failed_open()) if (ot_ctx.can_recover_from_failed_open())
{ {
DBUG_ASSERT(ot_ctx.remove_implicitly_used_deps());
close_tables_for_reopen(thd, start, close_tables_for_reopen(thd, start,
ot_ctx.start_of_statement_svp(), ot_ctx.start_of_statement_svp(),
ot_ctx.remove_implicitly_used_deps()); true);
if (ot_ctx.recover_from_failed_open()) if (ot_ctx.recover_from_failed_open())
goto error; goto error;
@@ -4753,6 +4752,7 @@ restart:
goto error; goto error;
error= FALSE; error= FALSE;
sroutine_to_open= &thd->lex->sroutines_list.first;
goto restart; 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 trying to reopen tables. NULL if no metadata locks
were held and thus all metadata locks should be were held and thus all metadata locks should be
released. 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. used by a statement should be removed.
*/ */
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
const MDL_savepoint &start_of_statement_svp, 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; 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 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. 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); my_bool mysql_rm_tmp_tables(void);
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
const MDL_savepoint &start_of_statement_svp, 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, bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db,
LEX_CSTRING *table, thr_lock_type lock_type); LEX_CSTRING *table, thr_lock_type lock_type);
TABLE_LIST *find_table_in_list(TABLE_LIST *table, TABLE_LIST *find_table_in_list(TABLE_LIST *table,
@@ -568,23 +568,6 @@ public:
return m_timeout; 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; } uint get_flags() const { return m_flags; }
/** /**