List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:October 3 2007 1:16pm
Subject:Re: bk commit into 5.2 tree (davi:1.2609) BUG#25858
View as plain text  
* Davi Arnaut <davi@stripped> [07/10/03 04:45]:
> ChangeSet@stripped, 2007-10-02 21:27:31-03:00, davi@stripped +21 -0
>   Bug#25858 Some DROP TABLE under LOCK TABLES can cause deadlocks
>   
>   When a client (connection) holds a lock on a table and attempts to
>   drop (obtain a exclusive lock) on a second table that is already held
>   by a second client and the second client then attempts to drop the table
>   that is held by the first client, leads to a circular wait deadlock. This
>   scenario is very similar to trying to drop (or rename) a table while
>   holding read locks and are correctly forbidden.
>   
>   The solution is to allow a drop table operation to continue only if the
>   table being dropped is write (exclusively) locked, or if the table is
>   temporary, or if the client is not holding any locks. Using this scheme
>   prevents the creation of a circular chain in which each client is waiting
>   for one table that the next client in the chain is holding.
>   
>   This is incompatible change, as can be seen by number of tests cases
>   that needed to be fixed, but is consistent with respect to behavior of
>   the different scenarios in which the circular wait might happen.

OK to push.

> diff -Nrup a/sql/lock.cc b/sql/lock.cc
> --- a/sql/lock.cc	2007-09-27 16:56:21 -03:00
> +++ b/sql/lock.cc	2007-10-02 21:27:23 -03:00
> @@ -1002,6 +1002,7 @@ int lock_table_name(THD *thd, TABLE_LIST
>    char  key[MAX_DBKEY_LENGTH];
>    char *db= table_list->db;
>    uint  key_length;
> +  bool  found_locked_table= FALSE;
>    HASH_SEARCH_STATE state;
>    DBUG_ENTER("lock_table_name");
>    DBUG_PRINT("enter",("db: %s  name: %s", db, table_list->table_name));
> @@ -1017,6 +1018,13 @@ int lock_table_name(THD *thd, TABLE_LIST
>           table = (TABLE*) hash_next(&open_cache,(uchar*) key,
>                                      key_length, &state))
>      {
> +      if (table->reginfo.lock_type < TL_WRITE)
> +      {
> +        if (table->in_use == thd)
> +          found_locked_table= TRUE;
> +        continue;
> +      }
> +
>        if (table->in_use == thd)
>        {
>          DBUG_PRINT("info", ("Table is in use"));
> @@ -1025,6 +1033,17 @@ int lock_table_name(THD *thd, TABLE_LIST
>          DBUG_RETURN(0);
>        }
>      }
> +  }
> +
> +  if (thd->locked_tables && thd->locked_tables->table_count
> &&
> +      ! find_temporary_table(thd, table_list->db, table_list->table_name))
> +  {
> +    if (found_locked_table)
> +      my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias);
> +    else
> +      my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_list->alias);
> +
> +    DBUG_RETURN(-1);
>    }
>  
>    if (!(table= table_cache_insert_placeholder(thd, key, key_length)))

-- 
-- Konstantin Osipov              Software Developer, Moscow, Russia
-- MySQL AB, www.mysql.com   The best DATABASE COMPANY in the GALAXY
Thread
bk commit into 5.2 tree (davi:1.2609) BUG#25858Davi Arnaut3 Oct
  • Re: bk commit into 5.2 tree (davi:1.2609) BUG#25858Konstantin Osipov3 Oct