Skip to content

Commit e0743bd

Browse files
committed
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
1 parent 0870b75 commit e0743bd

File tree

5 files changed

+13
-291
lines changed

5 files changed

+13
-291
lines changed

mysql-test/main/flush.result

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,12 +329,9 @@ flush tables t1 with read lock;
329329
handler t1 read a next;
330330
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
331331
unlock tables;
332-
#
333-
# Sic: lost handler position.
334-
#
335332
handler t1 read a next;
336333
a
337-
1
334+
3
338335
handler t1 close;
339336
drop table t1;
340337
#

mysql-test/main/flush.test

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,6 @@ flush tables t1 with read lock;
412412
--error ER_LOCK_OR_ACTIVE_TRANSACTION
413413
handler t1 read a next;
414414
unlock tables;
415-
--echo #
416-
--echo # Sic: lost handler position.
417-
--echo #
418415
handler t1 read a next;
419416
handler t1 close;
420417
drop table t1;

mysql-test/main/mdl_sync.result

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,117 +2010,6 @@ connection deadlock_con1;
20102010
connection default;
20112011
# Reaping ALTER. It should succeed and not produce ER_LOCK_DEADLOCK.
20122012
drop table t1;
2013-
#
2014-
# Now, test for a situation in which deadlock involves waiting not
2015-
# only in MDL subsystem but also for TDC. Such deadlocks should be
2016-
# successfully detected. If possible, they should be resolved without
2017-
# resorting to ER_LOCK_DEADLOCK error.
2018-
#
2019-
create table t1(i int);
2020-
create table t2(j int);
2021-
#
2022-
# First, let us check how we handle a simple scenario involving
2023-
# waits in MDL and TDC.
2024-
#
2025-
set debug_sync= 'RESET';
2026-
connection deadlock_con1;
2027-
# Start a statement, which will acquire SR metadata lock on t1, open it
2028-
# and then stop, before trying to acquire SW lock on t2 and opening it.
2029-
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
2030-
# Sending:
2031-
select * from t1 where i in (select j from t2 for update);
2032-
connection deadlock_con2;
2033-
# Wait till the above SELECT stops.
2034-
set debug_sync='now WAIT_FOR parked';
2035-
# The below FLUSH TABLES WITH READ LOCK should acquire
2036-
# SNW locks on t1 and t2 and wait till SELECT closes t1.
2037-
# Sending:
2038-
flush tables t1, t2 with read lock;
2039-
connection deadlock_con3;
2040-
# Wait until FLUSH TABLES WITH t1, t2 READ LOCK starts waiting
2041-
# for SELECT to close t1.
2042-
# Resume SELECT, so it tries to acquire SW lock on t1 and blocks,
2043-
# creating a deadlock. This deadlock should be detected and resolved
2044-
# by backing-off SELECT. As a result FTWRL should be able to finish.
2045-
set debug_sync='now SIGNAL go';
2046-
connection deadlock_con2;
2047-
# Reap FLUSH TABLES WITH READ LOCK.
2048-
unlock tables;
2049-
connection deadlock_con1;
2050-
# Reap SELECT.
2051-
i
2052-
#
2053-
# The same scenario with a slightly different order of events
2054-
# which emphasizes that setting correct deadlock detector weights
2055-
# for flush waits is important.
2056-
#
2057-
set debug_sync= 'RESET';
2058-
connection deadlock_con2;
2059-
set debug_sync='flush_tables_with_read_lock_after_acquire_locks SIGNAL parked WAIT_FOR go';
2060-
# The below FLUSH TABLES WITH READ LOCK should acquire
2061-
# SNW locks on t1 and t2 and wait on debug sync point.
2062-
# Sending:
2063-
flush tables t1, t2 with read lock;
2064-
connection deadlock_con1;
2065-
# Wait till FLUSH TABLE WITH READ LOCK stops.
2066-
set debug_sync='now WAIT_FOR parked';
2067-
# Start statement which will acquire SR metadata lock on t1, open
2068-
# it and then will block while trying to acquire SW lock on t2.
2069-
# Sending:
2070-
select * from t1 where i in (select j from t2 for update);
2071-
connection deadlock_con3;
2072-
# Wait till the above SELECT blocks.
2073-
# Resume FLUSH TABLES, so it tries to flush t1, thus creating
2074-
# a deadlock. This deadlock should be detected and resolved by
2075-
# backing-off SELECT. As a result FTWRL should be able to finish.
2076-
set debug_sync='now SIGNAL go';
2077-
connection deadlock_con2;
2078-
# Reap FLUSH TABLES WITH READ LOCK.
2079-
unlock tables;
2080-
connection deadlock_con1;
2081-
# Reap SELECT.
2082-
i
2083-
#
2084-
# Now a more complex scenario involving two connections
2085-
# waiting for MDL and one for TDC.
2086-
#
2087-
set debug_sync= 'RESET';
2088-
connection deadlock_con1;
2089-
# Start a statement which will acquire SR metadata lock on t2, open it
2090-
# and then stop, before trying to acquire SR on t1 and opening it.
2091-
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
2092-
# Sending:
2093-
select * from t2, t1;
2094-
connection deadlock_con2;
2095-
# Wait till the above SELECT stops.
2096-
set debug_sync='now WAIT_FOR parked';
2097-
# The below FLUSH TABLES WITH READ LOCK should acquire
2098-
# SNW locks on t2 and wait till SELECT closes t2.
2099-
# Sending:
2100-
flush tables t2 with read lock;
2101-
connection deadlock_con3;
2102-
# Wait until FLUSH TABLES WITH READ LOCK starts waiting
2103-
# for SELECT to close t2.
2104-
# The below DROP TABLES should acquire X lock on t1 and start
2105-
# waiting for X lock on t2.
2106-
# Sending:
2107-
drop tables t1, t2;
2108-
connection default;
2109-
# Wait until DROP TABLES starts waiting for X lock on t2.
2110-
# Resume SELECT, so it tries to acquire SR lock on t1 and blocks,
2111-
# creating a deadlock. This deadlock should be detected and resolved
2112-
# by backing-off SELECT. As a result, FTWRL should be able to finish.
2113-
set debug_sync='now SIGNAL go';
2114-
connection deadlock_con2;
2115-
# Reap FLUSH TABLES WITH READ LOCK.
2116-
# Unblock DROP TABLES.
2117-
unlock tables;
2118-
connection deadlock_con3;
2119-
# Reap DROP TABLES.
2120-
connection deadlock_con1;
2121-
# Reap SELECT. It should emit error about missing table.
2122-
ERROR 42S02: Table 'test.t2' doesn't exist
2123-
connection default;
21242013
set debug_sync= 'RESET';
21252014
disconnect deadlock_con1;
21262015
disconnect deadlock_con2;

mysql-test/main/mdl_sync.test

Lines changed: 0 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,170 +2493,6 @@ connection default;
24932493

24942494
drop table t1;
24952495

2496-
--echo #
2497-
--echo # Now, test for a situation in which deadlock involves waiting not
2498-
--echo # only in MDL subsystem but also for TDC. Such deadlocks should be
2499-
--echo # successfully detected. If possible, they should be resolved without
2500-
--echo # resorting to ER_LOCK_DEADLOCK error.
2501-
--echo #
2502-
create table t1(i int);
2503-
create table t2(j int);
2504-
2505-
--echo #
2506-
--echo # First, let us check how we handle a simple scenario involving
2507-
--echo # waits in MDL and TDC.
2508-
--echo #
2509-
set debug_sync= 'RESET';
2510-
2511-
connection deadlock_con1;
2512-
--echo # Start a statement, which will acquire SR metadata lock on t1, open it
2513-
--echo # and then stop, before trying to acquire SW lock on t2 and opening it.
2514-
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
2515-
--echo # Sending:
2516-
--send select * from t1 where i in (select j from t2 for update)
2517-
2518-
connection deadlock_con2;
2519-
--echo # Wait till the above SELECT stops.
2520-
set debug_sync='now WAIT_FOR parked';
2521-
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
2522-
--echo # SNW locks on t1 and t2 and wait till SELECT closes t1.
2523-
--echo # Sending:
2524-
send flush tables t1, t2 with read lock;
2525-
2526-
connection deadlock_con3;
2527-
--echo # Wait until FLUSH TABLES WITH t1, t2 READ LOCK starts waiting
2528-
--echo # for SELECT to close t1.
2529-
let $wait_condition=
2530-
select count(*) = 1 from information_schema.processlist
2531-
where state = "Waiting for table flush" and
2532-
info = "flush tables t1, t2 with read lock";
2533-
--source include/wait_condition.inc
2534-
2535-
--echo # Resume SELECT, so it tries to acquire SW lock on t1 and blocks,
2536-
--echo # creating a deadlock. This deadlock should be detected and resolved
2537-
--echo # by backing-off SELECT. As a result FTWRL should be able to finish.
2538-
set debug_sync='now SIGNAL go';
2539-
2540-
connection deadlock_con2;
2541-
--echo # Reap FLUSH TABLES WITH READ LOCK.
2542-
reap;
2543-
unlock tables;
2544-
2545-
connection deadlock_con1;
2546-
--echo # Reap SELECT.
2547-
reap;
2548-
2549-
--echo #
2550-
--echo # The same scenario with a slightly different order of events
2551-
--echo # which emphasizes that setting correct deadlock detector weights
2552-
--echo # for flush waits is important.
2553-
--echo #
2554-
set debug_sync= 'RESET';
2555-
2556-
connection deadlock_con2;
2557-
set debug_sync='flush_tables_with_read_lock_after_acquire_locks SIGNAL parked WAIT_FOR go';
2558-
2559-
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
2560-
--echo # SNW locks on t1 and t2 and wait on debug sync point.
2561-
--echo # Sending:
2562-
send flush tables t1, t2 with read lock;
2563-
2564-
connection deadlock_con1;
2565-
--echo # Wait till FLUSH TABLE WITH READ LOCK stops.
2566-
set debug_sync='now WAIT_FOR parked';
2567-
2568-
--echo # Start statement which will acquire SR metadata lock on t1, open
2569-
--echo # it and then will block while trying to acquire SW lock on t2.
2570-
--echo # Sending:
2571-
send select * from t1 where i in (select j from t2 for update);
2572-
2573-
connection deadlock_con3;
2574-
--echo # Wait till the above SELECT blocks.
2575-
let $wait_condition=
2576-
select count(*) = 1 from information_schema.processlist
2577-
where state = "Waiting for table metadata lock" and
2578-
info = "select * from t1 where i in (select j from t2 for update)";
2579-
--source include/wait_condition.inc
2580-
2581-
--echo # Resume FLUSH TABLES, so it tries to flush t1, thus creating
2582-
--echo # a deadlock. This deadlock should be detected and resolved by
2583-
--echo # backing-off SELECT. As a result FTWRL should be able to finish.
2584-
set debug_sync='now SIGNAL go';
2585-
2586-
connection deadlock_con2;
2587-
--echo # Reap FLUSH TABLES WITH READ LOCK.
2588-
reap;
2589-
unlock tables;
2590-
2591-
connection deadlock_con1;
2592-
--echo # Reap SELECT.
2593-
reap;
2594-
2595-
--echo #
2596-
--echo # Now a more complex scenario involving two connections
2597-
--echo # waiting for MDL and one for TDC.
2598-
--echo #
2599-
set debug_sync= 'RESET';
2600-
2601-
connection deadlock_con1;
2602-
--echo # Start a statement which will acquire SR metadata lock on t2, open it
2603-
--echo # and then stop, before trying to acquire SR on t1 and opening it.
2604-
set debug_sync='open_tables_after_open_and_process_table SIGNAL parked WAIT_FOR go';
2605-
--echo # Sending:
2606-
send select * from t2, t1;
2607-
2608-
connection deadlock_con2;
2609-
--echo # Wait till the above SELECT stops.
2610-
set debug_sync='now WAIT_FOR parked';
2611-
--echo # The below FLUSH TABLES WITH READ LOCK should acquire
2612-
--echo # SNW locks on t2 and wait till SELECT closes t2.
2613-
--echo # Sending:
2614-
send flush tables t2 with read lock;
2615-
2616-
connection deadlock_con3;
2617-
--echo # Wait until FLUSH TABLES WITH READ LOCK starts waiting
2618-
--echo # for SELECT to close t2.
2619-
let $wait_condition=
2620-
select count(*) = 1 from information_schema.processlist
2621-
where state = "Waiting for table flush" and
2622-
info = "flush tables t2 with read lock";
2623-
--source include/wait_condition.inc
2624-
2625-
--echo # The below DROP TABLES should acquire X lock on t1 and start
2626-
--echo # waiting for X lock on t2.
2627-
--echo # Sending:
2628-
send drop tables t1, t2;
2629-
2630-
connection default;
2631-
--echo # Wait until DROP TABLES starts waiting for X lock on t2.
2632-
let $wait_condition=
2633-
select count(*) = 1 from information_schema.processlist
2634-
where state = "Waiting for table metadata lock" and
2635-
info = "drop tables t1, t2";
2636-
--source include/wait_condition.inc
2637-
2638-
--echo # Resume SELECT, so it tries to acquire SR lock on t1 and blocks,
2639-
--echo # creating a deadlock. This deadlock should be detected and resolved
2640-
--echo # by backing-off SELECT. As a result, FTWRL should be able to finish.
2641-
set debug_sync='now SIGNAL go';
2642-
2643-
connection deadlock_con2;
2644-
--echo # Reap FLUSH TABLES WITH READ LOCK.
2645-
reap;
2646-
--echo # Unblock DROP TABLES.
2647-
unlock tables;
2648-
2649-
connection deadlock_con3;
2650-
--echo # Reap DROP TABLES.
2651-
reap;
2652-
2653-
connection deadlock_con1;
2654-
--echo # Reap SELECT. It should emit error about missing table.
2655-
--error ER_NO_SUCH_TABLE
2656-
reap;
2657-
2658-
connection default;
2659-
26602496
set debug_sync= 'RESET';
26612497

26622498
disconnect deadlock_con1;

sql/sql_reload.cc

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,6 @@ bool reload_acl_and_cache(THD *thd, unsigned long long options,
512512
bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
513513
{
514514
Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
515-
TABLE_LIST *table_list;
516515

517516
/*
518517
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)
545544

546545
DEBUG_SYNC(thd,"flush_tables_with_read_lock_after_acquire_locks");
547546

548-
for (table_list= all_tables; table_list;
547+
/* Reset ticket to satisfy asserts in open_tables(). */
548+
for (auto table_list= all_tables; table_list;
549549
table_list= table_list->next_global)
550-
{
551-
/* Request removal of table from cache. */
552-
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED,
553-
table_list->db.str,
554-
table_list->table_name.str);
555-
/* Reset ticket to satisfy asserts in open_tables(). */
556550
table_list->mdl_request.ticket= NULL;
557-
}
558551
}
559552

560553
thd->variables.option_bits|= OPTION_TABLE_LOCK;
@@ -589,6 +582,16 @@ bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
589582
}
590583
}
591584

585+
if (thd->lex->type & REFRESH_READ_LOCK)
586+
{
587+
for (auto table_list= all_tables; table_list;
588+
table_list= table_list->next_global)
589+
{
590+
if (table_list->table->file->extra(HA_EXTRA_FLUSH))
591+
goto error_reset_bits;
592+
}
593+
}
594+
592595
if (thd->locked_tables_list.init_locked_tables(thd))
593596
goto error_reset_bits;
594597

0 commit comments

Comments
 (0)