1--source include/have_debug_sync.inc 2--source include/have_gtid.inc 3 4# Save the initial number of concurrent sessions 5--source include/count_sessions.inc 6 7--echo # 8--echo # BUG#21463167 - GTIDS: LOCK_OPEN DEADLOCK WITH REVOKE INCIDENT + 9--echo # SHOW TABLE STATUS CONCURRENTLY 10--echo # 11 12CREATE USER u1; 13CREATE TABLE t1(a INT); 14CREATE VIEW v1 AS SELECT * FROM t1; 15 16CALL mtr.add_suppression("REVOKE failed while revoking all_privileges from a list of users."); 17 18--enable_connect_log 19 20--connect (con1, localhost, root,,) 21# Set force_mysql_revoke_all_fail in order to simulate partial execution failure 22# in mysql_revoke_all(). In this case execution flow go to the 'if' branch where 23# mysql_bin_log.write_incident is called. 24SET debug="+d,force_mysql_revoke_all_fail"; 25# When the sync point revoke_all_before_write_incident_to_binlog 26# will be hit a write lock for LOCK_grant has already been acquired 27# in mysql_revoke_all() and we are waiting for the signal revoke_all_cont 28# be emitted to go inside mysql_bin_log.write_incident() where LOCK_open 29# will be acquired. 30SET DEBUG_SYNC='revoke_all_before_write_incident_to_binlog SIGNAL revoke_all_has_lock_grant WAIT_FOR revoke_all_cont'; 31 32--connection default 33# Set the debug variable force_check_table_access_return_ok 34# in order to avoid calling of check_grant as part of handling 35# the statement SET DEBUG_SYNC="....". If we didn't do so we would be suspended on 36# waiting for LOCK_grant be released that had been acquired on handling REVOKE ALL. 37SET debug="+d,force_check_table_access_return_ok"; 38 39--connection con1 40# Processing of the following REVOKE ALL will be suspended on 41# the sync point revoke_all_before_write_incident_to_binlog waiting until 42# the signal revoke_all_cont be emitted. While suspending it holds 43# the lock LOCK_grant on write. 44--echo # Sending REVOKE ALL PRIVILEGES 45--send REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'u1'@'%' 46 47--connection default 48# In the default connection we are waiting until processing of the statement 49# REVOKE ALL PRIVILEGES hit the sync point revoke_all_before_write_incident_to_binlog. 50# When this happen the connection con1 holds LOCK_grant on write. 51SET DEBUG_SYNC='now WAIT_FOR revoke_all_has_lock_grant'; 52 53# When processing the statement SHOW TABLE STATUS we will hit the sync point 54# fill_effective_table_privileges that will emit signal revoke_all_cont. 55# At this point we know that REVOKE ALL PRIVILEGES has already acquired LOCK_grant. 56# Waken up thread that is handling REVOKE ALL PRIVILEGES will try to acquire 57# LOCK_open while executing mysql_bin_log.write_incident(). 58SET DEBUG_SYNC='fill_effective_table_privileges SIGNAL revoke_all_cont'; 59 60--replace_column 12 x 61# When there is a view while handling SHOW TABLE STATUS the function mysql_make_view() 62# is called from open_table(). LOCK_open has been acquired within open_table before calling 63# mysql_make_view and when we are trying to lock LOCK_grant on read from 64# revoke_all_before_write_incident_to_binlog we would get a deadlock without the patch. 65SHOW TABLE STATUS; 66 67--connection con1 68# Get execution result of REVOKE ALL PRIVILEGES. 69# We expect the error ER_REVOKE_GRANTS since the debug variable force_mysql_revoke_all_fail 70# was set to simulate failure of REVOKE ALL PRIVILEGES 71--echo # Reaping REVOKE ALL PRIVILEGES 72--error ER_REVOKE_GRANTS 73--reap 74 75--connection default 76--disconnect con1 77DROP USER u1; 78DROP VIEW v1; 79DROP TABLE t1; 80# Wait till we reached the initial number of concurrent sessions 81--source include/wait_until_count_sessions.inc 82--disable_connect_log 83 84SET debug=''; 85 86