#At file:///opt/local/work/5.0-41756/ based on revid:sergey.glukhov@stripped
2829 Konstantin Osipov 2009-10-28
A preview of the fix for
Bug#41756 "Strange error messages about locks from InnoDB".
Don't try to unlock rows unless certain that a) they were locked
b) they are not used.
added:
mysql-test/r/41756.result
mysql-test/t/41756-master.opt
mysql-test/t/41756.test
modified:
sql/item_subselect.cc
sql/records.cc
sql/sql_select.cc
sql/structs.h
=== added file 'mysql-test/r/41756.result'
--- a/mysql-test/r/41756.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/41756.result 2009-10-28 16:58:06 +0000
@@ -0,0 +1,20 @@
+#
+# Bug#41756 Strange error messages about locks from InnoDB
+#
+drop table if exists t1, t2;
+create table t1 (a int, b int primary key) engine=innodb;
+insert into t1 values (1,1), (null,2), (1,3), (1,4);
+create table t2 (a int, b int) engine=innodb;
+insert into t2 values (1,2), (1,2);
+select 1 from t1 natural join (select * from t2) as d for update;
+1
+commit;
+begin;
+select 1 from t1 natural join (select * from t2) as d for update;
+1
+#
+# Switching to connection con1
+delete from t1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+drop table t1, t2;
=== added file 'mysql-test/t/41756-master.opt'
--- a/mysql-test/t/41756-master.opt 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/41756-master.opt 2009-10-28 16:58:06 +0000
@@ -0,0 +1,2 @@
+--innodb-locks-unsafe-for-binlog
+--innodb-lock-wait-timeout=1
=== added file 'mysql-test/t/41756.test'
--- a/mysql-test/t/41756.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/41756.test 2009-10-28 16:58:06 +0000
@@ -0,0 +1,29 @@
+--source include/have_innodb.inc
+
+--echo #
+--echo # Bug#41756 Strange error messages about locks from InnoDB
+--echo #
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+create table t1 (a int, b int primary key) engine=innodb;
+insert into t1 values (1,1), (null,2), (1,3), (1,4);
+create table t2 (a int, b int) engine=innodb;
+insert into t2 values (1,2), (1,2);
+select 1 from t1 natural join (select * from t2) as d for update;
+commit;
+begin;
+select 1 from t1 natural join (select * from t2) as d for update;
+connect (con1,localhost,root,,);
+--echo #
+--echo # Switching to connection con1
+connection con1;
+--error ER_LOCK_WAIT_TIMEOUT
+delete from t1;
+disconnect con1;
+connection default;
+commit;
+
+drop table t1, t2;
+
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2009-07-16 15:43:46 +0000
+++ b/sql/item_subselect.cc 2009-10-28 16:58:06 +0000
@@ -1844,6 +1844,7 @@ int subselect_single_select_engine::exec
item->reset_value_registration();
JOIN_TAB *changed_tabs[MAX_TABLES];
JOIN_TAB **last_changed_tab= changed_tabs;
+ void rr_unlock_row(READ_RECORD *info);
if (item->have_guarded_conds())
{
/*
@@ -1869,6 +1870,7 @@ int subselect_single_select_engine::exec
tab->read_record.record= tab->table->record[0];
tab->read_record.thd= join->thd;
tab->read_record.ref_length= tab->table->file->ref_length;
+ tab->read_record.unlock_row= rr_unlock_row;
*(last_changed_tab++)= tab;
break;
}
=== modified file 'sql/records.cc'
--- a/sql/records.cc 2009-10-20 04:42:10 +0000
+++ b/sql/records.cc 2009-10-28 16:58:06 +0000
@@ -29,6 +29,8 @@ static int init_rr_cache(THD *thd, READ_
static int rr_cmp(uchar *a,uchar *b);
static int rr_index_first(READ_RECORD *info);
static int rr_index(READ_RECORD *info);
+void rr_unlock_row(READ_RECORD *info);
+void rr_dummy(READ_RECORD *info);
/*
@@ -61,6 +63,7 @@ void init_read_record_idx(READ_RECORD *i
info->file= table->file;
info->record= table->record[0];
info->print_error= print_error;
+ info->unlock_row= rr_unlock_row;
table->status=0; /* And it's always found */
if (!table->file->inited)
@@ -135,6 +138,7 @@ void init_read_record(READ_RECORD *info,
}
info->select=select;
info->print_error=print_error;
+ info->unlock_row= rr_unlock_row;
info->ignore_not_found_rows= 0;
table->status=0; /* And it's always found */
@@ -579,3 +583,14 @@ static int rr_cmp(uchar *a,uchar *b)
return (int) a[7] - (int) b[7];
#endif
}
+
+
+void rr_unlock_row(READ_RECORD *info)
+{
+ info->file->unlock_row();
+}
+
+
+void rr_dummy(READ_RECORD *info)
+{
+}
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2009-10-21 09:04:08 +0000
+++ b/sql/sql_select.cc 2009-10-28 16:58:06 +0000
@@ -6164,6 +6164,8 @@ make_join_readinfo(JOIN *join, ulonglong
bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
bool ordered_set= 0;
+ void rr_unlock_row(READ_RECORD *info);
+ void rr_dummy(READ_RECORD *info);
DBUG_ENTER("make_join_readinfo");
for (i=join->const_tables ; i < join->tables ; i++)
@@ -6172,6 +6174,7 @@ make_join_readinfo(JOIN *join, ulonglong
TABLE *table=tab->table;
tab->read_record.table= table;
tab->read_record.file=table->file;
+ tab->read_record.unlock_row= rr_unlock_row;
tab->next_select=sub_select; /* normal select */
/*
@@ -6215,6 +6218,7 @@ make_join_readinfo(JOIN *join, ulonglong
delete tab->quick;
tab->quick=0;
tab->read_first_record= join_read_key;
+ tab->read_record.unlock_row= rr_dummy;
tab->read_record.read_record= join_no_more_records;
if (table->used_keys.is_set(tab->ref.key) &&
!table->no_keyread)
@@ -10902,7 +10906,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
return NESTED_LOOP_NO_MORE_ROWS;
}
else
- join_tab->read_record.file->unlock_row();
+ join_tab->read_record.unlock_row(&join_tab->read_record);
}
else
{
@@ -10912,7 +10916,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
*/
join->examined_rows++;
join->thd->row_count++;
- join_tab->read_record.file->unlock_row();
+ join_tab->read_record.unlock_row(&join_tab->read_record);
}
return NESTED_LOOP_OK;
}
=== modified file 'sql/structs.h'
--- a/sql/structs.h 2009-01-21 18:45:23 +0000
+++ b/sql/structs.h 2009-10-28 16:58:06 +0000
@@ -122,11 +122,14 @@ class SQL_SELECT;
class THD;
class handler;
+typedef void (*Unlock_row_func)(st_read_record *);
+
typedef struct st_read_record { /* Parameter to read_record */
struct st_table *table; /* Head-form */
handler *file;
struct st_table **forms; /* head and ref forms */
int (*read_record)(struct st_read_record *);
+ Unlock_row_func unlock_row;
THD *thd;
SQL_SELECT *select;
uint cache_records;
Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20091028165806-pybzyomvixvx29t5.bundle
| Thread |
|---|
| • bzr commit into mysql-5.0 branch (kostja:2829) Bug#41756 | Konstantin Osipov | 28 Oct |