From: Luís Soares Date: May 13 2011 1:45pm Subject: Re: bzr commit into mysql-trunk-mtr branch (alfranio.correia:3080) WL#4832 List-Archive: http://lists.mysql.com/commits/137333 Message-Id: <4DCD3611.1010603@oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit Alfranio, Following my previous comments (http://lists.mysql.com/commits/134932), I have nothing else to point out. Patch looks OK. Thanks for considering my suggestion and for doing this work. Regards, Luís On 05/12/2011 10:51 PM, Alfranio Correia wrote: > #At file:///home/acorreia/workspace.oracle/repository.mysql/bzrwork/wl-4832/mysql-trunk/ based on revid:alfranio.correia@stripped > > 3080 Alfranio Correia 2011-05-12 > WL#4832 > > Refactored the code to make the Log events to go through a cache before > being written to the binary log. In particular, after the WL#2687 only > Query Log Events with DDLS, BEGIN, COMMIT and ROLLBACK, Incident Events > and Rotate Events were written directly to the binary log without > going through a cache. > > After this WL, only Incident Events and Rotate Events are still written > directly to the binary log. > @ mysql-test/extra/binlog_tests/binlog_cache_stat.test > Updated test case because DDLs go through the stmt-cache before being flushed. > @ mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test > Updated test case because DDLs go through the stmt-cache before being flushed. > @ mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result > Updated test case because DDLs go through the stmt-cache before being flushed. > @ mysql-test/suite/binlog/r/binlog_row_cache_stat.result > Updated test case because DDLs go through the stmt-cache before being flushed. > @ mysql-test/suite/binlog/r/binlog_stm_cache_stat.result > Updated test case because DDLs go through the stmt-cache before being flushed. > @ mysql-test/suite/rpl/r/rpl_crash_safe_master.result > The debug option was set before calling CREATE TABLE t2 causing an unexpected crash. > This started happening because the CREATE TABLE now goes to the cache where the > debug option causes a suicide. > @ mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result > Updated test case because DDLs go through the stmt-cache before being flushed. > @ mysql-test/suite/rpl/t/rpl_crash_safe_master.test > The debug option was set before calling CREATE TABLE t2 causing an unexpected crash. > This started happening because the CREATE TABLE now goes to the cache where the > debug option causes a suicide. > @ sql/binlog.cc > The following changes were made: > > . "BEGIN" is appended to either the trx- or stmt-cache when a transaction begins. > > > . "COMMIT/ROLLBACK" is appened to either the trx- or stmt-cache when a transaction ends. > > . DDLs go through the stmt-cache but are immediately written to the binary. > > . The code that decides which cache should be used was refactored and > simplified. > @ sql/binlog.h > use_trans_cache was merged into Query_log_event::Query_log_event and > write_incident(Incident_log_event *ev, bool lock) was created. > @ sql/log_event.cc > The routine that decides which cache should be used was improved by > merging code from the binlog.cc in order to ease maintenance and > improve supportability. > @ sql/log_event.h > Created two different variables to denoate when a change should go > through a cache or not and when it should be written to the binary > log. > > The first variable, event_cache_type, may assume: > > . EVENT_NO_CACHE > . EVENT_STMT_CACHE > . EVENT_TRANSACTIONAL_CACHE > > The variable, event_logging_type, may assume: > > . EVENT_NORMAL_LOGGING > . EVENT_IMMEDIATE_LOGGING > > Any event that does not go through a cache, such as an > Incident or a Rotate event, is tagged as > > . EVENT_NO_CACHE and EVENT_IMMEDIATE_LOGGING > > Query Log Events go through a cache and may be immediately written to the > binary log or written to it upon commit/rollback. In particular, > > . DDLS are tagged as EVENT_STMT_CACHE and EVENT_IMMEDIATE_LOGGING > > The remaining queries and events are tagged as: > > . EVENT_STMT_CACHE or EVENT_TRANSACTIONAL_CACHE and > EVENT_NORMAL_LOGGING > > Changed > > . use_trans_cache to is_using_trans_cache > . use_cache to is_using_stmt_cache > . used_direct_logging to is_using_immediate_logging > > in order to improve readability. > @ sql/log_event_old.cc > Changed use_trans_cache to is_using_trans_cache to improve readability. > @ sql/rpl_injector.cc > When an incident event is logged rotation is automatically forced. > @ sql/sql_class.h > Removed these member functions from the THD as they are now local to > the MYSQL_BIN_LOG after its improvement. > @ sql/sql_insert.cc > Removed this unecessary code after improving MYSQL_BIN_LOG as > an optimized version of binlog_start_trans_and_stmt is now > called for each event if RBR is in use. > @ sql/sql_parse.cc > When an incident event is logged rotation is automatically forced. > > modified: > mysql-test/extra/binlog_tests/binlog_cache_stat.test > mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test > mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result > mysql-test/suite/binlog/r/binlog_row_cache_stat.result > mysql-test/suite/binlog/r/binlog_stm_cache_stat.result > mysql-test/suite/rpl/r/rpl_crash_safe_master.result > mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result > mysql-test/suite/rpl/t/rpl_crash_safe_master.test > sql/binlog.cc > sql/binlog.h > sql/log_event.cc > sql/log_event.h > sql/log_event_old.cc > sql/rpl_injector.cc > sql/sql_class.h > sql/sql_insert.cc > sql/sql_parse.cc > === modified file 'mysql-test/extra/binlog_tests/binlog_cache_stat.test' > --- a/mysql-test/extra/binlog_tests/binlog_cache_stat.test 2010-11-05 17:42:37 +0000 > +++ b/mysql-test/extra/binlog_tests/binlog_cache_stat.test 2011-05-12 21:51:20 +0000 > @@ -20,13 +20,13 @@ create table t2 (a int) engine=myisam; > # > --echo **** Preparing the enviroment to check commit and its effect on status variables. > --echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. > ---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > flush status; > let $exp_cache= 0; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 0; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 0; > +let $exp_stmt_cache= 1; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -39,7 +39,7 @@ if (`SELECT $got_cache<> $exp_cache || > > --echo **** Transactional changes which are long enough so they will be flushed to disk... > --echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. > ---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > let $1=2000; > disable_query_log; > begin; > @@ -54,7 +54,7 @@ let $exp_cache= 1; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 1; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 0; > +let $exp_stmt_cache= 1; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -68,7 +68,7 @@ if (`SELECT $got_cache<> $exp_cache || > --echo **** Transactional changes which should not be flushed to disk and so should not > --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > ---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > commit; > @@ -76,7 +76,7 @@ let $exp_cache= 2; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 1; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 0; > +let $exp_stmt_cache= 1; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -90,7 +90,7 @@ if (`SELECT $got_cache<> $exp_cache || > --echo **** Non-Transactional changes which should not be flushed to disk and so should not > --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > ---echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > begin; > insert into t2 values( 1 ); > commit; > @@ -98,7 +98,7 @@ let $exp_cache= 2; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 1; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 1; > +let $exp_stmt_cache= 2; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -112,7 +112,7 @@ if (`SELECT $got_cache<> $exp_cache || > --echo **** Mixed changes which should not be flushed to disk and so should not > --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > --echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. > ---echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > insert into t2 values( 1 ); > @@ -121,7 +121,7 @@ let $exp_cache= 3; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 1; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 2; > +let $exp_stmt_cache= 3; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -137,13 +137,13 @@ if (`SELECT $got_cache<> $exp_cache || > # > --echo **** Preparing the enviroment to check abort and its effect on the status variables. > --echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. > ---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > flush status; > let $exp_cache= 0; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 0; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 0; > +let $exp_stmt_cache= 1; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -156,7 +156,7 @@ if (`SELECT $got_cache<> $exp_cache || > > --echo **** Transactional changes which are long enough so they will be flushed to disk... > --echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. > ---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > let $1=2000; > disable_query_log; > begin; > @@ -171,7 +171,7 @@ let $exp_cache= 1; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 1; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 0; > +let $exp_stmt_cache= 1; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -185,7 +185,7 @@ if (`SELECT $got_cache<> $exp_cache || > --echo **** Transactional changes which should not be flushed to disk and so should not > --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > ---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > rollback; > @@ -193,7 +193,7 @@ let $exp_cache= 2; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 1; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 0; > +let $exp_stmt_cache= 1; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -207,7 +207,7 @@ if (`SELECT $got_cache<> $exp_cache || > --echo **** Non-Transactional changes which should not be flushed to disk and so should not > --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > ---echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > begin; > insert into t2 values( 1 ); > rollback; > @@ -215,7 +215,7 @@ let $exp_cache= 2; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 1; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 1; > +let $exp_stmt_cache= 2; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > @@ -229,7 +229,7 @@ if (`SELECT $got_cache<> $exp_cache || > --echo **** Mixed changes which should not be flushed to disk and so should not > --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > --echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. > ---echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > +--echo **** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > insert into t2 values( 1 ); > @@ -238,7 +238,7 @@ let $exp_cache= 3; > let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1); > let $exp_disk= 1; > let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1); > -let $exp_stmt_cache= 2; > +let $exp_stmt_cache= 3; > let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1); > let $exp_stmt_disk= 0; > let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1); > > === modified file 'mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test' > --- a/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test 2011-02-23 20:01:27 +0000 > +++ b/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test 2011-05-12 21:51:20 +0000 > @@ -423,10 +423,6 @@ COMMIT; > > --connection slave > --let $slave_sql_errno= 1197 > -if (`SELECT @@binlog_format = 'ROW'`) > -{ > - --let $slave_sql_errno= 1534 > -} > source include/wait_for_slave_sql_error.inc; > > SELECT count(*) FROM t1; > > === modified file 'mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result' > --- a/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result 2010-11-05 17:42:37 +0000 > +++ b/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result 2011-05-12 21:51:20 +0000 > @@ -3,51 +3,51 @@ create table t1 (a int) engine=innodb; > create table t2 (a int) engine=myisam; > **** Preparing the enviroment to check commit and its effect on status variables. > **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > flush status; > **** Transactional changes which are long enough so they will be flushed to disk... > **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > **** Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > commit; > **** Non-Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > begin; > insert into t2 values( 1 ); > commit; > **** Mixed changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > insert into t2 values( 1 ); > commit; > **** Preparing the enviroment to check abort and its effect on the status variables. > **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > flush status; > **** Transactional changes which are long enough so they will be flushed to disk... > **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > **** Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > rollback; > **** Non-Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > begin; > insert into t2 values( 1 ); > rollback; > @@ -56,7 +56,7 @@ Warning 1196 Some non-transactional chan > **** Mixed changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > insert into t2 values( 1 ); > > === modified file 'mysql-test/suite/binlog/r/binlog_row_cache_stat.result' > --- a/mysql-test/suite/binlog/r/binlog_row_cache_stat.result 2010-11-05 17:42:37 +0000 > +++ b/mysql-test/suite/binlog/r/binlog_row_cache_stat.result 2011-05-12 21:51:20 +0000 > @@ -3,51 +3,51 @@ create table t1 (a int) engine=innodb; > create table t2 (a int) engine=myisam; > **** Preparing the enviroment to check commit and its effect on status variables. > **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > flush status; > **** Transactional changes which are long enough so they will be flushed to disk... > **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > **** Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > commit; > **** Non-Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > begin; > insert into t2 values( 1 ); > commit; > **** Mixed changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > insert into t2 values( 1 ); > commit; > **** Preparing the enviroment to check abort and its effect on the status variables. > **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > flush status; > **** Transactional changes which are long enough so they will be flushed to disk... > **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > **** Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > rollback; > **** Non-Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > begin; > insert into t2 values( 1 ); > rollback; > @@ -56,7 +56,7 @@ Warning 1196 Some non-transactional chan > **** Mixed changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > insert into t2 values( 1 ); > > === modified file 'mysql-test/suite/binlog/r/binlog_stm_cache_stat.result' > --- a/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result 2010-11-05 17:42:37 +0000 > +++ b/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result 2011-05-12 21:51:20 +0000 > @@ -3,51 +3,51 @@ create table t1 (a int) engine=innodb; > create table t2 (a int) engine=myisam; > **** Preparing the enviroment to check commit and its effect on status variables. > **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > flush status; > **** Transactional changes which are long enough so they will be flushed to disk... > **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > **** Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > commit; > **** Non-Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > begin; > insert into t2 values( 1 ); > commit; > **** Mixed changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > insert into t2 values( 1 ); > commit; > **** Preparing the enviroment to check abort and its effect on the status variables. > **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > flush status; > **** Transactional changes which are long enough so they will be flushed to disk... > **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > **** Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > rollback; > **** Non-Transactional changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > begin; > insert into t2 values( 1 ); > rollback; > @@ -56,7 +56,7 @@ Warning 1196 Some non-transactional chan > **** Mixed changes which should not be flushed to disk and so should not > **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use. > **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1. > -**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0. > +**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0. > begin; > insert into t1 values( 1 ); > insert into t2 values( 1 ); > > === modified file 'mysql-test/suite/rpl/r/rpl_crash_safe_master.result' > --- a/mysql-test/suite/rpl/r/rpl_crash_safe_master.result 2011-05-05 09:58:48 +0000 > +++ b/mysql-test/suite/rpl/r/rpl_crash_safe_master.result 2011-05-12 21:51:20 +0000 > @@ -69,7 +69,6 @@ include/stop_slave.inc > CREATE TABLE t1(a LONGBLOB) ENGINE=INNODB; > # Test case3: Set DEBUG POINT in the middle of binlog to > # make the master crash for transaction. > -SET SESSION debug="d,half_binlogged_transaction"; > BEGIN; > INSERT INTO t1 (a) VALUES (REPEAT('a',6144)); > INSERT INTO t1 (a) VALUES (REPEAT('a',6144)); > @@ -95,6 +94,7 @@ INSERT INTO t1 (a) VALUES (REPEAT('a',61 > INSERT INTO t1 (a) VALUES (REPEAT('a',6144)); > INSERT INTO t1 (a) VALUES (REPEAT('a',6144)); > INSERT INTO t1 (a) VALUES (REPEAT('a',6144)); > +SET SESSION debug="d,half_binlogged_transaction"; > COMMIT; > ERROR HY000: Lost connection to MySQL server during query > # Restart the master server > @@ -110,8 +110,8 @@ COUNT(*) > 0 > # Test case4: Set DEBUG POINT in the middle of binlog to > # make the master crash for non-transaction. > -SET SESSION debug="d,half_binlogged_transaction"; > CREATE TABLE t2(a LONGBLOB) ENGINE=MYISAM; > +SET SESSION debug="d,half_binlogged_transaction"; > INSERT INTO t2 (a) VALUES (REPEAT('a',16384)); > ERROR HY000: Lost connection to MySQL server during query > # Restart the master server > > === modified file 'mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result' > --- a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result 2011-02-23 20:01:27 +0000 > +++ b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result 2011-05-12 21:51:20 +0000 > @@ -150,7 +150,7 @@ SET GLOBAL binlog_stmt_cache_size= ORIGI > BEGIN; > Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times > COMMIT; > -include/wait_for_slave_sql_error.inc [errno=1534] > +include/wait_for_slave_sql_error.inc [errno=1197] > SELECT count(*) FROM t1; > count(*) > 0 > > === modified file 'mysql-test/suite/rpl/t/rpl_crash_safe_master.test' > --- a/mysql-test/suite/rpl/t/rpl_crash_safe_master.test 2011-05-05 09:58:48 +0000 > +++ b/mysql-test/suite/rpl/t/rpl_crash_safe_master.test 2011-05-12 21:51:20 +0000 > @@ -168,7 +168,6 @@ CREATE TABLE t1(a LONGBLOB) ENGINE=INNOD > > -- echo # Test case3: Set DEBUG POINT in the middle of binlog to > -- echo # make the master crash for transaction. > -SET SESSION debug="d,half_binlogged_transaction"; > BEGIN; > let $rows= 24; > WHILE($rows) > @@ -178,6 +177,7 @@ WHILE($rows) > } > # Write file to make mysql-test-run.pl expect crash and restart > -- exec echo "wait"> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect > +SET SESSION debug="d,half_binlogged_transaction"; > # Run the crashing query > -- error 2013 > COMMIT; > @@ -199,12 +199,12 @@ SELECT COUNT(*) FROM t1; > > -- echo # Test case4: Set DEBUG POINT in the middle of binlog to > -- echo # make the master crash for non-transaction. > -SET SESSION debug="d,half_binlogged_transaction"; > -# Write file to make mysql-test-run.pl expect crash and restart > --- exec echo "wait"> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect > -- let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1) > -- let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) > CREATE TABLE t2(a LONGBLOB) ENGINE=MYISAM; > +# Write file to make mysql-test-run.pl expect crash and restart > +-- exec echo "wait"> $MYSQLTEST_VARDIR/tmp/mysqld.1.expect > +SET SESSION debug="d,half_binlogged_transaction"; > -- error 2013 > INSERT INTO t2 (a) VALUES (REPEAT('a',16384)); > > > === modified file 'sql/binlog.cc' > --- a/sql/binlog.cc 2011-05-12 17:29:19 +0000 > +++ b/sql/binlog.cc 2011-05-12 21:51:20 +0000 > @@ -35,6 +35,7 @@ const char *log_bin_basename= 0; > MYSQL_BIN_LOG mysql_bin_log(&sync_binlog_period); > > static int binlog_init(void *p); > +static void binlog_start_trans_and_stmt(THD *thd, Log_event *start_event); > static int binlog_close_connection(handlerton *hton, THD *thd); > static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv); > static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv); > @@ -85,10 +86,17 @@ class binlog_cache_data > { > public: > > - binlog_cache_data(): m_pending(0), > - incident(FALSE), saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0), > - ptr_binlog_cache_disk_use(0) > - { } > + binlog_cache_data(bool trx_cache_arg, > + ulong max_binlog_cache_size_arg, > + ulong *ptr_binlog_cache_use_arg, > + ulong *ptr_binlog_cache_disk_use_arg) > + : trx_cache(trx_cache_arg), m_pending(0), incident(FALSE), > + saved_max_binlog_cache_size(max_binlog_cache_size_arg), > + ptr_binlog_cache_use(ptr_binlog_cache_use_arg), > + ptr_binlog_cache_disk_use(ptr_binlog_cache_disk_use_arg) > + { > + cache_log.end_of_file= saved_max_binlog_cache_size; > + } > > virtual ~binlog_cache_data() > { > @@ -116,11 +124,16 @@ public: > incident= TRUE; > } > > - bool has_incident(void) > + bool has_incident(void) const > { > return(incident); > } > > + bool is_trx_cache() const > + { > + return trx_cache; > + } > + > virtual void reset() > { > compute_statistics(); > @@ -137,36 +150,6 @@ public: > DBUG_ASSERT(empty()); > } > > - void set_binlog_cache_info(ulong param_max_binlog_cache_size, > - ulong *param_ptr_binlog_cache_use, > - ulong *param_ptr_binlog_cache_disk_use) > - { > - /* > - The assertions guarantee that the set_binlog_cache_info is > - called just once and information passed as parameters are > - never zero. > - > - This is done while calling the constructor binlog_cache_mngr. > - We cannot set informaton in the constructor binlog_cache_data > - because the space for binlog_cache_mngr is allocated through > - a placement new. > - > - In the future, we can refactor this and change it to avoid > - the set_binlog_info. > - */ > - DBUG_ASSERT(saved_max_binlog_cache_size == 0&& > - param_max_binlog_cache_size != 0&& > - ptr_binlog_cache_use == 0&& > - param_ptr_binlog_cache_use != 0&& > - ptr_binlog_cache_disk_use == 0&& > - param_ptr_binlog_cache_disk_use != 0); > - > - saved_max_binlog_cache_size= param_max_binlog_cache_size; > - ptr_binlog_cache_use= param_ptr_binlog_cache_use; > - ptr_binlog_cache_disk_use= param_ptr_binlog_cache_disk_use; > - cache_log.end_of_file= saved_max_binlog_cache_size; > - } > - > /* > Cache to store data before copying it to the binary log. > */ > @@ -189,6 +172,12 @@ protected: > cache_log.end_of_file= saved_max_binlog_cache_size; > } > > + /* > + Defines if this is either a trx-cache or stmt-cache, respectively, a > + transactional or non-transactional cache. > + */ > + bool trx_cache; > + > private: > /* > Pending binrows event. This event is the event where the rows are currently > @@ -243,9 +232,16 @@ private: > class binlog_trx_cache_data : public binlog_cache_data > { > public: > - binlog_trx_cache_data() : m_cannot_rollback(FALSE), > - before_stmt_pos(MY_OFF_T_UNDEF) > - {} > + binlog_trx_cache_data(bool trx_cache_arg, > + ulong max_binlog_cache_size_arg, > + ulong *ptr_binlog_cache_use_arg, > + ulong *ptr_binlog_cache_disk_use_arg) > + : binlog_cache_data(trx_cache_arg, > + max_binlog_cache_size_arg, > + ptr_binlog_cache_use_arg, > + ptr_binlog_cache_disk_use_arg), > + m_cannot_rollback(FALSE), before_stmt_pos(MY_OFF_T_UNDEF) > + { } > > void reset() > { > @@ -254,7 +250,7 @@ public: > binlog_cache_data::reset(); > } > > - bool cannot_rollback() > + bool cannot_rollback() const > { > return m_cannot_rollback; > } > @@ -269,9 +265,9 @@ public: > return my_b_tell(&cache_log); > } > > - my_off_t get_prev_position() > + my_off_t get_prev_position() const > { > - return(before_stmt_pos); > + return before_stmt_pos; > } > > void set_prev_position(my_off_t pos) > @@ -303,24 +299,26 @@ private: > Binlog position before the start of the current statement. > */ > my_off_t before_stmt_pos; > + > + binlog_trx_cache_data& operator=(const binlog_trx_cache_data& info); > + binlog_trx_cache_data(const binlog_trx_cache_data& info); > }; > > class binlog_cache_mngr { > public: > - binlog_cache_mngr(ulong param_max_binlog_stmt_cache_size, > - ulong param_max_binlog_cache_size, > - ulong *param_ptr_binlog_stmt_cache_use, > - ulong *param_ptr_binlog_stmt_cache_disk_use, > - ulong *param_ptr_binlog_cache_use, > - ulong *param_ptr_binlog_cache_disk_use) > - { > - stmt_cache.set_binlog_cache_info(param_max_binlog_stmt_cache_size, > - param_ptr_binlog_stmt_cache_use, > - param_ptr_binlog_stmt_cache_disk_use); > - trx_cache.set_binlog_cache_info(param_max_binlog_cache_size, > - param_ptr_binlog_cache_use, > - param_ptr_binlog_cache_disk_use); > - } > + binlog_cache_mngr(ulong max_binlog_stmt_cache_size_arg, > + ulong *ptr_binlog_stmt_cache_use_arg, > + ulong *ptr_binlog_stmt_cache_disk_use_arg, > + ulong max_binlog_cache_size_arg, > + ulong *ptr_binlog_cache_use_arg, > + ulong *ptr_binlog_cache_disk_use_arg) > + : stmt_cache(FALSE, max_binlog_stmt_cache_size_arg, > + ptr_binlog_stmt_cache_use_arg, > + ptr_binlog_stmt_cache_disk_use_arg), > + trx_cache(TRUE, max_binlog_cache_size_arg, > + ptr_binlog_cache_use_arg, > + ptr_binlog_cache_disk_use_arg) > + { } > > void reset_stmt_cache() > { > @@ -337,7 +335,7 @@ public: > trx_cache.set_cannot_rollback(); > } > > - bool trx_cache_cannot_rollback() > + bool trx_cache_cannot_rollback() const > { > return trx_cache.cannot_rollback(); > } > @@ -434,8 +432,6 @@ binlog_trans_log_savepos(THD *thd, my_of > { > DBUG_ENTER("binlog_trans_log_savepos"); > DBUG_ASSERT(pos != NULL); > - if (thd_get_ha_data(thd, binlog_hton) == NULL) > - thd->binlog_setup_trx_data(); > binlog_cache_mngr *const cache_mngr= > (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); > DBUG_ASSERT(mysql_bin_log.is_open()); > @@ -467,7 +463,6 @@ binlog_trans_log_truncate(THD *thd, my_o > DBUG_PRINT("enter", ("pos: %lu", (ulong) pos)); > > DBUG_ASSERT(thd_get_ha_data(thd, binlog_hton) != NULL); > - /* Only true if binlog_trans_log_savepos() wasn't called before */ > DBUG_ASSERT(pos != ~(my_off_t) 0); > > binlog_cache_mngr *const cache_mngr= > @@ -516,23 +511,27 @@ static int binlog_close_connection(handl > @param thd The thread whose transaction should be flushed > @param cache_data Pointer to the cache > @param end_ev The end event either commit/rollback > - @param is_transactional The type of the cache: transactional or > - non-transactional > > @return > nonzero if an error pops up when flushing the cache. > */ > static inline int > -binlog_flush_cache(THD *thd, binlog_cache_data* cache_data, Log_event *end_evt, > - bool is_transactional) > +binlog_flush_cache(THD *thd, binlog_cache_data* cache_data, Log_event *end_evt) > { > DBUG_ENTER("binlog_flush_cache"); > int error= 0; > > + DBUG_ASSERT((end_evt->is_using_trans_cache()&& cache_data->is_trx_cache()) || > + (!end_evt->is_using_trans_cache()&& !cache_data->is_trx_cache())); > + > if (!cache_data->empty()) > { > - if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional)) > + if (thd->binlog_flush_pending_rows_event(TRUE, cache_data->is_trx_cache())) > + DBUG_RETURN(1); > + > + if (end_evt->write(&cache_data->cache_log)) > DBUG_RETURN(1); > + > /* > Doing a commit or a rollback including non-transactional tables, > i.e., ending a transaction where we might write the transaction > @@ -543,8 +542,10 @@ binlog_flush_cache(THD *thd, binlog_cach > were, we would have to ensure that we're not ending a statement > inside a stored function. > */ > - error= mysql_bin_log.write(thd,&cache_data->cache_log, end_evt, > - cache_data->has_incident()); > + bool prepared= (end_evt->get_type_code() == XID_EVENT); > + error= mysql_bin_log.write(thd,&cache_data->cache_log, > + cache_data->has_incident(), > + prepared); > } > cache_data->reset(); > > @@ -565,10 +566,10 @@ static inline int > binlog_commit_flush_stmt_cache(THD *thd, > binlog_cache_mngr *cache_mngr) > { > + binlog_cache_data* cache_data=&cache_mngr->stmt_cache; > Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"), > - FALSE, TRUE, TRUE, 0); > - return (binlog_flush_cache(thd,&cache_mngr->stmt_cache,&end_evt, > - FALSE)); > + cache_data->is_trx_cache(), FALSE, TRUE, 0, TRUE); > + return binlog_flush_cache(thd, cache_data,&end_evt); > } > > /** > @@ -583,10 +584,10 @@ binlog_commit_flush_stmt_cache(THD *thd, > static inline int > binlog_commit_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr) > { > + binlog_cache_data* cache_data=&cache_mngr->trx_cache; > Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"), > - TRUE, TRUE, TRUE, 0); > - return (binlog_flush_cache(thd,&cache_mngr->trx_cache,&end_evt, > - TRUE)); > + cache_data->is_trx_cache(), FALSE, TRUE, 0, TRUE); > + return binlog_flush_cache(thd, cache_data,&end_evt); > } > > /** > @@ -601,10 +602,10 @@ binlog_commit_flush_trx_cache(THD *thd, > static inline int > binlog_rollback_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr) > { > + binlog_cache_data* cache_data=&cache_mngr->trx_cache; > Query_log_event end_evt(thd, STRING_WITH_LEN("ROLLBACK"), > - TRUE, TRUE, TRUE, 0); > - return (binlog_flush_cache(thd,&cache_mngr->trx_cache,&end_evt, > - TRUE)); > + cache_data->is_trx_cache(), FALSE, TRUE, 0, TRUE); > + return binlog_flush_cache(thd, cache_data,&end_evt); > } > > /** > @@ -622,8 +623,7 @@ binlog_commit_flush_trx_cache(THD *thd, > my_xid xid) > { > Xid_log_event end_evt(thd, xid); > - return (binlog_flush_cache(thd,&cache_mngr->trx_cache,&end_evt, > - TRUE)); > + return binlog_flush_cache(thd,&cache_mngr->trx_cache,&end_evt); > } > > /** > @@ -643,18 +643,13 @@ binlog_truncate_trx_cache(THD *thd, binl > { > DBUG_ENTER("binlog_truncate_trx_cache"); > int error=0; > - /* > - This function handles transactional changes and as such this flag > - equals to true. > - */ > - bool const is_transactional= TRUE; > > DBUG_PRINT("info", ("thd->options={ %s %s}, transaction: %s", > FLAGSTR(thd->variables.option_bits, OPTION_NOT_AUTOCOMMIT), > FLAGSTR(thd->variables.option_bits, OPTION_BEGIN), > all ? "all" : "stmt")); > > - thd->binlog_remove_pending_rows_event(TRUE, is_transactional); > + thd->binlog_remove_pending_rows_event(TRUE, TRUE); > /* > If rolling back an entire transaction or a single statement not > inside a transaction, we reset the transaction cache. > @@ -675,7 +670,7 @@ binlog_truncate_trx_cache(THD *thd, binl > else > cache_mngr->trx_cache.restore_prev_position(); > > - DBUG_ASSERT(thd->binlog_get_pending_rows_event(is_transactional) == NULL); > + DBUG_ASSERT(thd->binlog_get_pending_rows_event(TRUE) == NULL); > DBUG_RETURN(error); > } > > @@ -1148,33 +1143,6 @@ stmt_has_updated_trans_table(const THD * > return (FALSE); > } > > -/** > - This function checks if either a trx-cache or a non-trx-cache should > - be used. If @c bin_log_direct_non_trans_update is active or the format > - is either MIXED or ROW, the cache to be used depends on the flag @c > - is_transactional. > - > - On the other hand, if binlog_format is STMT or direct option is > - OFF, the trx-cache should be used if and only if the statement is > - transactional or the trx-cache is not empty. Otherwise, the > - non-trx-cache should be used. > - > - @param thd The client thread. > - @param is_transactional The changes are related to a trx-table. > - @return > - @c true if a trx-cache should be used, @c false otherwise. > -*/ > -bool use_trans_cache(const THD* thd, bool is_transactional) > -{ > - binlog_cache_mngr *const cache_mngr= > - (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); > - > - return > - ((thd->is_current_stmt_binlog_format_row() || > - thd->variables.binlog_direct_non_trans_update) ? is_transactional : > - (is_transactional || !cache_mngr->trx_cache.empty())); > -} > - > /** > This function checks if a transaction, either a multi-statement > or a single statement transaction is about to commit or not. > @@ -3532,7 +3500,7 @@ MYSQL_BIN_LOG::remove_pending_rows_event > DBUG_ASSERT(cache_mngr); > > binlog_cache_data *cache_data= > - cache_mngr->get_binlog_cache_data(use_trans_cache(thd, is_transactional)); > + cache_mngr->get_binlog_cache_data(is_transactional); > > if (Rows_log_event* pending= cache_data->pending()) > { > @@ -3569,7 +3537,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_row > DBUG_ASSERT(cache_mngr); > > binlog_cache_data *cache_data= > - cache_mngr->get_binlog_cache_data(use_trans_cache(thd, is_transactional)); > + cache_mngr->get_binlog_cache_data(is_transactional); > > DBUG_PRINT("info", ("cache_mngr->pending(): 0x%lx", (long) cache_data->pending())); > > @@ -3615,7 +3583,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve > */ > thd->binlog_evt_union.unioned_events= TRUE; > thd->binlog_evt_union.unioned_events_trans |= > - event_info->use_trans_cache(); > + event_info->is_using_trans_cache(); > DBUG_RETURN(0); > } > > @@ -3627,7 +3595,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve > bool const end_stmt= > thd->locked_tables_mode&& thd->lex->requires_prelocking(); > if (thd->binlog_flush_pending_rows_event(end_stmt, > - event_info->use_trans_cache())) > + event_info->is_using_trans_cache())) > DBUG_RETURN(error); > > /* > @@ -3652,28 +3620,15 @@ bool MYSQL_BIN_LOG::write(Log_event *eve > DBUG_RETURN(0); > #endif /* HAVE_REPLICATION */ > > - IO_CACHE *file= NULL; > - binlog_cache_mngr *cache_mngr= NULL; > - binlog_cache_data *cache_data= 0; > - bool is_trans_cache= FALSE; > - > - if (event_info->use_direct_logging()) > - { > - file=&log_file; > - mysql_mutex_lock(&LOCK_log); > - } > - else > - { > - if (thd->binlog_setup_trx_data()) > - goto err; > - > - cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); > - is_trans_cache= use_trans_cache(thd, event_info->use_trans_cache()); > - file= cache_mngr->get_binlog_cache_log(is_trans_cache); > - cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache); > + DBUG_ASSERT(event_info->is_using_trans_cache() || event_info->is_using_stmt_cache()); > + > + binlog_start_trans_and_stmt(thd, event_info); > > - thd->binlog_start_trans_and_stmt(); > - } > + bool is_trans_cache= event_info->is_using_trans_cache(); > + binlog_cache_mngr *cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); > + IO_CACHE *file= cache_mngr->get_binlog_cache_log(is_trans_cache); > + binlog_cache_data *cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache); > + > DBUG_PRINT("info",("event type: %d",event_info->get_type_code())); > > /* > @@ -3688,16 +3643,11 @@ bool MYSQL_BIN_LOG::write(Log_event *eve > { > if (!thd->is_current_stmt_binlog_format_row()) > { > - /* three possibility for cache_type at this point */ > - DBUG_ASSERT(event_info->cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE || > - event_info->cache_type == Log_event::EVENT_STMT_CACHE || > - event_info->cache_type == Log_event::EVENT_NO_CACHE); > - > if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt) > { > Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT, > thd->first_successful_insert_id_in_prev_stmt_for_binlog, > - event_info->cache_type); > + event_info->event_cache_type, event_info->event_logging_type); > if (e.write(file)) > goto err; > } > @@ -3708,14 +3658,16 @@ bool MYSQL_BIN_LOG::write(Log_event *eve > nb_elements())); > Intvar_log_event e(thd, (uchar) INSERT_ID_EVENT, > thd->auto_inc_intervals_in_cur_stmt_for_binlog. > - minimum(), event_info->cache_type); > + minimum(), event_info->event_cache_type, > + event_info->event_logging_type); > if (e.write(file)) > goto err; > } > if (thd->rand_used) > { > Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2, > - event_info->cache_type); > + event_info->event_cache_type, > + event_info->event_logging_type); > if (e.write(file)) > goto err; > } > @@ -3737,7 +3689,8 @@ bool MYSQL_BIN_LOG::write(Log_event *eve > user_var_event->length, > user_var_event->type, > user_var_event->charset_number, flags, > - event_info->cache_type); > + event_info->event_cache_type, > + event_info->event_logging_type); > if (e.write(file)) > goto err; > } > @@ -3763,25 +3716,12 @@ bool MYSQL_BIN_LOG::write(Log_event *eve > error= 0; > > err: > - if (event_info->use_direct_logging()) > + if (event_info->is_using_immediate_logging()) > { > - if (!error) > - { > - bool synced; > - if ((error= flush_and_sync(&synced))) > - goto unlock; > - > - if ((error= RUN_HOOK(binlog_storage, after_flush, > - (thd, log_file_name, file->pos_in_file, synced)))) > - { > - sql_print_error("Failed to run 'after_flush' hooks"); > - goto unlock; > - } > - signal_update(); > - rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); > - } > -unlock: > - mysql_mutex_unlock(&LOCK_log); > + error |= mysql_bin_log.write(thd,&cache_data->cache_log, > + cache_data->has_incident(), > + FALSE); > + cache_data->reset(); > } > > if (error) > @@ -4134,7 +4074,18 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE > return 0; // All OK > } > > -bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock) > +/** > + Writes an incident event to the binary log. > + > + @param ev Incident event to be written > + @param lock If the binary lock should be locked or not > + > + @retval > + 0 error > + @retval > + 1 success > +*/ > +bool MYSQL_BIN_LOG::write_incident(Incident_log_event *ev, bool lock) > { > uint error= 0; > DBUG_ENTER("MYSQL_BIN_LOG::write_incident"); > @@ -4142,40 +4093,61 @@ bool MYSQL_BIN_LOG::write_incident(THD * > if (!is_open()) > DBUG_RETURN(error); > > - LEX_STRING const write_error_msg= > - { C_STRING_WITH_LEN("error writing to the binary log") }; > - Incident incident= INCIDENT_LOST_EVENTS; > - Incident_log_event ev(thd, incident, write_error_msg); > if (lock) > mysql_mutex_lock(&LOCK_log); > - error= ev.write(&log_file); > + > + error= ev->write(&log_file); > + > if (lock) > { > if (!error&& !(error= flush_and_sync(0))) > { > signal_update(); > - error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED); > + error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED | > + RP_FORCE_ROTATE); > } > mysql_mutex_unlock(&LOCK_log); > } > + > DBUG_RETURN(error); > } > > /** > + Creates an incident event and writes it to the binary log. > + > + @param thd Thread variable > + @param ev Incident event to be written > + @param lock If the binary lock should be locked or not > + > + @retval > + 0 error > + @retval > + 1 success > +*/ > +bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock) > +{ > + DBUG_ENTER("MYSQL_BIN_LOG::write_incident"); > + > + if (!is_open()) > + DBUG_RETURN(0); > + > + LEX_STRING const write_error_msg= > + { C_STRING_WITH_LEN("error writing to the binary log") }; > + Incident incident= INCIDENT_LOST_EVENTS; > + Incident_log_event ev(thd, incident, write_error_msg); > + > + DBUG_RETURN(write_incident(&ev, lock)); > +} > + > +/** > Write a cached log entry to the binary log. > - - To support transaction over replication, we wrap the transaction > - with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log. > - We want to write a BEGIN/ROLLBACK block when a non-transactional table > - was updated in a transaction which was rolled back. This is to ensure > - that the same updates are run on the slave. > > - @param thd > + @param thd Thread variable > @param cache The cache to copy to the binlog > - @param commit_event The commit event to print after writing the > - contents of the cache. > @param incident Defines if an incident event should be created to > notify that some non-transactional changes did > not get into the binlog. > + @param prepared Defines if a transaction is part of a 2-PC. > > @note > We only come here if there is something in the cache. > @@ -4185,8 +4157,7 @@ bool MYSQL_BIN_LOG::write_incident(THD * > 'cache' needs to be reinitialized after this functions returns. > */ > > -bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event, > - bool incident) > +bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, bool incident, bool prepared) > { > DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)"); > mysql_mutex_lock(&LOCK_log); > @@ -4200,14 +4171,6 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C > */ > if (my_b_tell(cache)> 0) > { > - /* > - Log "BEGIN" at the beginning of every transaction. Here, a > - transaction is either a BEGIN..COMMIT block or a single > - statement in autocommit mode. > - */ > - Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, TRUE, TRUE, 0); > - if (qinfo.write(&log_file)) > - goto err; > DBUG_EXECUTE_IF("crash_before_writing_xid", > { > if ((write_error= write_cache(cache, false, true))) > @@ -4220,9 +4183,6 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C > if ((write_error= write_cache(cache, false, false))) > goto err; > > - if (commit_event&& commit_event->write(&log_file)) > - goto err; > - > if (incident&& write_incident(thd, FALSE)) > goto err; > > @@ -4256,7 +4216,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C > If the commit_event is not Xid_log_event (then it's a Query_log_event) > rotate binlog, if necessary. > */ > - if (commit_event&& commit_event->get_type_code() == XID_EVENT) > + if (prepared) > { > mysql_mutex_lock(&LOCK_prep_xids); > prepared_xids++; > @@ -4757,25 +4717,20 @@ int THD::binlog_setup_trx_data() > > cache_mngr= new (thd_get_ha_data(this, binlog_hton)) > binlog_cache_mngr(max_binlog_stmt_cache_size, > - max_binlog_cache_size, > &binlog_stmt_cache_use, > &binlog_stmt_cache_disk_use, > + max_binlog_cache_size, > &binlog_cache_use, > &binlog_cache_disk_use); > DBUG_RETURN(0); > } > > -/* > +/** > Function to start a statement and optionally a transaction for the > binary log. > > - SYNOPSIS > - binlog_start_trans_and_stmt() > - > - DESCRIPTION > - > - This function does three things: > - - Start a transaction if not in autocommit mode or if a BEGIN > + This function does three things: > + - Starts a transaction if not in autocommit mode or if a BEGIN > statement has been seen. > > - Start a statement transaction to allow us to truncate the cache. > @@ -4790,55 +4745,89 @@ int THD::binlog_setup_trx_data() > we should use the first. This means that calls to this function > can be used to start the statement before the first table map > event, to include some extra events. > - */ > > -void > -THD::binlog_start_trans_and_stmt() > + Note however that IMMEDIATE_LOGGING implies that the statement is > + written without BEGIN/COMMIT. > + > + @param thd Thread variable > + @param start_event The first event requested to be written into the > + binary log > + */ > +inline void binlog_start_trans_and_stmt(THD *thd, Log_event *start_event) > { > - binlog_cache_mngr *cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton); > DBUG_ENTER("binlog_start_trans_and_stmt"); > - DBUG_PRINT("enter", ("cache_mngr: %p cache_mngr->trx_cache.get_prev_position(): %lu", > - cache_mngr, > - (cache_mngr ? (ulong) cache_mngr->trx_cache.get_prev_position() : > - (ulong) 0))); > - > - if (cache_mngr == NULL || > - cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF) > - { > - this->binlog_set_stmt_begin(); > - if (in_multi_stmt_transaction_mode()) > - trans_register_ha(this, TRUE, binlog_hton); > - trans_register_ha(this, FALSE, binlog_hton); > + > + /* > + Initialize the cache manager if this was not done yet. > + */ > + if (thd_get_ha_data(thd, binlog_hton) == NULL) > + thd->binlog_setup_trx_data(); > + > + /* > + If the event is requesting immediatly logging, there is no need to go > + further and set savepoint and register callbacks. > + */ > + if (start_event->is_using_immediate_logging()) > + DBUG_VOID_RETURN; > + > + /* > + Retrieve the appropriated cache. > + */ > + bool is_transactional= start_event->is_using_trans_cache(); > + binlog_cache_mngr *cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); > + binlog_cache_data *cache= cache_mngr->get_binlog_cache_data(is_transactional); > + > + /* > + If this is the first call to this funciton while processing a statement, > + the transactional cache does not have a savepoint defined. So, in what > + follows: > + . an implicit savepoint is defined; > + . callbacks are registered; > + . binary log is set as read/write. > + > + The savepoint allows for truncating the trx-cache transactional changes > + fail. Callbacks are necessary to flush caches upon committing or rolling > + back a statement or a transaction. However, notifications do not happen > + if the binary log is set as read/write. > + */ > + if (cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF) > + { > /* > - Mark statement transaction as read/write. We never start > - a binary log transaction and keep it read-only, > - therefore it's best to mark the transaction read/write just > - at the same time we start it. > - Not necessary to mark the normal transaction read/write > - since the statement-level flag will be propagated automatically > - inside ha_commit_trans. > + Set an implicit savepoint in order to be able to truncate a trx-cache. > */ > - ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write(); > - } > - DBUG_VOID_RETURN; > -} > + my_off_t pos= 0; > + binlog_trans_log_savepos(thd,&pos); > + cache_mngr->trx_cache.set_prev_position(pos); > > -void THD::binlog_set_stmt_begin() { > - binlog_cache_mngr *cache_mngr= > - (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton); > + /* > + Set callbacks in order to be able to call commmit or rollback. > + */ > + if (thd->in_multi_stmt_transaction_mode()) > + trans_register_ha(thd, TRUE, binlog_hton); > + trans_register_ha(thd, FALSE, binlog_hton); > + > + /* > + Set the binary log as read/write otherwise callbacks are not called. > + */ > + thd->ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write(); > + } > > /* > - The call to binlog_trans_log_savepos() might create the cache_mngr > - structure, if it didn't exist before, so we save the position > - into an auto variable and then write it into the transaction > - data for the binary log (i.e., cache_mngr). > - */ > - my_off_t pos= 0; > - binlog_trans_log_savepos(this,&pos); > - cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton); > - cache_mngr->trx_cache.set_prev_position(pos); > -} > + If the cache is empty log "BEGIN" at the beginning of every transaction. > + Here, a transaction is either a BEGIN..COMMIT/ROLLBACK block or a single > + statement in autocommit mode. > + */ > + if (cache->empty()) > + { > + IO_CACHE *file= > + cache_mngr->get_binlog_cache_log(is_transactional); > + Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), > + is_transactional, FALSE, TRUE, 0, TRUE); > + qinfo.write(file); > + } > > + DBUG_VOID_RETURN; > +} > > /** > This function writes a table map to the binary log. > @@ -4875,14 +4864,13 @@ int THD::binlog_write_table_map(TABLE *t > Table_map_log_event > the_event(this, table, table->s->table_map_id, is_transactional); > > - if (binlog_table_maps == 0) > - binlog_start_trans_and_stmt(); > + binlog_start_trans_and_stmt(this,&the_event); > > binlog_cache_mngr *const cache_mngr= > (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton); > > IO_CACHE *file= > - cache_mngr->get_binlog_cache_log(use_trans_cache(this, is_transactional)); > + cache_mngr->get_binlog_cache_log(is_transactional); > > if (binlog_rows_query&& this->query()) > { > @@ -4926,7 +4914,7 @@ THD::binlog_get_pending_rows_event(bool > if (cache_mngr) > { > binlog_cache_data *cache_data= > - cache_mngr->get_binlog_cache_data(use_trans_cache(this, is_transactional)); > + cache_mngr->get_binlog_cache_data(is_transactional); > > rows= cache_data->pending(); > } > @@ -4946,16 +4934,13 @@ THD::binlog_get_pending_rows_event(bool > void > THD::binlog_set_pending_rows_event(Rows_log_event* ev, bool is_transactional) > { > - if (thd_get_ha_data(this, binlog_hton) == NULL) > - binlog_setup_trx_data(); > - > binlog_cache_mngr *const cache_mngr= > (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton); > > DBUG_ASSERT(cache_mngr); > > binlog_cache_data *cache_data= > - cache_mngr->get_binlog_cache_data(use_trans_cache(this, is_transactional)); > + cache_mngr->get_binlog_cache_data(is_transactional); > > cache_data->set_pending(ev); > } > @@ -5379,13 +5364,6 @@ THD::binlog_prepare_pending_rows_event(T > /* Fetch the type code for the RowsEventT template parameter */ > int const type_code= RowsEventT::TYPE_CODE; > > - /* > - There is no good place to set up the transactional data, so we > - have to do it here. > - */ > - if (binlog_setup_trx_data()) > - DBUG_RETURN(NULL); > - > Rows_log_event* pending= binlog_get_pending_rows_event(is_transactional); > > if (unlikely(pending&& !pending->is_valid())) > > === modified file 'sql/binlog.h' > --- a/sql/binlog.h 2011-05-12 17:29:19 +0000 > +++ b/sql/binlog.h 2011-05-12 21:51:20 +0000 > @@ -229,12 +229,13 @@ public: > int new_file(); > > bool write(Log_event* event_info); // binary log write > - bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident); > - > - bool write_incident(THD *thd, bool lock); > + bool write(THD *thd, IO_CACHE *cache, bool incident, bool prepared); > int write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync); > + > void set_write_error(THD *thd, bool is_transactional); > bool check_write_error(THD *thd); > + bool write_incident(THD *thd, bool lock); > + bool write_incident(Incident_log_event *ev, bool lock); > > void start_union_events(THD *thd, query_id_t query_id_param); > void stop_union_events(THD *thd); > @@ -320,7 +321,6 @@ extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG > > bool trans_has_updated_trans_table(const THD* thd); > bool stmt_has_updated_trans_table(const THD *thd); > -bool use_trans_cache(const THD* thd, bool is_transactional); > bool ending_trans(THD* thd, const bool all); > bool ending_single_stmt_trans(THD* thd, const bool all); > bool trans_cannot_safely_rollback(const THD* thd); > > === modified file 'sql/log_event.cc' > --- a/sql/log_event.cc 2011-05-12 17:29:19 +0000 > +++ b/sql/log_event.cc 2011-05-12 21:51:20 +0000 > @@ -678,18 +678,16 @@ const char* Log_event::get_type_str() > */ > > #ifndef MYSQL_CLIENT > -Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans) > +Log_event::Log_event(THD* thd_arg, uint16 flags_arg, > + enum_event_cache_type cache_type_arg, > + enum_event_logging_type logging_type_arg) > :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), > - cache_type(Log_event::EVENT_INVALID_CACHE), crc(0), thd(thd_arg), > - checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF) > + event_cache_type(cache_type_arg), > + event_logging_type(logging_type_arg), > + crc(0), thd(thd_arg), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF) > { > server_id= thd->server_id; > when= thd->start_time; > - > - if (using_trans) > - cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE; > - else > - cache_type= Log_event::EVENT_STMT_CACHE; > } > > /** > @@ -699,9 +697,11 @@ Log_event::Log_event(THD* thd_arg, uint1 > the binlog but we have no THD, so we need this minimal constructor). > */ > > -Log_event::Log_event() > - :temp_buf(0), exec_time(0), flags(0), crc(0), thd(0), > - checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF) > +Log_event::Log_event(enum_event_cache_type cache_type_arg, > + enum_event_logging_type logging_type_arg) > + :temp_buf(0), exec_time(0), flags(0), event_cache_type(cache_type_arg), > + event_logging_type(logging_type_arg), crc(0), thd(0), > + checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF) > { > server_id= ::server_id; > /* > @@ -720,8 +720,10 @@ Log_event::Log_event() > > Log_event::Log_event(const char* buf, > const Format_description_log_event* description_event) > - :temp_buf(0), exec_time(0), cache_type(Log_event::EVENT_INVALID_CACHE), > - crc(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF) > + :temp_buf(0), exec_time(0), > + event_cache_type(EVENT_INVALID_CACHE), > + event_logging_type(EVENT_INVALID_LOGGING), > + crc(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF) > { > #ifndef MYSQL_CLIENT > thd = 0; > @@ -904,18 +906,20 @@ void Log_event::init_show_field_list(Lis > my_bool Log_event::need_checksum() > { > DBUG_ENTER("Log_event::need_checksum"); > - my_bool ret; > + my_bool ret= FALSE; > /* > few callers of Log_event::write > (incl FD::write, FD constructing code on the slave side, Rotate relay log > and Stop event) > provides their checksum alg preference through Log_event::checksum_alg. > */ > - ret= (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) ? > - (checksum_alg != BINLOG_CHECKSUM_ALG_OFF) : > - ((binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF)&& > - (cache_type == Log_event::EVENT_NO_CACHE))? binlog_checksum_options : > - FALSE; > + if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) > + ret= (checksum_alg != BINLOG_CHECKSUM_ALG_OFF); > + else if (binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF&& > + event_cache_type == Log_event::EVENT_NO_CACHE) > + ret= binlog_checksum_options; > + else > + ret= FALSE; > > /* > FD calls the methods before data_written has been calculated. > @@ -955,7 +959,7 @@ my_bool Log_event::need_checksum() > DBUG_ASSERT(((get_type_code() != ROTATE_EVENT&& > get_type_code() != STOP_EVENT) || > get_type_code() != FORMAT_DESCRIPTION_EVENT) || > - cache_type == Log_event::EVENT_NO_CACHE); > + event_cache_type == Log_event::EVENT_NO_CACHE); > > DBUG_RETURN(ret); > } > @@ -2681,29 +2685,33 @@ Query_log_event::Query_log_event() > } > > > -/* > - SYNOPSIS > - Query_log_event::Query_log_event() > - thd_arg - thread handle > - query_arg - array of char representing the query > - query_length - size of the `query_arg' array > - using_trans - there is a modified transactional table > - suppress_use - suppress the generation of 'USE' statements > - errcode - the error code of the query > - > - DESCRIPTION > - Creates an event for binlogging > - The value for `errcode' should be supplied by caller. > +/** > + Creates a Query Log Event. > + > + @param thd_arg Thread handle > + @param query_arg Array of char representing the query > + @param query_length Size of the 'query_arg' array > + @param using_trans Indicates that there are transactional changes. > + @param immediate After being written to the binary log, the event > + must be flushed immediately. This indirectly implies > + the stmt-cache. > + @param suppress_use Suppress the generation of 'USE' statements > + @param errcode The error code of the query > + @param ignore Ignore user's statement, i.e. lex information, while > + deciding which cache must be used. > */ > Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, > ulong query_length, bool using_trans, > - bool direct, bool suppress_use, int errcode) > + bool immediate, bool suppress_use, > + int errcode, bool ignore_cmd_internals) > > :Log_event(thd_arg, > (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : > 0) | > (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0), > - using_trans), > + using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE : > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > data_buf(0), query(query_arg), catalog(thd_arg->catalog), > db(thd_arg->db), q_len((uint32) query_length), > thread_id(thd_arg->thread_id), > @@ -2781,62 +2789,146 @@ Query_log_event::Query_log_event(THD* th > else > time_zone_len= 0; > > - LEX *lex= thd->lex; > /* > - Defines that the statement will be written directly to the binary log > - without being wrapped by a BEGIN...COMMIT. Otherwise, the statement > - will be written to either the trx-cache or stmt-cache. > + In what follows, we define in which cache, trx-cache or stmt-cache, > + this Query Log Event will be written to. > > - Note that a cache will not be used if the parameter direct is TRUE. > + If ignore_cmd_internals is defined, we rely on the is_trans flag to > + choose the cache and this is done in the base class Log_event. False > + means that the stmt-cache will be used and upon statement commit/rollback > + the cache will be flushed to disk. True means that the trx-cache will > + be used and upon transaction commit/rollback the cache will be flushed > + to disk. > + > + If set immediate cache is defined, for convenience, we automatically > + use the stmt-cache. This mean that the statement will be written > + to the stmt-cache and immediately flushed to disk without waiting > + for a commit/rollback notification. > + > + For example, the cluster/ndb captures a request to execute a DDL > + statement and synchronously propagate it to all available MySQL > + servers. Unfortunately, the current protocol assumes that the > + generated events are immediately written to diks and does not check > + for commit/rollback. > + > + Upon dropping a connection, DDLs (i.e. DROP TEMPORARY TABLE) are > + generated and in this case the statements have the immediate flag > + set because there is no commit/rollback. > + > + If the immediate flag is not set, the decision on the cache is based > + on the current statement and the flag is_trans, which indicates if > + a transactional engine was updated. > + > + Statements are classifed as row producers (i.e. can_generate_row_events()) > + or non-row producers. Non-row producers, DDL in general, are treated > + as the immediate flag was set and for convenience are written to the > + stmt-cache and immediately flushed to disk. > + > + Row producers are handled in general according to the is_trans flag. > + False means that the stmt-cache will be used and upon statement > + commit/rollback the cache will be flushed to disk. True means that the > + trx-cache will be used and upon transaction commit/rollback the cache > + will be flushed to disk. > + > + Unfortunately, there are exceptions to this non-row and row producer > + rules: > + > + . The SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT does not > + have the flag is_trans set because there is no updated engine but > + must be written to the trx-cache. > + > + . SET does not have the flag is_trans set but, if auto-commit is off, > + must be written to the trx-cache. > + > + . CREATE TABLE is classfied as non-row producer but CREATE TEMPORARY > + must be handled as row producer. > + > + . DROP TABLE is classfied as non-row producer but DROP TEMPORARY > + must be handled as row producer. > + > + Finally, some statements that does not have the flag is_trans set may > + be written to the trx-cache based on the following criteria: > + > + . updated both a transactional and a non-transactional engine (i.e. > + stmt_has_updated_trans_table()). > + > + . accessed both a transactional and a non-transactional engine and > + is classified as unsafe (i.e. is_mixed_stmt_unsafe()). > + > + . is executed within a transaction and previously a transactional > + engine was updated and the flag binlog_direct_non_trans_update > + is set. > */ > - bool use_cache= FALSE; > - /* > - TRUE defines that the trx-cache must be used and by consequence the > - use_cache is TRUE. > + if (ignore_cmd_internals) > + return; > > - Note that a cache will not be used if the parameter direct is TRUE. > + /* > + TRUE defines that the trx-cache must be used. > */ > - bool trx_cache= FALSE; > - cache_type= Log_event::EVENT_INVALID_CACHE; > - > - switch (lex->sql_command) > + bool cmd_can_generate_row_events= FALSE; > + /* > + TRUE defines that the trx-cache must be used. > + */ > + bool cmd_must_go_to_trx_cache= FALSE; > + > + LEX *lex= thd->lex; > + if (!immediate) > { > - case SQLCOM_DROP_TABLE: > - use_cache= (lex->drop_temporary&& thd->in_multi_stmt_transaction_mode()); > - break; > - > - case SQLCOM_CREATE_TABLE: > - trx_cache= (lex->select_lex.item_list.elements&& > - thd->is_current_stmt_binlog_format_row()); > - use_cache= ((lex->create_info.options& HA_LEX_CREATE_TMP_TABLE)&& > - thd->in_multi_stmt_transaction_mode()) || trx_cache; > - break; > - case SQLCOM_SET_OPTION: > - use_cache= trx_cache= (lex->autocommit ? FALSE : TRUE); > - break; > - case SQLCOM_RELEASE_SAVEPOINT: > - case SQLCOM_ROLLBACK_TO_SAVEPOINT: > - case SQLCOM_SAVEPOINT: > - use_cache= trx_cache= TRUE; > - break; > - default: > - use_cache= sqlcom_can_generate_row_events(thd); > - break; > + switch (lex->sql_command) > + { > + case SQLCOM_DROP_TABLE: > + cmd_can_generate_row_events= lex->drop_temporary&& > + thd->in_multi_stmt_transaction_mode(); > + break; > + case SQLCOM_CREATE_TABLE: > + cmd_must_go_to_trx_cache= lex->select_lex.item_list.elements&& > + thd->is_current_stmt_binlog_format_row(); > + cmd_can_generate_row_events= > + ((lex->create_info.options& HA_LEX_CREATE_TMP_TABLE)&& > + thd->in_multi_stmt_transaction_mode()) || cmd_must_go_to_trx_cache; > + break; > + case SQLCOM_SET_OPTION: > + cmd_can_generate_row_events= cmd_must_go_to_trx_cache= > + (lex->autocommit ? FALSE : TRUE); > + break; > + case SQLCOM_RELEASE_SAVEPOINT: > + case SQLCOM_ROLLBACK_TO_SAVEPOINT: > + case SQLCOM_SAVEPOINT: > + cmd_can_generate_row_events= cmd_must_go_to_trx_cache= TRUE; > + break; > + default: > + cmd_can_generate_row_events= sqlcom_can_generate_row_events(thd); > + break; > + } > } > - > - if (!use_cache || direct) > + > + if (cmd_can_generate_row_events) > { > - cache_type= Log_event::EVENT_NO_CACHE; > + cmd_must_go_to_trx_cache= cmd_must_go_to_trx_cache || using_trans; > + if (cmd_must_go_to_trx_cache || stmt_has_updated_trans_table(thd) || > + thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(), > + thd->variables.binlog_direct_non_trans_update, > + trans_has_updated_trans_table(thd), > + thd->tx_isolation) || > + (!thd->variables.binlog_direct_non_trans_update&& trans_has_updated_trans_table(thd))) > + { > + event_logging_type= Log_event::EVENT_NORMAL_LOGGING; > + event_cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE; > + } > + else > + { > + event_logging_type= Log_event::EVENT_NORMAL_LOGGING; > + event_cache_type= Log_event::EVENT_STMT_CACHE; > + } > } > - else if (using_trans || trx_cache || stmt_has_updated_trans_table(thd) || > - thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(), > - thd->variables.binlog_direct_non_trans_update, > - trans_has_updated_trans_table(thd), > - thd->tx_isolation)) > - cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE; > else > - cache_type= Log_event::EVENT_STMT_CACHE; > - DBUG_ASSERT(cache_type != Log_event::EVENT_INVALID_CACHE); > + { > + event_logging_type= Log_event::EVENT_IMMEDIATE_LOGGING; > + event_cache_type= Log_event::EVENT_STMT_CACHE; > + } > + > + DBUG_ASSERT(event_cache_type != Log_event::EVENT_INVALID_CACHE); > + DBUG_ASSERT(event_logging_type != Log_event::EVENT_INVALID_LOGGING); > DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %llu", > (ulong) flags2, sql_mode)); > } > @@ -4828,7 +4920,9 @@ Load_log_event::Load_log_event(THD *thd_ > bool ignore, bool using_trans) > :Log_event(thd_arg, > thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0, > - using_trans), > + using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE : > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > thread_id(thd_arg->thread_id), > slave_proxy_id(thd_arg->variables.pseudo_thread_id), > num_fields(0),fields(0), > @@ -5473,9 +5567,9 @@ void Rotate_log_event::print(FILE* file, > Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg, > uint ident_len_arg, ulonglong pos_arg, > uint flags_arg) > - :Log_event(), new_log_ident(new_log_ident_arg), > - pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg : > - (uint) strlen(new_log_ident_arg)), flags(flags_arg) > + :Log_event(Log_event::EVENT_NO_CACHE, Log_event::EVENT_IMMEDIATE_LOGGING), > + new_log_ident(new_log_ident_arg), pos(pos_arg),ident_len(ident_len_arg ? > + ident_len_arg : (uint) strlen(new_log_ident_arg)), flags(flags_arg) > { > #ifndef DBUG_OFF > char buff[22]; > @@ -5483,7 +5577,8 @@ Rotate_log_event::Rotate_log_event(const > DBUG_PRINT("enter",("new_log_ident: %s pos: %s flags: %lu", new_log_ident_arg, > llstr(pos_arg, buff), (ulong) flags)); > #endif > - cache_type= EVENT_NO_CACHE; > + event_cache_type= EVENT_NO_CACHE; > + event_logging_type= EVENT_IMMEDIATE_LOGGING; > if (flags& DUP_NAME) > new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME)); > if (flags& RELAY_LOG) > @@ -6839,7 +6934,11 @@ Append_block_log_event::Append_block_log > uchar *block_arg, > uint block_len_arg, > bool using_trans) > - :Log_event(thd_arg,0, using_trans), block(block_arg), > + :Log_event(thd_arg, 0, > + using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE : > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > + block(block_arg), > block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg) > { > } > @@ -7006,7 +7105,11 @@ err: > #ifndef MYSQL_CLIENT > Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg, > bool using_trans) > - :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg) > + :Log_event(thd_arg, 0, > + using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE : > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > + file_id(thd_arg->file_id), db(db_arg) > { > } > #endif > @@ -7102,7 +7205,11 @@ int Delete_file_log_event::do_apply_even > Execute_load_log_event::Execute_load_log_event(THD *thd_arg, > const char* db_arg, > bool using_trans) > - :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg) > + :Log_event(thd_arg, 0, > + using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE : > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > + file_id(thd_arg->file_id), db(db_arg) > { > } > #endif > @@ -7318,9 +7425,9 @@ Execute_load_query_log_event(THD *thd_ar > ulong query_length_arg, uint fn_pos_start_arg, > uint fn_pos_end_arg, > enum_load_dup_handling dup_handling_arg, > - bool using_trans, bool direct, bool suppress_use, > + bool using_trans, bool immediate, bool suppress_use, > int errcode): > - Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, direct, > + Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, immediate, > suppress_use, errcode), > file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg), > fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg) > @@ -7595,8 +7702,11 @@ const char *sql_ex_info::init(const char > > #ifndef MYSQL_CLIENT > Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, > - MY_BITMAP const *cols, bool is_transactional) > - : Log_event(thd_arg, 0, is_transactional), > + MY_BITMAP const *cols, bool using_trans) > + : Log_event(thd_arg, 0, > + using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE : > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > m_row_count(0), > m_table(tbl_arg), > m_table_id(tid), > @@ -8518,8 +8628,11 @@ int Table_map_log_event::save_field_meta > */ > #if !defined(MYSQL_CLIENT) > Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, > - bool is_transactional) > - : Log_event(thd, 0, is_transactional), > + bool using_trans) > + : Log_event(thd, 0, > + using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE : > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > m_table(tbl), > m_dbnam(tbl->s->db.str), > m_dblen(m_dbnam ? tbl->s->db.length : 0), > > === modified file 'sql/log_event.h' > --- a/sql/log_event.h 2011-03-22 11:44:40 +0000 > +++ b/sql/log_event.h 2011-05-12 21:51:20 +0000 > @@ -926,9 +926,10 @@ public: > EVENT_SKIP_COUNT > }; > > +protected: > enum enum_event_cache_type > { > - EVENT_INVALID_CACHE, > + EVENT_INVALID_CACHE= 0, > /* > If possible the event should use a non-transactional cache before > being flushed to the binary log. This means that it must be flushed > @@ -943,15 +944,35 @@ public: > EVENT_TRANSACTIONAL_CACHE, > /* > The event must be written directly to the binary log without going > - through a cache. > + through any cache. > */ > EVENT_NO_CACHE, > - /** > + /* > If there is a need for different types, introduce them before this. > */ > EVENT_CACHE_COUNT > }; > > + enum enum_event_logging_type > + { > + EVENT_INVALID_LOGGING= 0, > + /* > + The event must be written to a cache and upon commit or rollback > + written to the binary log. > + */ > + EVENT_NORMAL_LOGGING, > + /* > + The event must be written to an empty cache and immediatly written > + to the binary log without waiting for any other event. > + */ > + EVENT_IMMEDIATE_LOGGING, > + /* > + If there is a need for different types, introduce them before this. > + */ > + EVENT_CACHE_LOGGING_COUNT > + }; > + > +public: > /* > The following type definition is to be used whenever data is placed > and manipulated in a common buffer. Use this typedef for buffers > @@ -1002,12 +1023,6 @@ public: > */ > uint16 flags; > > - /* > - Defines the type of the cache, if any, where the event will be > - stored before being flushed to disk. > - */ > - uint16 cache_type; > - > /** > A storage to cache the global system variable's value. > Handling of a separate event will be governed its member. > @@ -1015,14 +1030,28 @@ public: > ulong slave_exec_mode; > > /** > + Defines the type of the cache, if any, where the event will be > + stored before being flushed to disk. > + */ > + enum_event_cache_type event_cache_type; > + > + /** > + Defines when information, i.e. event or cache, will be flushed > + to disk. > + */ > + enum_event_logging_type event_logging_type; > + /** > Placeholder for event checksum while writing to binlog. > */ > ha_checksum crc; > #ifdef MYSQL_SERVER > THD* thd; > > - Log_event(); > - Log_event(THD* thd_arg, uint16 flags_arg, bool is_transactional); > + Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE, > + enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING); > + Log_event(THD* thd_arg, uint16 flags_arg, > + enum_event_cache_type cache_type_arg, > + enum_event_logging_type logging_type_arg); > /* > read_log_event() functions read an event from a binlog or relay > log; used by SHOW BINLOG EVENTS, the binlog_dump thread on the > @@ -1063,7 +1092,10 @@ public: > return thd ? thd->db : 0; > } > #else > - Log_event() : temp_buf(0) {} > + Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE, > + enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING) > + : temp_buf(0), event_cache_type(cache_type_arg), > + event_logging_type(logging_type_arg) { } > /* avoid having to link mysqlbinlog against libpthread */ > static Log_event* read_log_event(IO_CACHE* file, > const Format_description_log_event > @@ -1137,17 +1169,17 @@ public: > bool is_relay_log_event() const { return flags& LOG_EVENT_RELAY_LOG_F; } > bool is_ignorable_event() const { return flags& LOG_EVENT_IGNORABLE_F; } > bool is_no_filter_event() const { return flags& LOG_EVENT_NO_FILTER_F; } > - inline bool use_trans_cache() const > - { > - return (cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE); > + inline bool is_using_trans_cache() const > + { > + return (event_cache_type == EVENT_TRANSACTIONAL_CACHE); > } > - inline void set_direct_logging() > + inline bool is_using_stmt_cache() const > { > - cache_type = Log_event::EVENT_NO_CACHE; > + return(event_cache_type == EVENT_STMT_CACHE); > } > - inline bool use_direct_logging() > + inline bool is_using_immediate_logging() const > { > - return (cache_type == Log_event::EVENT_NO_CACHE); > + return(event_logging_type == EVENT_IMMEDIATE_LOGGING); > } > Log_event(const char* buf, const Format_description_log_event > *description_event); > @@ -1774,7 +1806,8 @@ public: > #ifdef MYSQL_SERVER > > Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, > - bool using_trans, bool direct, bool suppress_use, int error); > + bool using_trans, bool immediate, bool suppress_use, > + int error, bool ignore_command= FALSE); > const char* get_db() { return db; } > #ifdef HAVE_REPLICATION > void pack_info(Protocol* protocol); > @@ -2365,9 +2398,10 @@ public: > > #ifdef MYSQL_SERVER > Intvar_log_event(THD* thd_arg, uchar type_arg, ulonglong val_arg, > - uint16 cache_type_arg) > - :Log_event(thd_arg, 0, 0), val(val_arg), type(type_arg) > - { cache_type= cache_type_arg; } > + enum_event_cache_type cache_type_arg, > + enum_event_logging_type logging_type_arg) > + :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), > + val(val_arg), type(type_arg) { } > #ifdef HAVE_REPLICATION > void pack_info(Protocol* protocol); > #endif /* HAVE_REPLICATION */ > @@ -2442,9 +2476,10 @@ class Rand_log_event: public Log_event > > #ifdef MYSQL_SERVER > Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg, > - uint16 cache_type_arg) > - :Log_event(thd_arg, 0, 0), seed1(seed1_arg), seed2(seed2_arg) > - { cache_type= cache_type_arg; } > + enum_event_cache_type cache_type_arg, > + enum_event_logging_type logging_type_arg) > + :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), > + seed1(seed1_arg), seed2(seed2_arg) { } > #ifdef HAVE_REPLICATION > void pack_info(Protocol* protocol); > #endif /* HAVE_REPLICATION */ > @@ -2488,8 +2523,12 @@ class Xid_log_event: public Log_event > my_xid xid; > > #ifdef MYSQL_SERVER > - Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg, 0, TRUE), xid(x) > - { cache_type= EVENT_NO_CACHE; } > + Xid_log_event(THD* thd_arg, my_xid x) > + : Log_event(thd_arg, 0, > + Log_event::EVENT_TRANSACTIONAL_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > + xid(x) > + { } > #ifdef HAVE_REPLICATION > void pack_info(Protocol* protocol); > #endif /* HAVE_REPLICATION */ > @@ -2542,11 +2581,14 @@ public: > User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg, > char *val_arg, ulong val_len_arg, Item_result type_arg, > uint charset_number_arg, uchar flags_arg, > - uint16 cache_type_arg) > - :Log_event(thd_arg, 0, 0), name(name_arg), name_len(name_len_arg), val(val_arg), > - val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg), > - flags(flags_arg) > - { is_null= !val; cache_type= cache_type_arg; } > + enum_event_cache_type cache_type_arg, > + enum_event_logging_type logging_type_arg) > + :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), name(name_arg), > + name_len(name_len_arg), val(val_arg), val_len(val_len_arg), type(type_arg), > + charset_number(charset_number_arg), flags(flags_arg) > + { > + is_null= !val; > + } > void pack_info(Protocol* protocol); > #else > void print(FILE* file, PRINT_EVENT_INFO* print_event_info); > @@ -2986,7 +3028,7 @@ public: > ulong query_length, uint fn_pos_start_arg, > uint fn_pos_end_arg, > enum_load_dup_handling dup_handling_arg, > - bool using_trans, bool direct, > + bool using_trans, bool immediate, > bool suppress_use, int errcode); > #ifdef HAVE_REPLICATION > void pack_info(Protocol* protocol); > @@ -4006,18 +4048,20 @@ class Incident_log_event : public Log_ev > public: > #ifdef MYSQL_SERVER > Incident_log_event(THD *thd_arg, Incident incident) > - : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F, FALSE), m_incident(incident) > + : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F, Log_event::EVENT_NO_CACHE, > + Log_event::EVENT_IMMEDIATE_LOGGING), m_incident(incident) > { > DBUG_ENTER("Incident_log_event::Incident_log_event"); > DBUG_PRINT("enter", ("m_incident: %d", m_incident)); > m_message.str= NULL; /* Just as a precaution */ > m_message.length= 0; > - set_direct_logging(); > DBUG_VOID_RETURN; > } > > Incident_log_event(THD *thd_arg, Incident incident, LEX_STRING const msg) > - : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F, FALSE), m_incident(incident) > + : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F, > + Log_event::EVENT_NO_CACHE, > + Log_event::EVENT_IMMEDIATE_LOGGING), m_incident(incident) > { > DBUG_ENTER("Incident_log_event::Incident_log_event"); > DBUG_PRINT("enter", ("m_incident: %d", m_incident)); > @@ -4031,7 +4075,6 @@ public: > } > strmake(m_message.str, msg.str, msg.length); > m_message.length= msg.length; > - set_direct_logging(); > DBUG_VOID_RETURN; > } > #endif > @@ -4089,7 +4132,9 @@ class Ignorable_log_event : public Log_e > public: > #ifndef MYSQL_CLIENT > Ignorable_log_event(THD *thd_arg) > - : Log_event(thd_arg, LOG_EVENT_IGNORABLE_F, FALSE) > + : Log_event(thd_arg, LOG_EVENT_IGNORABLE_F, > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING) > { > DBUG_ENTER("Ignorable_log_event::Ignorable_log_event"); > DBUG_VOID_RETURN; > > === modified file 'sql/log_event_old.cc' > --- a/sql/log_event_old.cc 2010-11-01 05:40:27 +0000 > +++ b/sql/log_event_old.cc 2011-05-12 21:51:20 +0000 > @@ -1230,8 +1230,11 @@ int Update_rows_log_event_old::do_exec_r > #ifndef MYSQL_CLIENT > Old_rows_log_event::Old_rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, > MY_BITMAP const *cols, > - bool is_transactional) > - : Log_event(thd_arg, 0, is_transactional), > + bool using_trans) > + : Log_event(thd_arg, 0, > + using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE : > + Log_event::EVENT_STMT_CACHE, > + Log_event::EVENT_NORMAL_LOGGING), > m_row_count(0), > m_table(tbl_arg), > m_table_id(tid), > @@ -1746,7 +1749,7 @@ int Old_rows_log_event::do_apply_event(R > last_event_start_time here instead. > */ > if (table&& (table->s->primary_key == MAX_KEY)&& > - !use_trans_cache()&& get_flags(STMT_END_F) == RLE_NO_FLAGS) > + !is_using_trans_cache()&& get_flags(STMT_END_F) == RLE_NO_FLAGS) > { > /* > ------------ Temporary fix until WL#2975 is implemented --------- > > === modified file 'sql/rpl_injector.cc' > --- a/sql/rpl_injector.cc 2011-02-01 08:51:58 +0000 > +++ b/sql/rpl_injector.cc 2011-05-12 21:51:20 +0000 > @@ -256,15 +256,11 @@ void injector::new_trans(THD *thd, injec > int injector::record_incident(THD *thd, Incident incident) > { > Incident_log_event ev(thd, incident); > - if (int error= mysql_bin_log.write(&ev)) > - return error; > - return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); > + return mysql_bin_log.write_incident(&ev, TRUE); > } > > int injector::record_incident(THD *thd, Incident incident, LEX_STRING const message) > { > Incident_log_event ev(thd, incident, message); > - if (int error= mysql_bin_log.write(&ev)) > - return error; > - return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); > + return mysql_bin_log.write_incident(&ev, TRUE); > } > > === modified file 'sql/sql_class.h' > --- a/sql/sql_class.h 2011-05-12 17:29:19 +0000 > +++ b/sql/sql_class.h 2011-05-12 21:51:20 +0000 > @@ -1851,8 +1851,6 @@ public: > /* > Public interface to write RBR events to the binlog > */ > - void binlog_start_trans_and_stmt(); > - void binlog_set_stmt_begin(); > int binlog_write_table_map(TABLE *table, bool is_transactional, > bool binlog_rows_query); > int binlog_write_row(TABLE* table, bool is_transactional, > > === modified file 'sql/sql_insert.cc' > --- a/sql/sql_insert.cc 2011-05-12 17:29:19 +0000 > +++ b/sql/sql_insert.cc 2011-05-12 21:51:20 +0000 > @@ -3895,19 +3895,6 @@ select_create::prepare(List &value > hook_ptr=&hooks; > > unit= u; > - > - /* > - Start a statement transaction before the create if we are using > - row-based replication for the statement. If we are creating a > - temporary table, we need to start a statement transaction. > - */ > - if ((thd->lex->create_info.options& HA_LEX_CREATE_TMP_TABLE) == 0&& > - thd->is_current_stmt_binlog_format_row()&& > - mysql_bin_log.is_open()) > - { > - thd->binlog_start_trans_and_stmt(); > - } > - > DBUG_ASSERT(create_table->table == NULL); > > DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000);); > > === modified file 'sql/sql_parse.cc' > --- a/sql/sql_parse.cc 2011-05-12 17:29:19 +0000 > +++ b/sql/sql_parse.cc 2011-05-12 21:51:20 +0000 > @@ -2929,8 +2929,7 @@ end_with_restore_list: > if (incident) > { > Incident_log_event ev(thd, incident); > - (void) mysql_bin_log.write(&ev); /* error is ignored */ > - if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE)) > + if (mysql_bin_log.write_incident(&ev, TRUE)) > { > res= 1; > break; > > > > >