Description:
5.7 assertion mysqld: ./sql/binlog.cc:7987: virtual int MYSQL_BIN_LOG::prepare(THD*, bool): Assertion `thd->slave_thread ? opt_log_slave_updates : thd->variables.sql_log_bin' failed.
1) Slave is started with binlog enabled, but with slave updates not being logged, thus, it has chosen binlog not mmap as the transaction coordinator.
1) Use two different transactional engines within one transaction
3) A mixed engine transaction comes from the master. It should not be binlogged, but binlog acts as the transaction coordinator and asserts.
How to repeat:
Setup basic master-slave w/ binlog replication.
Master options:
server-id=1
log-bin=mysql-bin
max_connections=1000
plugin-load=TokuDB=ha_tokudb.so;TokuDB_trx=ha_tokudb.so;TokuDB_locks=ha_tokudb.so;TokuDB_lock_waits=ha_tokudb.so;TokuDB_file_map=ha_tokudb.so;TokuDB_fractal_tree_info=ha_tokudb.so;TokuDB_fractal_tree_block_map=ha_tokudb.so;TokuDB_background_job_status=ha_tokudb.so
Slave options:
server-id=2
log-bin=mysql-bin
log-slave-updates=0 ### Note, this is critical to reproducing the bug ###
max_connections=1000
plugin-load=TokuDB=ha_tokudb.so;TokuDB_trx=ha_tokudb.so;TokuDB_locks=ha_tokudb.so;TokuDB_lock_waits=ha_tokudb.so;TokuDB_file_map=ha_tokudb.so;TokuDB_fractal_tree_info=ha_tokudb.so;TokuDB_fractal_tree_block_map=ha_tokudb.so;TokuDB_background_job_status=ha_tokudb.so
On the master:
CREATE TABLE t1(`a` INT) ENGINE=TokuDB;
CREATE TABLE t2(`a` INT) ENGINE=InnoDB;
begin;
insert into t1 values (1);
insert into t2 values (1);
commit;
The slave will crash as it processes the commit.
Suggested fix:
diff --git a/sql/binlog.cc b/sql/binlog.cc
index 64680a1..390074c 100644
--- a/sql/binlog.cc
+++ b/sql/binlog.cc
@@ -7995,9 +7995,13 @@ int MYSQL_BIN_LOG::prepare(THD *thd, bool all)
/*
The applier thread explicitly overrides the value of sql_log_bin
with the value of log_slave_updates.
+ We may also end up here in some cases if we have a transaction with two
+ active transactional storage engines, such as is the case if this is a
+ replication applier and log_slave_updates=0.
*/
- DBUG_ASSERT(thd->slave_thread ?
- opt_log_slave_updates : thd->variables.sql_log_bin);
+ DBUG_ASSERT((thd->slave_thread ?
+ opt_log_slave_updates : thd->variables.sql_log_bin) ||
+ total_ha_2pc > 1);
/*
Set HA_IGNORE_DURABILITY to not flush the prepared record of the