Skip to content

Commit 7e21bee

Browse files
author
Mattias Jonsson
committed
Bug#11761296: 53775: QUERY ON PARTITIONED TABLE RETURNS CACHED
RESULT FROM PREVIOUS TRANSACTION The current Query Cache API is not fully compatible with the partitioning engine. There is no good way to implement support for QC due to: 1) a static callback for ha_partition would need to have access to all partition names and call the underlying callback for each [sub]partition with the correct name. 2) pruning would be impossible, even if one used the ulonglong engine_data due to if engine_data is changed, the table is invalidated by the QC. So the only viable solution to avoid incorrect data is to not allow caching of queries using partitioned tables. (There are some extra changes, due to removal of \r as line break)
1 parent 8b0f2c4 commit 7e21bee

7 files changed

+286
-34
lines changed

mysql-test/include/query_cache.inc

+25-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
# $engine_type -- storage engine to be tested
55
# $test_foreign_keys -- 0, skip foreign key tests
66
# -- 1, do not skip foreign key tests
7+
# $partitions_a -- partition by column 'a'
8+
# $partitions_id -- partition by column 'id'
9+
# $partitions_s1 -- partition by column 's1'
710
# have to be set before sourcing this script.
811
#
912
# Last update:
@@ -19,55 +22,69 @@ eval SET SESSION STORAGE_ENGINE = $engine_type;
1922
drop table if exists t1,t2,t3;
2023
--enable_warnings
2124

25+
set @save_query_cache_size = @@global.query_cache_size;
26+
set GLOBAL query_cache_size = 1355776;
27+
2228
#
2329
# Without auto_commit.
2430
#
2531
flush status;
2632
set autocommit=0;
27-
create table t1 (a int not null);
33+
eval create table t1 (a int not null)$partitions_a;
2834
insert into t1 values (1),(2),(3);
35+
--sorted_result
2936
select * from t1;
3037
show status like "Qcache_queries_in_cache";
3138
drop table t1;
3239
commit;
3340
set autocommit=1;
3441
begin;
35-
create table t1 (a int not null);
42+
eval create table t1 (a int not null)$partitions_a;
3643
insert into t1 values (1),(2),(3);
44+
--sorted_result
3745
select * from t1;
3846
show status like "Qcache_queries_in_cache";
3947
drop table t1;
4048
commit;
41-
create table t1 (a int not null);
42-
create table t2 (a int not null);
43-
create table t3 (a int not null);
49+
eval create table t1 (a int not null)$partitions_a;
50+
eval create table t2 (a int not null)$partitions_a;
51+
eval create table t3 (a int not null)$partitions_a;
4452
insert into t1 values (1),(2);
4553
insert into t2 values (1),(2);
4654
insert into t3 values (1),(2);
55+
--sorted_result
4756
select * from t1;
57+
--sorted_result
4858
select * from t2;
59+
--sorted_result
4960
select * from t3;
5061
show status like "Qcache_queries_in_cache";
5162
show status like "Qcache_hits";
5263
begin;
64+
--sorted_result
5365
select * from t1;
66+
--sorted_result
5467
select * from t2;
68+
--sorted_result
5569
select * from t3;
5670
show status like "Qcache_queries_in_cache";
5771
show status like "Qcache_hits";
5872
insert into t1 values (3);
5973
insert into t2 values (3);
6074
insert into t1 values (4);
75+
--sorted_result
6176
select * from t1;
77+
--sorted_result
6278
select * from t2;
79+
--sorted_result
6380
select * from t3;
6481
show status like "Qcache_queries_in_cache";
6582
show status like "Qcache_hits";
6683
commit;
6784
show status like "Qcache_queries_in_cache";
6885
drop table t3,t2,t1;
6986

70-
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id));
87+
eval CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id))$partitions_id;
7188
select count(*) from t1;
7289
insert into t1 (id) values (0);
7390
select count(*) from t1;
@@ -78,8 +95,6 @@ if ($test_foreign_keys)
7895
#
7996
# one statement roll back inside transation
8097
#
81-
let $save_query_cache_size=`select @@global.query_cache_size`;
82-
set GLOBAL query_cache_size=1355776;
8398
CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a));
8499
CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b));
85100
CREATE TABLE t3 ( id int(10) NOT NULL auto_increment, t1_id int(10) NOT NULL default '0', t2_id int(10) NOT NULL default '0', state int(11) default NULL, PRIMARY KEY (id), UNIQUE KEY t1_id (t1_id,t2_id), KEY t2_id (t2_id,t1_id), CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`), CONSTRAINT `t3_ibfk_2` FOREIGN KEY (`t2_id`) REFERENCES `t2` (`id`));
@@ -95,9 +110,6 @@ insert into t3 VALUES ( NULL, 1, 1, 2 );
95110
commit;
96111
select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc;
97112
drop table t3,t2,t1;
98-
--disable_query_log
99-
eval set GLOBAL query_cache_size=$save_query_cache_size;
100-
--enable_query_log
101113
}
102114

103115
#
@@ -118,7 +130,7 @@ SET GLOBAL query_cache_size = 200000;
118130
flush status;
119131
SET @@autocommit=1;
120132
eval SET SESSION STORAGE_ENGINE = $engine_type;
121-
CREATE TABLE t2 (s1 int, s2 varchar(1000), key(s1));
133+
eval CREATE TABLE t2 (s1 int, s2 varchar(1000), key(s1))$partitions_s1;
122134
INSERT INTO t2 VALUES (1,repeat('a',10)),(2,repeat('a',10)),(3,repeat('a',10)),(4,repeat('a',10));
123135
COMMIT;
124136
START TRANSACTION;
@@ -176,8 +188,8 @@ show status like "Qcache_queries_in_cache";
176188
show status like "Qcache_hits";
177189

178190
# Final cleanup
179-
eval set GLOBAL query_cache_size=$save_query_cache_size;
180191
disconnect connection1;
181192
--source include/wait_until_disconnected.inc
182193
connection default;
194+
set @@global.query_cache_size = @save_query_cache_size;
183195
drop table t2;

mysql-test/r/cache_innodb.result

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
SET SESSION STORAGE_ENGINE = InnoDB;
22
drop table if exists t1,t2,t3;
3+
set @save_query_cache_size = @@global.query_cache_size;
4+
set GLOBAL query_cache_size = 1355776;
35
flush status;
46
set autocommit=0;
57
create table t1 (a int not null);
@@ -100,7 +102,7 @@ show status like "Qcache_queries_in_cache";
100102
Variable_name Value
101103
Qcache_queries_in_cache 2
102104
drop table t3,t2,t1;
103-
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id));
105+
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id));
104106
select count(*) from t1;
105107
count(*)
106108
0
@@ -109,7 +111,6 @@ select count(*) from t1;
109111
count(*)
110112
1
111113
drop table t1;
112-
set GLOBAL query_cache_size=1355776;
113114
CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a));
114115
CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b));
115116
CREATE TABLE t3 ( id int(10) NOT NULL auto_increment, t1_id int(10) NOT NULL default '0', t2_id int(10) NOT NULL default '0', state int(11) default NULL, PRIMARY KEY (id), UNIQUE KEY t1_id (t1_id,t2_id), KEY t2_id (t2_id,t1_id), CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`), CONSTRAINT `t3_ibfk_2` FOREIGN KEY (`t2_id`) REFERENCES `t2` (`id`));
@@ -218,5 +219,5 @@ Qcache_queries_in_cache 1
218219
show status like "Qcache_hits";
219220
Variable_name Value
220221
Qcache_hits 1
221-
set GLOBAL query_cache_size=1048576;
222+
set @@global.query_cache_size = @save_query_cache_size;
222223
drop table t2;

mysql-test/r/partition_cache.result

+205
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
SET SESSION STORAGE_ENGINE = InnoDB;
2+
drop table if exists t1,t2,t3;
3+
set @save_query_cache_size = @@global.query_cache_size;
4+
set GLOBAL query_cache_size = 1355776;
5+
flush status;
6+
set autocommit=0;
7+
create table t1 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
8+
insert into t1 values (1),(2),(3);
9+
select * from t1;
10+
a
11+
1
12+
2
13+
3
14+
show status like "Qcache_queries_in_cache";
15+
Variable_name Value
16+
Qcache_queries_in_cache 0
17+
drop table t1;
18+
commit;
19+
set autocommit=1;
20+
begin;
21+
create table t1 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
22+
insert into t1 values (1),(2),(3);
23+
select * from t1;
24+
a
25+
1
26+
2
27+
3
28+
show status like "Qcache_queries_in_cache";
29+
Variable_name Value
30+
Qcache_queries_in_cache 0
31+
drop table t1;
32+
commit;
33+
create table t1 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
34+
create table t2 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
35+
create table t3 (a int not null) PARTITION BY KEY (a) PARTITIONS 3;
36+
insert into t1 values (1),(2);
37+
insert into t2 values (1),(2);
38+
insert into t3 values (1),(2);
39+
select * from t1;
40+
a
41+
1
42+
2
43+
select * from t2;
44+
a
45+
1
46+
2
47+
select * from t3;
48+
a
49+
1
50+
2
51+
show status like "Qcache_queries_in_cache";
52+
Variable_name Value
53+
Qcache_queries_in_cache 0
54+
show status like "Qcache_hits";
55+
Variable_name Value
56+
Qcache_hits 0
57+
begin;
58+
select * from t1;
59+
a
60+
1
61+
2
62+
select * from t2;
63+
a
64+
1
65+
2
66+
select * from t3;
67+
a
68+
1
69+
2
70+
show status like "Qcache_queries_in_cache";
71+
Variable_name Value
72+
Qcache_queries_in_cache 0
73+
show status like "Qcache_hits";
74+
Variable_name Value
75+
Qcache_hits 0
76+
insert into t1 values (3);
77+
insert into t2 values (3);
78+
insert into t1 values (4);
79+
select * from t1;
80+
a
81+
1
82+
2
83+
3
84+
4
85+
select * from t2;
86+
a
87+
1
88+
2
89+
3
90+
select * from t3;
91+
a
92+
1
93+
2
94+
show status like "Qcache_queries_in_cache";
95+
Variable_name Value
96+
Qcache_queries_in_cache 0
97+
show status like "Qcache_hits";
98+
Variable_name Value
99+
Qcache_hits 0
100+
commit;
101+
show status like "Qcache_queries_in_cache";
102+
Variable_name Value
103+
Qcache_queries_in_cache 0
104+
drop table t3,t2,t1;
105+
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) PARTITION BY HASH (id) PARTITIONS 3;
106+
select count(*) from t1;
107+
count(*)
108+
0
109+
insert into t1 (id) values (0);
110+
select count(*) from t1;
111+
count(*)
112+
1
113+
drop table t1;
114+
SET SESSION STORAGE_ENGINE = InnoDB;
115+
SET @@autocommit=1;
116+
connection default
117+
SHOW VARIABLES LIKE 'have_query_cache';
118+
Variable_name Value
119+
have_query_cache YES
120+
SET GLOBAL query_cache_size = 200000;
121+
flush status;
122+
SET @@autocommit=1;
123+
SET SESSION STORAGE_ENGINE = InnoDB;
124+
CREATE TABLE t2 (s1 int, s2 varchar(1000), key(s1)) PARTITION BY KEY (s1) PARTITIONS 3;
125+
INSERT INTO t2 VALUES (1,repeat('a',10)),(2,repeat('a',10)),(3,repeat('a',10)),(4,repeat('a',10));
126+
COMMIT;
127+
START TRANSACTION;
128+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
129+
count(*)
130+
0
131+
UPDATE t2 SET s2 = 'w' WHERE s1 = 3;
132+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
133+
count(*)
134+
1
135+
show status like "Qcache_queries_in_cache";
136+
Variable_name Value
137+
Qcache_queries_in_cache 0
138+
connection connection1
139+
START TRANSACTION;
140+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
141+
count(*)
142+
0
143+
INSERT INTO t2 VALUES (5,'w');
144+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
145+
count(*)
146+
1
147+
COMMIT;
148+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
149+
count(*)
150+
1
151+
show status like "Qcache_queries_in_cache";
152+
Variable_name Value
153+
Qcache_queries_in_cache 0
154+
connection default
155+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
156+
count(*)
157+
1
158+
COMMIT;
159+
show status like "Qcache_queries_in_cache";
160+
Variable_name Value
161+
Qcache_queries_in_cache 0
162+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
163+
count(*)
164+
2
165+
show status like "Qcache_queries_in_cache";
166+
Variable_name Value
167+
Qcache_queries_in_cache 0
168+
connection connection1
169+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
170+
count(*)
171+
2
172+
START TRANSACTION;
173+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
174+
count(*)
175+
2
176+
INSERT INTO t2 VALUES (6,'w');
177+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
178+
count(*)
179+
3
180+
connection default
181+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
182+
count(*)
183+
2
184+
START TRANSACTION;
185+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
186+
count(*)
187+
2
188+
DELETE from t2 WHERE s1=3;
189+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
190+
count(*)
191+
1
192+
COMMIT;
193+
connection connection1
194+
COMMIT;
195+
SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w';
196+
count(*)
197+
2
198+
show status like "Qcache_queries_in_cache";
199+
Variable_name Value
200+
Qcache_queries_in_cache 0
201+
show status like "Qcache_hits";
202+
Variable_name Value
203+
Qcache_hits 0
204+
set @@global.query_cache_size = @save_query_cache_size;
205+
drop table t2;

mysql-test/t/cache_innodb-master.opt

-1
This file was deleted.

mysql-test/t/partition_cache.test

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# t/cache_innodb.test
2+
#
3+
# Last update:
4+
# 2006-07-26 ML test refactored (MySQL 5.1)
5+
# main code t/innodb_cache.test --> include/query_cache.inc
6+
# new wrapper t/cache_innodb.test
7+
#
8+
9+
--source include/have_query_cache.inc
10+
11+
--source include/have_innodb.inc
12+
--source include/have_partition.inc
13+
let $engine_type= InnoDB;
14+
# Using SELECT to get a space as first character.
15+
let $partitions_a= `SELECT ' PARTITION BY KEY (a) PARTITIONS 3'`;
16+
let $partitions_id= `SELECT ' PARTITION BY HASH (id) PARTITIONS 3'`;
17+
let $partitions_s1= `SELECT ' PARTITION BY KEY (s1) PARTITIONS 3'`;
18+
# partitioning does not support FOREIGN KEYs
19+
let $test_foreign_keys= 0;
20+
21+
--source include/query_cache.inc

0 commit comments

Comments
 (0)