List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:January 17 2011 12:32pm
Subject:bzr push into mysql-5.1-telco-7.0 branch (ole.john.aske:4118 to 4119)
View as plain text  
 4119 Ole John Aske	2011-01-17
      Fix for bug##58750: 'out of connection objects' due to missing close()
      of prev. full_table_scan()'
      
      If ha_ndbcluster::read_range_first_to_buf() had to do a ::full_table_scan() 
      on a UNIQUE_INDEX, the resulting ScanOperation was not properly closed at end
      of its lifetime. If lots of such operations is executed within the 
      same transaction, we will eventually run out of operation or transaction objects.
      (Transaction objects is due to a dumnmy Hupp'ed transaction object is allocated as
      part of a ScanOperation)
            
      This fix ensures that ::close_scan() is called for any open cursors at start of
      ha_ndbcluster::read_range_first_to_buf().

    modified:
      mysql-test/suite/ndb/r/ndb_index_unique.result
      mysql-test/suite/ndb/t/ndb_index_unique.test
      sql/ha_ndbcluster.cc
 4118 Magnus Blåudd	2011-01-17 [merge]
      Merge

    modified:
      include/my_sys.h
      mysys/my_lockmem.c
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/ha_ndbcluster_binlog.cc
      sql/ha_ndbcluster_cond.cc
      sql/ha_ndbcluster_cond.h
      sql/ha_ndbcluster_glue.h
      storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
=== modified file 'mysql-test/suite/ndb/r/ndb_index_unique.result'
--- a/mysql-test/suite/ndb/r/ndb_index_unique.result	2010-11-14 14:16:10 +0000
+++ b/mysql-test/suite/ndb/r/ndb_index_unique.result	2011-01-17 12:31:29 +0000
@@ -889,3 +889,27 @@ a
 4
 set engine_condition_pushdown = @old_ecpd;
 drop table t1;
+create table t1 (pk int primary key, a int) engine=ndb;
+create table t2 (pk int primary key, uq int, a int, 
+unique key ix(uq,a) USING HASH) engine=ndb;
+Warnings:
+Warning	1121	Ndb does not support unique index on NULL valued attributes, index access with NULL value will become full table scan
+insert into t2 values
+(0,0,0), (1,1,0), (2,2,0), (3,3,0), (4,4,0),
+(5,5,1), (6,6,1), (7,7,1), (8,8,1), (9,9,1);
+insert into t1
+select
+t1.pk + t2.pk*10 + t3.pk*100 + t4.pk*1000, t1.a
+from
+t2 as t1, t2 as t2, t2 as t3, t2 as t4;
+explain
+SELECT STRAIGHT_JOIN count(*) FROM 
+t1 JOIN t2 ON t2.a=t1.a where t2.uq IS NULL;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	10000	
+1	SIMPLE	t2	ref	ix	ix	10	const,test.t1.a	1	Using where with pushed condition
+SELECT STRAIGHT_JOIN count(*) FROM 
+t1 JOIN t2 ON t2.a=t1.a where t2.uq IS NULL;
+count(*)
+0
+drop table t1,t2;

=== modified file 'mysql-test/suite/ndb/t/ndb_index_unique.test'
--- a/mysql-test/suite/ndb/t/ndb_index_unique.test	2010-11-14 14:16:10 +0000
+++ b/mysql-test/suite/ndb/t/ndb_index_unique.test	2011-01-17 12:31:29 +0000
@@ -514,4 +514,42 @@ set engine_condition_pushdown = @old_ecp
 
 drop table t1;
 
+#
+# Bug#58750: 'out of connection objects' due to missing close()
+# of prev. full_table_scan()
+#
+create table t1 (pk int primary key, a int) engine=ndb;
+create table t2 (pk int primary key, uq int, a int, 
+   unique key ix(uq,a) USING HASH) engine=ndb;
+
+insert into t2 values
+   (0,0,0), (1,1,0), (2,2,0), (3,3,0), (4,4,0),
+   (5,5,1), (6,6,1), (7,7,1), (8,8,1), (9,9,1);
+
+##
+# 10^4 cross product on t2 creates 10.000 rows:
+##
+insert into t1
+ select
+   t1.pk + t2.pk*10 + t3.pk*100 + t4.pk*1000, t1.a
+from
+  t2 as t1, t2 as t2, t2 as t3, t2 as t4;
+
+# Execute a 'scan(t1) join REF(t2) using ix'
+#  - Where condition 't2.uq IS NULL' in combination with 
+#    join cond. 't2.a=t1.a' will create the REF keys (NULL,t1.a).
+#    This will initiate a ::full_table_scan() which fails to
+#    close any open table scans.
+#  - Table scan(t1) will 'drive' the case above and eventually
+#    cause all ScanOperations / hupp'ed transactions to have been 
+#    consumed
+
+explain
+SELECT STRAIGHT_JOIN count(*) FROM 
+   t1 JOIN t2 ON t2.a=t1.a where t2.uq IS NULL;
+SELECT STRAIGHT_JOIN count(*) FROM 
+   t1 JOIN t2 ON t2.a=t1.a where t2.uq IS NULL;
+
+drop table t1,t2;
+
 # end of tests

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-01-14 15:12:39 +0000
+++ b/sql/ha_ndbcluster.cc	2011-01-17 12:31:29 +0000
@@ -3598,6 +3598,7 @@ int ha_ndbcluster::full_table_scan(const
     m_thd_ndb->m_pruned_scan_count += (op->getPruned()? 1 : 0);
   }
   
+  DBUG_ASSERT(m_active_cursor==NULL);
   m_active_cursor= op;
 
   if (uses_blob_value(table->read_set) &&
@@ -5448,6 +5449,9 @@ int ha_ndbcluster::read_range_first_to_b
   DBUG_ENTER("ha_ndbcluster::read_range_first_to_buf");
   DBUG_PRINT("info", ("desc: %d, sorted: %d", desc, sorted));
 
+  if (m_active_cursor && (error= close_scan()))
+    DBUG_RETURN(error);
+
   if (m_use_partition_pruning)
   {
     get_partition_set(table, buf, active_index, start_key, &part_spec);
@@ -5486,8 +5490,6 @@ int ha_ndbcluster::read_range_first_to_b
         start_key->length == key_info->key_length &&
         start_key->flag == HA_READ_KEY_EXACT)
     {
-      if (m_active_cursor && (error= close_scan()))
-        DBUG_RETURN(error);
       if (!m_thd_ndb->trans)
         if (unlikely(!start_transaction_key(active_index,
                                             start_key->key, error)))
@@ -5503,9 +5505,6 @@ int ha_ndbcluster::read_range_first_to_b
         start_key->flag == HA_READ_KEY_EXACT && 
         !check_null_in_key(key_info, start_key->key, start_key->length))
     {
-      if (m_active_cursor && (error= close_scan()))
-        DBUG_RETURN(error);
-
       if (!m_thd_ndb->trans)
         if (unlikely(!start_transaction_key(active_index,
                                             start_key->key, error)))

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-7.0 branch (ole.john.aske:4118 to 4119) Ole John Aske17 Jan