#At file:///opt/local/work/trunk-runtime-52114/ based on revid:jon.hauglid@stripped
3065 Konstantin Osipov 2010-06-29
A fix for Bug#54811 "Assert in mysql_lock_have_duplicate()".
Remove mysql_lock_have_duplicate(), since now we always
have TABLE_LIST objects for MyISAMMRG children
in lex->query_tables and keep it till the end of the
statement (sub-statement).
@ sql/lock.cc
Remove a function that is now unused.
@ sql/lock.h
Remove a function that is now unused.
@ sql/sql_base.cc
Don't try to search for duplicate table among THR_LOCK objects, TABLE_LIST list contains all used tables.
modified:
mysql-test/t/merge-big.test
sql/lock.cc
sql/lock.h
sql/sql_base.cc
=== modified file 'mysql-test/t/merge-big.test'
--- a/mysql-test/t/merge-big.test 2009-12-02 23:09:22 +0000
+++ b/mysql-test/t/merge-big.test 2010-06-29 11:16:11 +0000
@@ -51,7 +51,7 @@ connection default;
#--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE ID = $con1_id AND STATE = 'Table lock';
+ WHERE ID = $con1_id AND STATE = 'Waiting for table';
--source include/wait_condition.inc
#SELECT NOW();
--echo # Kick INSERT out of thr_multi_lock().
@@ -61,7 +61,7 @@ FLUSH TABLES;
#--sleep 8
#SELECT ID,STATE,INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
let $wait_condition= SELECT 1 FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE ID = $con1_id AND STATE = 'Table lock';
+ WHERE ID = $con1_id AND STATE = 'Waiting for table';
--source include/wait_condition.inc
#SELECT NOW();
--echo # Unlock and close table and wait for con1 to close too.
=== modified file 'sql/lock.cc'
--- a/sql/lock.cc 2010-06-11 15:28:18 +0000
+++ b/sql/lock.cc 2010-06-29 11:16:11 +0000
@@ -627,110 +627,6 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK
}
-/**
- Find duplicate lock in tables.
-
- Temporary tables are ignored here like they are ignored in
- get_lock_data(). If we allow two opens on temporary tables later,
- both functions should be checked.
-
- @param thd The current thread.
- @param needle The table to check for duplicate lock.
- @param haystack The list of tables to search for the dup lock.
-
- @note
- This is mainly meant for MERGE tables in INSERT ... SELECT
- situations. The 'real', underlying tables can be found only after
- the MERGE tables are opened. This function assumes that the tables are
- already locked.
-
- @retval
- NULL No duplicate lock found.
- @retval
- !NULL First table from 'haystack' that matches a lock on 'needle'.
-*/
-
-TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
- TABLE_LIST *haystack)
-{
- MYSQL_LOCK *mylock;
- TABLE **lock_tables;
- TABLE *table;
- TABLE *table2;
- THR_LOCK_DATA **lock_locks;
- THR_LOCK_DATA **table_lock_data;
- THR_LOCK_DATA **end_data;
- THR_LOCK_DATA **lock_data2;
- THR_LOCK_DATA **end_data2;
- DBUG_ENTER("mysql_lock_have_duplicate");
-
- /*
- Table may not be defined for derived or view tables.
- Table may not be part of a lock for delayed operations.
- */
- if (! (table= needle->table) || ! table->lock_count)
- goto end;
-
- /* A temporary table does not have locks. */
- if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
- goto end;
-
- /* Get command lock or LOCK TABLES lock. Maybe empty for INSERT DELAYED. */
- if (! (mylock= thd->lock))
- goto end;
-
- /* If we have less than two tables, we cannot have duplicates. */
- if (mylock->table_count < 2)
- goto end;
-
- lock_locks= mylock->locks;
- lock_tables= mylock->table;
-
- /* Prepare table related variables that don't change in loop. */
- DBUG_ASSERT((table->lock_position < mylock->table_count) &&
- (table == lock_tables[table->lock_position]));
- table_lock_data= lock_locks + table->lock_data_start;
- end_data= table_lock_data + table->lock_count;
-
- for (; haystack; haystack= haystack->next_global)
- {
- if (haystack->placeholder())
- continue;
- table2= haystack->table;
- if (table2->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
- continue;
-
- /* All tables in list must be in lock. */
- DBUG_ASSERT((table2->lock_position < mylock->table_count) &&
- (table2 == lock_tables[table2->lock_position]));
-
- for (lock_data2= lock_locks + table2->lock_data_start,
- end_data2= lock_data2 + table2->lock_count;
- lock_data2 < end_data2;
- lock_data2++)
- {
- THR_LOCK_DATA **lock_data;
- THR_LOCK *lock2= (*lock_data2)->lock;
-
- for (lock_data= table_lock_data;
- lock_data < end_data;
- lock_data++)
- {
- if ((*lock_data)->lock == lock2)
- {
- DBUG_PRINT("info", ("haystack match: '%s'", haystack->table_name));
- DBUG_RETURN(haystack);
- }
- }
- }
- }
-
- end:
- DBUG_PRINT("info", ("no duplicate found"));
- DBUG_RETURN(NULL);
-}
-
-
/** Unlock a set of external. */
static int unlock_external(THD *thd, TABLE **table,uint count)
=== modified file 'sql/lock.h'
--- a/sql/lock.h 2010-06-06 11:19:29 +0000
+++ b/sql/lock.h 2010-06-29 11:16:11 +0000
@@ -60,8 +60,6 @@ void mysql_lock_remove(THD *thd, MYSQL_L
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock);
bool mysql_lock_abort_for_thread(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
-TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
- TABLE_LIST *haystack);
void broadcast_refresh(void);
/* Lock based on name */
bool lock_table_names(THD *thd, TABLE_LIST *table_list);
=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc 2010-06-25 07:07:18 +0000
+++ b/sql/sql_base.cc 2010-06-29 11:16:11 +0000
@@ -2008,8 +2008,7 @@ TABLE_LIST* unique_table(THD *thd, TABLE
Table is unique if it is present only once in the global list
of tables and once in the list of table locks.
*/
- if (! (res= find_table_in_global_list(table_list, d_name, t_name)) &&
- ! (res= mysql_lock_have_duplicate(thd, table, table_list)))
+ if (! (res= find_table_in_global_list(table_list, d_name, t_name)))
break;
/* Skip if same underlying table. */
@@ -3204,8 +3203,7 @@ bool open_table(THD *thd, TABLE_LIST *ta
table_list->table= table;
DBUG_ASSERT(table->key_read == 0);
/* Tables may be reused in a sub statement. */
- if (table->file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN))
- table->file->extra(HA_EXTRA_DETACH_CHILDREN);
+ DBUG_ASSERT(! table->file->extra(HA_EXTRA_IS_ATTACHED_CHILDREN));
DBUG_RETURN(FALSE);
err_lock:
@@ -5563,11 +5561,25 @@ bool open_normal_and_derived_tables(THD
or schema tables) as free for reuse.
*/
-static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table)
+static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table_list)
{
- for (; table; table= table->next_global)
+ TABLE_LIST *table;
+ for (table= table_list; table; table= table->next_global)
if (!table->placeholder())
+ {
table->table->query_id= 0;
+ }
+ for (table= table_list; table; table= table->next_global)
+ if (!table->placeholder())
+ {
+ /*
+ Detach children of MyISAMMRG tables used in
+ sub-statements, they will be reattached at open.
+ This has to be done in a separate loop to make sure
+ that children have had their query_id cleared.
+ */
+ table->table->file->extra(HA_EXTRA_DETACH_CHILDREN);
+ }
}
Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20100629111611-pfdtq6dnuzvxr4an.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk-runtime branch (kostja:3065) Bug#54811 | Konstantin Osipov | 29 Jun |