List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:December 6 2010 11:38am
Subject:bzr commit into mysql-5.1-telco-7.0-spj-scan-vs-scan branch
(ole.john.aske:3388) Bug#58750
View as plain text  
#At file:///net/fimafeng09/export/home/tmp/oleja/mysql/mysql-5.1-telco-7.0-spj-scan-scan/ based on revid:ole.john.aske@stripped

 3388 Ole John Aske	2010-12-06
      SPJ-scan-scan: Cherry picked fix for bug#58750.
      
       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
=== 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	2010-12-06 11:38:21 +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	2010-12-06 11:38:21 +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	2010-12-01 22:00:42 +0000
+++ b/sql/ha_ndbcluster.cc	2010-12-06 11:38:21 +0000
@@ -5762,6 +5762,8 @@ int ha_ndbcluster::full_table_scan(const
 
     m_thd_ndb->m_scan_count++;
     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) &&
@@ -7671,6 +7673,9 @@ int ha_ndbcluster::read_range_first_to_b
   DBUG_ENTER("ha_ndbcluster::read_range_first_to_buf");
   DBUG_PRINT("enter", ("type: %d, sorted: %d, descending: %d", type, sorted, desc));
 
+  if (unlikely((error= close_scan())))
+    DBUG_RETURN(error);
+
   if (m_use_partition_pruning)
   {
     DBUG_ASSERT(!m_pushed_join);
@@ -7710,8 +7715,6 @@ int ha_ndbcluster::read_range_first_to_b
         start_key->length == key_info->key_length &&
         start_key->flag == HA_READ_KEY_EXACT)
     {
-      if ((error= close_scan()))
-        DBUG_RETURN(error);
       if (!m_thd_ndb->trans)
         if (unlikely(!start_transaction_key(active_index,
                                             start_key->key, error)))
@@ -7727,9 +7730,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 ((error= close_scan()))
-        DBUG_RETURN(error);
-
       if (!m_thd_ndb->trans)
         if (unlikely(!start_transaction_key(active_index,
                                             start_key->key, error)))


Attachment: [text/bzr-bundle] bzr/ole.john.aske@oracle.com-20101206113821-sqapd2qqs28vz9y6.bundle
Thread
bzr commit into mysql-5.1-telco-7.0-spj-scan-vs-scan branch(ole.john.aske:3388) Bug#58750Ole John Aske6 Dec