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:
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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; }
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user