List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:May 30 2011 6:25am
Subject:bzr commit into mysql-trunk branch (alfranio.correia:3125)
View as plain text  
#At file:///home/acorreia/workspace.oracle/repository.mysql/bzrwork/wl-4832/mysql-trunk-new/ based on revid:bjorn.munch@stripped

 3125 Alfranio Correia	2011-05-30 [merge]
      merge mysql-trunk (local) --> mysql-trunk

    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-26 15:20:09 +0000
+++ b/sql/binlog.cc	2011-05-30 06:25:47 +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.
@@ -3533,7 +3501,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())
   {
@@ -3570,7 +3538,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()));
 
@@ -3616,7 +3584,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);
   }
 
@@ -3628,7 +3596,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);
 
   /*
@@ -3653,28 +3621,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()));
 
     /*
@@ -3689,16 +3644,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;
         }
@@ -3709,14 +3659,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;
         }
@@ -3738,7 +3690,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;
           }
@@ -3764,25 +3717,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)
@@ -4135,7 +4075,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");
@@ -4143,40 +4094,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.
@@ -4186,8 +4158,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);
@@ -4201,14 +4172,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)))
@@ -4221,9 +4184,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;
 
@@ -4257,7 +4217,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++;
@@ -4656,12 +4616,11 @@ int MYSQL_BIN_LOG::recover(IO_CACHE *log
   Log_event  *ev;
   HASH xids;
   MEM_ROOT mem_root;
-  my_off_t last_valid_pos= *valid_pos;
   /*
     The flag is used for handling the case that a transaction
     is partially written to the binlog.
   */
-  bool in_transaction= TRUE;
+  bool in_transaction= FALSE;
 
   if (! fdle->is_valid() ||
       my_hash_init(&xids, &my_charset_bin, TC_LOG_PAGE_SIZE/3, 0,
@@ -4679,11 +4638,7 @@ int MYSQL_BIN_LOG::recover(IO_CACHE *log
     */
     if (ev->get_type_code() == QUERY_EVENT &&
         !strcmp(((Query_log_event*)ev)->query, "BEGIN"))
-    {
       in_transaction= TRUE;
-      *valid_pos= last_valid_pos;
-    }
-    last_valid_pos= my_b_tell(log);
 
     if (ev->get_type_code() == QUERY_EVENT &&
         !strcmp(((Query_log_event*)ev)->query, "COMMIT"))
@@ -4701,16 +4656,17 @@ int MYSQL_BIN_LOG::recover(IO_CACHE *log
       if (!x || my_hash_insert(&xids, x))
         goto err2;
     }
+
+    /*
+      Recorded valid position for the crashed binlog file
+      which did not contain incorrect events.
+    */
+    if (!log->error && !in_transaction)
+      *valid_pos= my_b_tell(log);
+
     delete ev;
   }
 
-  /*
-    Recorded valid position for the crashed binlog file
-    which did not contain incorrect events.
-  */
-  if (!log->error && !in_transaction)
-    *valid_pos= last_valid_pos;
-
   if (ha_recover(&xids))
     goto err2;
 
@@ -4758,25 +4714,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.
@@ -4791,55 +4742,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. 
@@ -4876,14 +4861,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())
   {
@@ -4927,7 +4911,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();
   }
@@ -4947,16 +4931,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);
 }
@@ -5380,13 +5361,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-16 14:30:54 +0000
+++ b/sql/binlog.h	2011-05-17 20:08:26 +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-26 15:20:09 +0000
+++ b/sql/log_event.cc	2011-05-30 06:25:47 +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)
@@ -6838,7 +6933,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)
 {
 }
@@ -7004,7 +7103,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
@@ -7100,7 +7203,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
@@ -7316,9 +7423,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)
@@ -7593,8 +7700,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),
@@ -8516,8 +8626,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-05-16 14:30:54 +0000
+++ b/sql/rpl_injector.cc	2011-05-17 20:08:26 +0000
@@ -245,15 +245,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-26 15:20:09 +0000
+++ b/sql/sql_class.h	2011-05-30 06:25:47 +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-26 15:20:09 +0000
+++ b/sql/sql_insert.cc	2011-05-30 06:25:47 +0000
@@ -3895,19 +3895,6 @@ select_create::prepare(List<Item> &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-26 15:20:09 +0000
+++ b/sql/sql_parse.cc	2011-05-30 06:25:47 +0000
@@ -2990,8 +2990,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;

No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).
Thread
bzr commit into mysql-trunk branch (alfranio.correia:3125) Alfranio Correia31 May