1# The include statement below is a temp one for tests that are yet to
2#be ported to run with InnoDB,
3#but needs to be kept for tests that would need MyISAM in future.
4--source include/force_myisam_default.inc
5
6# This test requires that --log-output includes 'table', and the general
7# log is on
8
9# embedded server causes different stat
10-- source include/not_embedded.inc
11
12# When running with valgrind, we switch off --check-testcases, and get
13# different connection_id below, and a content mismatch error.
14-- source include/not_valgrind.inc
15
16# Save the initial number of concurrent sessions
17--source include/count_sessions.inc
18
19# Disable concurrent inserts to avoid sporadic test failures as it might
20# affect the the value of variables used throughout the test case.
21set @old_concurrent_insert= @@global.concurrent_insert;
22set @@global.concurrent_insert= 0;
23
24# Disable logging to table, since this will also cause table locking and unlocking, which will
25# show up in SHOW STATUS and may cause sporadic failures
26
27SET @old_log_output = @@global.log_output;
28SET GLOBAL LOG_OUTPUT = 'FILE';
29
30# PS causes different statistics
31--disable_ps_protocol
32
33connect (con1,localhost,root,,);
34connect (con2,localhost,root,,);
35connection default;
36
37flush status;
38
39show status like 'Table_lock%';
40--disable_warnings
41select * from information_schema.session_status where variable_name like 'Table_lock%';
42--enable_warnings
43
44set sql_log_bin=0;
45set @old_general_log = @@global.general_log;
46set global general_log = 'OFF';
47--disable_warnings
48drop table if exists t1;
49--enable_warnings
50
51create table t1(n int) engine=myisam;
52insert into t1 values(1);
53select get_lock('mysqltest_lock', 100);
54
55connection con2;
56--echo # Switched to connection: con2
57--echo # Sending:
58--send update t1 set n = get_lock('mysqltest_lock', 100)
59
60connection con1;
61--echo # Switched to connection: con1
62--echo # Wait for the first UPDATE to get blocked.
63let $wait_condition= select count(*) from INFORMATION_SCHEMA.PROCESSLIST
64                     where STATE = "User lock" and
65                           INFO = "update t1 set n = get_lock('mysqltest_lock', 100)";
66--source include/wait_condition.inc
67
68let $ID= `select connection_id()`;
69--echo # Sending:
70--send update t1 set n = 3
71
72connection default;
73--echo # Switched to connection: default
74--echo # wait for the second UPDATE to get blocked
75let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST
76                     where ID = $ID and STATE = "Waiting for table level lock";
77--source include/wait_condition.inc
78select release_lock('mysqltest_lock');
79
80connection con2;
81--echo # Switched to connection: con2
82--echo # Reaping first UPDATE
83--reap
84select release_lock('mysqltest_lock');
85
86connection con1;
87--echo # Switched to connection: con1
88--echo # Reaping second UPDATE
89reap;
90show status like 'Table_locks_waited';
91
92connection default;
93--echo # Switched to connection: default
94drop table t1;
95set global general_log = @old_general_log;
96
97disconnect con2;
98disconnect con1;
99
100# End of 4.1 tests
101
102#
103# last_query_cost
104#
105
106select 1;
107show status like 'last_query_cost';
108create table t1 (a int);
109insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
110insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
111insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
112insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
113insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
114select * from t1 where a=6;
115show status like 'last_query_cost';
116# Ensure value dosn't change by second status call
117show status like 'last_query_cost';
118select 1;
119show status like 'last_query_cost';
120drop table t1;
121
122#
123# Test for Bug#15933 max_used_connections is wrong after FLUSH STATUS
124# if connections are cached
125#
126#
127# The first suggested fix from the bug report was chosen
128# (see http://bugs.mysql.com/bug.php?id=15933):
129#
130#   a) On flushing the status, set max_used_connections to
131#   threads_connected, not to 0.
132#
133#   b) Check if it is necessary to increment max_used_connections when
134#   taking a thread from the cache as well as when creating new threads
135#
136
137# Wait for at most $disconnect_timeout seconds for disconnects to finish.
138let $disconnect_timeout = 10;
139
140# Wait for any previous disconnects to finish.
141FLUSH STATUS;
142--disable_query_log
143--disable_result_log
144eval SET @wait_left = $disconnect_timeout;
145let $max_used_connections = `SHOW STATUS LIKE 'max_used_connections'`;
146eval SET @max_used_connections = SUBSTRING('$max_used_connections', 21)+0;
147let $wait_more = `SELECT @max_used_connections != 1 && @wait_left > 0`;
148while ($wait_more)
149{
150  sleep 1;
151  FLUSH STATUS;
152  SET @wait_left = @wait_left - 1;
153  let $max_used_connections = `SHOW STATUS LIKE 'max_used_connections'`;
154  eval SET @max_used_connections = SUBSTRING('$max_used_connections', 21)+0;
155  let $wait_more = `SELECT @max_used_connections != 1 && @wait_left > 0`;
156}
157--enable_query_log
158--enable_result_log
159
160# Prerequisite.
161SHOW STATUS LIKE 'max_used_connections';
162--disable_warnings
163SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections';
164--enable_warnings
165
166# Save original setting.
167SET @save_thread_cache_size=@@thread_cache_size;
168SET GLOBAL thread_cache_size=3;
169
170connect (con1,localhost,root,,);
171connect (con2,localhost,root,,);
172
173connection con1;
174disconnect con2;
175
176# Check that max_used_connections still reflects maximum value.
177SHOW STATUS LIKE 'max_used_connections';
178--disable_warnings
179SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections';
180--enable_warnings
181
182# Check that after flush max_used_connections equals to current number
183# of connections.  First wait for previous disconnect to finish.
184FLUSH STATUS;
185--disable_query_log
186--disable_result_log
187eval SET @wait_left = $disconnect_timeout;
188let $max_used_connections = `SHOW STATUS LIKE 'max_used_connections'`;
189eval SET @max_used_connections = SUBSTRING('$max_used_connections', 21)+0;
190let $wait_more = `SELECT @max_used_connections != 2 && @wait_left > 0`;
191while ($wait_more)
192{
193  sleep 1;
194  FLUSH STATUS;
195  SET @wait_left = @wait_left - 1;
196  let $max_used_connections = `SHOW STATUS LIKE 'max_used_connections'`;
197  eval SET @max_used_connections = SUBSTRING('$max_used_connections', 21)+0;
198  let $wait_more = `SELECT @max_used_connections != 2 && @wait_left > 0`;
199}
200--enable_query_log
201--enable_result_log
202# Check that we don't count disconnected thread any longer.
203SHOW STATUS LIKE 'max_used_connections';
204--disable_warnings
205SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections';
206--enable_warnings
207
208# Check that max_used_connections is updated when cached thread is
209# reused...
210connect (con2,localhost,root,,);
211SHOW STATUS LIKE 'max_used_connections';
212--disable_warnings
213SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections';
214--enable_warnings
215
216# ...and when new thread is created.
217connect (con3,localhost,root,,);
218SHOW STATUS LIKE 'max_used_connections';
219--disable_warnings
220SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections';
221--enable_warnings
222
223# Restore original setting.
224connection default;
225SET GLOBAL thread_cache_size=@save_thread_cache_size;
226
227disconnect con3;
228disconnect con2;
229disconnect con1;
230
231
232#
233# Bug#30377 EXPLAIN loses last_query_cost when used with UNION
234#
235
236CREATE TABLE t1 ( a INT );
237INSERT INTO t1 VALUES (1), (2);
238
239SELECT a FROM t1 LIMIT 1;
240SHOW SESSION STATUS LIKE 'Last_query_cost';
241
242EXPLAIN SELECT a FROM t1;
243SHOW SESSION STATUS LIKE 'Last_query_cost';
244
245SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a;
246SHOW SESSION STATUS LIKE 'Last_query_cost';
247
248EXPLAIN SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY a;
249SHOW SESSION STATUS LIKE 'Last_query_cost';
250
251SELECT a IN (SELECT a FROM t1) FROM t1 LIMIT 1;
252SHOW SESSION STATUS LIKE 'Last_query_cost';
253
254SELECT (SELECT a FROM t1 LIMIT 1) x FROM t1 LIMIT 1;
255SHOW SESSION STATUS LIKE 'Last_query_cost';
256
257SELECT * FROM t1 a, t1 b LIMIT 1;
258SHOW SESSION STATUS LIKE 'Last_query_cost';
259
260DROP TABLE t1;
261
262
263#
264# Bug#30252 Com_create_function is not incremented.
265#
266flush status;
267show status like 'Com%function';
268
269DELIMITER //;
270create function f1 (x INTEGER) returns integer
271  begin
272    declare ret integer;
273    set ret = x * 10;
274    return ret;
275  end //
276DELIMITER ;//
277
278drop function f1;
279
280show status like 'Com%function';
281
282#
283# Bug#37908 Skipped access right check caused server crash.
284#
285connect (root, localhost, root,,test);
286connection root;
287let $root_connection_id= `select connection_id()`;
288--disable_warnings
289create database db37908;
290--enable_warnings
291create table db37908.t1(f1 int);
292insert into db37908.t1 values(1);
293set @orig_sql_mode = @@sql_mode;
294set sql_mode=(select replace(@@sql_mode,'NO_AUTO_CREATE_USER',''));
295grant usage,execute on test.* to mysqltest_1@localhost;
296set sql_mode= @orig_sql_mode;
297delimiter |;
298create procedure proc37908() begin select 1; end |
299create function func37908() returns int sql security invoker
300  return (select * from db37908.t1 limit 1)|
301delimiter ;|
302
303connect (user1,localhost,mysqltest_1,,test);
304connection user1;
305let $user1_connection_id= `select connection_id()`;
306
307--error ER_TABLEACCESS_DENIED_ERROR
308select * from db37908.t1;
309--error ER_TABLEACCESS_DENIED_ERROR
310show status where variable_name ='uptime' and 2 in (select * from db37908.t1);
311--error ER_TABLEACCESS_DENIED_ERROR
312show procedure status where name ='proc37908' and 1 in (select f1 from db37908.t1);
313--error ER_TABLEACCESS_DENIED_ERROR
314show function status where name ='func37908' and 1 in (select func37908());
315
316connection default;
317disconnect user1;
318disconnect root;
319drop database db37908;
320drop procedure proc37908;
321drop function func37908;
322REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost;
323DROP USER mysqltest_1@localhost;
324# Wait till the sessions user1 and root are disconnected
325let $wait_condition =
326  SELECT COUNT(*) = 0
327  FROM information_schema.processlist
328  WHERE  id in ('$root_connection_id','$user1_connection_id');
329--source include/wait_condition.inc
330
331#
332# Bug#41131 "Questions" fails to increment - ignores statements instead stored procs
333#
334connect (con1,localhost,root,,);
335connection con1;
336--disable_warnings
337DROP PROCEDURE IF EXISTS p1;
338DROP FUNCTION IF EXISTS f1;
339--enable_warnings
340DELIMITER $$;
341CREATE FUNCTION f1() RETURNS INTEGER
342BEGIN
343  DECLARE foo INTEGER;
344  DECLARE bar INTEGER;
345  SET foo=1;
346  SET bar=2;
347  RETURN foo;
348END $$
349CREATE PROCEDURE p1()
350  BEGIN
351  SELECT 1;
352END $$
353DELIMITER ;$$
354let $org_queries= `SHOW STATUS LIKE 'Queries'`;
355SELECT f1();
356CALL p1();
357let $new_queries= `SHOW STATUS LIKE 'Queries'`;
358--disable_query_log
359let $diff= `SELECT SUBSTRING('$new_queries',9)-SUBSTRING('$org_queries',9)`;
360--enable_query_log
361eval SELECT $diff;
362disconnect con1;
363connection default;
364DROP PROCEDURE p1;
365DROP FUNCTION f1;
366
367# End of 5.1 tests
368
369
370--echo #
371--echo # Test coverage for status variables which were introduced by
372--echo # WL#5772 "Add partitioned Table Definition Cache to avoid
373--echo # using LOCK_open and its derivatives in DML queries".
374--echo #
375create table t1 (i int);
376create table t2 (j int);
377create table t3 (k int);
378--echo # Flush table cache to ensure that it is empty and reset status
379--echo # variables. Since to test cache overflow we will need to reduce
380--echo # its size, also save original table cache size.
381flush tables;
382flush status;
383set @old_table_open_cache= @@table_open_cache;
384
385--echo # Check that after reset all status variables are zero.
386show status like 'table_open_cache_%';
387
388--echo # The first statement accessing t1 after flush should result
389--echo # in table cache miss.
390select * from t1;
391show status like 'table_open_cache_%';
392
393--echo # The second statement accessing the same table should
394--echo # result in table cache hit.
395select * from t1;
396show status like 'table_open_cache_%';
397
398--echo # Again table cache miss if accessing different table.
399select * from t2;
400show status like 'table_open_cache_%';
401
402--echo # And cache hit then accessing it second time.
403select * from t2;
404show status like 'table_open_cache_%';
405
406--echo # The below statement should result in 2 cache hits and
407--echo # 4 cache misses since it needs 6 table instances in total.
408select * from t1 as a, t2 as b, t1 as c, t2 as d, t1 as e, t2 as f;
409show status like 'table_open_cache_%';
410
411--echo # Reduce size of table cache to check that status
412--echo # variable tracking cache overflows works.
413set @@global.table_open_cache= 4;
414
415--echo # The below statement should result in table cache hit, but
416--echo # as a side effect it should result in trimming of table
417--echo # cache by 2 TABLE instances, meaning that overflow counter
418--echo # will get increased by 2.
419select * from t1;
420show status like 'table_open_cache_%';
421
422--echo # This statement should result in 4 cache hits, 2 cache misses/
423--echo # overflows.
424select * from t1 as a, t2 as b, t1 as c, t2 as d, t1 as e, t2 as f;
425show status like 'table_open_cache_%';
426
427--echo # Finally, the below statement should result in 1 cache miss
428--echo # and 1 overflow since it accesses table which is not yet in
429--echo # cache and table cache is full.
430select * from t3;
431show status like 'table_open_cache_%';
432
433--echo # Cleanup
434set @@global.table_open_cache= @old_table_open_cache;
435drop tables t1, t2, t3;
436
437#
438# Bug#11766596: UPDATE A TIMESTAMP VARIABLE EVERY TIME REACHES MAX_USED_CONNECTIONS
439#
440
441connect (con1,localhost,root,,);
442--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*/DTVALUE/
443SHOW STATUS LIKE 'max_used_connections_time';
444--sleep 1
445connect (con2,localhost,root,,);
446--sleep 1
447connect (con3,localhost,root,,);
448
449--echo # Should report 4
450SHOW STATUS LIKE 'max_used_connections';
451
452let $time_1=`SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections_time'`;
453--sleep 1
454disconnect con2;
455let $time_2=`SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections_time'`;
456--sleep 1
457connect (con4,localhost,root,,);
458
459--echo # Should report 4
460SHOW STATUS LIKE 'max_used_connections';
461
462let $time_3=`SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections_time'`;
463
464--echo # This should report 0 as it must have the same value as above
465--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*/DTVALUE/
466--disable_query_log ONCE
467--eval SELECT TIMESTAMPDIFF(SECOND,'$time_1','$time_2') <> 0
468
469--echo # This should report 0 as timestamp is updated only when connection count strictly exceeds the previos highest value
470--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*/DTVALUE/
471--disable_query_log ONCE
472--eval SELECT TIMESTAMPDIFF(SECOND,'$time_1','$time_3') <> 0
473
474disconnect con1;
475disconnect con3;
476--sleep 1
477FLUSH STATUS;
478let $time_4=`SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections_time'`;
479
480--echo # This should not report 0 as FLUSH STATUS is called.
481--replace_regex /[0-9]*-[0-9]*-[0-9]* [0-9]*:[0-9]*:[0-9]*/DTVALUE/
482--disable_query_log ONCE
483--eval SELECT TIMESTAMPDIFF(SECOND,'$time_4','$time_3') <> 0
484
485disconnect con4;
486
487# Restore global concurrent_insert value. Keep in the end of the test file.
488--connection default
489set @@global.concurrent_insert= @old_concurrent_insert;
490SET GLOBAL log_output = @old_log_output;
491
492# Wait till we reached the initial number of concurrent sessions
493--source include/wait_until_count_sessions.inc
494
495