Commit b976fb14 authored by Konstantin Osipov's avatar Konstantin Osipov

A review comment for WL#4441 " LOCK_open: Remove requirement of

mutex protecting thd->open_tables".

We should not manipulate with table->s->version outside the 
table definition cache code, but use the TDC API
to achieve the desired result.

Fix one violation: close_all_tables_for_name().
parent 0cb90edf
...@@ -1022,6 +1022,9 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, ...@@ -1022,6 +1022,9 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
TABLE_LIST *tables_to_reopen= (tables ? tables : TABLE_LIST *tables_to_reopen= (tables ? tables :
thd->locked_tables_list.locked_tables()); thd->locked_tables_list.locked_tables());
/* Close open HANLER instances to avoid self-deadlock. */
mysql_ha_flush_tables(thd, tables_to_reopen);
for (TABLE_LIST *table_list= tables_to_reopen; table_list; for (TABLE_LIST *table_list= tables_to_reopen; table_list;
table_list= table_list->next_global) table_list= table_list->next_global)
{ {
...@@ -1049,7 +1052,8 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, ...@@ -1049,7 +1052,8 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
{ {
found= FALSE; found= FALSE;
/* /*
To avoid self and other kinds of deadlock we have to flush open HANDLERs. To a self-deadlock or deadlocks with other FLUSH threads
waiting on our open HANDLERs, we have to flush them.
*/ */
mysql_ha_flush(thd); mysql_ha_flush(thd);
DEBUG_SYNC(thd, "after_flush_unlock"); DEBUG_SYNC(thd, "after_flush_unlock");
...@@ -1308,8 +1312,7 @@ static void close_open_tables(THD *thd) ...@@ -1308,8 +1312,7 @@ static void close_open_tables(THD *thd)
/** /**
Close all open instances of the table but keep the MDL lock, Close all open instances of the table but keep the MDL lock.
if any.
Works both under LOCK TABLES and in the normal mode. Works both under LOCK TABLES and in the normal mode.
Removes all closed instances of the table from the table cache. Removes all closed instances of the table from the table cache.
...@@ -1323,6 +1326,8 @@ static void close_open_tables(THD *thd) ...@@ -1323,6 +1326,8 @@ static void close_open_tables(THD *thd)
In that case the documented behaviour is to In that case the documented behaviour is to
implicitly remove the table from LOCK TABLES implicitly remove the table from LOCK TABLES
list. list.
@pre Must be called with an X MDL lock on the table.
*/ */
void void
...@@ -1331,6 +1336,8 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, ...@@ -1331,6 +1336,8 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
{ {
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
uint key_length= share->table_cache_key.length; uint key_length= share->table_cache_key.length;
const char *db= key;
const char *table_name= db + share->db.length + 1;
memcpy(key, share->table_cache_key.str, key_length); memcpy(key, share->table_cache_key.str, key_length);
...@@ -1352,8 +1359,6 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, ...@@ -1352,8 +1359,6 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
*/ */
mysql_lock_remove(thd, thd->lock, table); mysql_lock_remove(thd, thd->lock, table);
/* Make sure the table is removed from the cache */
table->s->version= 0;
/* Inform handler that table will be dropped after close */ /* Inform handler that table will be dropped after close */
if (table->db_stat) /* Not true for partitioned tables. */ if (table->db_stat) /* Not true for partitioned tables. */
table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
...@@ -1365,7 +1370,14 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share, ...@@ -1365,7 +1370,14 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
prev= &table->next; prev= &table->next;
} }
} }
/* We have been removing tables from the table cache. */ /* Remove the table share from the cache. */
mysql_mutex_lock(&LOCK_open);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db, table_name);
mysql_mutex_unlock(&LOCK_open);
/*
There could be a FLUSH thread waiting
on the table to go away. Wake it up.
*/
broadcast_refresh(); broadcast_refresh();
} }
......
...@@ -833,6 +833,35 @@ void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables) ...@@ -833,6 +833,35 @@ void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables)
} }
/**
Close cursors of matching tables from the HANDLER's hash table.
@param thd Thread identifier.
@param tables The list of tables to flush.
*/
void mysql_ha_flush_tables(THD *thd, TABLE_LIST *all_tables)
{
DBUG_ENTER("mysql_ha_flush_tables");
for (TABLE_LIST *table_list= all_tables; table_list;
table_list= table_list->next_global)
{
TABLE_LIST *hash_tables= mysql_ha_find(thd, table_list);
/* Close all aliases of the same table. */
while (hash_tables)
{
TABLE_LIST *next_local= hash_tables->next_local;
if (hash_tables->table)
mysql_ha_close_table(thd, hash_tables);
hash_tables= next_local;
}
}
DBUG_VOID_RETURN;
}
/** /**
Flush (close and mark for re-open) all tables that should be should Flush (close and mark for re-open) all tables that should be should
be reopen. be reopen.
......
...@@ -28,6 +28,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables); ...@@ -28,6 +28,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables);
bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
void mysql_ha_flush(THD *thd); void mysql_ha_flush(THD *thd);
void mysql_ha_flush_tables(THD *thd, TABLE_LIST *all_tables);
void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables); void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables);
void mysql_ha_cleanup(THD *thd); void mysql_ha_cleanup(THD *thd);
void mysql_ha_move_tickets_after_trans_sentinel(THD *thd); void mysql_ha_move_tickets_after_trans_sentinel(THD *thd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment