5065 Mauritz Sundell 2012-12-19 [merge]
ndb - dbacc, some linear hash table fixes
added:
mysql-test/suite/ndb/r/ndb_one_fragment.result
mysql-test/suite/ndb/t/ndb_one_fragment.cnf
mysql-test/suite/ndb/t/ndb_one_fragment.test
modified:
storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
storage/ndb/src/kernel/vm/LHLevel.hpp
5064 Martin Skold 2012-12-18 [merge]
ndb - bump version to 7.0.38
modified:
configure.in
storage/ndb/ndb_configure.m4
=== added file 'mysql-test/suite/ndb/r/ndb_one_fragment.result'
--- a/mysql-test/suite/ndb/r/ndb_one_fragment.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_one_fragment.result 2012-12-19 19:16:12 +0000
@@ -0,0 +1,29 @@
+set max_heap_table_size = 286720000;
+create table t1 (a int primary key) engine=memory;
+load data local infile 'suite/ndb/data/table_data10000.dat' into table t1 columns terminated by ' ' (a, @col2);
+insert into t1 select a + 10000 from t1;;
+insert into t1 select a + 10000 * 2 from t1;;
+insert into t1 select a + 10000 * 2 * 2 from t1;;
+insert into t1 select a + 10000 * 2 * 2 * 2 from t1;;
+select count(*) from t1;
+count(*)
+160000
+alter table t1 engine=ndbcluster comment='NDB_TABLE=NOLOGGING' partition by key() partitions 1;
+create table t2 (a int primary key) engine=memory;
+insert into t2 select a from t1;
+the left join below should result in scanning t2 and do pk lookups in t1
+explain select if(isnull(t1.a),t2.a,NULL) missed, count(*) rows from t2 left join t1 on t1.a=t2.a group by if(isnull(t1.a),t2.a,NULL);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL # Using temporary; Using filesort
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a #
+the result rows with missed equal to NULL should count all rows (160000)
+the other rows are the failed lookups and there should not be any such
+select if(isnull(t1.a),t2.a,NULL) missed, count(*) rows from t2 left join t1 on t1.a=t2.a group by if(isnull(t1.a),t2.a,NULL);
+missed rows
+NULL 160000
+verify that it is not possible to reinsert all rows in t1 to itself
+affected rows should be zero
+insert ignore into t1 select a from t1;
+affected rows: 0
+info: Records: 160000 Duplicates: 160000 Warnings: 0
+drop table t1, t2;
=== added file 'mysql-test/suite/ndb/t/ndb_one_fragment.cnf'
--- a/mysql-test/suite/ndb/t/ndb_one_fragment.cnf 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_one_fragment.cnf 2012-12-19 19:16:12 +0000
@@ -0,0 +1,5 @@
+!include suite/ndb/my.cnf
+
+[cluster_config.1]
+DataMemory=10M
+IndexMemory=80M
=== added file 'mysql-test/suite/ndb/t/ndb_one_fragment.test'
--- a/mysql-test/suite/ndb/t/ndb_one_fragment.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_one_fragment.test 2012-12-19 19:16:12 +0000
@@ -0,0 +1,40 @@
+--source include/have_ndb.inc
+--source include/not_embedded.inc
+
+# Test is using error insert, check that binaries support it
+--source suite/ndb/t/have_ndb_error_insert.inc
+
+# Use small LoadFactors to force sparse hash table
+--exec $NDB_MGM --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" -e "all error 3003" >> $NDB_TOOLS_OUTPUT
+
+set max_heap_table_size = 286720000;
+create table t1 (a int primary key) engine=memory;
+load data local infile 'suite/ndb/data/table_data10000.dat' into table t1 columns terminated by ' ' (a, @col2);
+let $i = 4;
+let $b = 10000;
+while ($i)
+{
+--eval insert into t1 select a + $b from t1;
+ let $b = $b * 2;
+ dec $i;
+}
+select count(*) from t1;
+alter table t1 engine=ndbcluster comment='NDB_TABLE=NOLOGGING' partition by key() partitions 1;
+--exec $NDB_MGM --no-defaults --ndb-connectstring="$NDB_CONNECTSTRING" -e "all report memory" >> $NDB_TOOLS_OUTPUT
+create table t2 (a int primary key) engine=memory;
+insert into t2 select a from t1;
+
+--echo the left join below should result in scanning t2 and do pk lookups in t1
+--replace_column 9 #
+explain select if(isnull(t1.a),t2.a,NULL) missed, count(*) rows from t2 left join t1 on t1.a=t2.a group by if(isnull(t1.a),t2.a,NULL);
+--echo the result rows with missed equal to NULL should count all rows (160000)
+--echo the other rows are the failed lookups and there should not be any such
+select if(isnull(t1.a),t2.a,NULL) missed, count(*) rows from t2 left join t1 on t1.a=t2.a group by if(isnull(t1.a),t2.a,NULL);
+
+--echo verify that it is not possible to reinsert all rows in t1 to itself
+--echo affected rows should be zero
+--enable_info
+insert ignore into t1 select a from t1;
+--disable_info
+
+drop table t1, t2;
=== modified file 'storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp 2012-09-28 13:15:29 +0000
+++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp 2012-12-19 19:14:48 +0000
@@ -5487,7 +5487,7 @@ void Dbacc::expandcontainer(Signal* sign
{
jam();
idrOperationRecPtr.p->reducedHashValue =
- fragrecptr.p->level.reduce(getElementHash(idrOperationRecPtr));
+ fragrecptr.p->level.reduceForSplit(getElementHash(idrOperationRecPtr));
}
}
else
@@ -5501,7 +5501,7 @@ void Dbacc::expandcontainer(Signal* sign
{
jam();
reducedHashValue =
- fragrecptr.p->level.reduce(getElementHash(&excPageptr.p->word32[cexcElementptr], cexcForward));
+ fragrecptr.p->level.reduceForSplit(getElementHash(&excPageptr.p->word32[cexcElementptr], cexcForward));
}
tidrElemhead = ElementHeader::setReducedHashValue(tidrElemhead, reducedHashValue);
}
@@ -5586,7 +5586,7 @@ void Dbacc::expandcontainer(Signal* sign
{
jam();
idrOperationRecPtr.p->reducedHashValue =
- fragrecptr.p->level.reduce(getElementHash(idrOperationRecPtr));
+ fragrecptr.p->level.reduceForSplit(getElementHash(idrOperationRecPtr));
}
}
else
@@ -5600,7 +5600,7 @@ void Dbacc::expandcontainer(Signal* sign
{
jam();
reducedHashValue =
- fragrecptr.p->level.reduce(getElementHash(&lastPageptr.p->word32[tlastElementptr], tlastForward));
+ fragrecptr.p->level.reduceForSplit(getElementHash(&lastPageptr.p->word32[tlastElementptr], tlastForward));
}
tidrElemhead = ElementHeader::setReducedHashValue(tidrElemhead, reducedHashValue);
}
=== modified file 'storage/ndb/src/kernel/vm/LHLevel.hpp'
--- a/storage/ndb/src/kernel/vm/LHLevel.hpp 2012-09-28 13:11:17 +0000
+++ b/storage/ndb/src/kernel/vm/LHLevel.hpp 2012-12-19 19:17:00 +0000
@@ -129,6 +129,7 @@ private:
LHLevelRH& operator=(LHLevelRH const&); // Not to be implemented
public:
LHBits16 reduce(LHBits32 hash_value) const;
+ LHBits16 reduceForSplit(LHBits32 hash_value) const;
Uint8 getNeededValidBits(Uint8 bits) const;
LHBits32 enlarge(LHBits16 reduced_hash_value, Uint32 bucket_number) const;
};
@@ -436,9 +437,30 @@ inline LHBits16 LHLevelRH::reduce(LHBits
return LHBits16(hv);
}
+inline LHBits16 LHLevelRH::reduceForSplit(LHBits32 hash_value) const
+{
+ // As reduce() with an extra bit shifted out to compansate for a
+ // coming expand().
+ // But we do it on the LHBits32-value so we do not shift out
+ // one bit from the resulting LHBits16-value needlessly.
+ assert(!isEmpty());
+
+ if (!hash_value.valid_bits(maxp()))
+ return LHBits16();
+
+ Uint32 addr = hash_value.get_bits(maxp());
+ LHBits32 hv(hash_value);
+
+ // An extra shift out compared with reduce()
+ hv.shift_out(hashcheckbit() + 1);
+ if (addr < p())
+ hv.shift_out();
+ return LHBits16(hv);
+}
+
inline Uint8 LHLevelRH::getNeededValidBits(Uint8 bits) const
{
- Uint8 const usable_bits_in_hash_value = 4 * sizeof(LHBits32) - 1; // == 31
+ Uint8 const usable_bits_in_hash_value = 8 * sizeof(LHBits32) - 1; // == 31
return MIN(bits, usable_bits_in_hash_value - hashcheckbit());
}
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.1-telco-7.0 branch (mauritz.sundell:5064 to 5065) | Mauritz Sundell | 20 Dec |