Skip to content

Commit c7e3807

Browse files
committed
MDEV-9510 Segmentation fault in binlog thread causes crash
With combination of --log-bin and Galera the server may crash reporting two characteristic stacks: /usr/sbin/mysqld(_ZN13MYSQL_BIN_LOG13mark_xid_doneEmb+0xc7)[0x7f182a8e2cb7] /usr/sbin/mysqld(binlog_background_thread+0x2b5)[0x7f182a8e3275] or /usr/sbin/mysqld(_ZN13MYSQL_BIN_LOG21do_checkpoint_requestEm+0x9d)[0x7ff395b2dafd] /usr/sbin/mysqld(_ZN13MYSQL_BIN_LOG20checkpoint_and_purgeEm+0x11)[0x7ff395b2db91] /usr/sbin/mysqld(_ZN13MYSQL_BIN_LOG16rotate_and_purgeEb+0xc2)[0x7ff395b300b2] The reason of the failure appears to be non-matching decrements for `xid_count_per_binlog::xid_count` which can occur when a transaction is executed having its connection issued `SET @@sql_log_bin=0`. In such case the xid count is not incremented but its decrements still runs to turn `binlog_xid_count_list` into improper state which the following FLUSH BINARY LOGS exposes through the crash. *Note_1*: the regression test reuses an existing galera.sql_log_bin which does not run stably (even in its base form) by mtr with --log-bin. *Note_2*: 10.0-galera branch is free of this issue having missed MDEV-7205 fixes.
1 parent aae4932 commit c7e3807

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

mysql-test/suite/galera/r/sql_log_bin.result

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ INSERT INTO t1 VALUES (1);
66
# Disable binary logging for current session
77
SET SQL_LOG_BIN=OFF;
88
INSERT INTO t1 VALUES (2);
9+
FLUSH BINARY LOGS;
910
CREATE TABLE t2(c1 INT PRIMARY KEY) ENGINE=INNODB;
1011
INSERT INTO t2 VALUES (1);
1112
CREATE TABLE test.t3 AS SELECT * from t1;

mysql-test/suite/galera/t/sql_log_bin.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Test to check the behavior of galera cluster with sql_log_bin=ON|OFF & binary
22
# logging is disabled. sql_bin_log should not affect galera replication.
3+
#
4+
# The following bugfixes are tested:
5+
#
6+
# MDEV-9510: Segmentation fault in binlog thread.
7+
# A scenario otherwise causing a similar segfault is replayed.
8+
# The test must pass having no crashes.
9+
# The sequence of sql statements is provided by original
10+
# sql_log_bin.test augmented with a FLUSH BINLOG LOGS, below.
311

412
--source include/galera_cluster.inc
513
--source include/have_innodb.inc
@@ -15,6 +23,10 @@ INSERT INTO t1 VALUES (1);
1523
--echo # Disable binary logging for current session
1624
SET SQL_LOG_BIN=OFF;
1725
INSERT INTO t1 VALUES (2);
26+
27+
# MDEV-9510: the following binlog rotation due to FLUSH segfaults wo/ the fixes
28+
FLUSH BINARY LOGS;
29+
1830
CREATE TABLE t2(c1 INT PRIMARY KEY) ENGINE=INNODB;
1931
INSERT INTO t2 VALUES (1);
2032
CREATE TABLE test.t3 AS SELECT * from t1;

sql/log.cc

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7165,8 +7165,15 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd,
71657165
mode. Also, do not write the cached updates to binlog if binary logging is
71667166
disabled (log-bin/sql_log_bin).
71677167
*/
7168-
if (wsrep_emulate_bin_log || !(thd->variables.option_bits & OPTION_BIN_LOG))
7168+
if (wsrep_emulate_bin_log)
7169+
{
7170+
DBUG_RETURN(0);
7171+
}
7172+
else if (!(thd->variables.option_bits & OPTION_BIN_LOG))
7173+
{
7174+
cache_mngr->need_unlog= false;
71697175
DBUG_RETURN(0);
7176+
}
71707177

71717178
entry.thd= thd;
71727179
entry.cache_mngr= cache_mngr;
@@ -9489,11 +9496,19 @@ TC_LOG_BINLOG::log_and_order(THD *thd, my_xid xid, bool all,
94899496

94909497
if (err)
94919498
DBUG_RETURN(0);
9499+
9500+
bool need_unlog= cache_mngr->need_unlog;
9501+
/*
9502+
The transaction won't need the flag anymore.
9503+
Todo/fixme: consider to move the statement into cache_mngr->reset()
9504+
relocated to the current or later point.
9505+
*/
9506+
cache_mngr->need_unlog= false;
94929507
/*
94939508
If using explicit user XA, we will not have XID. We must still return a
94949509
non-zero cookie (as zero cookie signals error).
94959510
*/
9496-
if (!xid || !cache_mngr->need_unlog)
9511+
if (!xid || !need_unlog)
94979512
DBUG_RETURN(BINLOG_COOKIE_DUMMY(cache_mngr->delayed_error));
94989513
else
94999514
DBUG_RETURN(BINLOG_COOKIE_MAKE(cache_mngr->binlog_id,
@@ -9566,6 +9581,9 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint)
95669581
if (b->binlog_id == binlog_id)
95679582
{
95689583
--b->xid_count;
9584+
9585+
DBUG_ASSERT(b->xid_count >= 0); // catch unmatched (++) decrement
9586+
95699587
break;
95709588
}
95719589
first= false;

0 commit comments

Comments
 (0)