From: Mattias Jonsson Date: May 10 2011 12:16pm Subject: bzr commit into mysql-5.1 branch (mattias.jonsson:3683) Bug#11761296 List-Archive: http://lists.mysql.com/commits/136987 X-Bug: 11761296 Message-Id: <201105101216.p4ACGa1G005271@acsmt358.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0579405635==" --===============0579405635== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///C:/ade/mysql-bzr/b11761296-5.1/ based on revid:mattias.jonsson@stripped 3683 Mattias Jonsson 2011-05-10 Minor update to bug#11761296 after the first review. TODO: extend the test to also test cached pruned queries. added: mysql-test/r/partition_cache_myisam.result mysql-test/t/partition_cache_myisam.test modified: sql/ha_partition.cc === added file 'mysql-test/r/partition_cache_myisam.result' --- a/mysql-test/r/partition_cache_myisam.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/r/partition_cache_myisam.result 2011-05-10 12:16:35 +0000 @@ -0,0 +1,335 @@ +SET GLOBAL query_cache_size = 1024 * 1024; +SET SESSION STORAGE_ENGINE = MyISAM; +drop table if exists t1,t2,t3; +flush status; +set autocommit=0; +create table t1 (a int not null) PARTITION BY HASH (a) PARTITIONS 7; +insert into t1 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +drop table t1; +commit; +set autocommit=1; +begin; +create table t1 (a int not null) PARTITION BY HASH (a) PARTITIONS 7; +insert into t1 values (1),(2),(3); +select * from t1; +a +1 +2 +3 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +drop table t1; +commit; +create table t1 (a int not null) PARTITION BY HASH (a) PARTITIONS 7; +create table t2 (a int not null) PARTITION BY HASH (a) PARTITIONS 7; +create table t3 (a int not null) PARTITION BY HASH (a) PARTITIONS 7; +insert into t1 values (1),(2); +insert into t2 values (1),(2); +insert into t3 values (1),(2); +select * from t1; +a +1 +2 +select * from t2; +a +1 +2 +select * from t3; +a +1 +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 3 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 0 +begin; +select * from t1; +a +1 +2 +select * from t2; +a +1 +2 +select * from t3; +a +1 +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 6 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 0 +insert into t1 values (3); +insert into t2 values (3); +insert into t1 values (4); +select * from t1; +a +1 +2 +3 +4 +select * from t2; +a +1 +2 +3 +select * from t3; +a +1 +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 4 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 1 +commit; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 4 +drop table t3,t2,t1; +CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) PARTITION BY HASH (id) PARTITIONS 7; +select count(*) from t1; +count(*) +0 +insert into t1 (id) values (0); +select count(*) from t1; +count(*) +1 +drop table t1; +SET SESSION STORAGE_ENGINE = MyISAM; +SET @@autocommit=1; +connection default +SHOW VARIABLES LIKE 'have_query_cache'; +Variable_name Value +have_query_cache YES +SET GLOBAL query_cache_size = 200000; +flush status; +SET @@autocommit=1; +SET SESSION STORAGE_ENGINE = MyISAM; +CREATE TABLE t2 (s1 int, s2 varchar(1000), key(s1)) PARTITION BY HASH (s1) PARTITIONS 7; +INSERT INTO t2 VALUES (1,repeat('a',10)),(2,repeat('a',10)),(3,repeat('a',10)),(4,repeat('a',10)); +COMMIT; +START TRANSACTION; +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +0 +UPDATE t2 SET s2 = 'w' WHERE s1 = 3; +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +1 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +connection connection1 +START TRANSACTION; +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +1 +INSERT INTO t2 VALUES (5,'w'); +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +2 +COMMIT; +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +connection default +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +2 +COMMIT; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +connection connection1 +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +2 +START TRANSACTION; +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +2 +INSERT INTO t2 VALUES (6,'w'); +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +3 +connection default +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +3 +START TRANSACTION; +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +3 +DELETE from t2 WHERE s1=3; +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +2 +COMMIT; +connection connection1 +COMMIT; +SELECT sql_cache count(*) FROM t2 WHERE s2 = 'w'; +count(*) +2 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 2 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 6 +set GLOBAL query_cache_size=0; +drop table t2; +SET GLOBAL query_cache_size = 1024 * 1024; +create table t1 +(name varchar(128), +dept int, +primary key(dept,name)) +ENGINE=MyISAM +PARTITION BY RANGE (`dept`) +( +PARTITION d0 VALUES LESS THAN (1), +PARTITION d1 VALUES LESS THAN (2), +PARTITION d2 VALUES LESS THAN (3), +PARTITION d_other VALUES LESS THAN MAXVALUE); +set autocommit=0; +start transaction; +insert into t1(name,dept) values('a',1); +insert into t1(name,dept) values('b',1); +insert into t1(name,dept) values('c',1); +select count(*) from t1; +count(*) +3 +# expecting 3 +rollback; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +select count(*) from t1; +count(*) +3 +# expecting 0, and seeing 0 +select count(*) from t1; +count(*) +3 +# expecting 0, and seeing 3 before fix! +drop table t1; +CREATE TABLE `t1` +(`id` int(11) NOT NULL , +`created_at` datetime NOT NULL, +`cool` tinyint default 0 +) ENGINE=MyISAM; +ALTER TABLE t1 +PARTITION BY RANGE (TO_DAYS(created_at)) +(PARTITION month_2010_4 VALUES LESS THAN (734258), +PARTITION month_2010_5 VALUES LESS THAN (734289), +PARTITION month_max VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (1, now(), 0); +BEGIN; +UPDATE `t1` SET `cool` = 1 WHERE `id` = 1; +SELECT cool FROM `t1` WHERE (`t1`.id = 1) LIMIT 1; +cool +1 +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +SELECT cool FROM `t1` WHERE (`t1`.id = 1) LIMIT 1; +cool +1 +BEGIN; +SELECT cool FROM `t1` WHERE (`t1`.id = 1) LIMIT 1; +cool +1 +ROLLBACK; +SELECT cool FROM `t1` WHERE (`t1`.id = 1) LIMIT 1; +cool +1 +DROP TABLE `t1`; +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = MyISAM +PARTITION BY HASH (a) +PARTITIONS 5; +INSERT INTO t1 VALUES (11, 'Eleven'), (1, 'One'), (2, 'Two'), (12, 'aslasdrfa'), (7, 'sdfae'), (4, 'asdfees'), (14, '3asdf3'), (9, 'asdfeea'); +set autocommit=1; +FLUSH STATUS; +SELECT * FROM t1; +a b +11 Eleven +1 One +2 Two +12 aslasdrfa +7 sdfae +4 asdfees +14 3asdf3 +9 asdfeea +SHOW STATUS LIKE "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +SHOW STATUS LIKE "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +SHOW STATUS LIKE "Qcache_hits"; +Variable_name Value +Qcache_hits 0 +SELECT * FROM t1; +a b +11 Eleven +1 One +2 Two +12 aslasdrfa +7 sdfae +4 asdfees +14 3asdf3 +9 asdfeea +SHOW STATUS LIKE "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +SHOW STATUS LIKE "Qcache_inserts"; +Variable_name Value +Qcache_inserts 1 +SHOW STATUS LIKE "Qcache_hits"; +Variable_name Value +Qcache_hits 1 +FLUSH TABLES; +SELECT * FROM t1; +a b +11 Eleven +1 One +2 Two +12 aslasdrfa +7 sdfae +4 asdfees +14 3asdf3 +9 asdfeea +SHOW STATUS LIKE "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +SHOW STATUS LIKE "Qcache_inserts"; +Variable_name Value +Qcache_inserts 2 +SHOW STATUS LIKE "Qcache_hits"; +Variable_name Value +Qcache_hits 1 +DROP TABLE t1; +set GLOBAL query_cache_size=0; === added file 'mysql-test/t/partition_cache_myisam.test' --- a/mysql-test/t/partition_cache_myisam.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/t/partition_cache_myisam.test 2011-05-10 12:16:35 +0000 @@ -0,0 +1,105 @@ +--source include/have_query_cache.inc + +--source include/have_partition.inc +let $engine_type= MyISAM; +# partitioned MyISAM does NOT supports FOREIGN KEYs +let $test_foreign_keys= 0; + +# Using SELECT to get a space as first character. +let $partitions_a= `SELECT ' PARTITION BY HASH (a) PARTITIONS 7'`; +let $partitions_id= `SELECT ' PARTITION BY HASH (id) PARTITIONS 7'`; +let $partitions_s1= `SELECT ' PARTITION BY HASH (s1) PARTITIONS 7'`; + +--source include/query_cache.inc + +let $save_query_cache_size=`select @@global.query_cache_size`; +SET GLOBAL query_cache_size = 1024 * 1024; +create table t1 +(name varchar(128), + dept int, + primary key(dept,name)) +ENGINE=MyISAM +PARTITION BY RANGE (`dept`) +( + PARTITION d0 VALUES LESS THAN (1), + PARTITION d1 VALUES LESS THAN (2), + PARTITION d2 VALUES LESS THAN (3), + PARTITION d_other VALUES LESS THAN MAXVALUE); + +set autocommit=0; +start transaction; + +insert into t1(name,dept) values('a',1); +insert into t1(name,dept) values('b',1); +insert into t1(name,dept) values('c',1); + +select count(*) from t1; +--echo # expecting 3 +rollback; + +select count(*) from t1; +--echo # expecting 0, and seeing 0 + +select count(*) from t1; +--echo # expecting 0, and seeing 3 before fix! + +drop table t1; + + + +CREATE TABLE `t1` +(`id` int(11) NOT NULL , + `created_at` datetime NOT NULL, + `cool` tinyint default 0 +) ENGINE=MyISAM; + +ALTER TABLE t1 +PARTITION BY RANGE (TO_DAYS(created_at)) +(PARTITION month_2010_4 VALUES LESS THAN (734258), + PARTITION month_2010_5 VALUES LESS THAN (734289), + PARTITION month_max VALUES LESS THAN MAXVALUE); + +INSERT INTO t1 VALUES (1, now(), 0); + +BEGIN; + +UPDATE `t1` SET `cool` = 1 WHERE `id` = 1; + +SELECT cool FROM `t1` WHERE (`t1`.id = 1) LIMIT 1; + +ROLLBACK; + +SELECT cool FROM `t1` WHERE (`t1`.id = 1) LIMIT 1; + +BEGIN; + +SELECT cool FROM `t1` WHERE (`t1`.id = 1) LIMIT 1; + +ROLLBACK; + +SELECT cool FROM `t1` WHERE (`t1`.id = 1) LIMIT 1; + +DROP TABLE `t1`; + +CREATE TABLE t1 (a INT, b VARCHAR(64)) +ENGINE = MyISAM +PARTITION BY HASH (a) +PARTITIONS 5; +INSERT INTO t1 VALUES (11, 'Eleven'), (1, 'One'), (2, 'Two'), (12, 'aslasdrfa'), (7, 'sdfae'), (4, 'asdfees'), (14, '3asdf3'), (9, 'asdfeea'); +set autocommit=1; +FLUSH STATUS; +SELECT * FROM t1; +SHOW STATUS LIKE "Qcache_queries_in_cache"; +SHOW STATUS LIKE "Qcache_inserts"; +SHOW STATUS LIKE "Qcache_hits"; +SELECT * FROM t1; +SHOW STATUS LIKE "Qcache_queries_in_cache"; +SHOW STATUS LIKE "Qcache_inserts"; +SHOW STATUS LIKE "Qcache_hits"; +FLUSH TABLES; +SELECT * FROM t1; +SHOW STATUS LIKE "Qcache_queries_in_cache"; +SHOW STATUS LIKE "Qcache_inserts"; +SHOW STATUS LIKE "Qcache_hits"; +DROP TABLE t1; +eval set GLOBAL query_cache_size=$save_query_cache_size; === modified file 'sql/ha_partition.cc' --- a/sql/ha_partition.cc 2011-05-08 21:23:01 +0000 +++ b/sql/ha_partition.cc 2011-05-10 12:16:35 +0000 @@ -6465,7 +6465,8 @@ static my_bool partition_qc_check_callba else if (tot_parts <= 255) { uint8 *pruned_engine_data= (uint8*) engine_data; - DBUG_ASSERT(part_count < 8); + if (part_count >= 8) + break; if (!pruned_engine_data[part_count]) break; if ((part_id + 1) != pruned_engine_data[part_count]) @@ -6474,7 +6475,8 @@ static my_bool partition_qc_check_callba else { uint16 *pruned_engine_data= (uint16*) engine_data; - DBUG_ASSERT(part_count < 4); + if (part_count >= 4) + break; if (!pruned_engine_data[part_count]) break; if ((part_id + 1) != pruned_engine_data[part_count]) @@ -6545,15 +6547,17 @@ my_bool ha_partition::register_query_cac /* Check if it is possible to use pruning by using the unused engine_data. - Like: - TODO: Fix this scheme, fails if only first partition is used! - Solve by moving part_id range with one -> 1..m_tot_parts instead - of 0..(m_tot_parts - 1) + Use part_id range -> 1..m_tot_parts instead of 0..(m_tot_parts - 1). + This way if engine_data == 0 it means that no pruning was used. If <= 64 parts use as bitmap. If (> 64 parts && <= 255 parts && max 8 partitions used) use each byte as (partition id + 1) (uint8). If (> 255 parts && max 4 partitions used) use each pair of byte as (partition id + 1) (uint16). + TODO: Change the query cache api to store a 'blob' of arbitrary length + instead of a fixed length engine_data. Preferable a pointer + length which + the query cache will copy and store. Copying since the query cache manages + its own memory and its own limits. */ if (m_tot_parts <= 64) { @@ -6651,7 +6655,8 @@ my_bool ha_partition::register_query_cac if (!ha_data->static_qc_callback) { pthread_mutex_lock(&table_share->mutex); - ha_data->static_qc_callback= first_callback; + if (!ha_data->static_qc_callback) + ha_data->static_qc_callback= first_callback; pthread_mutex_unlock(&table_share->mutex); } --===============0579405635== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/mattias.jonsson@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: mattias.jonsson@stripped\ # qdxsuf7q8fnwfil9 # target_branch: file:///C:/ade/mysql-bzr/b11761296-5.1/ # testament_sha1: cb46c94fe9f879b69789413d6c937fdccf91f716 # timestamp: 2011-05-10 14:16:42 +0200 # base_revision_id: mattias.jonsson@stripped\ # mgo9udm02i4ug584 # # Begin bundle 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 --===============0579405635==--