mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 18:41:56 +01:00
Bug#41110: crash with handler command when used concurrently with alter table
Bug#41112: crash in mysql_ha_close_table/get_lock_data with alter table The problem is that the server wasn't handling robustly failures to re-open a table during a HANDLER .. READ statement. If the table needed to be re-opened due to it's storage engine being altered to one that doesn't support HANDLER, a reference (dangling pointer) to a closed table could be left in place and accessed in later attempts to fetch from the table using the handler. Also, if the server failed to set a error message if the re-open failed. These problems could lead to server crashes or hangs. The solution is to remove any references to a closed table and to set a error if reopening a table during a HANDLER .. READ statement fails. There is no test case in this change set as the test depends on a testing feature only available on 5.1 and later. sql/sql_handler.cc: Remove redundant reopen check. Set errors even if reopening table. Reset TABLE_LIST::table reference when the table is closed.
This commit is contained in:
parent
982f88fc31
commit
11b20f27af
1 changed files with 7 additions and 8 deletions
|
@ -151,6 +151,9 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
|
||||||
}
|
}
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark table as closed, ready for re-open if necessary. */
|
||||||
|
tables->table= NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -168,8 +171,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
|
||||||
'reopen' is set when a handler table is to be re-opened. In this case,
|
'reopen' is set when a handler table is to be re-opened. In this case,
|
||||||
'tables' is the pointer to the hashed TABLE_LIST object which has been
|
'tables' is the pointer to the hashed TABLE_LIST object which has been
|
||||||
saved on the original open.
|
saved on the original open.
|
||||||
'reopen' is also used to suppress the sending of an 'ok' message or
|
'reopen' is also used to suppress the sending of an 'ok' message.
|
||||||
error messages.
|
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@ -205,8 +207,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
|
||||||
strlen(tables->alias) + 1))
|
strlen(tables->alias) + 1))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info",("duplicate '%s'", tables->alias));
|
DBUG_PRINT("info",("duplicate '%s'", tables->alias));
|
||||||
if (! reopen)
|
my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias);
|
||||||
my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,8 +252,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
|
||||||
/* There can be only one table in '*tables'. */
|
/* There can be only one table in '*tables'. */
|
||||||
if (! (tables->table->file->table_flags() & HA_CAN_SQL_HANDLER))
|
if (! (tables->table->file->table_flags() & HA_CAN_SQL_HANDLER))
|
||||||
{
|
{
|
||||||
if (! reopen)
|
my_error(ER_ILLEGAL_HA, MYF(0), tables->alias);
|
||||||
my_error(ER_ILLEGAL_HA, MYF(0), tables->alias);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,8 +464,7 @@ retry:
|
||||||
|
|
||||||
if (need_reopen)
|
if (need_reopen)
|
||||||
{
|
{
|
||||||
mysql_ha_close_table(thd, tables);
|
mysql_ha_close_table(thd, hash_tables);
|
||||||
hash_tables->table= NULL;
|
|
||||||
/*
|
/*
|
||||||
The lock might have been aborted, we need to manually reset
|
The lock might have been aborted, we need to manually reset
|
||||||
thd->some_tables_deleted because handler's tables are closed
|
thd->some_tables_deleted because handler's tables are closed
|
||||||
|
|
Loading…
Add table
Reference in a new issue