mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
BUG#49522: Replication problem with mixed MyISAM/InnoDB
When using a non-transactional table (t1) on the master and with autocommit disabled, no COMMIT is recorded in the binary log ending the statement. Therefore, if the slave has t1 in a transactional engine, then it will be as if a transaction is started but never ends. This is actually BUG#29288 all over again. We fix this by cherrypicking the cset for BUG#29288 which was pushed to a later mysql version. The revision picked was: mats@sun.com-20090923094343-bnheplq8n95opjay . Additionally, a test case for covering the scenario depicted in the bug report is included in this cset.
This commit is contained in:
@@ -2406,13 +2406,29 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||
charset_database_number= thd_arg->variables.collation_database->number;
|
||||
|
||||
/*
|
||||
If we don't use flags2 for anything else than options contained in
|
||||
thd_arg->options, it would be more efficient to flags2=thd_arg->options
|
||||
(OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
|
||||
But it's likely that we don't want to use 32 bits for 3 bits; in the future
|
||||
we will probably want to reclaim the 29 bits. So we need the &.
|
||||
We only replicate over the bits of flags2 that we need: the rest
|
||||
are masked out by "& OPTIONS_WRITTEN_TO_BINLOG".
|
||||
|
||||
We also force AUTOCOMMIT=1. Rationale (cf. BUG#29288): After
|
||||
fixing BUG#26395, we always write BEGIN and COMMIT around all
|
||||
transactions (even single statements in autocommit mode). This is
|
||||
so that replication from non-transactional to transactional table
|
||||
and error recovery from XA to non-XA table should work as
|
||||
expected. The BEGIN/COMMIT are added in log.cc. However, there is
|
||||
one exception: MyISAM bypasses log.cc and writes directly to the
|
||||
binlog. So if autocommit is off, master has MyISAM, and slave has
|
||||
a transactional engine, then the slave will just see one long
|
||||
never-ending transaction. The only way to bypass explicit
|
||||
BEGIN/COMMIT in the binlog is by using a non-transactional table.
|
||||
So setting AUTOCOMMIT=1 will make this work as expected.
|
||||
|
||||
Note: explicitly replicate AUTOCOMMIT=1 from master. We do not
|
||||
assume AUTOCOMMIT=1 on slave; the slave still reads the state of
|
||||
the autocommit flag as written by the master to the binlog. This
|
||||
behavior may change after WL#4162 has been implemented.
|
||||
*/
|
||||
flags2= (uint32) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
|
||||
flags2= (uint32) (thd_arg->options &
|
||||
(OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
|
||||
DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
|
||||
DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
|
||||
DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
|
||||
|
||||
Reference in New Issue
Block a user