From: Ole John Aske Date: October 15 2010 1:47pm Subject: bzr commit into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (ole.john.aske:3312) List-Archive: http://lists.mysql.com/commits/120847 Message-Id: <20101015134744.850A021D@fimafeng09.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0053558336066398931==" --===============0053558336066398931== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #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 3312 Ole John Aske 2010-10-15 spj-svs: MRR read may fail to close cursors for pending ScanOperations causing 'out of transaction / operation / lock' errors depending on the database config. This fix is cherry picked from proposed fix for bug 57481, with the addition of an additional SPJ test for the same scenario. modified: mysql-test/suite/ndb/r/ndb_join_pushdown.result mysql-test/suite/ndb/r/ndb_read_multi_range.result mysql-test/suite/ndb/t/ndb_join_pushdown.test mysql-test/suite/ndb/t/ndb_read_multi_range.test sql/ha_ndbcluster.cc === modified file 'mysql-test/suite/ndb/r/ndb_join_pushdown.result' --- a/mysql-test/suite/ndb/r/ndb_join_pushdown.result 2010-10-11 12:11:05 +0000 +++ b/mysql-test/suite/ndb/r/ndb_join_pushdown.result 2010-10-15 13:47:38 +0000 @@ -4014,6 +4014,35 @@ id select_type table type possible_keys select * from t1 as x1, t1 as x2 where x1.a=x2.b and x1.b = 3; pk a b pk a b drop table t1; +create table t (pk int primary key, a int) engine=ndb; +insert into t values +(1,1), (2,1), +(4,3), (6,3), +(7,4), (8,4); +explain +SELECT DISTINCT STRAIGHT_JOIN table1.pk FROM +t AS table1 JOIN +(t AS table2 JOIN +(t AS table3 JOIN t AS table4 ON table3.pk = table4.a) +ON table2.pk = table3.pk ) +ON table1.a = table4.pk +WHERE table2.pk != 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE table1 ALL NULL NULL NULL NULL 6 Parent of 2 pushed join@1; Using temporary +1 SIMPLE table2 range PRIMARY PRIMARY 4 NULL 2 Parent of 2 pushed join@2; Using where with pushed condition; Distinct +1 SIMPLE table3 eq_ref PRIMARY PRIMARY 4 test.table2.pk 1 Child of pushed join@2; Distinct +1 SIMPLE table4 eq_ref PRIMARY PRIMARY 4 test.table1.a 1 Child of pushed join@1; Using where; Distinct +SELECT DISTINCT STRAIGHT_JOIN table1.pk FROM +t AS table1 JOIN +(t AS table2 JOIN +(t AS table3 JOIN t AS table4 ON table3.pk = table4.a) +ON table2.pk = table3.pk ) +ON table1.a = table4.pk +WHERE table2.pk != 6; +pk +1 +2 +drop table t; create temporary table spj_counts_at_end select counter_name, sum(val) AS val from ndbinfo.counters @@ -4029,32 +4058,32 @@ and spj_counts_at_end.counter_name <> 'L and spj_counts_at_end.counter_name <> 'SCAN_BATCHES_RETURNED'; counter_name spj_counts_at_end.val - spj_counts_at_startup.val CONST_PRUNED_RANGE_SCANS_RECEIVED 6 -LOCAL_TABLE_SCANS_SENT 194 +LOCAL_TABLE_SCANS_SENT 196 PRUNED_RANGE_SCANS_RECEIVED 16 -RANGE_SCANS_RECEIVED 195 -READS_NOT_FOUND 403 +RANGE_SCANS_RECEIVED 203 +READS_NOT_FOUND 405 READS_RECEIVED 61 -SCAN_ROWS_RETURNED 63591 -TABLE_SCANS_RECEIVED 194 +SCAN_ROWS_RETURNED 63641 +TABLE_SCANS_RECEIVED 196 select sum(spj_counts_at_end.val - spj_counts_at_startup.val) as 'LOCAL+REMOTE READS_SENT' from spj_counts_at_end, spj_counts_at_startup where spj_counts_at_end.counter_name = spj_counts_at_startup.counter_name and (spj_counts_at_end.counter_name = 'LOCAL_READS_SENT' or spj_counts_at_end.counter_name = 'REMOTE_READS_SENT'); LOCAL+REMOTE READS_SENT -29120 +29146 drop table spj_counts_at_startup; drop table spj_counts_at_end; scan_count -1990 +2000 pruned_scan_count 7 sorted_scan_count 44 pushed_queries_defined -335 +339 pushed_queries_dropped 11 pushed_queries_executed -259 +264 set ndb_join_pushdown = @save_ndb_join_pushdown; === modified file 'mysql-test/suite/ndb/r/ndb_read_multi_range.result' --- a/mysql-test/suite/ndb/r/ndb_read_multi_range.result 2009-02-03 13:35:56 +0000 +++ b/mysql-test/suite/ndb/r/ndb_read_multi_range.result 2010-10-15 13:47:38 +0000 @@ -588,3 +588,24 @@ i i 9 m m 13 v v 22 drop table t1, t2; +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); +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) < 4000; +explain +SELECT DISTINCT STRAIGHT_JOIN t1.pk FROM +t1 LEFT JOIN t2 ON t2.a = t1.a AND t2.pk != 6; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4000 Using temporary +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Distinct +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 'mysql-test/suite/ndb/t/ndb_join_pushdown.test' --- a/mysql-test/suite/ndb/t/ndb_join_pushdown.test 2010-10-11 12:11:05 +0000 +++ b/mysql-test/suite/ndb/t/ndb_join_pushdown.test 2010-10-15 13:47:38 +0000 @@ -2838,6 +2838,39 @@ select * from t1 as x1, t1 as x2 where x drop table t1; +######## +# Test correct cleanup of MRR accesses being executed multiple times. +# This used to be bug#57481, and this is a SPJ specific testcase in addition to +# the specific testcase commited together with patch for this bug. +####### +create table t (pk int primary key, a int) engine=ndb; +insert into t values + (1,1), (2,1), + (4,3), (6,3), + (7,4), (8,4); + +explain +SELECT DISTINCT STRAIGHT_JOIN table1.pk FROM + t AS table1 JOIN + (t AS table2 JOIN + (t AS table3 JOIN t AS table4 ON table3.pk = table4.a) + ON table2.pk = table3.pk ) + ON table1.a = table4.pk + WHERE table2.pk != 6; + +--sorted_result +SELECT DISTINCT STRAIGHT_JOIN table1.pk FROM + t AS table1 JOIN + (t AS table2 JOIN + (t AS table3 JOIN t AS table4 ON table3.pk = table4.a) + ON table2.pk = table3.pk ) + ON table1.a = table4.pk + WHERE table2.pk != 6; + +drop table t; + + + ######################################## # Verify DBSPJ counters for entire test: === 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 13:47:38 +0000 @@ -428,3 +428,53 @@ 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) < 4000; + + +# 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; + +--disable_result_log +SELECT DISTINCT STRAIGHT_JOIN t1.pk FROM + t1 LEFT JOIN t2 ON t2.a = t1.a AND t2.pk != 6; +--enable_result_log + +drop table t1, t2; === modified file 'sql/ha_ndbcluster.cc' --- a/sql/ha_ndbcluster.cc 2010-10-11 13:18:51 +0000 +++ b/sql/ha_ndbcluster.cc 2010-10-15 13:47:38 +0000 @@ -13707,6 +13707,7 @@ ha_ndbcluster::read_multi_range_first(KE ulong reclength= table_share->reclength; 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])); @@ -13731,6 +13732,15 @@ 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; @@ -13766,10 +13776,9 @@ ha_ndbcluster::read_multi_range_first(KE */ DBUG_ASSERT(cur_index_type != UNDEFINED_INDEX); + DBUG_ASSERT(m_multi_cursor == NULL); + DBUG_ASSERT(m_active_query == NULL); - DBUG_ASSERT(m_active_query == NULL);; - m_active_query= 0; - 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); @@ -13777,7 +13786,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) --===============0053558336066398931== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/ole.john.aske@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: ole.john.aske@stripped\ # dsgvvwgfo5nunok8 # target_branch: file:///net/fimafeng09/export/home/tmp/oleja/mysql\ # /mysql-5.1-telco-7.0-spj-scan-scan/ # testament_sha1: fadf025b4f574081163e288e8004bac131e903c5 # timestamp: 2010-10-15 15:47:44 +0200 # source_branch: bzr+ssh://oaske@stripped/bzrroot/server\ # /mysql-5.1-telco-7.0-spj/ # base_revision_id: ole.john.aske@stripped\ # 3mdg0xqfwa92yh0a # # Begin bundle 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 --===============0053558336066398931==--