Merge lp:~laurynas-biveinis/percona-server/ahi-partitions-5.6-5.5 into lp:percona-server/5.5

Proposed by Laurynas Biveinis
Status: Superseded
Proposed branch: lp:~laurynas-biveinis/percona-server/ahi-partitions-5.6-5.5
Merge into: lp:percona-server/5.5
Diff against target: 140 lines (+112/-3)
5 files modified
Percona-Server/mysql-test/suite/innodb/r/percona_ahi_partitions.result (+27/-0)
Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions-master.opt (+1/-0)
Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions.test (+62/-0)
Percona-Server/mysql-test/suite/sys_vars/r/innodb_adaptive_hash_index_partitions_basic.result (+8/-2)
Percona-Server/mysql-test/suite/sys_vars/t/innodb_adaptive_hash_index_partitions_basic.test (+14/-1)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/ahi-partitions-5.6-5.5
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Needs Fixing
Review via email: mp+181713@code.launchpad.net

This proposal has been superseded by a proposal from 2013-08-28.

Description of the change

Fix bug 1214449 (Adaptive hash index partitions not tested in MTR) by
creating a very basic partitioned AHI testcase.

This is done as a prerequisite for AHI partitions 5.6 port. No 5.6 MP is being submitted now, the testcase 5.6 merge will be submitted together with that port.

http://jenkins.percona.com/job/percona-server-5.5-param/831/

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Looks good, except that the test does too much unnecessary stuff:

On Fri, Aug 23 2013 06:12:30 +0000, Laurynas Biveinis wrote:

> === added file 'Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions.test'
> --- Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions.test 1970-01-01 00:00:00 +0000
> +++ Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions.test 2013-08-23 06:11:41 +0000
> @@ -0,0 +1,72 @@
> +#
> +# Basic test for InnoDB adaptive hash index partitions.
> +# TODO: add another testcase that uses DEBUG_SYNC to check the partition locking
> +#
> +--source include/have_innodb.inc
> +
> +# Check setup
> +SELECT @@GLOBAL.innodb_adaptive_hash_index;
> +SELECT @@GLOBAL.innodb_adaptive_hash_index_partitions;
> +
> +FLUSH STATUS;

FLUSH STATUS has no effect on InnoDB status vars, so that’s redundant.

> +
> +SELECT VARIABLE_VALUE INTO @ahi_searches_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS
> + WHERE VARIABLE_NAME = 'Innodb_adaptive_hash_hash_searches';
> +
> +--disable_warnings
> +DROP TABLE IF EXISTS t1, t2, t3;
> +--enable_warnings

You don’t really need that. Please forget it, and stop copy-pasting from
other tests.

> +
> +# 6 index trees across 4 AHI partitions
> +CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c CHAR(200), INDEX b(b)) ENGINE=InnoDB;
> +CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(200), INDEX b(b)) ENGINE=InnoDB;
> +CREATE TABLE t3 (a INT PRIMARY KEY, b INT, c CHAR(200), INDEX b(b)) ENGINE=InnoDB;
> +
> +--echo Filling tables
> +--disable_query_log
> +let $i=4000;
> +while ($i)
> +{
> + eval INSERT INTO t1 VALUES ($i, $i, REPEAT("a", 200));
> + eval INSERT INTO t2 VALUES ($i, $i, REPEAT("a", 200));
> + eval INSERT INTO t3 VALUES ($i, $i, REPEAT("a", 200));
> + dec $i;
> +}

What’s the point in creating megabytes of data (and slowing down the
test considerably) just to query a few pages max later? I tried changing
4000 to 2 and the test still passes.

> +
> +--echo Querying
> +--disable_result_log
> +let $i=1000;
> +while ($i)
> +{
> + SELECT b FROM t1 WHERE a=1;
> + SELECT a FROM t1 WHERE b=1;
> + SELECT b FROM t2 WHERE a=2;
> + SELECT a FROM t2 WHERE b=2;
> + SELECT b FROM t3 WHERE a=3;
> + SELECT a FROM t3 WHERE b=3;
> + dec $i;
> +}

Same here. 200 iterations seems to be sufficient for AHI to be involved.

> +--enable_result_log
> +--enable_query_log
> +
> +# AHI hash tables should have some cells now
> +SELECT VARIABLE_VALUE > 0 AS should_be_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS
> + WHERE VARIABLE_NAME = 'Innodb_adaptive_hash_cells';
> +

This is a pointless check. AHI hash cells are static (they are allocated
on startup), so this value is constant throughout the test.

review: Needs Fixing
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

> > +--disable_warnings
> > +DROP TABLE IF EXISTS t1, t2, t3;
> > +--enable_warnings
>
> You don’t really need that. Please forget it, and stop copy-pasting from
> other tests.

Heh, OK. I don't copy-paste, this is something I type by heart in every testcase :)

> What’s the point in creating megabytes of data (and slowing down the
> test considerably) just to query a few pages max later? I tried changing
> 4000 to 2 and the test still passes.

So the problems I tried to avoid here and with the excessive querying below is that 1) AHI builds reluctantly on small index trees, hence I tried to create height 2 trees; 2) AHI builds reluctantly anyway when there are few queries, as it keeps some profitability counters.

So for example if we reduced the data to just a few rows and executed the query loop twice, then for some reason only one index tree (t1 primary index) gets AHI and other indexes do not. The testcase still passes because I didn't know how to write "all index trees use AHI".

Admittedly currently I am unable to quantify the "reluctantly" above to produce a precise testcase and couldn't allocate time for research it, so went for an overkill instead.

Revision history for this message
Alexey Kopytov (akopytov) wrote :

On Tue, 27 Aug 2013 09:20:21 -0000, Laurynas Biveinis wrote:
>>> +--disable_warnings
>>> +DROP TABLE IF EXISTS t1, t2, t3;
>>> +--enable_warnings
>>
>> You don’t really need that. Please forget it, and stop copy-pasting from
>> other tests.
>
> Heh, OK. I don't copy-paste, this is something I type by heart in every testcase :)
>

Yet it's being enforced in reviews ;)

>> What’s the point in creating megabytes of data (and slowing down the
>> test considerably) just to query a few pages max later? I tried changing
>> 4000 to 2 and the test still passes.
>
> So the problems I tried to avoid here and with the excessive querying below is that 1) AHI builds reluctantly on small index trees, hence I tried to create height 2 trees; 2) AHI builds reluctantly anyway when there are few queries, as it keeps some profitability counters.
>
> So for example if we reduced the data to just a few rows and executed the query loop twice, then for some reason only one index tree (t1 primary index) gets AHI and other indexes do not. The testcase still passes because I didn't know how to write "all index trees use AHI".
>
> Admittedly currently I am unable to quantify the "reluctantly" above to produce a precise testcase and couldn't allocate time for research it, so went for an overkill instead.
>

I did a little more testing and it appears that SELECTs in the test case
do not contribute anything at all to adaptive hash building. I.e.
everything is built on the INSERT stage if it's long enough.

However, that's easy to fix by creating a unique index on the b column,
i.e. replace range scans in queries like "SELECT a FROM t1 WHERE b=1;"
with index lookups on 'b'. In this case, adaptive hash indexes are built
on tables with just a few rows, and about 200 SELECT queries.

Another comment I've got after reviewing the 5.6 MP: since we went for
providing basic AHI tests for 5.5, why don't provide a sys_var test as
well, as done in 5.6 MP?

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

> >> What’s the point in creating megabytes of data (and slowing down the
> >> test considerably) just to query a few pages max later? I tried changing
> >> 4000 to 2 and the test still passes.
> >
> > So the problems I tried to avoid here and with the excessive querying below
> is that 1) AHI builds reluctantly on small index trees, hence I tried to
> create height 2 trees; 2) AHI builds reluctantly anyway when there are few
> queries, as it keeps some profitability counters.
> >
> > So for example if we reduced the data to just a few rows and executed the
> query loop twice, then for some reason only one index tree (t1 primary index)
> gets AHI and other indexes do not. The testcase still passes because I didn't
> know how to write "all index trees use AHI".
> >
> > Admittedly currently I am unable to quantify the "reluctantly" above to
> produce a precise testcase and couldn't allocate time for research it, so went
> for an overkill instead.
> >
>
> I did a little more testing and it appears that SELECTs in the test case
> do not contribute anything at all to adaptive hash building. I.e.
> everything is built on the INSERT stage if it's long enough.
>
> However, that's easy to fix by creating a unique index on the b column,
> i.e. replace range scans in queries like "SELECT a FROM t1 WHERE b=1;"
> with index lookups on 'b'. In this case, adaptive hash indexes are built
> on tables with just a few rows, and about 200 SELECT queries.

I tried making b indexes unique, but then was not sure how to adjust queries, i.e. why SELECT a FROM t1 WHERE b=1 is not an index lookup? Does it mean to use b as covering index, i.e. SELECT b FROM t1 WHERE b=1? But this one is too easy for the query optimizer to optimize away. I tried this and it did not appear to increase AHI. Since you said you did some testing, could you please share the queries?

Thanks,

Revision history for this message
Alexey Kopytov (akopytov) wrote :

On Tue, Aug 27 2013 14:51:23 +0000, Laurynas Biveinis wrote:

>>
>> I did a little more testing and it appears that SELECTs in the test case
>> do not contribute anything at all to adaptive hash building. I.e.
>> everything is built on the INSERT stage if it's long enough.
>>
>> However, that's easy to fix by creating a unique index on the b column,
>> i.e. replace range scans in queries like "SELECT a FROM t1 WHERE b=1;"
>> with index lookups on 'b'. In this case, adaptive hash indexes are built
>> on tables with just a few rows, and about 200 SELECT queries.
>
> I tried making b indexes unique, but then was not sure how to adjust
> queries, i.e. why SELECT a FROM t1 WHERE b=1 is not an index lookup?

It is an index lookup if there’s a unique index on b.

> Does it mean to use b as covering index, i.e. SELECT b FROM t1 WHERE
> b=1? But this one is too easy for the query optimizer to optimize
> away. I tried this and it did not appear to increase AHI. Since you
> said you did some testing, could you please share the queries?
>

It works with any columns in SELECT queries for me (whether it’s is ‘a’,
‘b’ or ‘*’). Example:

Tables:

CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;
CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;
CREATE TABLE t3 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;

Insert stage:

let $i=3;
while ($i)
{
        eval INSERT INTO t1 VALUES ($i, $i, REPEAT("a", 200));
        eval INSERT INTO t2 VALUES ($i, $i, REPEAT("a", 200));
        eval INSERT INTO t3 VALUES ($i, $i, REPEAT("a", 200));
        dec $i;
}

Querying:

let $i=200;
while ($i)
{
        SELECT a FROM t1 WHERE b=1;
        SELECT b FROM t1 WHERE a=1;
        SELECT a FROM t2 WHERE b=2;
        SELECT b FROM t2 WHERE a=2;
        SELECT a FROM t3 WHERE b=3;
        SELECT b FROM t3 WHERE a=3;
        dec $i;
}

Innodb_adaptive_hash_hash_searches:
before querying: 0,
after querying: 414

is_hashed pages in the buffer pool:
before querying: 0
after querying: 6

Debug log:

btr_search_build_page_hash_index(test/t1.b)
btr_search_build_page_hash_index(test/t1.PRIMARY)
btr_search_build_page_hash_index(test/t2.b)
btr_search_build_page_hash_index(test/t2.PRIMARY)
btr_search_build_page_hash_index(test/t3.b)
btr_search_build_page_hash_index(test/t3.PRIMARY)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'Percona-Server/mysql-test/suite/innodb/r/percona_ahi_partitions.result'
2--- Percona-Server/mysql-test/suite/innodb/r/percona_ahi_partitions.result 1970-01-01 00:00:00 +0000
3+++ Percona-Server/mysql-test/suite/innodb/r/percona_ahi_partitions.result 2013-08-28 07:02:05 +0000
4@@ -0,0 +1,27 @@
5+SELECT @@GLOBAL.innodb_adaptive_hash_index;
6+@@GLOBAL.innodb_adaptive_hash_index
7+1
8+SELECT @@GLOBAL.innodb_adaptive_hash_index_partitions;
9+@@GLOBAL.innodb_adaptive_hash_index_partitions
10+4
11+SELECT VARIABLE_VALUE INTO @ahi_searches_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS
12+WHERE VARIABLE_NAME = 'Innodb_adaptive_hash_hash_searches';
13+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;
14+CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;
15+CREATE TABLE t3 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;
16+Filling tables
17+Querying
18+SELECT VARIABLE_VALUE INTO @ahi_searches_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS
19+WHERE VARIABLE_NAME = 'Innodb_adaptive_hash_hash_searches';
20+SELECT @ahi_searches_2 - @ahi_searches_1 > 0 AS should_be_1;
21+should_be_1
22+1
23+SELECT COUNT(*) > 0 AS should_be_1 FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
24+WHERE PAGE_STATE LIKE "MEMORY";
25+should_be_1
26+1
27+SELECT COUNT(*) >= 6 AS should_be_1 FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
28+WHERE IS_HASHED LIKE "YES";
29+should_be_1
30+1
31+DROP TABLE t1, t2, t3;
32
33=== added file 'Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions-master.opt'
34--- Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions-master.opt 1970-01-01 00:00:00 +0000
35+++ Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions-master.opt 2013-08-28 07:02:05 +0000
36@@ -0,0 +1,1 @@
37+--innodb-adaptive-hash-index-partitions=4
38
39=== added file 'Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions.test'
40--- Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions.test 1970-01-01 00:00:00 +0000
41+++ Percona-Server/mysql-test/suite/innodb/t/percona_ahi_partitions.test 2013-08-28 07:02:05 +0000
42@@ -0,0 +1,62 @@
43+#
44+# Basic test for InnoDB adaptive hash index partitions.
45+# TODO: add another testcase that uses DEBUG_SYNC to check the partition locking
46+#
47+--source include/have_innodb.inc
48+
49+# Check setup
50+SELECT @@GLOBAL.innodb_adaptive_hash_index;
51+SELECT @@GLOBAL.innodb_adaptive_hash_index_partitions;
52+
53+SELECT VARIABLE_VALUE INTO @ahi_searches_1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS
54+ WHERE VARIABLE_NAME = 'Innodb_adaptive_hash_hash_searches';
55+
56+# 6 index trees across 4 AHI partitions
57+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;
58+CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;
59+CREATE TABLE t3 (a INT PRIMARY KEY, b INT, c CHAR(200), UNIQUE INDEX b(b)) ENGINE=InnoDB;
60+
61+--echo Filling tables
62+--disable_query_log
63+let $i=3;
64+while ($i)
65+{
66+ eval INSERT INTO t1 VALUES ($i, $i, REPEAT("a", 200));
67+ eval INSERT INTO t2 VALUES ($i, $i, REPEAT("a", 200));
68+ eval INSERT INTO t3 VALUES ($i, $i, REPEAT("a", 200));
69+ dec $i;
70+}
71+
72+--echo Querying
73+--disable_result_log
74+let $i=200;
75+while ($i)
76+{
77+ SELECT a FROM t1 WHERE a=1;
78+ SELECT b FROM t1 WHERE b=1;
79+ SELECT a FROM t2 WHERE a=2;
80+ SELECT b FROM t2 WHERE b=2;
81+ SELECT a FROM t3 WHERE a=3;
82+ SELECT b FROM t3 WHERE b=3;
83+ dec $i;
84+}
85+--enable_result_log
86+--enable_query_log
87+
88+# TODO: test Innodb_adaptive_hash_heap_buffers too. But it requires large AHI
89+# to become non-zero?
90+
91+# AHI should have been used for queries, but the exact lower bound is hard to determine
92+SELECT VARIABLE_VALUE INTO @ahi_searches_2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS
93+ WHERE VARIABLE_NAME = 'Innodb_adaptive_hash_hash_searches';
94+SELECT @ahi_searches_2 - @ahi_searches_1 > 0 AS should_be_1;
95+
96+# Buffer pool must contain AHI pages now
97+SELECT COUNT(*) > 0 AS should_be_1 FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
98+ WHERE PAGE_STATE LIKE "MEMORY";
99+
100+# Buffer pool must contain no less than the number of index trees hashed pages now
101+SELECT COUNT(*) >= 6 AS should_be_1 FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
102+ WHERE IS_HASHED LIKE "YES";
103+
104+DROP TABLE t1, t2, t3;
105
106=== modified file 'Percona-Server/mysql-test/suite/sys_vars/r/innodb_adaptive_hash_index_partitions_basic.result'
107--- Percona-Server/mysql-test/suite/sys_vars/r/innodb_adaptive_hash_index_partitions_basic.result 2012-04-18 23:26:11 +0000
108+++ Percona-Server/mysql-test/suite/sys_vars/r/innodb_adaptive_hash_index_partitions_basic.result 2013-08-28 07:02:05 +0000
109@@ -1,3 +1,9 @@
110-SELECT @@global.innodb_adaptive_hash_index_partitions;
111-@@global.innodb_adaptive_hash_index_partitions
112+SELECT @@GLOBAL.innodb_adaptive_hash_index_partitions;
113+@@GLOBAL.innodb_adaptive_hash_index_partitions
114 1
115+SET @@GLOBAL.innodb_adaptive_hash_index_partitions=1;
116+ERROR HY000: Variable 'innodb_adaptive_hash_index_partitions' is a read only variable
117+SELECT @@LOCAL.innodb_adaptive_hash_index_partitions;
118+ERROR HY000: Variable 'innodb_adaptive_hash_index_partitions' is a GLOBAL variable
119+SELECT @@SESSION.innodb_adaptive_hash_index_partitions;
120+ERROR HY000: Variable 'innodb_adaptive_hash_index_partitions' is a GLOBAL variable
121
122=== modified file 'Percona-Server/mysql-test/suite/sys_vars/t/innodb_adaptive_hash_index_partitions_basic.test'
123--- Percona-Server/mysql-test/suite/sys_vars/t/innodb_adaptive_hash_index_partitions_basic.test 2012-04-18 23:26:11 +0000
124+++ Percona-Server/mysql-test/suite/sys_vars/t/innodb_adaptive_hash_index_partitions_basic.test 2013-08-28 07:02:05 +0000
125@@ -1,1 +1,14 @@
126-SELECT @@global.innodb_adaptive_hash_index_partitions;
127+# A sys_vars suite test for innodb_adaptive_hash_index_partitions.
128+
129+--source include/have_innodb.inc
130+
131+SELECT @@GLOBAL.innodb_adaptive_hash_index_partitions;
132+
133+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
134+SET @@GLOBAL.innodb_adaptive_hash_index_partitions=1;
135+
136+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
137+SELECT @@LOCAL.innodb_adaptive_hash_index_partitions;
138+
139+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
140+SELECT @@SESSION.innodb_adaptive_hash_index_partitions;

Subscribers

People subscribed via source and target branches