--source include/not_embedded.inc --source include/have_perfschema.inc UPDATE performance_schema.setup_instruments SET enabled = 'NO', timed = 'YES'; UPDATE performance_schema.setup_instruments SET enabled = 'YES' WHERE name in ('wait/io/table/sql/handler', 'wait/lock/table/sql/handler', 'wait/lock/metadata/sql/mdl'); set @orig_sql_mode= @@sql_mode; set sql_mode= (select replace(@@sql_mode,'NO_AUTO_CREATE_USER','')); grant ALL on *.* to user1@localhost; grant ALL on *.* to user2@localhost; set sql_mode= @orig_sql_mode; insert into performance_schema.setup_objects (object_type, object_schema, object_name, enabled, timed) values ('TABLE', 'mtr', '%', 'NO', 'NO'); --echo # Switch to (con1, localhost, user1, , ) connect (con1, localhost, user1, , ); let $user1_tid=`select THREAD_ID from performance_schema.threads where PROCESSLIST_ID=connection_id()`; --echo # Switch to (con2, localhost, user2, , ) connect (con2, localhost, user2, , ); let $user2_tid=`select THREAD_ID from performance_schema.threads where PROCESSLIST_ID=connection_id()`; --connection default --disable_query_log --eval set @user1_tid= $user1_tid; --eval set @user2_tid= $user2_tid; --enable_query_log --disable_warnings drop function if exists thread_id_name; --enable_warnings --delimiter // create function thread_id_name(THREAD_ID int) returns varchar(16) begin if (THREAD_ID IS NULL) then return NULL; end if; if (THREAD_ID = @user1_tid) then return "USER1"; end if; if (THREAD_ID = @user2_tid) then return "USER2"; end if; return "OTHER"; end; // delimiter ;// select thread_id_name(NULL); select thread_id_name(@user1_tid); select thread_id_name(@user2_tid); prepare dump_metadata_locks from "select OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, LOCK_TYPE, LOCK_DURATION, LOCK_STATUS, thread_id_name(OWNER_THREAD_ID) as OWNER_THREAD_ID from performance_schema.metadata_locks order by OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, LOCK_TYPE, LOCK_DURATION, LOCK_STATUS, OWNER_THREAD_ID;"; prepare dump_table_handles from "select OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, INTERNAL_LOCK, EXTERNAL_LOCK, thread_id_name(OWNER_THREAD_ID) as OWNER_THREAD_ID from performance_schema.table_handles order by OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, INTERNAL_LOCK, EXTERNAL_LOCK, OWNER_THREAD_ID;"; prepare dump_waits_current from "select thread_id_name(THREAD_ID) as THREAD_ID, EVENT_NAME, TIMER_START is not NULL as TIMER_START_SET, TIMER_END is not NULL as TIMER_END_SET, OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, INDEX_NAME, OPERATION from performance_schema.events_waits_current where event_name = \'wait/lock/metadata/sql/mdl\';"; prepare dump_waits_history_long from "select thread_id_name(THREAD_ID) as THREAD_ID, EVENT_NAME, TIMER_START is not NULL as TIMER_START_SET, TIMER_END is not NULL as TIMER_END_SET, OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, INDEX_NAME, OPERATION from performance_schema.events_waits_history_long where event_name = \'wait/lock/metadata/sql/mdl\';"; # reset lost counters truncate table performance_schema.events_statements_summary_by_digest; flush status; flush tables; --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT 'initial value'); INSERT INTO t1 (id) VALUES (1), (2), (3), (4), (5), (6), (7), (8); TRUNCATE TABLE performance_schema.events_waits_history_long; TRUNCATE TABLE performance_schema.events_waits_history; TRUNCATE TABLE performance_schema.events_waits_current; --connection con1 BEGIN; # MDL lock granted immediately, no wait. SELECT * from t1 where id=1; --connection default echo "---- Marker 1 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con1 # The MDL lock is now released COMMIT; --connection default echo "---- Marker 2 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con1 BEGIN; # MDL lock is granted immediately, no wait UPDATE t1 set b="new value" where id=2; --connection default echo "---- Marker 3 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con2 BEGIN; # MDL lock is PENDING : waiting for the update transaction --send DROP TABLE t1; --connection default # Wait for the DROP TABLE t1 to block let $wait_condition= select count(*) = 1 from performance_schema.events_waits_current where event_name = 'wait/lock/metadata/sql/mdl' and object_name = 't1'; --source include/wait_condition.inc echo "---- Marker 4 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con1 # MDL lock on the update is released, # MDL pending lock is granted for the drop table, then released. COMMIT; --connection con2 # complete DROP TABLE t1 --reap --connection default echo "---- Marker 5 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection default TRUNCATE TABLE performance_schema.events_waits_history_long; TRUNCATE TABLE performance_schema.events_waits_history; TRUNCATE TABLE performance_schema.events_waits_current; create table t1 (a int); --connection con1 # Get MDL read lock LOCK TABLE t1 READ; --connection default echo "---- Marker 6 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con2 # User1 has a READ LOCK # User2 waiting for WRITE LOCK --send LOCK TABLE t1 write; --connection default # Wait for the LOCK TABLE t1 write to block let $wait_condition= select count(*) = 1 from performance_schema.events_waits_current where event_name = 'wait/lock/metadata/sql/mdl' and object_name = 't1'; --source include/wait_condition.inc echo "---- Marker 7 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con1 # User1 releases a READ LOCK # User2 granted a WRITE LOCK UNLOCK TABLES; --connection con2 # Complete LOCK TABLE t1 write --reap --connection default echo "---- Marker 8 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con1 # User2 granted a WRITE LOCK # User1 waits for a READ LOCK --send LOCK TABLES t1 read; --connection default # Wait for the LOCK TABLES t1 READ to block let $wait_condition= select count(*) = 1 from performance_schema.events_waits_current where event_name = 'wait/lock/metadata/sql/mdl' and object_name = 't1'; --source include/wait_condition.inc echo "---- Marker 9 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con2 UNLOCK TABLES; --connection con1 # Complete LOCK TABLE t1 read --reap --connection default echo "---- Marker 10 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con1 UNLOCK TABLES; --connection default echo "---- Marker 11 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results TRUNCATE TABLE performance_schema.events_waits_history_long; TRUNCATE TABLE performance_schema.events_waits_history; TRUNCATE TABLE performance_schema.events_waits_current; --connection con1 BEGIN; # MDL lock is granted immediately, no wait UPDATE LOW_PRIORITY t1 SET a=8; --connection default echo "---- Marker 12 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con1 COMMIT; --connection default TRUNCATE TABLE performance_schema.events_waits_history_long; TRUNCATE TABLE performance_schema.events_waits_history; TRUNCATE TABLE performance_schema.events_waits_current; --connection con1 SELECT GET_LOCK('test', 0); --connection default echo "---- Marker 13 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con2 --send SELECT GET_LOCK('test', 120); --connection default let $wait_condition= select count(*) = 1 from performance_schema.events_waits_current where event_name = 'wait/lock/metadata/sql/mdl' and object_name = 'test'; --source include/wait_condition.inc echo "---- Marker 14 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con1 SELECT RELEASE_LOCK('test'); --connection con2 --reap --connection default echo "---- Marker 15 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results --connection con2 SELECT RELEASE_LOCK('test'); --connection default echo "---- Marker 16 ----"; --vertical_results execute dump_metadata_locks; execute dump_table_handles; execute dump_waits_current; execute dump_waits_history_long; --horizontal_results # Cleanup --disconnect con1 --disconnect con2 --connection default drop table t1; UPDATE performance_schema.setup_instruments SET enabled = 'YES', timed = 'YES'; revoke all privileges, grant option from user1@localhost; revoke all privileges, grant option from user2@localhost; drop user user1@localhost; drop user user2@localhost; drop function thread_id_name; drop prepare dump_metadata_locks; drop prepare dump_table_handles; drop prepare dump_waits_current; drop prepare dump_waits_history_long; delete from performance_schema.setup_objects where object_schema='mtr'; # In case of failure, will indicate the root cause show global status like "performance_schema%";