Commit 3181f5d2 authored by msvensson@neptunus.homeip.net's avatar msvensson@neptunus.homeip.net

Merged "query cache for ndb" to 5.0

parents 459fa7f1 efd5ed2f
......@@ -152,6 +152,7 @@ mronstrom@build.mysql.com
mronstrom@mysql.com
mskold@mysql.com
msvensson@build.mysql.com
msvensson@neptunus.homeip.net
mwagner@cash.mwagner.org
mwagner@evoq.mwagner.org
mwagner@here.mwagner.org
......@@ -160,6 +161,7 @@ mwagner@work.mysql.com
mydev@mysql.com
mysql@home.(none)
mysql@mc04.(none)
mysqldev@bk-internal.mysql.com
mysqldev@build.mysql2.com
mysqldev@melody.local
mysqldev@mysql.com
......
# Setup connections to both MySQL Servers connected to the cluster
connect (server1,127.0.0.1,root,,test,$MASTER_MYPORT,);
connect (server2,127.0.0.1,root,,test,$MASTER_MYPORT1,);
# Check that server1 has NDB support
connection server1;
disable_query_log;
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
flush tables;
@r/have_ndb.require show variables like "have_ndbcluster";
@r/server_id.require show variables like "server_id";
enable_query_log;
# Check that server2 has NDB support
connection server2;
disable_query_log;
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
flush tables;
@r/have_ndb.require show variables like "have_ndbcluster";
@r/server_id1.require show variables like "server_id";
enable_query_log;
# Set the default connection to 'server1'
connection server1;
......@@ -2,6 +2,4 @@
disable_query_log;
show variables like "have_ndbcluster";
enable_query_log;
#connect (server1,127.0.0.1,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
#connect (server2,127.0.0.1,root,,test,$MASTER_MYPORT1,$MASTER_MYSOCK1);
#connection server1;
drop table if exists t1;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
reset query cache;
flush status;
drop table if exists t1,t2;
CREATE TABLE t1 (a int) ENGINE=ndbcluster;
CREATE TABLE t2 (a int);
CREATE TABLE t1 ( pk int not null primary key,
a int, b int not null, c varchar(20)) ENGINE=ndbcluster;
insert into t1 value (1, 2, 3, 'First row');
select * from t1;
a
pk a b c
1 2 3 First row
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
Qcache_queries_in_cache 1
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 0
Qcache_inserts 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
select * from t2;
a
select * from t1;
pk a b c
1 2 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
update t1 set a=3 where pk=1;
select * from t1;
pk a b c
1 3 3 First row
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
insert into t1 value (2, 7, 8, 'Second row');
insert into t1 value (4, 5, 6, 'Fourth row');
select * from t1;
pk a b c
2 7 8 Second row
4 5 6 Fourth row
1 3 3 First row
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
select * from t1;
pk a b c
2 7 8 Second row
4 5 6 Fourth row
1 3 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 2
select * from t1 where b=3;
pk a b c
1 3 3 First row
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 2
select * from t1 where b=3;
pk a b c
1 3 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 3
delete from t1 where c='Fourth row';
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
select * from t1 where b=3;
pk a b c
1 3 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 3
use test;
select * from t1;
pk a b c
2 7 8 Second row
1 3 3 First row
select * from t1 where b=3;
pk a b c
1 3 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 4
update t1 set a=4 where b=3;
use test;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 7
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 5
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
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
Qcache_inserts 7
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
Qcache_hits 7
begin;
update t1 set a=5 where pk=1;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 7
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 7
select * from t1;
a
select * from t2;
a
pk a b c
2 7 8 Second row
1 4 3 First row
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
Qcache_inserts 8
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
drop table t1, t2;
Qcache_hits 7
commit;
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 8
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 7
select * from t1;
pk a b c
2 7 8 Second row
1 5 3 First row
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 9
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 7
select * from t1;
pk a b c
2 7 8 Second row
1 5 3 First row
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 9
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 8
drop table t1;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
SET GLOBAL query_cache_size=0;
drop table if exists t1;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
set GLOBAL ndb_cache_check_time=5;
reset query cache;
flush status;
CREATE TABLE t1 ( pk int not null primary key,
a int, b int not null, c varchar(20)) ENGINE=ndbcluster;
insert into t1 value (1, 2, 3, 'First row');
select * from t1;
pk a b c
1 2 3 First row
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;
pk a b c
1 2 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
update t1 set a=3 where pk=1;
select * from t1;
pk a b c
1 3 3 First row
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
insert into t1 value (2, 7, 8, 'Second row');
insert into t1 value (4, 5, 6, 'Fourth row');
select * from t1;
pk a b c
2 7 8 Second row
4 5 6 Fourth row
1 3 3 First row
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
select * from t1;
pk a b c
2 7 8 Second row
4 5 6 Fourth row
1 3 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 2
select * from t1 where b=3;
pk a b c
1 3 3 First row
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 2
select * from t1 where b=3;
pk a b c
1 3 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 3
delete from t1 where c='Fourth row';
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
select * from t1 where b=3;
pk a b c
1 3 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 3
use test;
select * from t1;
pk a b c
2 7 8 Second row
1 3 3 First row
select * from t1 where b=3;
pk a b c
1 3 3 First row
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 4
update t1 set a=4 where b=3;
use test;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 7
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 5
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
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 7
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 7
begin;
update t1 set a=5 where pk=1;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 7
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 7
select * from t1;
pk a b c
2 7 8 Second row
1 4 3 First row
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 8
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 7
commit;
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 8
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 7
select * from t1;
pk a b c
2 7 8 Second row
1 5 3 First row
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 9
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 7
select * from t1;
pk a b c
2 7 8 Second row
1 5 3 First row
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 9
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 8
drop table t1;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
SET GLOBAL query_cache_size=0;
SET GLOBAL ndb_cache_check_time=0;
drop table if exists t1, t2;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
reset query cache;
flush status;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
reset query cache;
flush status;
create table t1 (a int) engine=ndbcluster;
create table t2 (a int) engine=ndbcluster;
insert into t1 value (2);
insert into t2 value (3);
select * from t1;
a
2
select * from t2;
a
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 2
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 0
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
select * from t1;
a
2
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
update t1 set a=3 where a=2;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 2
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
select * from t1;
a
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 2
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
drop table t1, t2;
drop table if exists t1, t2;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
set GLOBAL ndb_cache_check_time=1;
reset query cache;
flush status;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
set GLOBAL ndb_cache_check_time=1;
reset query cache;
flush status;
create table t1 (a int) engine=ndbcluster;
create table t2 (a int) engine=ndbcluster;
insert into t1 value (2);
insert into t2 value (3);
select * from t1;
a
2
select * from t2;
a
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 2
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 0
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
select * from t1;
a
2
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
update t1 set a=3 where a=2;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 2
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 2
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
select * from t1;
a
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 2
show status like "Qcache_inserts";
Variable_name Value
Qcache_inserts 3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
drop table t1, t2;
drop table if exists t1, t2, t3, t4;
flush status;
create table t1 (a int) engine=ndbcluster;
create table t2 (a int) engine=ndbcluster;
insert into t1 value (2);
insert into t2 value (3);
select * from t1;
a
2
select * from t2;
a
3
show status like 'handler_discover%';
Variable_name Value
Handler_discover 0
flush status;
select * from t1;
a
2
update t1 set a=3 where a=2;
show status like 'handler_discover%';
Variable_name Value
Handler_discover 1
create table t3 (a int not null primary key, b varchar(22),
c int, last_col text) engine=ndb;
insert into t3 values(1, 'Hi!', 89, 'Longtext column');
create table t4 (pk int primary key, b int) engine=ndb;
select * from t1;
a
3
select * from t3;
a b c last_col
1 Hi! 89 Longtext column
show status like 'handler_discover%';
Variable_name Value
Handler_discover 1
show tables like 't4';
Tables_in_test (t4)
t4
show status like 'handler_discover%';
Variable_name Value
Handler_discover 2
show tables;
Tables_in_test
t1
t2
t3
t4
drop table t1, t2, t3, t4;
Variable_name Value
server_id 1
Variable_name Value
server_id 102
-- source include/have_query_cache.inc
-- source include/have_ndb.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
# Turn on and reset query cache
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
reset query cache;
flush status;
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
# Create test table in NDB
CREATE TABLE t1 ( pk int not null primary key,
a int, b int not null, c varchar(20)) ENGINE=ndbcluster;
insert into t1 value (1, 2, 3, 'First row');
# Perform one query which should be inerted in query cache
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
# Perform the same query and make sure the query cache is hit
select * from t1;
show status like "Qcache_hits";
# Update the table and make sure the correct data is returned
update t1 set a=3 where pk=1;
select * from t1;
show status like "Qcache_inserts";
show status like "Qcache_hits";
# Insert a new record and make sure the correct data is returned
insert into t1 value (2, 7, 8, 'Second row');
insert into t1 value (4, 5, 6, 'Fourth row');
select * from t1;
show status like "Qcache_inserts";
show status like "Qcache_hits";
select * from t1;
show status like "Qcache_hits";
# Perform a "new" query and make sure the query cache is not hit
select * from t1 where b=3;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
# Same query again...
select * from t1 where b=3;
show status like "Qcache_hits";
CREATE TABLE t1 (a int) ENGINE=ndbcluster;
CREATE TABLE t2 (a int);
# Delete from the table
delete from t1 where c='Fourth row';
show status like "Qcache_queries_in_cache";
select * from t1 where b=3;
show status like "Qcache_hits";
# Start another connection and check that the query cache is hit
connect (con1,localhost,root,,);
connection con1;
use test;
select * from t1;
select * from t1 where b=3;
show status like "Qcache_hits";
# Update the table and switch to other connection
update t1 set a=4 where b=3;
connect (con2,localhost,root,,);
connection con2;
use test;
show status like "Qcache_queries_in_cache";
select * from t1;
select * from t1;
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con1;
select * from t1;
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
select * from t2;
# Use transactions and make sure the query cache is not updated until
# transaction is commited
begin;
update t1 set a=5 where pk=1;
# Note!! the below test shows that table is invalidated
# before transaction is committed
# TODO Fix so that cache is not invalidated HERE!
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con2;
select * from t1;
select * from t2;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con1;
commit;
# TODO Here query is invalidated once again, commit count in NDB has changed
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con2;
select * from t1;
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con1;
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
drop table t1;
drop table t1, t2;
show status like "Qcache_queries_in_cache";
SET GLOBAL query_cache_size=0;
-- source include/have_query_cache.inc
-- source include/have_ndb.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
# Turn on and reset query cache
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
# Turn on thread that will fetch commit count for open tables
set GLOBAL ndb_cache_check_time=5;
reset query cache;
flush status;
# Wait for thread to wake up and start "working"
sleep 20;
# Create test table in NDB
CREATE TABLE t1 ( pk int not null primary key,
a int, b int not null, c varchar(20)) ENGINE=ndbcluster;
insert into t1 value (1, 2, 3, 'First row');
# Perform one query which should be inerted in query cache
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
# Perform the same query and make sure the query cache is hit
select * from t1;
show status like "Qcache_hits";
# Update the table and make sure the correct data is returned
update t1 set a=3 where pk=1;
select * from t1;
show status like "Qcache_inserts";
show status like "Qcache_hits";
# Insert a new record and make sure the correct data is returned
insert into t1 value (2, 7, 8, 'Second row');
insert into t1 value (4, 5, 6, 'Fourth row');
select * from t1;
show status like "Qcache_inserts";
show status like "Qcache_hits";
select * from t1;
show status like "Qcache_hits";
# Perform a "new" query and make sure the query cache is not hit
select * from t1 where b=3;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
# Same query again...
select * from t1 where b=3;
show status like "Qcache_hits";
# Delete from the table
delete from t1 where c='Fourth row';
show status like "Qcache_queries_in_cache";
select * from t1 where b=3;
show status like "Qcache_hits";
# Start another connection and check that the query cache is hit
connect (con1,localhost,root,,);
connection con1;
use test;
select * from t1;
select * from t1 where b=3;
show status like "Qcache_hits";
# Update the table and switch to other connection
update t1 set a=4 where b=3;
connect (con2,localhost,root,,);
connection con2;
use test;
show status like "Qcache_queries_in_cache";
select * from t1;
select * from t1;
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con1;
select * from t1;
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
# Use transactions and make sure the query cache is not updated until
# transaction is commited
begin;
update t1 set a=5 where pk=1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con2;
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con1;
commit;
# Sleep to let the query cache thread update commit count
sleep 10;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con2;
select * from t1;
show status like "Qcache_inserts";
show status like "Qcache_hits";
connection con1;
select * from t1;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
drop table t1;
show status like "Qcache_queries_in_cache";
SET GLOBAL query_cache_size=0;
SET GLOBAL ndb_cache_check_time=0;
-- source include/have_query_cache.inc
-- source include/have_ndb.inc
-- source include/have_multi_ndb.inc
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
# Turn on and reset query cache on server1
connection server1;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
reset query cache;
flush status;
# Turn on and reset query cache on server2
connection server2;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
reset query cache;
flush status;
# Create test tables in NDB and load them into cache
# on server1
connection server1;
create table t1 (a int) engine=ndbcluster;
create table t2 (a int) engine=ndbcluster;
insert into t1 value (2);
insert into t2 value (3);
select * from t1;
select * from t2;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
# Connect server2, load table in to cache, then update the table
connection server2;
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";
update t1 set a=3 where a=2;
# Connect to server1 and check that cache is invalidated
# and correct data is returned
connection server1;
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";
drop table t1, t2;
-- source include/have_query_cache.inc
-- source include/have_ndb.inc
-- source include/have_multi_ndb.inc
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
# Turn on and reset query cache on server1
connection server1;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
set GLOBAL ndb_cache_check_time=1;
reset query cache;
flush status;
# Turn on and reset query cache on server2
connection server2;
set GLOBAL query_cache_type=on;
set GLOBAL query_cache_size=1355776;
set GLOBAL ndb_cache_check_time=1;
reset query cache;
flush status;
# Sleep so that the query cache check thread has time to start
sleep 15;
# Create test tables in NDB and load them into cache
# on server1
connection server1;
create table t1 (a int) engine=ndbcluster;
create table t2 (a int) engine=ndbcluster;
insert into t1 value (2);
insert into t2 value (3);
select * from t1;
select * from t2;
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
# Connect server2, load table in to cache, then update the table
connection server2;
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";
update t1 set a=3 where a=2;
# Sleep so that the query cache check thread has time to run
sleep 5;
# Connect to server1 and check that cache is invalidated
# and correct data is returned
connection server1;
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";
drop table t1, t2;
-- source include/have_ndb.inc
-- source include/have_multi_ndb.inc
--disable_warnings
drop table if exists t1, t2, t3, t4;
--enable_warnings
flush status;
# Create test tables on server1
create table t1 (a int) engine=ndbcluster;
create table t2 (a int) engine=ndbcluster;
insert into t1 value (2);
insert into t2 value (3);
select * from t1;
select * from t2;
show status like 'handler_discover%';
# Connect to server2 and use the tables from there
connection server2;
flush status;
select * from t1;
update t1 set a=3 where a=2;
show status like 'handler_discover%';
# Create a new table on server2
create table t3 (a int not null primary key, b varchar(22),
c int, last_col text) engine=ndb;
insert into t3 values(1, 'Hi!', 89, 'Longtext column');
create table t4 (pk int primary key, b int) engine=ndb;
# Check that the tables are accessible from server1
connection server1;
select * from t1;
select * from t3;
show status like 'handler_discover%';
show tables like 't4';
show status like 'handler_discover%';
show tables;
drop table t1, t2, t3, t4;
......@@ -787,8 +787,9 @@ innobase_query_caching_of_table_permitted(
char* full_name, /* in: concatenation of database name,
the null character '\0', and the table
name */
uint full_name_len) /* in: length of the full name, i.e.
uint full_name_len, /* in: length of the full name, i.e.
len(dbname) + len(tablename) + 1 */
ulonglong *unused) /* unused for this engine */
{
ibool is_autocommit;
trx_t* trx;
......
......@@ -33,6 +33,10 @@ typedef struct st_innobase_share {
} INNOBASE_SHARE;
my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
uint full_name_len,
ulonglong *unused);
/* The class defining a handle to an Innodb table */
class ha_innobase: public handler
{
......@@ -173,6 +177,20 @@ class ha_innobase: public handler
void init_table_handle_for_HANDLER();
ulonglong get_auto_increment();
uint8 table_cache_type() { return HA_CACHE_TBL_ASKTRANSACT; }
/*
ask handler about permission to cache table during query registration
*/
my_bool cached_table_registration(THD *thd, char *table_key,
uint key_length,
qc_engine_callback *call_back,
ulonglong *engine_data)
{
*call_back= innobase_query_caching_of_table_permitted;
*engine_data= 0;
return innobase_query_caching_of_table_permitted(thd, table_key,
key_length,
engine_data);
}
static char *get_mysql_bin_log_name();
static ulonglong get_mysql_bin_log_pos();
bool primary_key_is_clustered() { return true; }
......@@ -253,8 +271,6 @@ bool innodb_show_status(THD* thd);
bool innodb_mutex_show_status(THD* thd);
void innodb_export_status(void);
my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
uint full_name_len);
void innobase_release_temporary_latches(void* innobase_tid);
void innobase_store_binlog_offset_and_flush_log(char *binlog_name,longlong offset);
......
This diff is collapsed.
......@@ -37,6 +37,7 @@ class NdbBlob;
// connectstring to cluster if given by mysqld
extern const char *ndbcluster_connectstring;
extern ulong ndb_cache_check_time;
typedef enum ndb_index_type {
UNDEFINED_INDEX = 0,
......@@ -59,6 +60,7 @@ typedef struct st_ndbcluster_share {
pthread_mutex_t mutex;
char *table_name;
uint table_name_length,use_count;
uint commit_count;
} NDB_SHARE;
/*
......@@ -155,7 +157,10 @@ class ha_ndbcluster: public handler
static Thd_ndb* seize_thd_ndb();
static void release_thd_ndb(Thd_ndb* thd_ndb);
uint8 table_cache_type();
my_bool cached_table_registration(THD *thd, char *table_key,
uint key_length,
qc_engine_callback *engine_callback,
ulonglong *engine_data);
private:
int alter_table_name(const char *to);
int drop_table();
......@@ -256,7 +261,6 @@ class ha_ndbcluster: public handler
bool m_force_send;
ha_rows m_autoincrement_prefetch;
bool m_transaction_on;
bool m_use_local_query_cache;
bool m_disable_multi_read;
byte *m_multi_range_result_ptr;
......
......@@ -234,15 +234,6 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
}
}
bool ha_caching_allowed(THD* thd, char* table_key,
uint key_length, uint8 cache_type)
{
#ifdef HAVE_INNOBASE_DB
if (cache_type == HA_CACHE_TBL_ASKTRANSACT)
return innobase_query_caching_of_table_permitted(thd, table_key, key_length);
#endif
return 1;
}
/*
......
......@@ -592,6 +592,15 @@ public:
/* Type of table for caching query */
virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
/* ask handler about permission to cache table during query registration */
virtual my_bool cached_table_registration(THD *thd, char *table_key,
uint key_length,
qc_engine_callback *engine_callback,
ulonglong *engine_data)
{
*engine_callback= 0;
return 1;
}
/*
RETURN
......@@ -622,8 +631,6 @@ extern TYPELIB tx_isolation_typelib;
T != DB_TYPE_BERKELEY_DB && \
T != DB_TYPE_NDBCLUSTER)
bool ha_caching_allowed(THD* thd, char* table_key,
uint key_length, uint8 cache_type);
enum db_type ha_resolve_by_name(const char *name, uint namelen);
const char *ha_get_storage_engine(enum db_type db_type);
handler *get_new_handler(TABLE *table, enum db_type db_type);
......
......@@ -401,6 +401,9 @@ inline THD *_current_thd(void)
}
#define current_thd _current_thd()
typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
uint key_length,
ulonglong *engine_data);
#include "sql_string.h"
#include "sql_list.h"
#include "sql_map.h"
......
......@@ -291,6 +291,7 @@ my_bool opt_console= 0, opt_bdb, opt_innodb, opt_isam, opt_ndbcluster;
#ifdef HAVE_NDBCLUSTER_DB
const char *opt_ndbcluster_connectstring= 0;
my_bool opt_ndb_shm, opt_ndb_optimized_node_selection;
ulong opt_ndb_cache_check_time= 0;
#endif
my_bool opt_readonly, use_temp_pool, relay_log_purge;
my_bool opt_sync_bdb_logs, opt_sync_frm;
......@@ -4174,7 +4175,7 @@ enum options_mysqld
OPT_INNODB, OPT_ISAM,
OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT,
OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION,
OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
OPT_SKIP_SAFEMALLOC,
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
......@@ -4702,6 +4703,10 @@ Disable with --skip-ndbcluster (will save memory).",
(gptr*) &opt_ndb_optimized_node_selection,
(gptr*) &opt_ndb_optimized_node_selection,
0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
{ "ndb_cache_check_time", OPT_NDB_CACHE_CHECK_TIME,
"A dedicated thread is created to update cached commit count value at the given interval.",
(gptr*) &opt_ndb_cache_check_time, (gptr*) &opt_ndb_cache_check_time, 0, GET_ULONG, REQUIRED_ARG,
0, 0, LONG_TIMEOUT, 0, 1, 0},
#endif
{"new", 'n', "Use very new possible 'unsafe' functions.",
(gptr*) &global_system_variables.new_mode,
......
......@@ -405,6 +405,7 @@ sys_var_thd_bool
sys_ndb_use_exact_count("ndb_use_exact_count", &SV::ndb_use_exact_count);
sys_var_thd_bool
sys_ndb_use_transactions("ndb_use_transactions", &SV::ndb_use_transactions);
sys_var_long_ptr sys_ndb_cache_check_time("ndb_cache_check_time", &ndb_cache_check_time);
#endif
/* Time/date/datetime formats */
......@@ -677,6 +678,7 @@ sys_var *sys_variables[]=
&sys_ndb_force_send,
&sys_ndb_use_exact_count,
&sys_ndb_use_transactions,
&sys_ndb_cache_check_time,
#endif
&sys_unique_checks,
&sys_updatable_views_with_limit,
......@@ -857,6 +859,7 @@ struct show_var_st init_vars[]= {
{sys_ndb_force_send.name, (char*) &sys_ndb_force_send, SHOW_SYS},
{sys_ndb_use_exact_count.name,(char*) &sys_ndb_use_exact_count, SHOW_SYS},
{sys_ndb_use_transactions.name,(char*) &sys_ndb_use_transactions, SHOW_SYS},
{sys_ndb_cache_check_time.name,(char*) &sys_ndb_cache_check_time, SHOW_SYS},
#endif
{sys_net_buffer_length.name,(char*) &sys_net_buffer_length, SHOW_SYS},
{sys_net_read_timeout.name, (char*) &sys_net_read_timeout, SHOW_SYS},
......
......@@ -914,12 +914,12 @@ end:
int
Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
{
ulonglong engine_data;
Query_cache_query *query;
Query_cache_block *first_result_block, *result_block;
Query_cache_block_table *block_table, *block_table_end;
ulong tot_length;
Query_cache_query_flags flags;
bool check_tables;
DBUG_ENTER("Query_cache::send_result_to_client");
if (query_cache_size == 0 || thd->variables.query_cache_type == 0)
......@@ -1027,7 +1027,6 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
goto err_unlock;
}
check_tables= query->tables_type() & HA_CACHE_TBL_ASKTRANSACT;
// Check access;
block_table= query_block->table(0);
block_table_end= block_table+query_block->n_tables;
......@@ -1088,19 +1087,30 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
goto err_unlock; // Parse query
}
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
if (check_tables && !ha_caching_allowed(thd, table->db(),
engine_data= table->engine_data();
if (table->callback() &&
!(*table->callback())(thd, table->db(),
table->key_length(),
table->type()))
&engine_data))
{
DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s",
table_list.db, table_list.alias));
BLOCK_UNLOCK_RD(query_block);
if (engine_data != table->engine_data())
{
DBUG_PRINT("qcache",
("Handler require invalidation queries of %s.%s %lld-%lld",
table_list.db, table_list.alias,
engine_data, table->engine_data()));
invalidate_table(table->db(), table->key_length());
}
else
thd->lex->safe_to_cache_query= 0; // Don't try to cache this
goto err_unlock; // Parse query
}
else
DBUG_PRINT("qcache", ("handler allow caching (%d) %s,%s",
check_tables, table_list.db, table_list.alias));
DBUG_PRINT("qcache", ("handler allow caching %s,%s",
table_list.db, table_list.alias));
}
move_to_query_list_end(query_block);
hits++;
......@@ -2128,7 +2138,9 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
if (!insert_table(tables_used->table->s->key_length,
tables_used->table->s->table_cache_key, block_table,
tables_used->db_length,
tables_used->table->file->table_cache_type()))
tables_used->table->file->table_cache_type(),
tables_used->callback_func,
tables_used->engine_data))
break;
if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM)
......@@ -2144,9 +2156,13 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
uint key_length= filename_2_table_key(key, table->table->filename,
&db_length);
(++block_table)->n= ++n;
/*
There are not callback function for for MyISAM, and engine data
*/
if (!insert_table(key_length, key, block_table,
db_length,
tables_used->table->file->table_cache_type()))
tables_used->table->file->table_cache_type(),
0, 0))
goto err;
}
}
......@@ -2173,7 +2189,9 @@ err:
my_bool
Query_cache::insert_table(uint key_len, char *key,
Query_cache_block_table *node,
uint32 db_length, uint8 cache_type)
uint32 db_length, uint8 cache_type,
qc_engine_callback callback,
ulonglong engine_data)
{
DBUG_ENTER("Query_cache::insert_table");
DBUG_PRINT("qcache", ("insert table node 0x%lx, len %d",
......@@ -2183,6 +2201,23 @@ Query_cache::insert_table(uint key_len, char *key,
hash_search(&tables, (byte*) key,
key_len));
if (table_block &&
table_block->table()->engine_data() != engine_data)
{
DBUG_PRINT("qcache",
("Handler require invalidation queries of %s.%s %lld-%lld",
table_block->table()->db(),
table_block->table()->table(),
engine_data,
table_block->table()->engine_data()));
/*
as far as we delete all queries with this table, table block will be
deleted, too
*/
invalidate_table(table_block);
table_block= 0;
}
if (table_block == 0)
{
DBUG_PRINT("qcache", ("new table block from 0x%lx (%u)",
......@@ -2213,6 +2248,8 @@ Query_cache::insert_table(uint key_len, char *key,
header->table(db + db_length + 1);
header->key_length(key_len);
header->type(cache_type);
header->callback(callback);
header->engine_data(engine_data);
}
Query_cache_block_table *list_root = table_block->table(0);
......@@ -2733,9 +2770,10 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
for (; tables_used; tables_used= tables_used->next_global)
{
TABLE *table= tables_used->table;
if (!ha_caching_allowed(thd, table->s->table_cache_key,
if (!handler->cached_table_registration(thd, table->s->table_cache_key,
table->s->key_length,
table->file->table_cache_type()))
&tables_used->callback_func,
&tables_used->engine_data))
{
DBUG_PRINT("qcache", ("Handler does not allow caching for %s.%s",
tables_used->db, tables_used->alias));
......
......@@ -146,6 +146,10 @@ struct Query_cache_table
char *tbl;
uint32 key_len;
uint8 table_type;
/* unique for every engine reference */
qc_engine_callback callback_func;
/* data need by some engines */
ulonglong engine_data_buff;
inline char *db() { return (char *) data(); }
inline char *table() { return tbl; }
......@@ -154,6 +158,10 @@ struct Query_cache_table
inline void key_length(uint32 len) { key_len= len; }
inline uint8 type() { return table_type; }
inline void type(uint8 t) { table_type= t; }
inline qc_engine_callback callback() { return callback_func; }
inline void callback(qc_engine_callback fn){ callback_func= fn; }
inline ulonglong engine_data() { return engine_data_buff; }
inline void engine_data(ulonglong data) { engine_data_buff= data; }
inline gptr data()
{
return (gptr)(((byte*)this)+
......@@ -282,7 +290,9 @@ protected:
TABLE_COUNTER_TYPE tables);
my_bool insert_table(uint key_len, char *key,
Query_cache_block_table *node,
uint32 db_length, uint8 cache_type);
uint32 db_length, uint8 cache_type,
qc_engine_callback callback,
ulonglong engine_data);
void unlink_table(Query_cache_block_table *node);
Query_cache_block *get_free_block (ulong len, my_bool not_less,
ulong min);
......
......@@ -387,6 +387,10 @@ typedef struct st_table_list
uint effective_algorithm; /* which algorithm was really used */
uint privilege_backup; /* place for saving privileges */
GRANT_INFO grant;
/* data need by some engines in query cache*/
ulonglong engine_data;
/* call back function for asking handler about caching in query cache */
qc_engine_callback callback_func;
thr_lock_type lock_type;
uint outer_join; /* Which join type */
uint shared; /* Used in multi-upd */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment