List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:October 15 2010 12:28pm
Subject:bzr commit into mysql-5.1-telco-7.1 branch (ole.john.aske:3880) Bug#57481
View as plain text  
#At file:///net/fimafeng09/export/home/tmp/oleja/mysql/mysql-5.1-telco-7.1/ based on revid:jonas@stripped

 3880 Ole John Aske	2010-10-15
      Proposed patch for bug#57481
      
      ha_ndbcluster::read_multi_range_first() should close any previous completed scan operations.
      
      MTR result file *not* included due to its size.....

    modified:
      mysql-test/suite/ndb/t/ndb_read_multi_range.test
      sql/ha_ndbcluster.cc
=== modified file 'mysql-test/suite/ndb/t/ndb_read_multi_range.test'
--- a/mysql-test/suite/ndb/t/ndb_read_multi_range.test	2010-09-22 11:36:01 +0000
+++ b/mysql-test/suite/ndb/t/ndb_read_multi_range.test	2010-10-15 12:28:26 +0000
@@ -428,3 +428,52 @@ select * from t1
     or (a = 'v')
     order by a asc, b asc;
 drop table t1, t2;
+
+########################
+# Check propper reinit of a mrr executed multiple time as part of a join.
+# The mrr access is driven by a scan and executed as for every tuple 
+# in the scaned table.
+#
+# In certain queries the optimizer don't read the entire mrr result set
+# before it fetch the next tuple from the scanned table. 
+# The next mrr operation would then still have an open scan which wasn't
+# cleaned up as expected. This may cause all available NdbOperation,
+# NdbTransaction or lock objects to be consumed before the operation 
+# could finish.
+#####################
+
+create table t1 (pk int primary key, a int) engine=ndb;
+create table t2 (pk int primary key, a int) engine=ndb;
+
+insert into t2 values
+   (0,0), (1,1), (2,2), (3,3), (4,4),
+   (5,5), (6,6), (7,7), (8,8), (9,9);
+
+##
+# 10^4 cross product on t2 creates 10.000 rows:
+# Insert volume has been tunes to insert only 3.000
+# of these as this is sufficient to produce an 'out of connection objects'
+##
+insert into t1
+ select
+   t1.a + t2.a*10 + t3.a*100 + t4.a*1000, 
+   (t1.a + t2.a*10 + t3.a*100 + t4.a*1000) / 1000
+from
+  t2 as t1, t2 as t2, t2 as t3, t2 as t4
+where (t1.a + t2.a*10 + t3.a*100 + t4.a*1000) < 3000;
+
+
+# Execute a 'scan(t1) join mrr(t2)'
+#  - 'DISTINCT t1.pk' will cause optimizer to stop fetching mrr(t2) 
+#     when the first matching 't2.a = t1.a' is found.
+#  - 'LEFT JOIN' is to ensure that 'Using join buffer' is *not* used
+#
+explain
+SELECT DISTINCT STRAIGHT_JOIN t1.pk FROM 
+   t1 LEFT JOIN t2 ON t2.a = t1.a AND t2.pk != 6;
+
+--sorted_result
+SELECT DISTINCT STRAIGHT_JOIN t1.pk FROM 
+   t1 LEFT JOIN t2 ON t2.a = t1.a AND t2.pk != 6;
+
+drop table t1, t2;

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2010-10-11 06:48:37 +0000
+++ b/sql/ha_ndbcluster.cc	2010-10-15 12:28:26 +0000
@@ -11648,6 +11648,7 @@ ha_ndbcluster::read_multi_range_first(KE
   const NdbOperation* op;
   Thd_ndb *thd_ndb= m_thd_ndb;
   NdbTransaction *trans= m_thd_ndb->trans;
+  int error;
 
   DBUG_ENTER("ha_ndbcluster::read_multi_range_first");
   DBUG_PRINT("info", ("blob fields=%d read_set=0x%x", table_share->blob_fields, table->read_set->bitmap[0]));
@@ -11669,6 +11670,14 @@ ha_ndbcluster::read_multi_range_first(KE
                                                 sorted, 
                                                 buffer));
   }
+
+  /**
+   * There may still be an open m_multi_cursor from the previous mrr access on this handler.
+   * Close it now to free up resources for this NdbScanOperation.
+   */ 
+  if (unlikely(error= close_scan()))
+    DBUG_RETURN(error);
+
   thd_ndb->query_state|= NDB_QUERY_MULTI_READ_RANGE;
   m_disable_multi_read= FALSE;
 
@@ -11704,8 +11713,8 @@ ha_ndbcluster::read_multi_range_first(KE
   */
 
   DBUG_ASSERT(cur_index_type != UNDEFINED_INDEX);
+  DBUG_ASSERT(m_multi_cursor==NULL);
 
-  m_multi_cursor= 0;
   const NdbOperation* lastOp= trans ? trans->getLastDefinedOperation() : 0;
   NdbOperation::LockMode lm= 
     (NdbOperation::LockMode)get_ndb_lock_type(m_lock.type, table->read_set);
@@ -11713,7 +11722,6 @@ ha_ndbcluster::read_multi_range_first(KE
   const uchar *end_of_buffer= buffer->buffer_end;
   uint num_scan_ranges= 0;
   uint i;
-  int error;
   bool any_real_read= FALSE;
 
   if (m_read_before_write_removal_possible)


Attachment: [text/bzr-bundle] bzr/ole.john.aske@oracle.com-20101015122826-x4hqwwdvq2itz4yr.bundle
Thread
bzr commit into mysql-5.1-telco-7.1 branch (ole.john.aske:3880) Bug#57481Ole John Aske15 Oct