mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-5.1-runtime
into gbichot3.local:/home/mysql_src/mysql-5.1-runtime-735-realfix
This commit is contained in:
@ -1,7 +1,4 @@
|
||||
-- require r/have_query_cache.require
|
||||
# As PS are not cached we disable them to ensure the we get the right number
|
||||
# of query cache hits
|
||||
-- disable_ps_protocol
|
||||
disable_query_log;
|
||||
show variables like "have_query_cache";
|
||||
enable_query_log;
|
||||
|
@ -1325,4 +1325,27 @@ start transaction;
|
||||
insert into t1(c1) select c1 from v1;
|
||||
drop table t1, t2, t3;
|
||||
drop view v1;
|
||||
create table t1(c1 int);
|
||||
insert into t1 values(1),(10),(100);
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
10
|
||||
100
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
10
|
||||
100
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
10
|
||||
100
|
||||
select * from t1;
|
||||
c1
|
||||
1
|
||||
10
|
||||
100
|
||||
drop table t1;
|
||||
set global query_cache_size=0;
|
||||
|
204
mysql-test/r/query_cache_sql_prepare.result
Normal file
204
mysql-test/r/query_cache_sql_prepare.result
Normal file
@ -0,0 +1,204 @@
|
||||
set global query_cache_size=100000;
|
||||
flush status;
|
||||
create table t1(c1 int);
|
||||
insert into t1 values(1),(10),(100);
|
||||
prepare stmt1 from "select * from t1 where c1=10";
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 0
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 1
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 2
|
||||
prepare stmt2 from "select * from t1 where c1=10";
|
||||
execute stmt2;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 3
|
||||
execute stmt2;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 4
|
||||
execute stmt2;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 5
|
||||
prepare stmt3 from "select * from t1 where c1=10";
|
||||
execute stmt3;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 6
|
||||
execute stmt3;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 7
|
||||
execute stmt3;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 8
|
||||
select * from t1 where c1=10;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 9
|
||||
flush tables;
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 9
|
||||
select * from t1 where c1=10;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
prepare stmt1 from "select * from t1 where c1=?";
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
set @a=1;
|
||||
execute stmt1 using @a;
|
||||
c1
|
||||
1
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
set @a=100;
|
||||
execute stmt1 using @a;
|
||||
c1
|
||||
100
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
set @a=10;
|
||||
execute stmt1 using @a;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
prepare stmt1 from "select * from t1 where c1=10";
|
||||
set global query_cache_size=0;
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
set global query_cache_size=100000;
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 10
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 11
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
set global query_cache_size=0;
|
||||
prepare stmt1 from "select * from t1 where c1=10";
|
||||
set global query_cache_size=100000;
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
execute stmt1;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
set global query_cache_size=0;
|
||||
prepare stmt1 from "select * from t1 where c1=?";
|
||||
set global query_cache_size=100000;
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
set @a=1;
|
||||
execute stmt1 using @a;
|
||||
c1
|
||||
1
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
set @a=100;
|
||||
execute stmt1 using @a;
|
||||
c1
|
||||
100
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
set @a=10;
|
||||
execute stmt1 using @a;
|
||||
c1
|
||||
10
|
||||
show status like 'Qcache_hits';
|
||||
Variable_name Value
|
||||
Qcache_hits 12
|
||||
drop table t1;
|
||||
set global query_cache_size=0;
|
||||
flush status;
|
@ -1,6 +1,8 @@
|
||||
# Grant tests not performed with embedded server
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_query_cache.inc
|
||||
# See at the end of the test why we disable the ps protocol (*)
|
||||
-- disable_ps_protocol
|
||||
|
||||
#
|
||||
# Test grants with query cache
|
||||
@ -151,3 +153,27 @@ drop database mysqltest;
|
||||
set GLOBAL query_cache_size=default;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
# (*) Why we disable the ps protocol: because in normal protocol,
|
||||
# a SELECT failing due to insufficient privileges increments
|
||||
# Qcache_not_cached, while in ps-protocol, no.
|
||||
# In detail: in normal protocol,
|
||||
# the "access denied" errors on SELECT are issued at (stack trace):
|
||||
# mysql_parse/mysql_execute_command/execute_sqlcom_select/handle_select/
|
||||
# mysql_select/JOIN::prepare/setup_wild/insert_fields/
|
||||
# check_grant_all_columns/my_error/my_message_sql, which then calls
|
||||
# push_warning/query_cache_abort: at this moment,
|
||||
# query_cache_store_query() has been called, so query exists in cache,
|
||||
# so thd->net.query_cache_query!=NULL, so query_cache_abort() removes
|
||||
# the query from cache, which causes a query_cache.refused++ (thus,
|
||||
# a Qcache_not_cached++).
|
||||
# While in ps-protocol, the error is issued at prepare time;
|
||||
# for this mysql_test_select() is called, not execute_sqlcom_select()
|
||||
# (and that also leads to JOIN::prepare/etc). Thus, as
|
||||
# query_cache_store_query() has not been called,
|
||||
# thd->net.query_cache_query==NULL, so query_cache_abort() does nothing:
|
||||
# Qcache_not_cached is not incremented.
|
||||
# As this test prints Qcache_not_cached after SELECT failures,
|
||||
# we cannot enable this test in ps-protocol.
|
||||
|
||||
--enable_ps_protocol
|
||||
|
@ -36,7 +36,11 @@ insert into t1 value (2);
|
||||
insert into t2 value (3);
|
||||
select * from t1;
|
||||
# Run the check query once to load it into qc on server1
|
||||
# See at the end of this test why we need to disable ps-protocol for
|
||||
# this query (*)
|
||||
--disable_ps_protocol
|
||||
select a != 3 from t1;
|
||||
--enable_ps_protocol
|
||||
select * from t2;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
show status like "Qcache_inserts";
|
||||
@ -93,3 +97,30 @@ set GLOBAL query_cache_size=0;
|
||||
set GLOBAL ndb_cache_check_time=0;
|
||||
reset query cache;
|
||||
flush status;
|
||||
|
||||
# (*) Why we need to execute the query in non-ps mode.
|
||||
# The principle of this test is: two mysqlds connected to one cluster,
|
||||
# both using their query cache. Queries are cached in server1
|
||||
# ("select a!=3 from t1", "select * from t1"),
|
||||
# table t1 is modified in server2, we want to see that this invalidates
|
||||
# the query cache of server1. Invalidation with NDB works like this:
|
||||
# when a query is found in the query cache, NDB is asked if the tables
|
||||
# have changed. In this test, ha_ndbcluster calls NDB every millisecond
|
||||
# to collect change information about tables.
|
||||
# Due to this millisecond delay, there is need for a loop ("while...")
|
||||
# in this test, which waits until a query1 ("select a!=3 from t1") is
|
||||
# invalidated (which is equivalent to it returning
|
||||
# up-to-date results), and then expects query2 ("select * from t1")
|
||||
# to have been invalidated (see up-to-date results).
|
||||
# But when enabling --ps-protocol in this test, the logic breaks,
|
||||
# because query1 is still done via mysql_real_query() (see mysqltest.c:
|
||||
# eval_expr() always uses mysql_real_query()). So, query1 returning
|
||||
# up-to-date results is not a sign of it being invalidated in the cache,
|
||||
# because it was NOT in the cache ("select a!=3 from t1" on line 39
|
||||
# was done with prep stmts, while `select a!=3 from t1` is not,
|
||||
# thus the second does not see the first in the cache). Thus, we may run
|
||||
# query2 when cache still has not been invalidated.
|
||||
# The solution is to make the initial "select a!=3 from t1" run
|
||||
# as a normal query, this repairs the broken logic.
|
||||
# But note, "select * from t1" is still using prepared statements
|
||||
# which was the goal of this test with --ps-protocol.
|
||||
|
@ -907,4 +907,24 @@ start transaction;
|
||||
insert into t1(c1) select c1 from v1;
|
||||
drop table t1, t2, t3;
|
||||
drop view v1;
|
||||
|
||||
|
||||
#
|
||||
# If running with --ps-protocol:
|
||||
# see if a query from the text protocol is served with results cached
|
||||
# from a query which used the binary (which would be wrong, results
|
||||
# are in different formats); if that happens, the results will
|
||||
# be incorrect and the test will fail.
|
||||
#
|
||||
|
||||
create table t1(c1 int);
|
||||
insert into t1 values(1),(10),(100);
|
||||
select * from t1;
|
||||
-- disable_ps_protocol
|
||||
select * from t1;
|
||||
select * from t1;
|
||||
-- enable_ps_protocol
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
set global query_cache_size=0;
|
||||
|
144
mysql-test/t/query_cache_sql_prepare.test
Normal file
144
mysql-test/t/query_cache_sql_prepare.test
Normal file
@ -0,0 +1,144 @@
|
||||
# This is to see how statements prepared via the PREPARE SQL command
|
||||
# go into the query cache: if using parameters they cannot; if not
|
||||
# using parameters they can.
|
||||
# Query cache is abbreviated as "QC"
|
||||
|
||||
-- source include/have_query_cache.inc
|
||||
|
||||
connect (con1,127.0.0.1,root,,test,$MASTER_MYPORT,);
|
||||
connection default;
|
||||
|
||||
set global query_cache_size=100000;
|
||||
flush status;
|
||||
create table t1(c1 int);
|
||||
insert into t1 values(1),(10),(100);
|
||||
|
||||
# Prepared statements has no parameters, query caching should happen
|
||||
prepare stmt1 from "select * from t1 where c1=10";
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
# Another prepared statement (same text, same connection), should hit the QC
|
||||
prepare stmt2 from "select * from t1 where c1=10";
|
||||
execute stmt2;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt2;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt2;
|
||||
show status like 'Qcache_hits';
|
||||
# Another prepared statement (same text, other connection), should hit the QC
|
||||
connection con1;
|
||||
prepare stmt3 from "select * from t1 where c1=10";
|
||||
execute stmt3;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt3;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt3;
|
||||
show status like 'Qcache_hits';
|
||||
connection default;
|
||||
# A non-prepared statement (same text, same connection), should hit
|
||||
# the QC (as it uses the text protocol like SQL EXECUTE).
|
||||
# But if it uses the binary protocol, it will not hit. So we make sure
|
||||
# that it uses the text protocol:
|
||||
-- disable_ps_protocol
|
||||
select * from t1 where c1=10;
|
||||
show status like 'Qcache_hits';
|
||||
# A non-prepared statement (same text, other connection), should hit
|
||||
# the QC. To test that it hits the result of SQL EXECUTE, we need to
|
||||
# empty/repopulate the QC (to remove the result from the non-prepared
|
||||
# SELECT just above).
|
||||
flush tables;
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
connection con1;
|
||||
select * from t1 where c1=10;
|
||||
show status like 'Qcache_hits';
|
||||
-- enable_ps_protocol
|
||||
connection default;
|
||||
|
||||
# Prepared statement has parameters, query caching should not happen
|
||||
prepare stmt1 from "select * from t1 where c1=?";
|
||||
show status like 'Qcache_hits';
|
||||
set @a=1;
|
||||
execute stmt1 using @a;
|
||||
show status like 'Qcache_hits';
|
||||
set @a=100;
|
||||
execute stmt1 using @a;
|
||||
show status like 'Qcache_hits';
|
||||
set @a=10;
|
||||
execute stmt1 using @a;
|
||||
show status like 'Qcache_hits';
|
||||
|
||||
# See if enabling/disabling the query cache between PREPARE and
|
||||
# EXECUTE is an issue; the expected result is that the query cache
|
||||
# will not be used.
|
||||
# Indeed, decision to read/write the query cache is taken at PREPARE
|
||||
# time, so if the query cache was disabled at PREPARE time then no
|
||||
# execution of the statement will read/write the query cache.
|
||||
# If the query cache was enabled at PREPARE time, but disabled at
|
||||
# EXECUTE time, at EXECUTE time the query cache internal functions do
|
||||
# nothing so again the query cache is not read/written. But if the
|
||||
# query cache is re-enabled before another execution then that
|
||||
# execution will read/write the query cache.
|
||||
|
||||
# QC is enabled at PREPARE
|
||||
prepare stmt1 from "select * from t1 where c1=10";
|
||||
# then QC is disabled at EXECUTE
|
||||
set global query_cache_size=0;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
# then QC is re-enabled for more EXECUTE.
|
||||
set global query_cache_size=100000;
|
||||
# Note that this execution will not hit results from the
|
||||
# beginning of the test (because QC has been emptied meanwhile by
|
||||
# setting its size to 0).
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
|
||||
# QC is disabled at PREPARE
|
||||
set global query_cache_size=0;
|
||||
prepare stmt1 from "select * from t1 where c1=10";
|
||||
# then QC is enabled at EXECUTE
|
||||
set global query_cache_size=100000;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
execute stmt1;
|
||||
show status like 'Qcache_hits';
|
||||
|
||||
# QC is disabled at PREPARE
|
||||
set global query_cache_size=0;
|
||||
prepare stmt1 from "select * from t1 where c1=?";
|
||||
# then QC is enabled at EXECUTE
|
||||
set global query_cache_size=100000;
|
||||
show status like 'Qcache_hits';
|
||||
set @a=1;
|
||||
execute stmt1 using @a;
|
||||
show status like 'Qcache_hits';
|
||||
set @a=100;
|
||||
execute stmt1 using @a;
|
||||
show status like 'Qcache_hits';
|
||||
set @a=10;
|
||||
execute stmt1 using @a;
|
||||
show status like 'Qcache_hits';
|
||||
|
||||
|
||||
drop table t1;
|
||||
|
||||
set global query_cache_size=0;
|
||||
flush status; # reset Qcache status variables for next tests
|
Reference in New Issue
Block a user