mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#19784790: ASSERTION `PART_SHARE->PARTITIONS_SHARE_REFS->NUM_PARTS
>= M_TOT_PARTS' FAILED. This patch is taken from MySQL, originally written by Mattias Jonsson Here follows the original commit message: Problem in handle_alter_part_error(), result in altered partition_info object was still used if table was under LOCK TABLES. Solution was to always close and destroy all table and table_share instances if exclusive mdl lock was possible. If not succeeding in get an exlusive lock (only possible during rollback of DDL), at least close and destroy this table instance. rb#7361. Approved by Mikael and Aditya.
This commit is contained in:
@ -6808,41 +6808,30 @@ static int alter_close_table(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
static void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
|
||||
bool action_completed,
|
||||
bool drop_partition,
|
||||
bool frm_install,
|
||||
bool close_table)
|
||||
bool frm_install)
|
||||
{
|
||||
partition_info *part_info= lpt->part_info;
|
||||
THD *thd= lpt->thd;
|
||||
partition_info *part_info= lpt->part_info->get_clone(thd);
|
||||
TABLE *table= lpt->table;
|
||||
DBUG_ENTER("handle_alter_part_error");
|
||||
DBUG_ASSERT(table->m_needs_reopen);
|
||||
|
||||
if (close_table)
|
||||
/*
|
||||
All instances of this table needs to be closed.
|
||||
Better to do that here, than leave the cleaning up to others.
|
||||
Acquire EXCLUSIVE mdl lock if not already acquired.
|
||||
*/
|
||||
if (!thd->mdl_context.is_lock_owner(MDL_key::TABLE, lpt->db.str,
|
||||
lpt->table_name.str,
|
||||
MDL_EXCLUSIVE) &&
|
||||
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
|
||||
{
|
||||
/*
|
||||
All instances of this table needs to be closed.
|
||||
Better to do that here, than leave the cleaning up to others.
|
||||
Aquire EXCLUSIVE mdl lock if not already aquired.
|
||||
*/
|
||||
if (!thd->mdl_context.is_lock_owner(MDL_key::TABLE, lpt->db.str,
|
||||
lpt->table_name.str,
|
||||
MDL_EXCLUSIVE))
|
||||
{
|
||||
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
|
||||
{
|
||||
/* At least remove this instance on failure */
|
||||
goto err_exclusive_lock;
|
||||
}
|
||||
}
|
||||
/* Ensure the share is destroyed and reopened. */
|
||||
if (part_info)
|
||||
part_info= part_info->get_clone(thd);
|
||||
close_all_tables_for_name(thd, table->s, HA_EXTRA_NOT_USED, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
err_exclusive_lock:
|
||||
/*
|
||||
Did not succeed in getting exclusive access to the table.
|
||||
|
||||
Since we have altered a cached table object (and its part_info) we need
|
||||
at least to remove this instance so it will not be reused.
|
||||
|
||||
Temporarily remove it from the locked table list, so that it will get
|
||||
reopened.
|
||||
*/
|
||||
@ -6854,11 +6843,14 @@ err_exclusive_lock:
|
||||
the table cache.
|
||||
*/
|
||||
mysql_lock_remove(thd, thd->lock, table);
|
||||
if (part_info)
|
||||
part_info= part_info->get_clone(thd);
|
||||
close_thread_table(thd, &thd->open_tables);
|
||||
lpt->table_list->table= NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ensure the share is destroyed and reopened. */
|
||||
close_all_tables_for_name(thd, table->s, HA_EXTRA_NOT_USED, NULL);
|
||||
}
|
||||
|
||||
if (part_info->first_log_entry &&
|
||||
execute_ddl_log_entry(thd, part_info->first_log_entry->entry_pos))
|
||||
@ -6876,17 +6868,20 @@ err_exclusive_lock:
|
||||
/* Table is still ok, but we left a shadow frm file behind. */
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
|
||||
"%s %s",
|
||||
"Operation was unsuccessful, table is still intact,",
|
||||
"but it is possible that a shadow frm file was left behind");
|
||||
"Operation was unsuccessful, table is still "
|
||||
"intact, but it is possible that a shadow frm "
|
||||
"file was left behind");
|
||||
}
|
||||
else
|
||||
{
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
|
||||
"%s %s %s %s",
|
||||
"Operation was unsuccessful, table is still intact,",
|
||||
"but it is possible that a shadow frm file was left behind.",
|
||||
"It is also possible that temporary partitions are left behind,",
|
||||
"these could be empty or more or less filled with records");
|
||||
"Operation was unsuccessful, table is still "
|
||||
"intact, but it is possible that a shadow frm "
|
||||
"file was left behind.",
|
||||
"It is also possible that temporary partitions "
|
||||
"are left behind, these could be empty or more "
|
||||
"or less filled with records");
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -6894,14 +6889,15 @@ err_exclusive_lock:
|
||||
if (frm_install)
|
||||
{
|
||||
/*
|
||||
Failed during install of shadow frm file, table isn't intact
|
||||
and dropped partitions are still there
|
||||
Failed during install of shadow frm file, table isn't intact
|
||||
and dropped partitions are still there
|
||||
*/
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
|
||||
"%s %s %s",
|
||||
"Failed during alter of partitions, table is no longer intact.",
|
||||
"The frm file is in an unknown state, and a backup",
|
||||
"is required.");
|
||||
"Failed during alter of partitions, table is no "
|
||||
"longer intact.",
|
||||
"The frm file is in an unknown state, and a "
|
||||
"backup is required.");
|
||||
}
|
||||
else if (drop_partition)
|
||||
{
|
||||
@ -6913,8 +6909,9 @@ err_exclusive_lock:
|
||||
*/
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
|
||||
"%s %s",
|
||||
"Failed during drop of partitions, table is intact.",
|
||||
"Manual drop of remaining partitions is required");
|
||||
"Failed during drop of partitions, table is "
|
||||
"intact.",
|
||||
"Manual drop of remaining partitions is required");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -6925,9 +6922,10 @@ err_exclusive_lock:
|
||||
*/
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,
|
||||
"%s %s %s",
|
||||
"Failed during renaming of partitions. We are now in a position",
|
||||
"where table is not reusable",
|
||||
"Table is disabled by writing ancient frm file version into it");
|
||||
"Failed during renaming of partitions. We are now "
|
||||
"in a position where table is not reusable",
|
||||
"Table is disabled by writing ancient frm file "
|
||||
"version into it");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6953,8 +6951,8 @@ err_exclusive_lock:
|
||||
completed.
|
||||
*/
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, 1,"%s %s",
|
||||
"Operation was successfully completed by failure handling,",
|
||||
"after failure of normal operation");
|
||||
"Operation was successfully completed by failure "
|
||||
"handling, after failure of normal operation");
|
||||
}
|
||||
}
|
||||
|
||||
@ -7032,7 +7030,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
ALTER_PARTITION_PARAM_TYPE lpt_obj;
|
||||
ALTER_PARTITION_PARAM_TYPE *lpt= &lpt_obj;
|
||||
bool action_completed= FALSE;
|
||||
bool close_table_on_failure= FALSE;
|
||||
bool frm_install= FALSE;
|
||||
MDL_ticket *mdl_ticket= table->mdl_ticket;
|
||||
DBUG_ENTER("fast_alter_partition_table");
|
||||
@ -7171,13 +7168,11 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) ||
|
||||
ERROR_INJECT_CRASH("crash_drop_partition_3") ||
|
||||
ERROR_INJECT_ERROR("fail_drop_partition_3") ||
|
||||
(close_table_on_failure= TRUE, FALSE) ||
|
||||
write_log_drop_partition(lpt) ||
|
||||
(action_completed= TRUE, FALSE) ||
|
||||
ERROR_INJECT_CRASH("crash_drop_partition_4") ||
|
||||
ERROR_INJECT_ERROR("fail_drop_partition_4") ||
|
||||
alter_close_table(lpt) ||
|
||||
(close_table_on_failure= FALSE, FALSE) ||
|
||||
ERROR_INJECT_CRASH("crash_drop_partition_5") ||
|
||||
ERROR_INJECT_ERROR("fail_drop_partition_5") ||
|
||||
((!thd->lex->no_write_to_binlog) &&
|
||||
@ -7197,8 +7192,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
ERROR_INJECT_CRASH("crash_drop_partition_9") ||
|
||||
ERROR_INJECT_ERROR("fail_drop_partition_9"))
|
||||
{
|
||||
handle_alter_part_error(lpt, action_completed, TRUE, frm_install,
|
||||
close_table_on_failure);
|
||||
handle_alter_part_error(lpt, action_completed, TRUE, frm_install);
|
||||
goto err;
|
||||
}
|
||||
if (alter_partition_lock_handling(lpt))
|
||||
@ -7246,14 +7240,12 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED) ||
|
||||
ERROR_INJECT_CRASH("crash_add_partition_3") ||
|
||||
ERROR_INJECT_ERROR("fail_add_partition_3") ||
|
||||
(close_table_on_failure= TRUE, FALSE) ||
|
||||
write_log_add_change_partition(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_add_partition_4") ||
|
||||
ERROR_INJECT_ERROR("fail_add_partition_4") ||
|
||||
mysql_change_partitions(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_add_partition_5") ||
|
||||
ERROR_INJECT_ERROR("fail_add_partition_5") ||
|
||||
(close_table_on_failure= FALSE, FALSE) ||
|
||||
alter_close_table(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_add_partition_6") ||
|
||||
ERROR_INJECT_ERROR("fail_add_partition_6") ||
|
||||
@ -7275,8 +7267,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
ERROR_INJECT_CRASH("crash_add_partition_10") ||
|
||||
ERROR_INJECT_ERROR("fail_add_partition_10"))
|
||||
{
|
||||
handle_alter_part_error(lpt, action_completed, FALSE, frm_install,
|
||||
close_table_on_failure);
|
||||
handle_alter_part_error(lpt, action_completed, FALSE, frm_install);
|
||||
goto err;
|
||||
}
|
||||
if (alter_partition_lock_handling(lpt))
|
||||
@ -7343,7 +7334,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
mysql_write_frm(lpt, WFRM_WRITE_SHADOW) ||
|
||||
ERROR_INJECT_CRASH("crash_change_partition_2") ||
|
||||
ERROR_INJECT_ERROR("fail_change_partition_2") ||
|
||||
(close_table_on_failure= TRUE, FALSE) ||
|
||||
write_log_add_change_partition(lpt) ||
|
||||
ERROR_INJECT_CRASH("crash_change_partition_3") ||
|
||||
ERROR_INJECT_ERROR("fail_change_partition_3") ||
|
||||
@ -7354,7 +7344,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
ERROR_INJECT_CRASH("crash_change_partition_5") ||
|
||||
ERROR_INJECT_ERROR("fail_change_partition_5") ||
|
||||
alter_close_table(lpt) ||
|
||||
(close_table_on_failure= FALSE, FALSE) ||
|
||||
ERROR_INJECT_CRASH("crash_change_partition_6") ||
|
||||
ERROR_INJECT_ERROR("fail_change_partition_6") ||
|
||||
write_log_final_change_partition(lpt) ||
|
||||
@ -7381,8 +7370,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
|
||||
ERROR_INJECT_CRASH("crash_change_partition_12") ||
|
||||
ERROR_INJECT_ERROR("fail_change_partition_12"))
|
||||
{
|
||||
handle_alter_part_error(lpt, action_completed, FALSE, frm_install,
|
||||
close_table_on_failure);
|
||||
handle_alter_part_error(lpt, action_completed, FALSE, frm_install);
|
||||
goto err;
|
||||
}
|
||||
if (alter_partition_lock_handling(lpt))
|
||||
|
Reference in New Issue
Block a user