Skip to content

Commit 9be1f53

Browse files
author
Neha Kumari
committed
Bug#28091735:COMMIT HANGS IF BINLOG_GROUP_COMMIT_SYNC_DELAY NOT MULTIPLE OF 1/10TH OF ITSELF
Analysis: Setting binlog_group_commit_sync_no_delay_count option means that the server exits the wait procedure if the number of sessions reaches the count given before the timeout i.e is set in binlog_group_commit_sync_delay elapses. In order to check if session count has reached the given limit, the waiting time is broken into small intervals called as delta. The delta is calculated as 1/10th of total wait time. After each delta waiting time is elapsed queue size is checked to see if count has reached. If count is not reached then wait time is modified "to_wait = to_wait - delta". This process is repeated until to_wait > 0 and count has not been reached. delta is calculated like this ulong delta= DBUG_EVALUATE_IF("bgc_set_infinite_delay", 100000, max<ulong>(1, (to_wait * 0.1))); When to_wait which is the value of sync_delay is a non multiple of the delta(3) like lets say 32, as this is not a multiple of to_wait time there will be a point in the waiting code where to_wait = 2, and then to_wait(2) = to_wait(2) - delta(3) = -1 now as to_wait is of type ulong so the value will be wrapped and to_wait = 18446744073709551615 [ULONG_MAX]. This will make the waiting loop continue forever.
1 parent 94208bc commit 9be1f53

7 files changed

+58
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CREATE TABLE t(s INT);
2+
SET GLOBAL binlog_group_commit_sync_delay = 32;
3+
SET GLOBAL binlog_group_commit_sync_no_delay_count = 0;
4+
BEGIN;
5+
INSERT INTO t VALUES(10);
6+
COMMIT;
7+
SET GLOBAL binlog_group_commit_sync_delay = 0;
8+
SET GLOBAL binlog_group_commit_sync_no_delay_count = 0;
9+
DROP TABLE t;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# ==== Purpose ====
2+
#
3+
# This test will set a value for binlog_group_commit_sync_delay
4+
# which will be a non multiple of delta(the waiting time is
5+
# broken into smaller chunks called as delta), and execute some
6+
# transactions after that.
7+
#
8+
# The test verifies that server does not hang when a non multiple of 10
9+
# is assigned to binlog_group_commit_sync_delay variable.
10+
#
11+
# Related bugs and Worklogs
12+
#
13+
# Bug#28091735:COMMIT WILL HANG IF BINLOG_GROUP_COMMIT_SYNC_DELAY
14+
# IS NOT A MULTIPLE OF 10
15+
16+
# this is binlog format agnostic
17+
--source include/have_binlog_format_row.inc
18+
19+
--let $bgcd_saved = `SELECT @@GLOBAL.binlog_group_commit_sync_delay`
20+
--let $bgcc_saved = `SELECT @@GLOBAL.binlog_group_commit_sync_no_delay_count`
21+
22+
CREATE TABLE t(s INT);
23+
24+
# Set the delay to a non multiple of delta, in this case
25+
# delta will be 3, MAX(1, wait_time * .1) and so it will not be
26+
# a multiple of the waiting time which is 32
27+
28+
SET GLOBAL binlog_group_commit_sync_delay = 32;
29+
SET GLOBAL binlog_group_commit_sync_no_delay_count = 0;
30+
31+
BEGIN;
32+
INSERT INTO t VALUES(10);
33+
COMMIT; # Hangs here without the fix
34+
35+
#cleanup
36+
37+
--eval SET GLOBAL binlog_group_commit_sync_delay = $bgcd_saved
38+
--eval SET GLOBAL binlog_group_commit_sync_no_delay_count = $bgcc_saved
39+
DROP TABLE t;
40+

sql/binlog.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -2252,19 +2252,19 @@ THD *Stage_manager::Mutex_queue::fetch_and_empty()
22522252
DBUG_RETURN(result);
22532253
}
22542254

2255-
void Stage_manager::wait_count_or_timeout(ulong count, ulong usec, StageID stage)
2255+
void Stage_manager::wait_count_or_timeout(ulong count, long usec, StageID stage)
22562256
{
2257-
ulong to_wait=
2257+
long to_wait=
22582258
DBUG_EVALUATE_IF("bgc_set_infinite_delay", LONG_MAX, usec);
22592259
/*
22602260
For testing purposes while waiting for inifinity
22612261
to arrive, we keep checking the queue size at regular,
22622262
small intervals. Otherwise, waiting 0.1 * infinite
22632263
is too long.
22642264
*/
2265-
ulong delta=
2265+
long delta=
22662266
DBUG_EVALUATE_IF("bgc_set_infinite_delay", 100000,
2267-
max<ulong>(1, (to_wait * 0.1)));
2267+
max<long>(1, (to_wait * 0.1)));
22682268

22692269
while (to_wait > 0 && (count == 0 || static_cast<ulong>(m_queue[stage].get_size()) < count))
22702270
{

sql/binlog.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ class Stage_manager {
246246
session is waiting on
247247
@param stage which stage queue size to compare count against.
248248
*/
249-
void wait_count_or_timeout(ulong count, ulong usec, StageID stage);
249+
void wait_count_or_timeout(ulong count, long usec, StageID stage);
250250

251251
void signal_done(THD *queue);
252252

sql/mysqld.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ ulonglong max_binlog_cache_size=0;
473473
ulong slave_max_allowed_packet= 0;
474474
ulong binlog_stmt_cache_size=0;
475475
int32 opt_binlog_max_flush_queue_time= 0;
476-
ulong opt_binlog_group_commit_sync_delay= 0;
476+
long opt_binlog_group_commit_sync_delay= 0;
477477
ulong opt_binlog_group_commit_sync_no_delay_count= 0;
478478
ulonglong max_binlog_stmt_cache_size=0;
479479
ulong query_cache_size=0;

sql/mysqld.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -246,7 +246,7 @@ extern ulong open_files_limit;
246246
extern ulong binlog_cache_size, binlog_stmt_cache_size;
247247
extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size;
248248
extern int32 opt_binlog_max_flush_queue_time;
249-
extern ulong opt_binlog_group_commit_sync_delay;
249+
extern long opt_binlog_group_commit_sync_delay;
250250
extern ulong opt_binlog_group_commit_sync_no_delay_count;
251251
extern ulong max_binlog_size, max_relay_log_size;
252252
extern ulong slave_max_allowed_packet;

sql/sys_vars.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ static Sys_var_int32 Sys_binlog_max_flush_queue_time(
748748
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0),
749749
DEPRECATED(""));
750750

751-
static Sys_var_ulong Sys_binlog_group_commit_sync_delay(
751+
static Sys_var_long Sys_binlog_group_commit_sync_delay(
752752
"binlog_group_commit_sync_delay",
753753
"The number of microseconds the server waits for the "
754754
"binary log group commit sync queue to fill before "

0 commit comments

Comments
 (0)