mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-23824 SIGSEGV in end_io_cache on REPAIR LOCAL TABLE for Aria table
Bugs fixed: - prepare_for_repair() didn't close all open files if table opened failed because of out-of-memory - If dd_recreate_table() failed, the data file was not properly restored from it's temporary name - Aria repair initializing code didn't properly clear all used structs before calling error, which caused crashed in memory-free calls. - maria_delete_table() didn't register if table open failed. This could calls my_error() to be called without returning 1 to the caller, which cased failures in my_ok() Note when merging to 10.5: - Remove the #if MYSQL_VERSION from sql_admin.cc
This commit is contained in:
@ -91,10 +91,10 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table,
|
||||
static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
int error= 0;
|
||||
int error= 0, create_error= 0;
|
||||
TABLE tmp_table, *table;
|
||||
TABLE_LIST *pos_in_locked_tables= 0;
|
||||
TABLE_SHARE *share;
|
||||
TABLE_SHARE *share= 0;
|
||||
bool has_mdl_lock= FALSE;
|
||||
char from[FN_REFLEN],tmp[FN_REFLEN+32];
|
||||
const char **ext;
|
||||
@ -207,6 +207,23 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
HA_EXTRA_NOT_USED, NULL);
|
||||
table_list->table= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Table open failed, maybe because we run out of memory.
|
||||
Close all open tables and relaese all MDL locks
|
||||
*/
|
||||
#if MYSQL_VERSION < 100500
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
|
||||
table->s->db.str, table->s->table_name.str,
|
||||
TRUE);
|
||||
#else
|
||||
tdc_release_share(share);
|
||||
share->tdc->flush(thd, true);
|
||||
share= 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
After this point we have an exclusive metadata lock on our table
|
||||
in both cases when table was successfully open in mysql_admin_table()
|
||||
@ -220,11 +237,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
goto end;
|
||||
}
|
||||
if (dd_recreate_table(thd, table_list->db.str, table_list->table_name.str))
|
||||
{
|
||||
error= send_check_errmsg(thd, table_list, "repair",
|
||||
"Failed generating table from .frm file");
|
||||
goto end;
|
||||
}
|
||||
create_error= send_check_errmsg(thd, table_list, "repair",
|
||||
"Failed generating table from .frm file");
|
||||
/*
|
||||
'FALSE' for 'using_transactions' means don't postpone
|
||||
invalidation till the end of a transaction, but do it
|
||||
@ -237,6 +251,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
"Failed restoring .MYD file");
|
||||
goto end;
|
||||
}
|
||||
if (create_error)
|
||||
goto end;
|
||||
|
||||
if (thd->locked_tables_list.locked_tables())
|
||||
{
|
||||
@ -264,7 +280,8 @@ end:
|
||||
if (table == &tmp_table)
|
||||
{
|
||||
closefrm(table);
|
||||
tdc_release_share(table->s);
|
||||
if (share)
|
||||
tdc_release_share(share);
|
||||
}
|
||||
/* In case of a temporary table there will be no metadata lock. */
|
||||
if (unlikely(error) && has_mdl_lock)
|
||||
@ -592,6 +609,12 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
#endif
|
||||
DBUG_PRINT("admin", ("table: %p", table->table));
|
||||
|
||||
if (table->schema_table)
|
||||
{
|
||||
result_code= HA_ADMIN_NOT_IMPLEMENTED;
|
||||
goto send_result;
|
||||
}
|
||||
|
||||
if (prepare_func)
|
||||
{
|
||||
DBUG_PRINT("admin", ("calling prepare_func"));
|
||||
@ -650,12 +673,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
goto send_result;
|
||||
}
|
||||
|
||||
if (table->schema_table)
|
||||
{
|
||||
result_code= HA_ADMIN_NOT_IMPLEMENTED;
|
||||
goto send_result;
|
||||
}
|
||||
|
||||
if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
|
Reference in New Issue
Block a user