From cc6bb008edff3bef2f5549c50ad0363fda901f77 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Wed, 14 Nov 2018 19:29:32 +0100 Subject: [PATCH] Fix fractional timeout values used with WAIT_FOR_EXECUTED_GTID_SET The casting logic here resulted in the timeout double to be cast into a ulonglong before the multiplication happened. This resulted in all timeouts being rounded down to whole seconds. The behavior is visible with statements like the following: mysql> SELECT WAIT_FOR_EXECUTED_GTID_SET('16d22a8b-e803-11e8-b46f-003d70c354d2:9067', 0.1); +------------------------------------------------------------------------------+ | WAIT_FOR_EXECUTED_GTID_SET('16d22a8b-e803-11e8-b46f-003d70c354d2:9067', 0.1) | +------------------------------------------------------------------------------+ | 1 | +------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT WAIT_FOR_EXECUTED_GTID_SET('16d22a8b-e803-11e8-b46f-003d70c354d2:9067', 0.5); +------------------------------------------------------------------------------+ | WAIT_FOR_EXECUTED_GTID_SET('16d22a8b-e803-11e8-b46f-003d70c354d2:9067', 0.5) | +------------------------------------------------------------------------------+ | 1 | +------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT WAIT_FOR_EXECUTED_GTID_SET('16d22a8b-e803-11e8-b46f-003d70c354d2:9067', 1.0); +------------------------------------------------------------------------------+ | WAIT_FOR_EXECUTED_GTID_SET('16d22a8b-e803-11e8-b46f-003d70c354d2:9067', 1.0) | +------------------------------------------------------------------------------+ | 1 | +------------------------------------------------------------------------------+ 1 row in set (1.00 sec) mysql> SELECT WAIT_FOR_EXECUTED_GTID_SET('16d22a8b-e803-11e8-b46f-003d70c354d2:9067', 1.5); +------------------------------------------------------------------------------+ | WAIT_FOR_EXECUTED_GTID_SET('16d22a8b-e803-11e8-b46f-003d70c354d2:9067', 1.5) | +------------------------------------------------------------------------------+ | 1 | +------------------------------------------------------------------------------+ 1 row in set (1.00 sec) The query execution time here shows the problem. Everything between 0.0 and 1.0 is rounted to a wait time of 0.0 seconds. When using a value in a 1.0 to 2.0 window, it rounds down to 1 seconds as visible in the query execution time. After this change it works as expected, again visible in the query execution time: mysql> SELECT WAIT_FOR_EXECUTED_GTID_SET('f9702b80-e826-11e8-b833-f64268411190:4', 1.0); +---------------------------------------------------------------------------+ | WAIT_FOR_EXECUTED_GTID_SET('f9702b80-e826-11e8-b833-f64268411190:4', 1.0) | +---------------------------------------------------------------------------+ | 1 | +---------------------------------------------------------------------------+ 1 row in set (1.01 sec) mysql> SELECT WAIT_FOR_EXECUTED_GTID_SET('f9702b80-e826-11e8-b833-f64268411190:4', 0.5); +---------------------------------------------------------------------------+ | WAIT_FOR_EXECUTED_GTID_SET('f9702b80-e826-11e8-b833-f64268411190:4', 0.5) | +---------------------------------------------------------------------------+ | 1 | +---------------------------------------------------------------------------+ 1 row in set (0.50 sec) mysql> SELECT WAIT_FOR_EXECUTED_GTID_SET('f9702b80-e826-11e8-b833-f64268411190:4', 0.1); +---------------------------------------------------------------------------+ | WAIT_FOR_EXECUTED_GTID_SET('f9702b80-e826-11e8-b833-f64268411190:4', 0.1) | +---------------------------------------------------------------------------+ | 1 | +---------------------------------------------------------------------------+ 1 row in set (0.10 sec) --- sql/rpl_gtid_state.cc | 2 +- sql/rpl_rli.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/rpl_gtid_state.cc b/sql/rpl_gtid_state.cc index 97f514ea437..910a3ff6e51 100644 --- a/sql/rpl_gtid_state.cc +++ b/sql/rpl_gtid_state.cc @@ -299,7 +299,7 @@ bool Gtid_state::wait_for_gtid_set(THD *thd, Gtid_set *wait_for, DBUG_ASSERT(wait_for->get_sid_map() == global_sid_map); if (timeout > 0) - set_timespec_nsec(&abstime, (ulonglong)timeout * 1000000000ULL); + set_timespec_nsec(&abstime, (ulonglong)(timeout * 1000000000ULL)); /* Algorithm: diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index 51e775084aa..c282e8ca25e 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -569,7 +569,7 @@ int Relay_log_info::wait_for_pos(THD *thd, String *log_name, longlong log_pos, DEBUG_SYNC(thd, "begin_master_pos_wait"); - set_timespec_nsec(&abstime, (ulonglong)timeout * 1000000000ULL); + set_timespec_nsec(&abstime, (ulonglong)(timeout * 1000000000ULL)); mysql_mutex_lock(&data_lock); thd->ENTER_COND(&data_cond, &data_lock, &stage_waiting_for_the_slave_thread_to_advance_position, @@ -779,7 +779,7 @@ int Relay_log_info::wait_for_gtid_set(THD *thd, const Gtid_set *wait_gtid_set, DEBUG_SYNC(thd, "begin_wait_for_gtid_set"); - set_timespec_nsec(&abstime, (ulonglong)timeout * 1000000000ULL); + set_timespec_nsec(&abstime, (ulonglong)(timeout * 1000000000ULL)); mysql_mutex_lock(&data_lock); if (update_THD_status)