List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:February 4 2011 2:17pm
Subject:bzr commit into mysql-trunk branch (alfranio.correia:3564) WL#4832
View as plain text  
#At file:///home/acorreia/workspace.oracle/repository.mysql/bzrwork/wl-4832/mysql-trunk/ based on revid:alfranio.correia@stripped

 3564 Alfranio Correia	2011-02-04
      WL#4832
     @ 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_row_binlog_max_cache_size.result
        Updated test case because DDLs go through the stmt-cache before being flushed.
     @ 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 a immediately written to the binary.
        
        . Simplified the logic that decides which cache should be used.
        
        . Merged binlog_start_trans_and_stmt() and binlog_set_stmt_begin().
     @ sql/binlog.h
        use_trans_cache was merged into Query_log_event::Query_log_event and
        created write_incident(Incident_log_event *ev, bool lock).
     @ sql/log_event.cc
        Any Query event that requests an immediate logging such as DDLs are
        tagged as EVENT_IMMEDIATE_LOGGING and EVENT_NO_CACHE. Other statements
        are tagged as EVENT_NORMAL_LOGGING.
        
        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
     @ sql/rpl_injector.cc
        When an incident event is logged rotation is automatically forced.
     @ sql/sql_class.h
        Removed this classes 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 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_row_binlog_max_cache_size.result
      sql/binlog.cc
      sql/binlog.h
      sql/log_event.cc
      sql/log_event.h
      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-02-04 14:17:40 +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	2010-12-19 17:22:30 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test	2011-02-04 14:17:40 +0000
@@ -422,10 +422,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-02-04 14:17:40 +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-02-04 14:17:40 +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-02-04 14:17:40 +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_row_binlog_max_cache_size.result'
--- a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result	2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result	2011-02-04 14:17:40 +0000
@@ -149,7 +149,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 'sql/binlog.cc'
--- a/sql/binlog.cc	2011-01-05 05:21:07 +0000
+++ b/sql/binlog.cc	2011-02-04 14:17:40 +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,7 +86,7 @@ class binlog_cache_data
 {
 public:
 
-  binlog_cache_data(): m_pending(0),
+  binlog_cache_data(): is_transactional(FALSE), m_pending(0),
   incident(FALSE), saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0),
   ptr_binlog_cache_disk_use(0)
   { }
@@ -121,6 +122,11 @@ public:
     return(incident);
   }
 
+  bool has_trans_updates()
+  {
+    return(is_transactional);
+  }
+
   virtual void reset()
   {
     compute_statistics();
@@ -189,6 +195,12 @@ protected:
     cache_log.end_of_file= saved_max_binlog_cache_size;
   }
 
+  /*
+    Defines if the cache stores transactional or non-transactional
+    updates.
+  */
+  bool is_transactional;
+
 private:
   /*
     Pending binrows event. This event is the event where the rows are currently
@@ -245,7 +257,9 @@ class binlog_trx_cache_data : public bin
 public:
   binlog_trx_cache_data() : m_cannot_rollback(FALSE),
   before_stmt_pos(MY_OFF_T_UNDEF)
-  {}
+  { 
+    is_transactional= TRUE; 
+  }
 
   void reset()
   {
@@ -303,6 +317,9 @@ 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 {
@@ -434,8 +451,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,12 +482,12 @@ 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=
     (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
   cache_mngr->trx_cache.restore_savepoint(pos);
+
   DBUG_VOID_RETURN;
 }
 
@@ -516,23 +531,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->use_trans_cache() && cache_data->has_trans_updates()) ||
+              (!end_evt->use_trans_cache() && !cache_data->has_trans_updates()));
+
   if (!cache_data->empty())
   {
-    if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional))
+    if (thd->binlog_flush_pending_rows_event(TRUE, cache_data->has_trans_updates()))
+      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 +562,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 +586,15 @@ 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->has_trans_updates(), FALSE, TRUE, 0);
+  /*
+    Force the use of the stmt-cache because the current statement may
+    be something that makes Query_log_event to choose another cache.
+  */
+  end_evt.set_cache(cache_data->has_trans_updates());
+  return (binlog_flush_cache(thd, cache_data, &end_evt));
 }
 
 /**
@@ -583,10 +609,15 @@ 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->has_trans_updates(), FALSE, TRUE, 0);
+  /*
+    Force the use of the trx-cache because the current statement may
+    be something that makes Query_log_event to choose another cache.
+  */
+  end_evt.set_cache(cache_data->has_trans_updates());
+  return (binlog_flush_cache(thd, cache_data, &end_evt));
 }
 
 /**
@@ -601,10 +632,15 @@ 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->has_trans_updates(), FALSE, TRUE, 0);
+  /*
+    Force the use of the trx-cache because the current statement may
+    be something that makes Query_log_event to choose another cache.
+  */
+  end_evt.set_cache(cache_data->has_trans_updates());
+  return (binlog_flush_cache(thd, cache_data, &end_evt));
 }
 
 /**
@@ -622,8 +658,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 +678,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 +705,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);
 }
 
@@ -1102,33 +1132,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.
@@ -3199,7 +3202,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())
   {
@@ -3236,7 +3239,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()));
 
@@ -3318,30 +3321,16 @@ 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->use_trans_cache() || event_info->use_stmt_cache());
+    
+    binlog_start_trans_and_stmt(thd, event_info);
 
-      thd->binlog_start_trans_and_stmt();
-    }
+    bool is_trans_cache= event_info->use_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()));
-
     /*
        No check for auto events flag here - this write method should
        never be called if auto-events are enabled.
@@ -3354,16 +3343,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;
         }
@@ -3374,14 +3358,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;
         }
@@ -3403,7 +3389,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;
           }
@@ -3420,28 +3407,18 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
 
     error= 0;
 
+    /*
+      Checks if a non-transactional event was written to a trx-cache.
+    */
     if (is_trans_cache && stmt_cannot_safely_rollback(thd))
       cache_mngr->set_trx_cache_cannot_rollback();
 err:
-    if (event_info->use_direct_logging())
+    if (event_info->use_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)
@@ -3791,7 +3768,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");
@@ -3799,40 +3787,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.
@@ -3842,8 +3851,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);
@@ -3857,14 +3865,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)))
@@ -3877,9 +3877,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;
 
@@ -3913,7 +3910,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++;
@@ -4322,17 +4319,12 @@ int THD::binlog_setup_trx_data()
   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.
@@ -4347,55 +4339,86 @@ 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()
+  @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->use_immediate_logging())
+    DBUG_VOID_RETURN;
+
+  /*
+    Retrieve the appropriated cache.
+  */
+  bool is_transactional= start_event->use_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);
+    qinfo.set_cache(is_transactional);
+    qinfo.write(file);
+  }
 
+  DBUG_VOID_RETURN;
+}
 
 /**
   This function writes a table map to the binary log. 
@@ -4432,14 +4455,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())
   {
@@ -4483,7 +4505,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();
   }
@@ -4503,16 +4525,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);
 }
@@ -4936,13 +4955,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-01-05 05:21:07 +0000
+++ b/sql/binlog.h	2011-02-04 14:17:40 +0000
@@ -198,12 +198,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);
@@ -284,7 +285,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 stmt_cannot_safely_rollback(const THD* thd);

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2011-01-28 14:49:41 +0000
+++ b/sql/log_event.cc	2011-02-04 14:17:40 +0000
@@ -684,16 +684,18 @@ const char* Log_event::get_type_str()
 #ifndef MYSQL_CLIENT
 Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
   :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(EVENT_INVALID_CACHE),
+  event_logging_type(EVENT_INVALID_LOGGING),
+  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;
+    event_cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
   else
-    cache_type= Log_event::EVENT_STMT_CACHE;
+    event_cache_type= Log_event::EVENT_STMT_CACHE;
+  event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
 }
 
 /**
@@ -724,8 +726,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;
@@ -918,8 +922,8 @@ my_bool Log_event::need_checksum()
   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;
+     (event_cache_type == Log_event::EVENT_NO_CACHE))?
+    binlog_checksum_options : FALSE;
 
   /*
     FD calls the methods before data_written has been calculated.
@@ -959,7 +963,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);
 }
@@ -2688,23 +2692,20 @@ 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 an event for binlogging.
+
+  @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  There is a modified transactional table
+  @param immediate    Should be flushed immediately
+  @param suppress_use Suppress the generation of 'USE' statements
+  @param errcode      The error code of the query
 */
 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)
 
   :Log_event(thd_arg,
              (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
@@ -2804,7 +2805,8 @@ Query_log_event::Query_log_event(THD* th
     Note that a cache will not be used if the parameter direct is TRUE.
   */
   bool trx_cache= FALSE;
-  cache_type= Log_event::EVENT_INVALID_CACHE;
+  event_cache_type= Log_event::EVENT_INVALID_CACHE;
+  event_logging_type= Log_event::EVENT_INVALID_LOGGING;
 
   switch (lex->sql_command)
   {
@@ -2831,19 +2833,29 @@ Query_log_event::Query_log_event(THD* th
       break;
   }
 
-  if (!use_cache || direct)
+  if (!use_cache || immediate)
   {
-    cache_type= Log_event::EVENT_NO_CACHE;
+    event_logging_type= Log_event::EVENT_IMMEDIATE_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;
+                                          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
-    cache_type= Log_event::EVENT_STMT_CACHE;
-  DBUG_ASSERT(cache_type != Log_event::EVENT_INVALID_CACHE);
+  {
+    event_logging_type= Log_event::EVENT_NORMAL_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));
 }
@@ -5489,7 +5501,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)
@@ -7326,9 +7339,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)

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2011-01-11 05:13:23 +0000
+++ b/sql/log_event.h	2011-02-04 14:17:40 +0000
@@ -920,9 +920,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
@@ -937,15 +938,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
@@ -996,22 +1017,28 @@ 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.
   */
   ulong slave_exec_mode;
 
+  /*
+    Defines the type of the cache, if any, where the event will be
+    stored before being flushed to disk.
+  */
+  uint16 event_cache_type;
+
+  /*
+    Defines when information, i.e. event or cache will be stored into
+    disk.
+  */
+  uint16 event_logging_type;
   /**
     Placeholder for event checksum while writing to binlog.
    */
   ha_checksum crc;
+
 #ifdef MYSQL_SERVER
   THD* thd;
 
@@ -1131,16 +1158,29 @@ 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; }
   inline bool use_trans_cache() const
-  { 
-    return (cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE);
+  {
+    return (event_cache_type == EVENT_TRANSACTIONAL_CACHE);
   }
-  inline void set_direct_logging()
+  inline bool use_stmt_cache() const
   {
-    cache_type = Log_event::EVENT_NO_CACHE;
+    return(event_cache_type == EVENT_STMT_CACHE);
   }
-  inline bool use_direct_logging()
+  inline bool use_immediate_logging() const
   {
-    return (cache_type == Log_event::EVENT_NO_CACHE);
+    return(event_logging_type == EVENT_IMMEDIATE_LOGGING);
+  }
+  inline void set_cache(bool is_transactional)
+  {
+    event_logging_type= EVENT_NORMAL_LOGGING;
+    if (is_transactional)
+      event_cache_type= EVENT_TRANSACTIONAL_CACHE;
+    else
+      event_cache_type= EVENT_STMT_CACHE;
+  }
+  inline void set_no_cache()
+  {
+    event_logging_type= EVENT_IMMEDIATE_LOGGING;
+    event_cache_type = EVENT_NO_CACHE;
   }
   Log_event(const char* buf, const Format_description_log_event
             *description_event);
@@ -1767,7 +1807,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);
   const char* get_db() { return db; }
 #ifdef HAVE_REPLICATION
   void pack_info(Protocol* protocol);
@@ -2358,9 +2399,12 @@ public:
 
 #ifdef MYSQL_SERVER
   Intvar_log_event(THD* thd_arg, uchar type_arg, ulonglong val_arg,
-                   uint16 cache_type_arg)
+                   uint16 cache_type_arg, uint16 logging_type_arg)
     :Log_event(thd_arg, 0, 0), val(val_arg), type(type_arg)
-  { cache_type= cache_type_arg; }
+  {
+    event_cache_type= cache_type_arg;
+    event_logging_type= logging_type_arg;
+  }
 #ifdef HAVE_REPLICATION
   void pack_info(Protocol* protocol);
 #endif /* HAVE_REPLICATION */
@@ -2435,9 +2479,12 @@ 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)
+                 uint16 cache_type_arg, uint16 logging_type_arg)
     :Log_event(thd_arg, 0, 0), seed1(seed1_arg), seed2(seed2_arg)
-    { cache_type= cache_type_arg; }
+    { 
+      event_cache_type= cache_type_arg; 
+      event_logging_type= logging_type_arg;
+    }
 #ifdef HAVE_REPLICATION
   void pack_info(Protocol* protocol);
 #endif /* HAVE_REPLICATION */
@@ -2482,7 +2529,7 @@ class Xid_log_event: public Log_event
 
 #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; }
+  { }
 #ifdef HAVE_REPLICATION
   void pack_info(Protocol* protocol);
 #endif /* HAVE_REPLICATION */
@@ -2535,11 +2582,15 @@ 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)
+                     uint16 cache_type_arg, uint16 logging_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; }
+    { 
+      is_null= !val;
+      event_cache_type= cache_type_arg;
+      event_logging_type= logging_type_arg;
+    }
   void pack_info(Protocol* protocol);
 #else
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
@@ -2979,7 +3030,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);
@@ -4005,7 +4056,8 @@ public:
     DBUG_PRINT("enter", ("m_incident: %d", m_incident));
     m_message.str= NULL;                    /* Just as a precaution */
     m_message.length= 0;
-    set_direct_logging();
+    event_cache_type= Log_event::EVENT_NO_CACHE;
+    event_logging_type= Log_event::EVENT_IMMEDIATE_LOGGING;
     DBUG_VOID_RETURN;
   }
 
@@ -4024,7 +4076,8 @@ public:
     }
     strmake(m_message.str, msg.str, msg.length);
     m_message.length= msg.length;
-    set_direct_logging();
+    event_cache_type= Log_event::EVENT_NO_CACHE;
+    event_logging_type= Log_event::EVENT_IMMEDIATE_LOGGING;
     DBUG_VOID_RETURN;
   }
 #endif

=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc	2010-12-10 16:55:50 +0000
+++ b/sql/rpl_injector.cc	2011-02-04 14:17:40 +0000
@@ -242,15 +242,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-01-28 14:49:41 +0000
+++ b/sql/sql_class.h	2011-02-04 14:17:40 +0000
@@ -1642,8 +1642,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-01-28 14:49:41 +0000
+++ b/sql/sql_insert.cc	2011-02-04 14:17:40 +0000
@@ -3895,23 +3895,9 @@ select_create::prepare(List<Item> &value
 
   MY_HOOKS hooks(this, create_table, select_tables);
   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););
 
   if (!(table= create_table_from_items(thd, create_info, create_table,

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2011-01-28 14:49:41 +0000
+++ b/sql/sql_parse.cc	2011-02-04 14:17:40 +0000
@@ -2816,8 +2816,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;


Attachment: [text/bzr-bundle] bzr/alfranio.correia@oracle.com-20110204141740-dy01q4iei4iqb48i.bundle
Thread
bzr commit into mysql-trunk branch (alfranio.correia:3564) WL#4832Alfranio Correia4 Feb
  • Re: bzr commit into mysql-trunk branch (alfranio.correia:3564) WL#4832Mats Kindahl10 Mar
    • Re: bzr commit into mysql-trunk branch (alfranio.correia:3564) WL#4832Alfranio Correia10 Mar
      • Re: bzr commit into mysql-trunk branch (alfranio.correia:3564) WL#4832Mats Kindahl10 Mar
  • Re: bzr commit into mysql-trunk branch (alfranio.correia:3564) WL#4832Luís Soares15 Mar
    • Re: bzr commit into mysql-trunk branch (alfranio.correia:3564) WL#4832Alfranio Correia17 Mar