From: Ole John Aske Date: December 6 2010 11:40am Subject: bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (ole.john.aske:3387 to 3388) Bug#58750 List-Archive: http://lists.mysql.com/commits/126124 X-Bug: 58750 Message-Id: <20101206114015.893E7222@fimafeng09.norway.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 3387 Ole John Aske 2010-12-03 SPJ-scan-scan: Cherry picked fix for bug#57034 into SPJ branch. modified: mysql-test/r/join_outer.result mysql-test/t/join_outer.test sql/item_cmpfunc.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))) No bundle (reason: useless for push emails).