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 Aske | 17 Jan |