* Davi Arnaut <davi@stripped> [07/08/15 09:42]:
> ChangeSet@stripped, 2007-08-15 02:13:39-03:00, davi@stripped +3 -0
> Bug#25856 (HANDLER table OPEN in one connection lock DROP TABLE in another one)
>
> mysql_ha_open calls mysql_ha_close on the error path (unsupported) to close the
> (opened) table before inserting it into the tables hash list handler_tables_hash) but
> mysql_ha_close only closes tables which are on the hash list, causing the table to be left
> open and locked.
>
> This change moves the table close logic into a separate function that is always
> called on the error path of mysql_ha_open or on a normal handler close (mysql_ha_close).
>
The patch is OK to push into 5.0-runtime, please see items below
that should be done before pushing.
> --- a/mysql-test/t/handler.test 2006-08-20 12:47:28 -03:00
> +++ b/mysql-test/t/handler.test 2007-08-15 02:09:44 -03:00
> @@ -427,3 +427,15 @@ select * from t1;
> # Just to be sure and not confuse the next test case writer.
> drop table if exists t1;
>
> +#
> +# Bug#25856 - HANDLER table OPEN in one connection lock DROP TABLE in another one
> +#
Please add:
--disable_warnings
drop table if exists t1;
--enable_warnings
> +create table t1 (a int) ENGINE=MEMORY;
> +# client 2
> +connection con2;
> +--error 1031
> +handler t1 open;
> +# client 1
> +connection default;
> +drop table t1;
You could also use something like
--echo --> client 2
instead of
# client 2
That will simplify reading of the result log.
> diff -Nrup a/sql/sql_handler.cc b/sql/sql_handler.cc
> --- a/sql/sql_handler.cc 2007-05-11 13:33:11 -03:00
> +++ b/sql/sql_handler.cc 2007-08-15 02:09:44 -03:00
> @@ -119,6 +119,50 @@ static void mysql_ha_hash_free(TABLE_LIS
> my_free((char*) tables, MYF(0));
> }
>
> +/*
> + Close a HANDLER table.
> +
> + SYNOPSIS
> + mysql_ha_close_table()
> + thd Thread identifier.
> + tables A list of tables with the first entry to close.
> +
> + DESCRIPTION
> + Though this function takes a list of tables, only the first list entry
> + will be closed.
> + Broadcasts refresh if it closed the table.
> +
> + RETURN
> + Nothing
> +*/
Please convert to Doxygen style, as described here:
http://forge.mysql.com/wiki/MySQL_Internals_Coding_Guidelines
> +static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
> +{
> + TABLE **table_ptr;
> +
> + /*
> + Though we could take the table pointer from hash_tables->table,
> + we must follow the thd->handler_tables chain anyway, as we need the
> + address of the 'next' pointer referencing this table
> + for close_thread_table().
> + */
> + for (table_ptr= &(thd->handler_tables);
> + *table_ptr && (*table_ptr != tables->table);
> + table_ptr= &(*table_ptr)->next)
> + ;
> +
> + if (*table_ptr)
> + {
> + (*table_ptr)->file->ha_index_or_rnd_end();
> + VOID(pthread_mutex_lock(&LOCK_open));
> + if (close_thread_table(thd, table_ptr))
> + {
> + /* Tell threads waiting for refresh that something has happened */
> + broadcast_refresh();
> + }
> + VOID(pthread_mutex_unlock(&LOCK_open));
> + }
> +}
--
-- Konstantin Osipov Software Developer, Moscow, Russia
-- MySQL AB, www.mysql.com The best DATABASE COMPANY in the GALAXY