@@ -1022,6 +1022,9 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
1022
1022
TABLE_LIST *tables_to_reopen= (tables ? tables :
1023
1023
thd->locked_tables_list .locked_tables ());
1024
1024
1025
+ /* Close open HANLER instances to avoid self-deadlock. */
1026
+ mysql_ha_flush_tables (thd, tables_to_reopen);
1027
+
1025
1028
for (TABLE_LIST *table_list= tables_to_reopen; table_list;
1026
1029
table_list= table_list->next_global )
1027
1030
{
@@ -1049,7 +1052,8 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
1049
1052
{
1050
1053
found= FALSE ;
1051
1054
/*
1052
- To avoid self and other kinds of deadlock we have to flush open HANDLERs.
1055
+ To a self-deadlock or deadlocks with other FLUSH threads
1056
+ waiting on our open HANDLERs, we have to flush them.
1053
1057
*/
1054
1058
mysql_ha_flush (thd);
1055
1059
DEBUG_SYNC (thd, " after_flush_unlock" );
@@ -1308,8 +1312,7 @@ static void close_open_tables(THD *thd)
1308
1312
1309
1313
1310
1314
/* *
1311
- Close all open instances of the table but keep the MDL lock,
1312
- if any.
1315
+ Close all open instances of the table but keep the MDL lock.
1313
1316
1314
1317
Works both under LOCK TABLES and in the normal mode.
1315
1318
Removes all closed instances of the table from the table cache.
@@ -1323,6 +1326,8 @@ static void close_open_tables(THD *thd)
1323
1326
In that case the documented behaviour is to
1324
1327
implicitly remove the table from LOCK TABLES
1325
1328
list.
1329
+
1330
+ @pre Must be called with an X MDL lock on the table.
1326
1331
*/
1327
1332
1328
1333
void
@@ -1331,6 +1336,8 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
1331
1336
{
1332
1337
char key[MAX_DBKEY_LENGTH];
1333
1338
uint key_length= share->table_cache_key .length ;
1339
+ const char *db= key;
1340
+ const char *table_name= db + share->db .length + 1 ;
1334
1341
1335
1342
memcpy (key, share->table_cache_key .str , key_length);
1336
1343
@@ -1352,8 +1359,6 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
1352
1359
*/
1353
1360
mysql_lock_remove (thd, thd->lock , table);
1354
1361
1355
- /* Make sure the table is removed from the cache */
1356
- table->s ->version = 0 ;
1357
1362
/* Inform handler that table will be dropped after close */
1358
1363
if (table->db_stat ) /* Not true for partitioned tables. */
1359
1364
table->file ->extra (HA_EXTRA_PREPARE_FOR_DROP);
@@ -1365,7 +1370,14 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
1365
1370
prev= &table->next ;
1366
1371
}
1367
1372
}
1368
- /* We have been removing tables from the table cache. */
1373
+ /* Remove the table share from the cache. */
1374
+ mysql_mutex_lock (&LOCK_open);
1375
+ tdc_remove_table (thd, TDC_RT_REMOVE_ALL, db, table_name);
1376
+ mysql_mutex_unlock (&LOCK_open);
1377
+ /*
1378
+ There could be a FLUSH thread waiting
1379
+ on the table to go away. Wake it up.
1380
+ */
1369
1381
broadcast_refresh ();
1370
1382
}
1371
1383
0 commit comments