mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge parallel replication async deadlock kill into 10.2.
Conflicts: sql/mysqld.cc sql/slave.cc
This commit is contained in:
@ -107,6 +107,25 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Wait for any pending deadlock kills. Since deadlock kills happen
|
||||
asynchronously, we need to be sure they will be completed before starting a
|
||||
new transaction. Otherwise the new transaction might suffer a spurious kill.
|
||||
*/
|
||||
static void
|
||||
wait_for_pending_deadlock_kill(THD *thd, rpl_group_info *rgi)
|
||||
{
|
||||
PSI_stage_info old_stage;
|
||||
|
||||
mysql_mutex_lock(&thd->LOCK_wakeup_ready);
|
||||
thd->ENTER_COND(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready,
|
||||
&stage_waiting_for_deadlock_kill, &old_stage);
|
||||
while (rgi->killed_for_retry == rpl_group_info::RETRY_KILL_PENDING)
|
||||
mysql_cond_wait(&thd->COND_wakeup_ready, &thd->LOCK_wakeup_ready);
|
||||
thd->EXIT_COND(&old_stage);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
finish_event_group(rpl_parallel_thread *rpt, uint64 sub_id,
|
||||
rpl_parallel_entry *entry, rpl_group_info *rgi)
|
||||
@ -212,6 +231,8 @@ finish_event_group(rpl_parallel_thread *rpt, uint64 sub_id,
|
||||
entry->stop_on_error_sub_id= sub_id;
|
||||
mysql_mutex_unlock(&entry->LOCK_parallel_entry);
|
||||
|
||||
if (rgi->killed_for_retry == rpl_group_info::RETRY_KILL_PENDING)
|
||||
wait_for_pending_deadlock_kill(thd, rgi);
|
||||
thd->clear_error();
|
||||
thd->reset_killed();
|
||||
/*
|
||||
@ -610,7 +631,6 @@ convert_kill_to_deadlock_error(rpl_group_info *rgi)
|
||||
{
|
||||
thd->clear_error();
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
||||
rgi->killed_for_retry= false;
|
||||
thd->reset_killed();
|
||||
}
|
||||
}
|
||||
@ -701,14 +721,16 @@ do_retry:
|
||||
thd->wait_for_commit_ptr->unregister_wait_for_prior_commit();
|
||||
DBUG_EXECUTE_IF("inject_mdev8031", {
|
||||
/* Simulate that we get deadlock killed at this exact point. */
|
||||
rgi->killed_for_retry= true;
|
||||
rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED;
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->killed= KILL_CONNECTION;
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
});
|
||||
rgi->cleanup_context(thd, 1);
|
||||
wait_for_pending_deadlock_kill(thd, rgi);
|
||||
thd->reset_killed();
|
||||
thd->clear_error();
|
||||
rgi->killed_for_retry = rpl_group_info::RETRY_KILL_NONE;
|
||||
|
||||
/*
|
||||
If we retry due to a deadlock kill that occurred during the commit step, we
|
||||
@ -847,7 +869,7 @@ do_retry:
|
||||
{
|
||||
/* Simulate that we get deadlock killed during open_binlog(). */
|
||||
thd->reset_for_next_command();
|
||||
rgi->killed_for_retry= true;
|
||||
rgi->killed_for_retry= rpl_group_info::RETRY_KILL_KILLED;
|
||||
mysql_mutex_lock(&thd->LOCK_thd_data);
|
||||
thd->killed= KILL_CONNECTION;
|
||||
mysql_mutex_unlock(&thd->LOCK_thd_data);
|
||||
@ -1747,7 +1769,7 @@ rpl_parallel_thread::get_rgi(Relay_log_info *rli, Gtid_log_event *gtid_ev,
|
||||
rgi->relay_log= rli->last_inuse_relaylog;
|
||||
rgi->retry_start_offset= rli->future_event_relay_log_pos-event_size;
|
||||
rgi->retry_event_count= 0;
|
||||
rgi->killed_for_retry= false;
|
||||
rgi->killed_for_retry= rpl_group_info::RETRY_KILL_NONE;
|
||||
|
||||
return rgi;
|
||||
}
|
||||
|
Reference in New Issue
Block a user