1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-15456 Server crashes upon adding or dropping a partition in ALTER under LOCK TABLE after ER_SAME_NAME_PARTITION

ALTER TABLE ... ADD PARTITION modifies the open TABLE structure,
and sets table->need_reopen=1 to reset these modifications
in case of an error.

But under LOCK TABLES the table isn't get reopened, despite need_reopen.

Fixed by reopening need_reopen tables under LOCK TABLE.
This commit is contained in:
Sergei Golubchik
2018-04-20 10:10:33 +02:00
parent 86718fda4e
commit bcb36ee21e
12 changed files with 58 additions and 15 deletions

View File

@ -568,7 +568,7 @@ err_with_reopen:
old locks. This should always succeed (unless some external process
has removed the tables)
*/
thd->locked_tables_list.reopen_tables(thd);
thd->locked_tables_list.reopen_tables(thd, false);
/*
Since downgrade_lock() won't do anything with shared
metadata lock it is much simpler to go through all open tables rather
@ -952,7 +952,10 @@ void close_thread_tables(THD *thd)
we will exit this function a few lines below.
*/
if (! thd->lex->requires_prelocking())
{
thd->locked_tables_list.reopen_tables(thd, true);
DBUG_VOID_RETURN;
}
/*
We are in the top-level statement of a prelocked statement,
@ -2973,7 +2976,7 @@ unlink_all_closed_tables(THD *thd, MYSQL_LOCK *lock, size_t reopen_count)
*/
bool
Locked_tables_list::reopen_tables(THD *thd)
Locked_tables_list::reopen_tables(THD *thd, bool need_reopen)
{
Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN);
size_t reopen_count= 0;
@ -2984,8 +2987,20 @@ Locked_tables_list::reopen_tables(THD *thd)
for (TABLE_LIST *table_list= m_locked_tables;
table_list; table_list= table_list->next_global)
{
if (table_list->table) /* The table was not closed */
continue;
if (need_reopen)
{
if (!table_list->table || !table_list->table->needs_reopen())
continue;
/* no need to remove the table from the TDC here, thus (TABLE*)1 */
close_all_tables_for_name(thd, table_list->table->s,
HA_EXTRA_NOT_USED, (TABLE*)1);
DBUG_ASSERT(table_list->table == NULL);
}
else
{
if (table_list->table) /* The table was not closed */
continue;
}
/* Links into thd->open_tables upon success */
if (open_table(thd, table_list, thd->mem_root, &ot_ctx))