Commit e0743bd1 authored by Sergey Vojtovich's avatar Sergey Vojtovich

Let "FTWRL <table_list>" use extra(HA_EXTRA_FLUSH)

Rather than flushing caches with tdc_remove_table(TDC_RT_REMOVE_UNUSED)
flush them with extra(HA_EXTRA_FLUSH) instead. This goes inline with
regular FTWRL.

Part of MDEV-17882 - Cleanup refresh version
parent 0870b75a
......@@ -329,12 +329,9 @@ flush tables t1 with read lock;
handler t1 read a next;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables;
#
# Sic: lost handler position.
#
handler t1 read a next;
a
1
3
handler t1 close;
drop table t1;
#
......
......@@ -412,9 +412,6 @@ flush tables t1 with read lock;
--error ER_LOCK_OR_ACTIVE_TRANSACTION
handler t1 read a next;
unlock tables;
--echo #
--echo # Sic: lost handler position.
--echo #
handler t1 read a next;
handler t1 close;
drop table t1;
......
......@@ -2010,117 +2010,6 @@ connection deadlock_con1;
connection default;
# Reaping ALTER. It should succeed and not produce ER_LOCK_DEADLOCK.
drop table t1;
#
# Now, test for a situation in which deadlock involves waiting not
# only in MDL subsystem but also for TDC. Such deadlocks should be
# successfully detected. If possible, they should be resolved without
# resorting to ER_LOCK_DEADLOCK error.
#
create table t1(i int);
create table t2(j int);
#
# First, let us check how we handle a simple scenario involving
# waits in MDL and TDC.
#
set debug_sync= 'RESET';
connection deadlock_con1;
# Start a statement, which will acquire SR metadata lock on t1, open it
# and then stop, before trying to acquire SW lock on t2 and opening it.
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
# Sending:
select * from t1 where i in (select j from t2 for update);
connection deadlock_con2;
# Wait till the above SELECT stops.
set debug_sync='now WAIT_FOR parked';
# The below FLUSH TABLES WITH READ LOCK should acquire
# SNW locks on t1 and t2 and wait till SELECT closes t1.
# Sending:
flush tables t1, t2 with read lock;
connection deadlock_con3;
# Wait until FLUSH TABLES WITH t1, t2 READ LOCK starts waiting
# for SELECT to close t1.
# Resume SELECT, so it tries to acquire SW lock on t1 and blocks,
# creating a deadlock. This deadlock should be detected and resolved
# by backing-off SELECT. As a result FTWRL should be able to finish.
set debug_sync='now SIGNAL go';
connection deadlock_con2;
# Reap FLUSH TABLES WITH READ LOCK.
unlock tables;
connection deadlock_con1;
# Reap SELECT.
i
#
# The same scenario with a slightly different order of events
# which emphasizes that setting correct deadlock detector weights
# for flush waits is important.
#
set debug_sync= 'RESET';
connection deadlock_con2;
set debug_sync='flush_tables_with_read_lock_after_acquire_locks SIGNAL parked WAIT_FOR go';
# The below FLUSH TABLES WITH READ LOCK should acquire
# SNW locks on t1 and t2 and wait on debug sync point.
# Sending:
flush tables t1, t2 with read lock;
connection deadlock_con1;
# Wait till FLUSH TABLE WITH READ LOCK stops.
set debug_sync='now WAIT_FOR parked';
# Start statement which will acquire SR metadata lock on t1, open
# it and then will block while trying to acquire SW lock on t2.
# Sending:
select * from t1 where i in (select j from t2 for update);
connection deadlock_con3;
# Wait till the above SELECT blocks.
# Resume FLUSH TABLES, so it tries to flush t1, thus creating
# a deadlock. This deadlock should be detected and resolved by
# backing-off SELECT. As a result FTWRL should be able to finish.
set debug_sync='now SIGNAL go';
connection deadlock_con2;
# Reap FLUSH TABLES WITH READ LOCK.
unlock tables;
connection deadlock_con1;
# Reap SELECT.
i
#
# Now a more complex scenario involving two connections
# waiting for MDL and one for TDC.
#
set debug_sync= 'RESET';
connection deadlock_con1;
# Start a statement which will acquire SR metadata lock on t2, open it
# and then stop, before trying to acquire SR on t1 and opening it.
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
# Sending:
select * from t2, t1;
connection deadlock_con2;
# Wait till the above SELECT stops.
set debug_sync='now WAIT_FOR parked';
# The below FLUSH TABLES WITH READ LOCK should acquire
# SNW locks on t2 and wait till SELECT closes t2.
# Sending:
flush tables t2 with read lock;
connection deadlock_con3;
# Wait until FLUSH TABLES WITH READ LOCK starts waiting
# for SELECT to close t2.
# The below DROP TABLES should acquire X lock on t1 and start
# waiting for X lock on t2.
# Sending:
drop tables t1, t2;
connection default;
# Wait until DROP TABLES starts waiting for X lock on t2.
# Resume SELECT, so it tries to acquire SR lock on t1 and blocks,
# creating a deadlock. This deadlock should be detected and resolved
# by backing-off SELECT. As a result, FTWRL should be able to finish.
set debug_sync='now SIGNAL go';
connection deadlock_con2;
# Reap FLUSH TABLES WITH READ LOCK.
# Unblock DROP TABLES.
unlock tables;
connection deadlock_con3;
# Reap DROP TABLES.
connection deadlock_con1;
# Reap SELECT. It should emit error about missing table.
ERROR 42S02: Table 'test.t2' doesn't exist
connection default;
set debug_sync= 'RESET';
disconnect deadlock_con1;
disconnect deadlock_con2;
......
......@@ -2493,170 +2493,6 @@ connection default;
drop table t1;
--echo #
--echo # Now, test for a situation in which deadlock involves waiting not
--echo # only in MDL subsystem but also for TDC. Such deadlocks should be
--echo # successfully detected. If possible, they should be resolved without
--echo # resorting to ER_LOCK_DEADLOCK error.
--echo #
create table t1(i int);
create table t2(j int);
--echo #
--echo # First, let us check how we handle a simple scenario involving
--echo # waits in MDL and TDC.
--echo #
set debug_sync= 'RESET';
connection deadlock_con1;
--echo # Start a statement, which will acquire SR metadata lock on t1, open it
--echo # and then stop, before trying to acquire SW lock on t2 and opening it.
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
--echo # Sending:
--send select * from t1 where i in (select j from t2 for update)
connection deadlock_con2;
--echo # Wait till the above SELECT stops.
set debug_sync='now WAIT_FOR parked';
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
--echo # SNW locks on t1 and t2 and wait till SELECT closes t1.
--echo # Sending:
send flush tables t1, t2 with read lock;
connection deadlock_con3;
--echo # Wait until FLUSH TABLES WITH t1, t2 READ LOCK starts waiting
--echo # for SELECT to close t1.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table flush" and
info = "flush tables t1, t2 with read lock";
--source include/wait_condition.inc
--echo # Resume SELECT, so it tries to acquire SW lock on t1 and blocks,
--echo # creating a deadlock. This deadlock should be detected and resolved
--echo # by backing-off SELECT. As a result FTWRL should be able to finish.
set debug_sync='now SIGNAL go';
connection deadlock_con2;
--echo # Reap FLUSH TABLES WITH READ LOCK.
reap;
unlock tables;
connection deadlock_con1;
--echo # Reap SELECT.
reap;
--echo #
--echo # The same scenario with a slightly different order of events
--echo # which emphasizes that setting correct deadlock detector weights
--echo # for flush waits is important.
--echo #
set debug_sync= 'RESET';
connection deadlock_con2;
set debug_sync='flush_tables_with_read_lock_after_acquire_locks SIGNAL parked WAIT_FOR go';
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
--echo # SNW locks on t1 and t2 and wait on debug sync point.
--echo # Sending:
send flush tables t1, t2 with read lock;
connection deadlock_con1;
--echo # Wait till FLUSH TABLE WITH READ LOCK stops.
set debug_sync='now WAIT_FOR parked';
--echo # Start statement which will acquire SR metadata lock on t1, open
--echo # it and then will block while trying to acquire SW lock on t2.
--echo # Sending:
send select * from t1 where i in (select j from t2 for update);
connection deadlock_con3;
--echo # Wait till the above SELECT blocks.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table metadata lock" and
info = "select * from t1 where i in (select j from t2 for update)";
--source include/wait_condition.inc
--echo # Resume FLUSH TABLES, so it tries to flush t1, thus creating
--echo # a deadlock. This deadlock should be detected and resolved by
--echo # backing-off SELECT. As a result FTWRL should be able to finish.
set debug_sync='now SIGNAL go';
connection deadlock_con2;
--echo # Reap FLUSH TABLES WITH READ LOCK.
reap;
unlock tables;
connection deadlock_con1;
--echo # Reap SELECT.
reap;
--echo #
--echo # Now a more complex scenario involving two connections
--echo # waiting for MDL and one for TDC.
--echo #
set debug_sync= 'RESET';
connection deadlock_con1;
--echo # Start a statement which will acquire SR metadata lock on t2, open it
--echo # and then stop, before trying to acquire SR on t1 and opening it.
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
--echo # Sending:
send select * from t2, t1;
connection deadlock_con2;
--echo # Wait till the above SELECT stops.
set debug_sync='now WAIT_FOR parked';
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
--echo # SNW locks on t2 and wait till SELECT closes t2.
--echo # Sending:
send flush tables t2 with read lock;
connection deadlock_con3;
--echo # Wait until FLUSH TABLES WITH READ LOCK starts waiting
--echo # for SELECT to close t2.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table flush" and
info = "flush tables t2 with read lock";
--source include/wait_condition.inc
--echo # The below DROP TABLES should acquire X lock on t1 and start
--echo # waiting for X lock on t2.
--echo # Sending:
send drop tables t1, t2;
connection default;
--echo # Wait until DROP TABLES starts waiting for X lock on t2.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table metadata lock" and
info = "drop tables t1, t2";
--source include/wait_condition.inc
--echo # Resume SELECT, so it tries to acquire SR lock on t1 and blocks,
--echo # creating a deadlock. This deadlock should be detected and resolved
--echo # by backing-off SELECT. As a result, FTWRL should be able to finish.
set debug_sync='now SIGNAL go';
connection deadlock_con2;
--echo # Reap FLUSH TABLES WITH READ LOCK.
reap;
--echo # Unblock DROP TABLES.
unlock tables;
connection deadlock_con3;
--echo # Reap DROP TABLES.
reap;
connection deadlock_con1;
--echo # Reap SELECT. It should emit error about missing table.
--error ER_NO_SUCH_TABLE
reap;
connection default;
set debug_sync= 'RESET';
disconnect deadlock_con1;
......
......@@ -512,7 +512,6 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
{
Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
TABLE_LIST *table_list;
/*
This is called from SQLCOM_FLUSH, the transaction has
......@@ -545,16 +544,10 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
DEBUG_SYNC(thd,"flush_tables_with_read_lock_after_acquire_locks");
for (table_list= all_tables; table_list;
/* Reset ticket to satisfy asserts in open_tables(). */
for (auto table_list= all_tables; table_list;
table_list= table_list->next_global)
{
/* Request removal of table from cache. */
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
table_list->db.str,
table_list->table_name.str);
/* Reset ticket to satisfy asserts in open_tables(). */
table_list->mdl_request.ticket= NULL;
}
}
thd->variables.option_bits|= OPTION_TABLE_LOCK;
......@@ -589,6 +582,16 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
}
}
if (thd->lex->type & REFRESH_READ_LOCK)
{
for (auto table_list= all_tables; table_list;
table_list= table_list->next_global)
{
if (table_list->table->file->extra(HA_EXTRA_FLUSH))
goto error_reset_bits;
}
}
if (thd->locked_tables_list.init_locked_tables(thd))
goto error_reset_bits;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment