List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:October 28 2009 4:58pm
Subject:bzr commit into mysql-5.0 branch (kostja:2829) Bug#41756
View as plain text  
#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#41756Konstantin Osipov28 Oct