Skip to content

Commit bb2c1a5

Browse files
committed
Merge parallel replication async deadlock kill into 10.1
2 parents de7f877 + 7e0c9de commit bb2c1a5

File tree

9 files changed

+267
-45
lines changed

9 files changed

+267
-45
lines changed

mysql-test/suite/perfschema/r/threads_mysql.result

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ processlist_info NULL
4444
unified_parent_thread_id unified parent_thread_id
4545
role NULL
4646
instrumented YES
47+
name thread/sql/slave_background
48+
type BACKGROUND
49+
processlist_user NULL
50+
processlist_host NULL
51+
processlist_db NULL
52+
processlist_command NULL
53+
processlist_info NULL
54+
unified_parent_thread_id unified parent_thread_id
55+
role NULL
56+
instrumented YES
4757
CREATE TEMPORARY TABLE t1 AS
4858
SELECT thread_id FROM performance_schema.threads
4959
WHERE name LIKE 'thread/sql%';
@@ -105,4 +115,5 @@ parent_thread_name child_thread_name
105115
thread/sql/event_scheduler thread/sql/event_worker
106116
thread/sql/main thread/sql/one_connection
107117
thread/sql/main thread/sql/signal_handler
118+
thread/sql/main thread/sql/slave_background
108119
thread/sql/one_connection thread/sql/event_scheduler

sql/mysqld.cc

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ static bool binlog_format_used= false;
382382
LEX_STRING opt_init_connect, opt_init_slave;
383383
mysql_cond_t COND_thread_cache;
384384
static mysql_cond_t COND_flush_thread_cache;
385-
mysql_cond_t COND_slave_init;
385+
mysql_cond_t COND_slave_background;
386386
static DYNAMIC_ARRAY all_options;
387387

388388
/* Global variables */
@@ -720,7 +720,7 @@ mysql_mutex_t
720720
LOCK_crypt,
721721
LOCK_global_system_variables,
722722
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
723-
LOCK_connection_count, LOCK_error_messages, LOCK_slave_init;
723+
LOCK_connection_count, LOCK_error_messages, LOCK_slave_background;
724724

725725
mysql_mutex_t LOCK_stats, LOCK_global_user_client_stats,
726726
LOCK_global_table_stats, LOCK_global_index_stats;
@@ -902,7 +902,7 @@ PSI_mutex_key key_LOCK_gtid_waiting;
902902

903903
PSI_mutex_key key_LOCK_after_binlog_sync;
904904
PSI_mutex_key key_LOCK_prepare_ordered, key_LOCK_commit_ordered,
905-
key_LOCK_slave_init;
905+
key_LOCK_slave_background;
906906
PSI_mutex_key key_TABLE_SHARE_LOCK_share;
907907

908908
static PSI_mutex_info all_server_mutexes[]=
@@ -968,7 +968,7 @@ static PSI_mutex_info all_server_mutexes[]=
968968
{ &key_LOCK_prepare_ordered, "LOCK_prepare_ordered", PSI_FLAG_GLOBAL},
969969
{ &key_LOCK_after_binlog_sync, "LOCK_after_binlog_sync", PSI_FLAG_GLOBAL},
970970
{ &key_LOCK_commit_ordered, "LOCK_commit_ordered", PSI_FLAG_GLOBAL},
971-
{ &key_LOCK_slave_init, "LOCK_slave_init", PSI_FLAG_GLOBAL},
971+
{ &key_LOCK_slave_background, "LOCK_slave_background", PSI_FLAG_GLOBAL},
972972
{ &key_LOG_INFO_lock, "LOG_INFO::lock", 0},
973973
{ &key_LOCK_thread_count, "LOCK_thread_count", PSI_FLAG_GLOBAL},
974974
{ &key_LOCK_thread_cache, "LOCK_thread_cache", PSI_FLAG_GLOBAL},
@@ -1023,7 +1023,7 @@ PSI_cond_key key_TC_LOG_MMAP_COND_queue_busy;
10231023
PSI_cond_key key_COND_rpl_thread_queue, key_COND_rpl_thread,
10241024
key_COND_rpl_thread_stop, key_COND_rpl_thread_pool,
10251025
key_COND_parallel_entry, key_COND_group_commit_orderer,
1026-
key_COND_prepare_ordered, key_COND_slave_init;
1026+
key_COND_prepare_ordered, key_COND_slave_background;
10271027
PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
10281028

10291029
static PSI_cond_info all_server_conds[]=
@@ -1073,15 +1073,15 @@ static PSI_cond_info all_server_conds[]=
10731073
{ &key_COND_parallel_entry, "COND_parallel_entry", 0},
10741074
{ &key_COND_group_commit_orderer, "COND_group_commit_orderer", 0},
10751075
{ &key_COND_prepare_ordered, "COND_prepare_ordered", 0},
1076-
{ &key_COND_slave_init, "COND_slave_init", 0},
1076+
{ &key_COND_slave_background, "COND_slave_background", 0},
10771077
{ &key_COND_wait_gtid, "COND_wait_gtid", 0},
10781078
{ &key_COND_gtid_ignore_duplicates, "COND_gtid_ignore_duplicates", 0}
10791079
};
10801080

10811081
PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
10821082
key_thread_handle_manager, key_thread_main,
10831083
key_thread_one_connection, key_thread_signal_hand,
1084-
key_thread_slave_init, key_rpl_parallel_thread;
1084+
key_thread_slave_background, key_rpl_parallel_thread;
10851085

10861086
static PSI_thread_info all_server_threads[]=
10871087
{
@@ -1107,7 +1107,7 @@ static PSI_thread_info all_server_threads[]=
11071107
{ &key_thread_main, "main", PSI_FLAG_GLOBAL},
11081108
{ &key_thread_one_connection, "one_connection", 0},
11091109
{ &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
1110-
{ &key_thread_slave_init, "slave_init", PSI_FLAG_GLOBAL},
1110+
{ &key_thread_slave_background, "slave_background", PSI_FLAG_GLOBAL},
11111111
{ &key_rpl_parallel_thread, "rpl_parallel_thread", 0}
11121112
};
11131113

@@ -2268,8 +2268,8 @@ static void clean_up_mutexes()
22682268
mysql_cond_destroy(&COND_prepare_ordered);
22692269
mysql_mutex_destroy(&LOCK_after_binlog_sync);
22702270
mysql_mutex_destroy(&LOCK_commit_ordered);
2271-
mysql_mutex_destroy(&LOCK_slave_init);
2272-
mysql_cond_destroy(&COND_slave_init);
2271+
mysql_mutex_destroy(&LOCK_slave_background);
2272+
mysql_cond_destroy(&COND_slave_background);
22732273
DBUG_VOID_RETURN;
22742274
}
22752275

@@ -4638,9 +4638,9 @@ static int init_thread_environment()
46384638
MY_MUTEX_INIT_SLOW);
46394639
mysql_mutex_init(key_LOCK_commit_ordered, &LOCK_commit_ordered,
46404640
MY_MUTEX_INIT_SLOW);
4641-
mysql_mutex_init(key_LOCK_slave_init, &LOCK_slave_init,
4641+
mysql_mutex_init(key_LOCK_slave_background, &LOCK_slave_background,
46424642
MY_MUTEX_INIT_SLOW);
4643-
mysql_cond_init(key_COND_slave_init, &COND_slave_init, NULL);
4643+
mysql_cond_init(key_COND_slave_background, &COND_slave_background, NULL);
46444644

46454645
#ifdef HAVE_OPENSSL
46464646
mysql_mutex_init(key_LOCK_des_key_file,
@@ -10131,6 +10131,9 @@ PSI_stage_info stage_waiting_for_rpl_thread_pool= { 0, "Waiting while replicatio
1013110131
PSI_stage_info stage_master_gtid_wait_primary= { 0, "Waiting in MASTER_GTID_WAIT() (primary waiter)", 0};
1013210132
PSI_stage_info stage_master_gtid_wait= { 0, "Waiting in MASTER_GTID_WAIT()", 0};
1013310133
PSI_stage_info stage_gtid_wait_other_connection= { 0, "Waiting for other master connection to process GTID received on multiple master connections", 0};
10134+
PSI_stage_info stage_slave_background_process_request= { 0, "Processing requests", 0};
10135+
PSI_stage_info stage_slave_background_wait_request= { 0, "Waiting for requests", 0};
10136+
PSI_stage_info stage_waiting_for_deadlock_kill= { 0, "Waiting for parallel replication deadlock handling to complete", 0};
1013410137

1013510138
#ifdef HAVE_PSI_INTERFACE
1013610139

@@ -10255,7 +10258,9 @@ PSI_stage_info *all_server_stages[]=
1025510258
& stage_waiting_to_get_readlock,
1025610259
& stage_master_gtid_wait_primary,
1025710260
& stage_master_gtid_wait,
10258-
& stage_gtid_wait_other_connection
10261+
& stage_gtid_wait_other_connection,
10262+
& stage_slave_background_process_request,
10263+
& stage_slave_background_wait_request
1025910264
};
1026010265

1026110266
PSI_socket_key key_socket_tcpip, key_socket_unix, key_socket_client_connection;

sql/mysqld.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,8 @@ extern PSI_cond_key key_COND_wait_gtid, key_COND_gtid_ignore_duplicates;
341341

342342
extern PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
343343
key_thread_handle_manager, key_thread_kill_server, key_thread_main,
344-
key_thread_one_connection, key_thread_signal_hand, key_thread_slave_init,
345-
key_rpl_parallel_thread;
344+
key_thread_one_connection, key_thread_signal_hand,
345+
key_thread_slave_background, key_rpl_parallel_thread;
346346

347347
extern PSI_file_key key_file_binlog, key_file_binlog_index, key_file_casetest,
348348
key_file_dbopt, key_file_des_key_file, key_file_ERRMSG, key_select_to_file,
@@ -488,6 +488,9 @@ extern PSI_stage_info stage_waiting_for_rpl_thread_pool;
488488
extern PSI_stage_info stage_master_gtid_wait_primary;
489489
extern PSI_stage_info stage_master_gtid_wait;
490490
extern PSI_stage_info stage_gtid_wait_other_connection;
491+
extern PSI_stage_info stage_slave_background_process_request;
492+
extern PSI_stage_info stage_slave_background_wait_request;
493+
extern PSI_stage_info stage_waiting_for_deadlock_kill;
491494

492495
#ifdef HAVE_PSI_STATEMENT_INTERFACE
493496
/**
@@ -556,7 +559,7 @@ extern mysql_mutex_t
556559
LOCK_slave_list, LOCK_active_mi, LOCK_manager,
557560
LOCK_global_system_variables, LOCK_user_conn,
558561
LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count,
559-
LOCK_slave_init;
562+
LOCK_slave_background;
560563
extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_thread_count;
561564
#ifdef HAVE_OPENSSL
562565
extern char* des_key_file;
@@ -568,7 +571,7 @@ extern mysql_rwlock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
568571
extern mysql_rwlock_t LOCK_system_variables_hash;
569572
extern mysql_cond_t COND_thread_count;
570573
extern mysql_cond_t COND_manager;
571-
extern mysql_cond_t COND_slave_init;
574+
extern mysql_cond_t COND_slave_background;
572575
extern int32 thread_running;
573576
extern int32 thread_count, service_thread_count;
574577

sql/rpl_parallel.cc

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,25 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev)
107107
}
108108

109109

110+
/*
111+
Wait for any pending deadlock kills. Since deadlock kills happen
112+
asynchronously, we need to be sure they will be completed before starting a
113+
new transaction. Otherwise the new transaction might suffer a spurious kill.
114+
*/
115+
static void
116+
wait_for_pending_deadlock_kill(THD *thd, rpl_group_info *rgi)
117+
{
118+
PSI_stage_info old_stage;
119+
120+
mysql_mutex_lock(&thd->LOCK_wakeup_ready);
121+
thd->ENTER_COND(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready,
122+
&stage_waiting_for_deadlock_kill, &old_stage);
123+
while (rgi->killed_for_retry == rpl_group_info::RETRY_KILL_PENDING)
124+
mysql_cond_wait(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready);
125+
thd->EXIT_COND(&old_stage);
126+
}
127+
128+
110129
static void
111130
finish_event_group(rpl_parallel_thread *rpt, uint64 sub_id,
112131
rpl_parallel_entry *entry, rpl_group_info *rgi)
@@ -212,6 +231,8 @@ finish_event_group(rpl_parallel_thread *rpt, uint64 sub_id,
212231
entry->stop_on_error_sub_id= sub_id;
213232
mysql_mutex_unlock(&entry->LOCK_parallel_entry);
214233

234+
if (rgi->killed_for_retry == rpl_group_info::RETRY_KILL_PENDING)
235+
wait_for_pending_deadlock_kill(thd, rgi);
215236
thd->clear_error();
216237
thd->reset_killed();
217238
/*
@@ -604,7 +625,6 @@ convert_kill_to_deadlock_error(rpl_group_info *rgi)
604625
{
605626
thd->clear_error();
606627
my_error(ER_LOCK_DEADLOCK, MYF(0));
607-
rgi->killed_for_retry= false;
608628
thd->reset_killed();
609629
}
610630
}
@@ -695,14 +715,16 @@ retry_event_group(rpl_group_info *rgi, rpl_parallel_thread *rpt,
695715
thd->wait_for_commit_ptr->unregister_wait_for_prior_commit();
696716
DBUG_EXECUTE_IF("inject_mdev8031", {
697717
/* Simulate that we get deadlock killed at this exact point. */
698-
rgi->killed_for_retry= true;
718+
rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED;
699719
mysql_mutex_lock(&thd->LOCK_thd_data);
700720
thd->killed= KILL_CONNECTION;
701721
mysql_mutex_unlock(&thd->LOCK_thd_data);
702722
});
703723
rgi->cleanup_context(thd, 1);
724+
wait_for_pending_deadlock_kill(thd, rgi);
704725
thd->reset_killed();
705726
thd->clear_error();
727+
rgi->killed_for_retry = rpl_group_info::RETRY_KILL_NONE;
706728

707729
/*
708730
If we retry due to a deadlock kill that occurred during the commit step, we
@@ -841,7 +863,7 @@ retry_event_group(rpl_group_info *rgi, rpl_parallel_thread *rpt,
841863
{
842864
/* Simulate that we get deadlock killed during open_binlog(). */
843865
thd->reset_for_next_command();
844-
rgi->killed_for_retry= true;
866+
rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED;
845867
mysql_mutex_lock(&thd->LOCK_thd_data);
846868
thd->killed= KILL_CONNECTION;
847869
mysql_mutex_unlock(&thd->LOCK_thd_data);
@@ -1741,7 +1763,7 @@ rpl_parallel_thread::get_rgi(Relay_log_info *rli, Gtid_log_event *gtid_ev,
17411763
rgi->relay_log= rli->last_inuse_relaylog;
17421764
rgi->retry_start_offset= rli->future_event_relay_log_pos-event_size;
17431765
rgi->retry_event_count= 0;
1744-
rgi->killed_for_retry= false;
1766+
rgi->killed_for_retry= rpl_group_info::RETRY_KILL_NONE;
17451767

17461768
return rgi;
17471769
}

sql/rpl_rli.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,12 @@ struct rpl_group_info
712712
*/
713713
SPECULATE_WAIT
714714
} speculation;
715-
bool killed_for_retry;
715+
enum enum_retry_killed {
716+
RETRY_KILL_NONE = 0,
717+
RETRY_KILL_PENDING,
718+
RETRY_KILL_KILLED
719+
};
720+
uchar killed_for_retry;
716721

717722
rpl_group_info(Relay_log_info *rli_);
718723
~rpl_group_info();

0 commit comments

Comments
 (0)