# Tests for PERFORMANCE_SCHEMA

--source include/not_embedded.inc
--source include/have_perfschema.inc

#
# Important note:
# this test is extremely sensitive to how threads are running inside the server,
# so it has it's own -master.opt file, to enforce it runs alone in mysqld
#

# Setup

flush status;
flush tables;

# Remove to debug
--disable_result_log

# Make sure the internal server caches are all full
select * from performance_schema.mutex_instances;
select * from performance_schema.rwlock_instances;
select * from performance_schema.cond_instances;
select * from performance_schema.file_instances;

select count(*) from performance_schema.mutex_instances
  into @v0_mutex_instances;

select count(*) from performance_schema.rwlock_instances
  into @v0_rwlock_instances;

select count(*) from performance_schema.cond_instances
  into @v0_cond_instances;

select count(*) from performance_schema.file_instances
  into @v0_file_instances;

select count(*) from performance_schema.mutex_instances
  into @v1_mutex_instances;

select count(*) from performance_schema.rwlock_instances
  into @v1_rwlock_instances;

select count(*) from performance_schema.cond_instances
  into @v1_cond_instances;

select count(*) from performance_schema.file_instances
  into @v1_file_instances;

select count(name), name from performance_schema.mutex_instances
  group by name;

select count(name), name from performance_schema.rwlock_instances
  group by name;

select count(name), name from performance_schema.cond_instances
  group by name;

select count(event_name), event_name from performance_schema.file_instances
  group by event_name;

begin;
create table test.t1(a int) engine = innodb;
create table test.t2(a int) engine = innodb;
create table test.t3(a int) engine = innodb;
create table test.t4(a int) engine = innodb;
create table test.t5(a int) engine = innodb;
create table test.t6(a int) engine = innodb;
create table test.t7(a int) engine = innodb;
create table test.t8(a int) engine = innodb;
create table test.t9(a int) engine = innodb;
create table test.t10(a int) engine = innodb;

# Make sure there is at least 1 table handle,
# to fully initialize the storage engine share if needed.
select * from test.t1;
select * from test.t2;
select * from test.t3;
select * from test.t4;
select * from test.t5;
select * from test.t6;
select * from test.t7;
select * from test.t8;
select * from test.t9;
select * from test.t10;
commit;

select count(*) from performance_schema.mutex_instances
  into @v2_mutex_instances;

select count(*) from performance_schema.rwlock_instances
  into @v2_rwlock_instances;

select count(*) from performance_schema.cond_instances
  into @v2_cond_instances;

select count(*) from performance_schema.file_instances
  into @v2_file_instances;

select count(name), name from performance_schema.mutex_instances
  group by name;

select count(name), name from performance_schema.rwlock_instances
  group by name;

select count(name), name from performance_schema.cond_instances
  group by name;

select count(event_name), event_name from performance_schema.file_instances
  group by event_name;

select @v2_mutex_instances, @v1_mutex_instances, @v0_mutex_instances;
select @v2_rwlock_instances, @v1_rwlock_instances, @v0_rwlock_instances;
select @v2_cond_instances, @v1_cond_instances, @v0_cond_instances;
select @v2_file_instances, @v1_file_instances, @v0_file_instances;

select round((@v2_mutex_instances - @v1_mutex_instances) / 10)
  into @mutex_per_share;
select round((@v2_rwlock_instances - @v1_rwlock_instances) / 10)
  into @rwlock_per_share;
select round((@v2_cond_instances - @v1_cond_instances) / 10)
  into @cond_per_share;
select round((@v2_file_instances - @v1_file_instances) / 10)
  into @file_per_share;

connect (con1, localhost, root,,);
select "con1 connected";

connect (con2, localhost, root,,);
select "con2 connected";

connect (con3, localhost, root,,);
select "con3 connected";

connect (con4, localhost, root,,);
select "con4 connected";

connect (con5, localhost, root,,);
select "con5 connected";

connect (con6, localhost, root,,);
select "con6 connected";

connect (con7, localhost, root,,);
select "con7 connected";

connect (con8, localhost, root,,);
select "con8 connected";

connect (con9, localhost, root,,);
select "con9 connected";

connect (con10, localhost, root,,);
select "con10 connected";

connection default;

select count(*) from performance_schema.mutex_instances
  into @v3_mutex_instances;

select count(*) from performance_schema.rwlock_instances
  into @v3_rwlock_instances;

select count(*) from performance_schema.cond_instances
  into @v3_cond_instances;

select count(*) from performance_schema.file_instances
  into @v3_file_instances;

select count(name), name from performance_schema.mutex_instances
  group by name;

select count(name), name from performance_schema.rwlock_instances
  group by name;

select count(name), name from performance_schema.cond_instances
  group by name;

select count(event_name), event_name from performance_schema.file_instances
  group by event_name;

select @v3_mutex_instances, @v2_mutex_instances;
select @v3_rwlock_instances, @v2_rwlock_instances;
select @v3_cond_instances, @v2_cond_instances;
select @v3_file_instances, @v2_file_instances;

select round((@v3_mutex_instances - @v2_mutex_instances) / 10)
  into @mutex_per_con;
select round((@v3_rwlock_instances - @v2_rwlock_instances) / 10)
  into @rwlock_per_con;
select round((@v3_cond_instances - @v2_cond_instances) / 10)
  into @cond_per_con;
select round((@v3_file_instances - @v2_file_instances) / 10)
  into @file_per_con;

--connection con1

lock table test.t1 write, test.t2 write, test.t3 write, test.t4 write,
test.t5 write, test.t6 write, test.t7 write, test.t8 write, test.t9 write,
test.t10 write;

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con2

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con3

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con4

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con5

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con6

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con7

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con8

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con9

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

--connection con10

--send
select t1.*, t2.*, t3.*, t4.*, t5.*, t6.*, t7.*, t8.*, t9.*, t10.*
  from t1, t2, t3, t4, t5, t6, t7, t8, t9, t10;

connection default;

select count(*) from performance_schema.mutex_instances
  into @v4_mutex_instances;

select count(*) from performance_schema.rwlock_instances
  into @v4_rwlock_instances;

select count(*) from performance_schema.cond_instances
  into @v4_cond_instances;

select count(*) from performance_schema.file_instances
  into @v4_file_instances;

select count(name), name from performance_schema.mutex_instances
  group by name;

select count(name), name from performance_schema.rwlock_instances
  group by name;

select count(name), name from performance_schema.cond_instances
  group by name;

select count(event_name), event_name from performance_schema.file_instances
  group by event_name;

select @v4_mutex_instances, @v3_mutex_instances;
select @v4_rwlock_instances, @v3_rwlock_instances;
select @v4_cond_instances, @v3_cond_instances;
select @v4_file_instances, @v3_file_instances;

select round((@v4_mutex_instances - @v3_mutex_instances) / 10)
  into @mutex_per_handle;
select round((@v4_rwlock_instances - @v3_rwlock_instances) / 10)
  into @rwlock_per_handle;
select round((@v4_cond_instances - @v3_cond_instances) / 10)
  into @cond_per_handle;
select round((@v4_file_instances - @v3_file_instances) / 10)
  into @file_per_handle;

--connection con1
--reap

unlock tables;

--connection con2
--reap

--connection con3
--reap

--connection con4
--reap

--connection con5
--reap

--connection con6
--reap

--connection con7
--reap

--connection con8
--reap

--connection con9
--reap

--connection con10
--reap

--disconnect con1
--disconnect con2
--disconnect con3
--disconnect con4
--disconnect con5
--disconnect con6
--disconnect con7
--disconnect con8
--disconnect con9
--disconnect con10

--connection default

drop table test.t1;
drop table test.t2;
drop table test.t3;
drop table test.t4;
drop table test.t5;
drop table test.t6;
drop table test.t7;
drop table test.t8;
drop table test.t9;
drop table test.t10;

--enable_result_log

#
# This test must have *_lost = 0,
# otherwise the measurement is just wrong.
#

show status like "performance_schema%";

#
# Expecting 2:
# - wait/synch/mutex/sql/MDL_wait::LOCK_wait_status
# - wait/synch/mutex/sql/TABLE_SHARE::LOCK_ha_data
# plus mutexes used inside the storage engine
# This is very storage engine dependent
# For innodb:
# - wait/synch/mutex/innodb/autoinc_mutex
# - wait/synch/mutex/innodb/os_mutex
# Note that depending on the platform,
# and the version of the compiler used,
# code in the server may use either native platform atomics
# or a mutex.
# Note also that in DEBUG builds, code uses more mutexes.
# Because of all these parameters,
# this test is disabled, as predicting an exact number is difficult.
# 
# commented: select @mutex_per_share <= 5;

#
# Expecting 1:
# - wait/synch/rwlock/sql/MDL_lock::rwlock
# plus rwlocks used inside the storage engine
# This is very storage engine dependent
#
select @rwlock_per_share <= 3;

#
# Expecting 0:
#
select @cond_per_share;

#
# Expecting 1:
# - wait/io/file/sql/FRM
# plus files used inside the storage engine
# This is very storage engine dependent
#
select @file_per_share <= 3;

#
# Expecting 3:
# - wait/synch/mutex/mysys/my_thread_var::mutex
# - wait/synch/mutex/mysys/THR_LOCK::mutex
# - wait/synch/mutex/sql/THD::LOCK_thd_data
#
select @mutex_per_con;

#
# Expecting 1:
# - wait/synch/rwlock/sql/MDL_context::LOCK_waiting_for
#
select @rwlock_per_con;

#
# Expecting 2:
# - wait/synch/cond/mysys/my_thread_var::suspend
# - wait/synch/cond/sql/MDL_context::COND_wait_status
#
select @cond_per_con;

#
# Expecting 0:
#
select @file_per_con;

#
# Expecting 0:
#
select @mutex_per_handle;

#
# Expecting 0:
#
select @rwlock_per_handle;

#
# Expecting 0:
#
select @cond_per_handle;

#
# Expecting 0:
#
select @file_per_handle;

#
# IMPORTANT NOTE:
# when any measurement here changes, the heuristics
# in storage/perfschema/pfs_autosize.cc need to be updated.
# Note that this in turns will lead to different estimations for automated
# sizing, and imply to update the results for sizing_*.
#

# commented: (@mutex_per_share <= 5)
# Mutexes are not instrumented by default,
# not enforcing mutex estimates

select if(
      (@rwlock_per_share <= 3)
  AND (@cond_per_share = 0)
  AND (@file_per_share <= 3)
  AND (@mutex_per_con = 3)
  AND (@rwlock_per_con = 1)
  AND (@cond_per_con = 2)
  AND (@file_per_con = 0)
  AND (@mutex_per_handle = 0)
  AND (@rwlock_per_handle = 0)
  AND (@cond_per_handle = 0)
  AND (@file_per_handle = 0),
  "OK: heuristics are up to date",
  "FAILED: heuristics need to be updated")
  as status;

