#At file:///opt/local/work/mysql-5.1-bugteam/ based on revid:bjorn.munch@stripped
2912 Konstantin Osipov 2009-05-27
A tentative fix for Bug#43685 "Lock table affects other non-related
tables"
FLUSH TABLE <table_list> in 5.1 would wait for all tables with
old versions to go away from the table definition cache,
rather than only waiting for tables in the <table_list>.
The fix is to back-port a more elaborate FLUSH TABLES
implementation from 6.0.
modified:
sql/sql_base.cc
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2009-05-15 13:03:22 +0000
+++ b/sql/sql_base.cc 2009-05-27 11:43:52 +0000
@@ -957,34 +957,51 @@ bool close_cached_tables(THD *thd, TABLE
while (found && ! thd->killed)
{
found=0;
- for (uint idx=0 ; idx < open_cache.records ; idx++)
+ if (! tables)
{
- TABLE *table=(TABLE*) hash_element(&open_cache,idx);
- /* Avoid a self-deadlock. */
- if (table->in_use == thd)
- continue;
- /*
- Note that we wait here only for tables which are actually open, and
- not for placeholders with TABLE::open_placeholder set. Waiting for
- latter will cause deadlock in the following scenario, for example:
-
- conn1: lock table t1 write;
- conn2: lock table t2 write;
- conn1: flush tables;
- conn2: flush tables;
-
- It also does not make sense to wait for those of placeholders that
- are employed by CREATE TABLE as in this case table simply does not
- exist yet.
- */
- if (table->needs_reopen_or_name_lock() && (table->db_stat ||
- (table->open_placeholder && wait_for_placeholders)))
- {
- found=1;
- DBUG_PRINT("signal", ("Waiting for COND_refresh"));
- pthread_cond_wait(&COND_refresh,&LOCK_open);
- break;
- }
+ for (uint idx=0 ; idx < open_cache.records ; idx++)
+ {
+ TABLE *table=(TABLE*) hash_element(&open_cache,idx);
+ /* Avoid a self-deadlock. */
+ if (table->in_use == thd)
+ continue;
+ /*
+ Note that we wait here only for tables which are actually open, and
+ not for placeholders with TABLE::open_placeholder set. Waiting for
+ latter will cause deadlock in the following scenario, for example:
+
+ conn1: lock table t1 write;
+ conn2: lock table t2 write;
+ conn1: flush tables;
+ conn2: flush tables;
+
+ It also does not make sense to wait for those of placeholders that
+ are employed by CREATE TABLE as in this case table simply does not
+ exist yet.
+ */
+ if (table->needs_reopen_or_name_lock() && (table->db_stat ||
+ (table->open_placeholder && wait_for_placeholders)))
+ {
+ found=1;
+ DBUG_PRINT("signal", ("Waiting for COND_refresh"));
+ pthread_cond_wait(&COND_refresh,&LOCK_open);
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (TABLE_LIST *table= tables; table; table= table->next_local)
+ {
+ TABLE_SHARE *share= get_cached_table_share(table->db,
+ table->table_name);
+ if (share && share->version != refresh_version)
+ {
+ found= 1;
+ pthread_cond_wait(&COND_refresh,&LOCK_open);
+ break;
+ }
+ }
}
}
/*
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (kostja:2912) Bug#43685 | Konstantin Osipov | 27 May |