summaryrefslogtreecommitdiff
path: root/sql/semisync_master.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2022-05-09 22:04:06 +0200
committerSergei Golubchik <serg@mariadb.org>2022-05-09 22:04:06 +0200
commitef781162ff2eb97f405b19dc150ab674e91dbc05 (patch)
tree63b897dece50ab65652174af4cd0aabd8f3a8505 /sql/semisync_master.cc
parente9af6b2a4d8750c32d4953f08f8bc5f2e33cb9e3 (diff)
parent16cebed54065ad9e18953aa86d48f6007d53c2d3 (diff)
downloadmariadb-git-ef781162ff2eb97f405b19dc150ab674e91dbc05.tar.gz
Merge branch '10.4' into 10.5
Diffstat (limited to 'sql/semisync_master.cc')
-rw-r--r--sql/semisync_master.cc65
1 files changed, 58 insertions, 7 deletions
diff --git a/sql/semisync_master.cc b/sql/semisync_master.cc
index cfe29824328..0e72ff441c4 100644
--- a/sql/semisync_master.cc
+++ b/sql/semisync_master.cc
@@ -463,6 +463,37 @@ void Repl_semi_sync_master::cleanup()
delete m_active_tranxs;
}
+int Repl_semi_sync_master::sync_get_master_wait_sessions()
+{
+ int wait_sessions;
+ lock();
+ wait_sessions= rpl_semi_sync_master_wait_sessions;
+ unlock();
+ return wait_sessions;
+}
+
+void Repl_semi_sync_master::create_timeout(struct timespec *out,
+ struct timespec *start_arg)
+{
+ struct timespec *start_ts;
+ struct timespec now_ts;
+ if (!start_arg)
+ {
+ set_timespec(now_ts, 0);
+ start_ts= &now_ts;
+ }
+ else
+ {
+ start_ts= start_arg;
+ }
+
+ long diff_secs= (long) (m_wait_timeout / TIME_THOUSAND);
+ long diff_nsecs= (long) ((m_wait_timeout % TIME_THOUSAND) * TIME_MILLION);
+ long nsecs= start_ts->tv_nsec + diff_nsecs;
+ out->tv_sec= start_ts->tv_sec + diff_secs + nsecs / TIME_BILLION;
+ out->tv_nsec= nsecs % TIME_BILLION;
+}
+
void Repl_semi_sync_master::lock()
{
mysql_mutex_lock(&LOCK_binlog);
@@ -862,13 +893,6 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name,
m_wait_file_name, (ulong)m_wait_file_pos));
}
- /* Calcuate the waiting period. */
- long diff_secs = (long) (m_wait_timeout / TIME_THOUSAND);
- long diff_nsecs = (long) ((m_wait_timeout % TIME_THOUSAND) * TIME_MILLION);
- long nsecs = start_ts.tv_nsec + diff_nsecs;
- abstime.tv_sec = start_ts.tv_sec + diff_secs + nsecs/TIME_BILLION;
- abstime.tv_nsec = nsecs % TIME_BILLION;
-
/* In semi-synchronous replication, we wait until the binlog-dump
* thread has received the reply on the relevant binlog segment from the
* replication slave.
@@ -879,12 +903,20 @@ int Repl_semi_sync_master::commit_trx(const char* trx_wait_binlog_name,
*/
rpl_semi_sync_master_wait_sessions++;
+ /* We keep track of when this thread is awaiting an ack to ensure it is
+ * not killed while awaiting an ACK if a shutdown is issued.
+ */
+ set_thd_awaiting_semisync_ack(thd, TRUE);
+
DBUG_PRINT("semisync", ("%s: wait %lu ms for binlog sent (%s, %lu)",
"Repl_semi_sync_master::commit_trx",
m_wait_timeout,
m_wait_file_name, (ulong)m_wait_file_pos));
+ create_timeout(&abstime, &start_ts);
wait_result = cond_timewait(&abstime);
+
+ set_thd_awaiting_semisync_ack(thd, FALSE);
rpl_semi_sync_master_wait_sessions--;
if (wait_result != 0)
@@ -1320,6 +1352,25 @@ void Repl_semi_sync_master::set_export_stats()
unlock();
}
+void Repl_semi_sync_master::await_slave_reply()
+{
+ struct timespec abstime;
+
+ DBUG_ENTER("Repl_semi_sync_master::::await_slave_reply");
+ lock();
+
+ /* Just return if there is nothing to wait for */
+ if (!rpl_semi_sync_master_wait_sessions)
+ goto end;
+
+ create_timeout(&abstime, NULL);
+ cond_timewait(&abstime);
+
+end:
+ unlock();
+ DBUG_VOID_RETURN;
+}
+
/* Get the waiting time given the wait's staring time.
*
* Return: