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().
This commit is contained in:
parent
0cb90edfe5
commit
b976fb1444
@ -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,
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
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)
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
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,
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
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);
|
|||||||
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user