Skip to content

Commit 93f5d40

Browse files
committed
Fixed debug_sync timeout in deadlock_drop_table
The issue was that we sent two different signals to different threads after each other. The DEBUG_SYNC functionality cannot handle this (as the signal is stored in a global variable) and the first one can get lost. Fixed by using the same signal for both threads.
1 parent 15e1fbc commit 93f5d40

File tree

6 files changed

+30
-6
lines changed

6 files changed

+30
-6
lines changed

mysql-test/suite/mariabackup/deadlock_drop_table.result renamed to mysql-test/suite/stress/r/deadlock_drop_table.result

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,11 @@ a b c
1919
1 NULL NULL
2020
set debug_sync='now SIGNAL go';
2121
set debug_sync='now WAIT_FOR parked2';
22-
set debug_sync='before_wait_for_refs SIGNAL waiting WAIT_FOR go3';
22+
set debug_sync='before_wait_for_refs SIGNAL waiting WAIT_FOR go2';
2323
drop table t1;;
2424
connection con2;
2525
set debug_sync='now WAIT_FOR waiting';
2626
set debug_sync='now SIGNAL go2';
27-
set debug_sync='now SIGNAL go3';
2827
connection default;
2928
connection con1;
3029
connection default;

mysql-test/suite/mariabackup/deadlock_drop_table.test renamed to mysql-test/suite/stress/t/deadlock_drop_table.test

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ set debug_sync='now WAIT_FOR parked';
1919
select * from t1;
2020
set debug_sync='now SIGNAL go';
2121
set debug_sync='now WAIT_FOR parked2';
22-
set debug_sync='before_wait_for_refs SIGNAL waiting WAIT_FOR go3';
22+
set debug_sync='before_wait_for_refs SIGNAL waiting WAIT_FOR go2';
2323
--send drop table t1;
2424
--connection con2
2525
set debug_sync='now WAIT_FOR waiting';
2626
set debug_sync='now SIGNAL go2';
27-
set debug_sync='now SIGNAL go3';
27+
28+
# Write out show processlist if the debug sync point times out
29+
let $wait_condition= select count(*)=0 from information_schema.processlist where state like "%debug%";
30+
source include/wait_condition.inc;
31+
2832
--connection default
2933
--reap
3034
--connection con1

sql/backup.cc

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,16 +258,19 @@ static bool backup_flush(THD *thd)
258258

259259
static bool backup_block_ddl(THD *thd)
260260
{
261+
PSI_stage_info org_stage;
261262
DBUG_ENTER("backup_block_ddl");
262263

263264
kill_delayed_threads();
264265
mysql_ha_cleanup_no_free(thd);
265266

267+
thd->backup_stage(&org_stage);
268+
THD_STAGE_INFO(thd, stage_waiting_for_flush);
266269
/* Wait until all non trans statements has ended */
267270
if (thd->mdl_context.upgrade_shared_lock(backup_flush_ticket,
268271
MDL_BACKUP_WAIT_FLUSH,
269272
thd->variables.lock_wait_timeout))
270-
DBUG_RETURN(1);
273+
goto err;
271274

272275
/*
273276
Remove not used tables from the table share. Flush all changes to
@@ -284,6 +287,7 @@ static bool backup_block_ddl(THD *thd)
284287
We didn't do this lock above, as we wanted DDL's to be executed while
285288
we wait for non transactional tables (which may take a while).
286289
*/
290+
THD_STAGE_INFO(thd, stage_waiting_for_ddl);
287291
if (thd->mdl_context.upgrade_shared_lock(backup_flush_ticket,
288292
MDL_BACKUP_WAIT_DDL,
289293
thd->variables.lock_wait_timeout))
@@ -293,12 +297,16 @@ static bool backup_block_ddl(THD *thd)
293297
was called so that this function can be called again
294298
*/
295299
backup_flush_ticket->downgrade_lock(MDL_BACKUP_FLUSH);
296-
DBUG_RETURN(1);
300+
goto err;
297301
}
298302

299303
/* There can't be anything more that needs to be logged to ddl log */
304+
THD_STAGE_INFO(thd, org_stage);
300305
stop_ddl_logging();
301306
DBUG_RETURN(0);
307+
err:
308+
THD_STAGE_INFO(thd, org_stage);
309+
DBUG_RETURN(1);
302310
}
303311

304312

sql/debug_sync.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -995,6 +995,15 @@ static char *debug_sync_number(ulong *number_p, char *actstrptr,
995995
The input string needs to be ASCII NUL ('\0') terminated. We split
996996
nul-terminated tokens in it without copy.
997997
998+
@note
999+
The current implementation does not support two 'now SIGNAL xxx' commands
1000+
in a row for multiple threads as the first one can get lost while
1001+
the waiting threads are sleeping on mysql_cond_timedwait().
1002+
One reason for this is that the signal name is stored in a global variable
1003+
that is overwritten. A better way would be to store all signals in
1004+
an array together with a 'time' when the signal was sent. This array
1005+
should be checked on broadcast.
1006+
9981007
@see the function comment of debug_sync_token() for more constraints
9991008
for the string.
10001009
*/

sql/mysqld.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9146,6 +9146,8 @@ PSI_stage_info stage_slave_background_process_request= { 0, "Processing requests
91469146
PSI_stage_info stage_slave_background_wait_request= { 0, "Waiting for requests", 0};
91479147
PSI_stage_info stage_waiting_for_deadlock_kill= { 0, "Waiting for parallel replication deadlock handling to complete", 0};
91489148
PSI_stage_info stage_starting= { 0, "starting", 0};
9149+
PSI_stage_info stage_waiting_for_flush= { 0, "Waiting for non trans tables to be flushed", 0};
9150+
PSI_stage_info stage_waiting_for_ddl= { 0, "Waiting for DDLs", 0};
91499151

91509152
PSI_memory_key key_memory_DATE_TIME_FORMAT;
91519153
PSI_memory_key key_memory_DDL_LOG_MEMORY_ENTRY;

sql/mysqld.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,9 @@ extern PSI_stage_info stage_upgrading_lock;
639639
extern PSI_stage_info stage_user_lock;
640640
extern PSI_stage_info stage_user_sleep;
641641
extern PSI_stage_info stage_verifying_table;
642+
extern PSI_stage_info stage_waiting_for_ddl;
642643
extern PSI_stage_info stage_waiting_for_delay_list;
644+
extern PSI_stage_info stage_waiting_for_flush;
643645
extern PSI_stage_info stage_waiting_for_gtid_to_be_written_to_binary_log;
644646
extern PSI_stage_info stage_waiting_for_handler_insert;
645647
extern PSI_stage_info stage_waiting_for_handler_lock;

0 commit comments

Comments
 (0)