Bug #54562 | SBR mistakes SAVEPOINT statement for accessing a transactional table | ||
---|---|---|---|
Submitted: | 16 Jun 2010 19:18 | ||
Reporter: | Elena Stepanova | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S3 (Non-critical) |
Version: | 5.5.3-m3, 5.5.5-m3 | OS: | Any |
Assigned to: | Assigned Account | CPU Architecture: | Any |
Tags: | regression |
[16 Jun 2010 19:18]
Elena Stepanova
[29 Jun 2010 15:53]
Alfranio Tavares Correia Junior
Context: binlog_direct_non_transactional_updates= 0 binlog_format= STATEMENT The "savepoint" is written to the T-cache (i.e. trx-cache) as expected and after that any non-transactional statement is written to the T-cache because it is assumed that a transactional engine was updated. This happens due to the following code: bool trans_has_updated_trans_table(const THD* thd) { binlog_cache_mngr *const cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); return (cache_mngr ? !cache_mngr->trx_cache.empty() : 0); }
[9 Jul 2010 13:50]
Elena Stepanova
Obviously, the same binlog record shuffling and eventual replication failure happens if instead of SAVEPOINT statement we update a temporary table, even if it is a pure MyISAM table; the same warning "Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction" is thrown in this case. This is old news that temporary tables behave somewhat like transactional tables (added mostly for SystemQA as an explanation why the failure is so widespread in system tests); but again -- if it is not fixable, it makes sense at least to produce a more appropriate message. Test case with temporary tables instead of SAVEPOINT: --source include/have_log_bin.inc --source include/have_binlog_format_statement.inc SET GLOBAL binlog_direct_non_transactional_updates=0; --disable_warnings drop database if exists systest2; --enable_warnings create database systest2; use systest2; CREATE TABLE systest2.tbnum0_eng1 (f1 tinyint) ENGINE = MyISAM; INSERT INTO systest2.tbnum0_eng1 VALUES (82),(83),(98),(99); FLUSH LOGS; --connect (con51,localhost,root,,test) CREATE TEMPORARY TABLE systest2.tmp ( i INT ) ENGINE = MyISAM; INSERT INTO systest2.tmp VALUES (1), (2), (3); USE systest2; start transaction; delete from tbnum0_eng1 where f1=83; SHOW BINLOG EVENTS IN 'master-bin.000002'; DELETE FROM tmp WHERE i = 1; delete from tbnum0_eng1 where f1=82; SHOW BINLOG EVENTS IN 'master-bin.000002'; --connect (con52,localhost,root,,test) USE systest2; delete from tbnum0_eng1 where f1=99; SHOW BINLOG EVENTS IN 'master-bin.000002'; --connection con51 commit; SHOW BINLOG EVENTS IN 'master-bin.000002'; --disconnect con51 --disconnect con52 --connection default DROP DATABASE systest2; --exit
[15 Jul 2010 9:56]
Alfranio Tavares Correia Junior
See also BUG#47326.
[15 Jul 2010 10:09]
Alfranio Tavares Correia Junior
See also BUG#47327.
[11 Oct 2010 15:37]
Alfranio Tavares Correia Junior
Comments "[9 Jul 15:50] Elena Stepanova" are no valid afte BUG#53452. Basically, the comments say that spurious warning messages may be printed out when temporary tables are used. This happened because temporary tables were handle somehow like transactional tables in what concerned writes to the binary log. However, after BUG#53452, temporary tables are handled according to the engine in use and the spurious warnings described in "[9 Jul 15:50] Elena Stepanova" don't happen.