diff options
author | Andrei Elkin <andrei.elkin@mariadb.com> | 2017-10-16 19:32:02 +0300 |
---|---|---|
committer | Andrei Elkin <andrei.elkin@mariadb.com> | 2017-10-25 17:23:18 +0300 |
commit | 780c30e07d1761bd7030cc7e50e1798a2d4ffeef (patch) | |
tree | 4cacdaa39b68785a28d47bd68982954b64f08250 | |
parent | f9b50c065718a237cb3474dda45062e4c7926240 (diff) | |
download | mariadb-git-bb-10.1-mdev9510-andrei.tar.gz |
MDEV-9510 Segmentation fault in binlog thread causes crashbb-10.1-mdev9510-andrei
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.
-rw-r--r-- | mysql-test/suite/galera/r/sql_log_bin.result | 1 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/sql_log_bin.test | 12 | ||||
-rw-r--r-- | sql/log.cc | 22 |
3 files changed, 33 insertions, 2 deletions
diff --git a/mysql-test/suite/galera/r/sql_log_bin.result b/mysql-test/suite/galera/r/sql_log_bin.result index 237725ec9a7..a2ebafe5231 100644 --- a/mysql-test/suite/galera/r/sql_log_bin.result +++ b/mysql-test/suite/galera/r/sql_log_bin.result @@ -6,6 +6,7 @@ INSERT INTO t1 VALUES (1); # Disable binary logging for current session SET SQL_LOG_BIN=OFF; INSERT INTO t1 VALUES (2); +FLUSH BINARY LOGS; CREATE TABLE t2(c1 INT PRIMARY KEY) ENGINE=INNODB; INSERT INTO t2 VALUES (1); CREATE TABLE test.t3 AS SELECT * from t1; diff --git a/mysql-test/suite/galera/t/sql_log_bin.test b/mysql-test/suite/galera/t/sql_log_bin.test index 615bc4c30af..9f8f7c84486 100644 --- a/mysql-test/suite/galera/t/sql_log_bin.test +++ b/mysql-test/suite/galera/t/sql_log_bin.test @@ -1,5 +1,13 @@ # Test to check the behavior of galera cluster with sql_log_bin=ON|OFF & binary # logging is disabled. sql_bin_log should not affect galera replication. +# +# The following bugfixes are tested: +# +# MDEV-9510: Segmentation fault in binlog thread. +# A scenario otherwise causing a similar segfault is replayed. +# The test must pass having no crashes. +# The sequence of sql statements is provided by original +# sql_log_bin.test augmented with a FLUSH BINLOG LOGS, below. --source include/galera_cluster.inc --source include/have_innodb.inc @@ -15,6 +23,10 @@ INSERT INTO t1 VALUES (1); --echo # Disable binary logging for current session SET SQL_LOG_BIN=OFF; INSERT INTO t1 VALUES (2); + +# MDEV-9510: the following binlog rotation due to FLUSH segfaults wo/ the fixes +FLUSH BINARY LOGS; + CREATE TABLE t2(c1 INT PRIMARY KEY) ENGINE=INNODB; INSERT INTO t2 VALUES (1); CREATE TABLE test.t3 AS SELECT * from t1; diff --git a/sql/log.cc b/sql/log.cc index a9f486d88c1..85148b74b9d 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -7043,8 +7043,15 @@ MYSQL_BIN_LOG::write_transaction_to_binlog(THD *thd, mode. Also, do not write the cached updates to binlog if binary logging is disabled (log-bin/sql_log_bin). */ - if (wsrep_emulate_bin_log || !(thd->variables.option_bits & OPTION_BIN_LOG)) + if (wsrep_emulate_bin_log) + { + DBUG_RETURN(0); + } + else if (!(thd->variables.option_bits & OPTION_BIN_LOG)) + { + cache_mngr->need_unlog= false; DBUG_RETURN(0); + } entry.thd= thd; entry.cache_mngr= cache_mngr; @@ -9367,11 +9374,19 @@ TC_LOG_BINLOG::log_and_order(THD *thd, my_xid xid, bool all, if (err) DBUG_RETURN(0); + + bool need_unlog= cache_mngr->need_unlog; + /* + The transaction won't need the flag anymore. + Todo/fixme: consider to move the statement into cache_mngr->reset() + relocated to the current or later point. + */ + cache_mngr->need_unlog= false; /* If using explicit user XA, we will not have XID. We must still return a non-zero cookie (as zero cookie signals error). */ - if (!xid || !cache_mngr->need_unlog) + if (!xid || !need_unlog) DBUG_RETURN(BINLOG_COOKIE_DUMMY(cache_mngr->delayed_error)); else DBUG_RETURN(BINLOG_COOKIE_MAKE(cache_mngr->binlog_id, @@ -9444,6 +9459,9 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint) if (b->binlog_id == binlog_id) { --b->xid_count; + + DBUG_ASSERT(b->xid_count > 0); // catch unmatched (++) decrement + break; } first= false; |