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

 3564 Alfranio Correia	2011-02-02
      Draft for WL#4832
      
      . The patch is based on BUG#56184 which is not pushed yet.
      . It is missing proper comments.
      . There are some checksum failures.

    modified:
      mysql-test/extra/binlog_tests/binlog_cache_stat.test
      mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test
      mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result
      mysql-test/suite/binlog/r/binlog_row_cache_stat.result
      mysql-test/suite/binlog/r/binlog_stm_cache_stat.result
      mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result
      sql/binlog.cc
      sql/binlog.h
      sql/log_event.cc
      sql/log_event.h
      sql/rpl_injector.cc
      sql/sql_class.h
      sql/sql_insert.cc
      sql/sql_parse.cc
=== modified file 'mysql-test/extra/binlog_tests/binlog_cache_stat.test'
--- a/mysql-test/extra/binlog_tests/binlog_cache_stat.test	2010-11-05 17:42:37 +0000
+++ b/mysql-test/extra/binlog_tests/binlog_cache_stat.test	2011-02-02 23:41:09 +0000
@@ -20,13 +20,13 @@ create table t2 (a int) engine=myisam;
 #
 --echo **** Preparing the enviroment to check commit and its effect on status variables.
 --echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 flush status;
 let $exp_cache= 0;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 0;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 0;
+let $exp_stmt_cache= 1;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -39,7 +39,7 @@ if (`SELECT $got_cache <> $exp_cache ||
 
 --echo **** Transactional changes which are long enough so they will be flushed to disk...
 --echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 let $1=2000;
 disable_query_log;
 begin;
@@ -54,7 +54,7 @@ let $exp_cache= 1;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 1;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 0;
+let $exp_stmt_cache= 1;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -68,7 +68,7 @@ if (`SELECT $got_cache <> $exp_cache ||
 --echo **** Transactional changes which should not be flushed to disk and so should not
 --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 commit;
@@ -76,7 +76,7 @@ let $exp_cache= 2;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 1;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 0;
+let $exp_stmt_cache= 1;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -90,7 +90,7 @@ if (`SELECT $got_cache <> $exp_cache ||
 --echo **** Non-Transactional changes which should not be flushed to disk and so should not
 --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
---echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t2 values( 1 );
 commit;
@@ -98,7 +98,7 @@ let $exp_cache= 2;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 1;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 1;
+let $exp_stmt_cache= 2;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -112,7 +112,7 @@ if (`SELECT $got_cache <> $exp_cache ||
 --echo **** Mixed changes which should not be flushed to disk and so should not
 --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 --echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
---echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 insert into t2 values( 1 );
@@ -121,7 +121,7 @@ let $exp_cache= 3;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 1;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 2;
+let $exp_stmt_cache= 3;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -137,13 +137,13 @@ if (`SELECT $got_cache <> $exp_cache ||
 #
 --echo **** Preparing the enviroment to check abort and its effect on the status variables.
 --echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 flush status;
 let $exp_cache= 0;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 0;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 0;
+let $exp_stmt_cache= 1;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -156,7 +156,7 @@ if (`SELECT $got_cache <> $exp_cache ||
 
 --echo **** Transactional changes which are long enough so they will be flushed to disk...
 --echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 let $1=2000;
 disable_query_log;
 begin;
@@ -171,7 +171,7 @@ let $exp_cache= 1;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 1;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 0;
+let $exp_stmt_cache= 1;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -185,7 +185,7 @@ if (`SELECT $got_cache <> $exp_cache ||
 --echo **** Transactional changes which should not be flushed to disk and so should not
 --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
---echo **** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 rollback;
@@ -193,7 +193,7 @@ let $exp_cache= 2;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 1;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 0;
+let $exp_stmt_cache= 1;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -207,7 +207,7 @@ if (`SELECT $got_cache <> $exp_cache ||
 --echo **** Non-Transactional changes which should not be flushed to disk and so should not
 --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 --echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
---echo **** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t2 values( 1 );
 rollback;
@@ -215,7 +215,7 @@ let $exp_cache= 2;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 1;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 1;
+let $exp_stmt_cache= 2;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);
@@ -229,7 +229,7 @@ if (`SELECT $got_cache <> $exp_cache ||
 --echo **** Mixed changes which should not be flushed to disk and so should not
 --echo **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 --echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
---echo **** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
+--echo **** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 insert into t2 values( 1 );
@@ -238,7 +238,7 @@ let $exp_cache= 3;
 let $got_cache= query_get_value(show status like "binlog_cache_use", Value, 1);
 let $exp_disk= 1;
 let $got_disk= query_get_value(show status like "binlog_cache_disk_use", Value, 1);
-let $exp_stmt_cache= 2;
+let $exp_stmt_cache= 3;
 let $got_stmt_cache= query_get_value(show status like "binlog_stmt_cache_use", Value, 1);
 let $exp_stmt_disk= 0;
 let $got_stmt_disk= query_get_value(show status like "binlog_stmt_cache_disk_use", Value, 1);

=== modified file 'mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test'
--- a/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test	2010-12-19 17:22:30 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_binlog_max_cache_size.test	2011-02-02 23:41:09 +0000
@@ -422,10 +422,6 @@ COMMIT;
 
 --connection slave
 --let $slave_sql_errno= 1197
-if (`SELECT @@binlog_format = 'ROW'`)
-{
-  --let $slave_sql_errno= 1534
-}
 source include/wait_for_slave_sql_error.inc;
 
 SELECT count(*) FROM t1;

=== modified file 'mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result'
--- a/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result	2010-11-05 17:42:37 +0000
+++ b/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result	2011-02-02 23:41:09 +0000
@@ -3,51 +3,51 @@ create table t1 (a int) engine=innodb;
 create table t2 (a int) engine=myisam;
 **** Preparing the enviroment to check commit and its effect on status variables.
 **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 flush status;
 **** Transactional changes which are long enough so they will be flushed to disk...
 **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 **** Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 commit;
 **** Non-Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t2 values( 1 );
 commit;
 **** Mixed changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 insert into t2 values( 1 );
 commit;
 **** Preparing the enviroment to check abort and its effect on the status variables.
 **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 flush status;
 **** Transactional changes which are long enough so they will be flushed to disk...
 **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 **** Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 rollback;
 **** Non-Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t2 values( 1 );
 rollback;
@@ -56,7 +56,7 @@ Warning	1196	Some non-transactional chan
 **** Mixed changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 insert into t2 values( 1 );

=== modified file 'mysql-test/suite/binlog/r/binlog_row_cache_stat.result'
--- a/mysql-test/suite/binlog/r/binlog_row_cache_stat.result	2010-11-05 17:42:37 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_cache_stat.result	2011-02-02 23:41:09 +0000
@@ -3,51 +3,51 @@ create table t1 (a int) engine=innodb;
 create table t2 (a int) engine=myisam;
 **** Preparing the enviroment to check commit and its effect on status variables.
 **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 flush status;
 **** Transactional changes which are long enough so they will be flushed to disk...
 **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 **** Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 commit;
 **** Non-Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t2 values( 1 );
 commit;
 **** Mixed changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 insert into t2 values( 1 );
 commit;
 **** Preparing the enviroment to check abort and its effect on the status variables.
 **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 flush status;
 **** Transactional changes which are long enough so they will be flushed to disk...
 **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 **** Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 rollback;
 **** Non-Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t2 values( 1 );
 rollback;
@@ -56,7 +56,7 @@ Warning	1196	Some non-transactional chan
 **** Mixed changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 insert into t2 values( 1 );

=== modified file 'mysql-test/suite/binlog/r/binlog_stm_cache_stat.result'
--- a/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result	2010-11-05 17:42:37 +0000
+++ b/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result	2011-02-02 23:41:09 +0000
@@ -3,51 +3,51 @@ create table t1 (a int) engine=innodb;
 create table t2 (a int) engine=myisam;
 **** Preparing the enviroment to check commit and its effect on status variables.
 **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 flush status;
 **** Transactional changes which are long enough so they will be flushed to disk...
 **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 **** Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 commit;
 **** Non-Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t2 values( 1 );
 commit;
 **** Mixed changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 insert into t2 values( 1 );
 commit;
 **** Preparing the enviroment to check abort and its effect on the status variables.
 **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 flush status;
 **** Transactional changes which are long enough so they will be flushed to disk...
 **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 **** Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 0, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 rollback;
 **** Non-Transactional changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 1, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t2 values( 1 );
 rollback;
@@ -56,7 +56,7 @@ Warning	1196	Some non-transactional chan
 **** Mixed changes which should not be flushed to disk and so should not
 **** increase either binlog_cache_disk_use or binlog_stmt_cache_disk_use.
 **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
-**** Expected: binlog_stmt_cache_use = 2, binlog_stmt_cache_disk_use = 0.
+**** Expected: binlog_stmt_cache_use = 3, binlog_stmt_cache_disk_use = 0.
 begin;
 insert into t1 values( 1 );
 insert into t2 values( 1 );

=== modified file 'mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result'
--- a/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result	2010-12-19 17:22:30 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_binlog_max_cache_size.result	2011-02-02 23:41:09 +0000
@@ -149,7 +149,7 @@ SET GLOBAL binlog_stmt_cache_size= ORIGI
 BEGIN;
 Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times
 COMMIT;
-include/wait_for_slave_sql_error.inc [errno=1534]
+include/wait_for_slave_sql_error.inc [errno=1197]
 SELECT count(*) FROM t1;
 count(*)
 0

=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2011-01-05 05:21:07 +0000
+++ b/sql/binlog.cc	2011-02-02 23:41:09 +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, uint16 cache_type);
 static int binlog_close_connection(handlerton *hton, THD *thd);
 static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv);
 static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv);
@@ -85,7 +86,7 @@ class binlog_cache_data
 {
 public:
 
-  binlog_cache_data(): m_pending(0),
+  binlog_cache_data(): is_transactional(FALSE), m_pending(0),
   incident(FALSE), saved_max_binlog_cache_size(0), ptr_binlog_cache_use(0),
   ptr_binlog_cache_disk_use(0)
   { }
@@ -121,6 +122,11 @@ public:
     return(incident);
   }
 
+  bool has_trans_updates()
+  {
+    return(is_transactional);
+  }
+
   virtual void reset()
   {
     compute_statistics();
@@ -189,6 +195,12 @@ protected:
     cache_log.end_of_file= saved_max_binlog_cache_size;
   }
 
+  /*
+    Defines if a the cache stores transactional or non-transactional
+    updates.
+  */
+  bool is_transactional;
+
 private:
   /*
     Pending binrows event. This event is the event where the rows are currently
@@ -245,7 +257,9 @@ class binlog_trx_cache_data : public bin
 public:
   binlog_trx_cache_data() : m_cannot_rollback(FALSE),
   before_stmt_pos(MY_OFF_T_UNDEF)
-  {}
+  { 
+    is_transactional= TRUE; 
+  }
 
   void reset()
   {
@@ -303,6 +317,9 @@ private:
     Binlog position before the start of the current statement.
   */
   my_off_t before_stmt_pos;
+
+  binlog_trx_cache_data& operator=(const binlog_trx_cache_data& info);
+  binlog_trx_cache_data(const binlog_trx_cache_data& info);
 };
 
 class binlog_cache_mngr {
@@ -434,8 +451,6 @@ binlog_trans_log_savepos(THD *thd, my_of
 {
   DBUG_ENTER("binlog_trans_log_savepos");
   DBUG_ASSERT(pos != NULL);
-  if (thd_get_ha_data(thd, binlog_hton) == NULL)
-    thd->binlog_setup_trx_data();
   binlog_cache_mngr *const cache_mngr=
     (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
   DBUG_ASSERT(mysql_bin_log.is_open());
@@ -467,12 +482,12 @@ binlog_trans_log_truncate(THD *thd, my_o
   DBUG_PRINT("enter", ("pos: %lu", (ulong) pos));
 
   DBUG_ASSERT(thd_get_ha_data(thd, binlog_hton) != NULL);
-  /* Only true if binlog_trans_log_savepos() wasn't called before */
   DBUG_ASSERT(pos != ~(my_off_t) 0);
 
   binlog_cache_mngr *const cache_mngr=
     (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
   cache_mngr->trx_cache.restore_savepoint(pos);
+
   DBUG_VOID_RETURN;
 }
 
@@ -523,16 +538,22 @@ static int binlog_close_connection(handl
     nonzero if an error pops up when flushing the cache.
 */
 static inline int
-binlog_flush_cache(THD *thd, binlog_cache_data* cache_data, Log_event *end_evt,
-                   bool is_transactional)
+binlog_flush_cache(THD *thd, binlog_cache_data* cache_data, Log_event *end_evt)
 {
   DBUG_ENTER("binlog_flush_cache");
   int error= 0;
 
+  DBUG_ASSERT((end_evt->use_trans_cache() && cache_data->has_trans_updates()) ||
+              (!end_evt->use_trans_cache() && !cache_data->has_trans_updates()));
+
   if (!cache_data->empty())
   {
-    if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional))
+    if (thd->binlog_flush_pending_rows_event(TRUE, cache_data->has_trans_updates()))
       DBUG_RETURN(1);
+
+    if (end_evt->write(&cache_data->cache_log))
+      DBUG_RETURN(1);
+ 
     /*
       Doing a commit or a rollback including non-transactional tables,
       i.e., ending a transaction where we might write the transaction
@@ -543,8 +564,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 +588,11 @@ static inline int
 binlog_commit_flush_stmt_cache(THD *thd,
                                binlog_cache_mngr *cache_mngr)
 {
+  binlog_cache_data* cache_data= &cache_mngr->stmt_cache;
   Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"),
-                          FALSE, TRUE, TRUE, 0);
-  return (binlog_flush_cache(thd, &cache_mngr->stmt_cache, &end_evt,
-                             FALSE));
+                          cache_data->has_trans_updates(), FALSE, TRUE, 0);
+  end_evt.set_cache_type(Log_event::EVENT_STMT_CACHE);
+  return (binlog_flush_cache(thd, cache_data, &end_evt));
 }
 
 /**
@@ -583,10 +607,11 @@ binlog_commit_flush_stmt_cache(THD *thd,
 static inline int
 binlog_commit_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr)
 {
+  binlog_cache_data* cache_data= &cache_mngr->trx_cache;
   Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"),
-                          TRUE, TRUE, TRUE, 0);
-  return (binlog_flush_cache(thd, &cache_mngr->trx_cache, &end_evt,
-                             TRUE));
+                          cache_data->has_trans_updates(), FALSE, TRUE, 0);
+  end_evt.set_cache_type(Log_event::EVENT_TRANSACTIONAL_CACHE);
+  return (binlog_flush_cache(thd, cache_data, &end_evt));
 }
 
 /**
@@ -601,10 +626,11 @@ binlog_commit_flush_trx_cache(THD *thd,
 static inline int
 binlog_rollback_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr)
 {
+  binlog_cache_data* cache_data= &cache_mngr->trx_cache;
   Query_log_event end_evt(thd, STRING_WITH_LEN("ROLLBACK"),
-                          TRUE, TRUE, TRUE, 0);
-  return (binlog_flush_cache(thd, &cache_mngr->trx_cache, &end_evt,
-                             TRUE));
+                          cache_data->has_trans_updates(), FALSE, TRUE, 0);
+  end_evt.set_cache_type(Log_event::EVENT_TRANSACTIONAL_CACHE);
+  return (binlog_flush_cache(thd, cache_data, &end_evt));
 }
 
 /**
@@ -622,8 +648,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 +668,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 +695,7 @@ binlog_truncate_trx_cache(THD *thd, binl
   else
     cache_mngr->trx_cache.restore_prev_position();
 
-  DBUG_ASSERT(thd->binlog_get_pending_rows_event(is_transactional) == NULL);
+  DBUG_ASSERT(thd->binlog_get_pending_rows_event(TRUE) == NULL);
   DBUG_RETURN(error);
 }
 
@@ -1102,33 +1122,6 @@ stmt_has_updated_trans_table(const THD *
   return (FALSE);
 }
 
-/** 
-  This function checks if either a trx-cache or a non-trx-cache should
-  be used. If @c bin_log_direct_non_trans_update is active or the format
-  is either MIXED or ROW, the cache to be used depends on the flag @c
-  is_transactional. 
-
-  On the other hand, if binlog_format is STMT or direct option is
-  OFF, the trx-cache should be used if and only if the statement is
-  transactional or the trx-cache is not empty. Otherwise, the
-  non-trx-cache should be used.
-
-  @param thd              The client thread.
-  @param is_transactional The changes are related to a trx-table.
-  @return
-    @c true if a trx-cache should be used, @c false otherwise.
-*/
-bool use_trans_cache(const THD* thd, bool is_transactional)
-{
-  binlog_cache_mngr *const cache_mngr=
-    (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
-
-  return
-    ((thd->is_current_stmt_binlog_format_row() ||
-     thd->variables.binlog_direct_non_trans_update) ? is_transactional :
-     (is_transactional || !cache_mngr->trx_cache.empty()));
-}
-
 /**
   This function checks if a transaction, either a multi-statement
   or a single statement transaction is about to commit or not.
@@ -3199,7 +3192,7 @@ MYSQL_BIN_LOG::remove_pending_rows_event
   DBUG_ASSERT(cache_mngr);
 
   binlog_cache_data *cache_data=
-    cache_mngr->get_binlog_cache_data(use_trans_cache(thd, is_transactional));
+    cache_mngr->get_binlog_cache_data(is_transactional);
 
   if (Rows_log_event* pending= cache_data->pending())
   {
@@ -3236,7 +3229,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()));
 
@@ -3323,22 +3316,23 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
     binlog_cache_data *cache_data= 0;
     bool is_trans_cache= FALSE;
 
-    if (event_info->use_direct_logging())
+    if (event_info->use_immediate_logging())
     {
-      file= &log_file;
-      mysql_mutex_lock(&LOCK_log);
+      binlog_start_trans_and_stmt(thd, Log_event::EVENT_IMMEDIATE_LOGGING);
+      cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
+      file= cache_mngr->get_binlog_cache_log(FALSE);
+      cache_data= cache_mngr->get_binlog_cache_data(FALSE);
     }
     else
     {
-      if (thd->binlog_setup_trx_data())
-        goto err;
-
+      is_trans_cache= event_info->use_trans_cache();
+      
+      binlog_start_trans_and_stmt(thd,
+        is_trans_cache ? Log_event::EVENT_TRANSACTIONAL_CACHE :
+                         Log_event::EVENT_STMT_CACHE);
       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);
-
-      thd->binlog_start_trans_and_stmt();
     }
     DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
 
@@ -3357,7 +3351,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
         /* 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);
+                    event_info->cache_type == Log_event::EVENT_IMMEDIATE_LOGGING);
  
         if (thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt)
         {
@@ -3420,28 +3414,18 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
 
     error= 0;
 
+    /*
+      Checks if a non-transactional event was written to a trx-cache.
+    */
     if (is_trans_cache && stmt_cannot_safely_rollback(thd))
       cache_mngr->set_trx_cache_cannot_rollback();
 err:
-    if (event_info->use_direct_logging())
+    if (event_info->use_immediate_logging())
     {
-      if (!error)
-      {
-        bool synced;
-        if ((error= flush_and_sync(&synced)))
-          goto unlock;
-
-        if ((error= RUN_HOOK(binlog_storage, after_flush,
-                 (thd, log_file_name, file->pos_in_file, synced))))
-        {
-          sql_print_error("Failed to run 'after_flush' hooks");
-          goto unlock;
-        }
-        signal_update();
-        rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
-      }
-unlock:
-      mysql_mutex_unlock(&LOCK_log);
+      error |= mysql_bin_log.write(thd, &cache_data->cache_log,
+                                   cache_data->has_incident(),
+                                   FALSE);
+      cache_data->reset();
     }
 
     if (error)
@@ -3791,7 +3775,7 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE
   return 0;                                     // All OK
 }
 
-bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock)
+bool MYSQL_BIN_LOG::write_incident(Incident_log_event *ev, bool lock)
 {
   uint error= 0;
   DBUG_ENTER("MYSQL_BIN_LOG::write_incident");
@@ -3799,25 +3783,40 @@ 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);
 }
 
+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
@@ -3842,8 +3841,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *
     'cache' needs to be reinitialized after this functions returns.
 */
 
-bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event,
-                          bool incident)
+bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, bool incident, bool prepared)
 {
   DBUG_ENTER("MYSQL_BIN_LOG::write(THD *, IO_CACHE *, Log_event *)");
   mysql_mutex_lock(&LOCK_log);
@@ -3857,14 +3855,6 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
      */
     if (my_b_tell(cache) > 0)
     {
-      /*
-        Log "BEGIN" at the beginning of every transaction.  Here, a
-        transaction is either a BEGIN..COMMIT block or a single
-        statement in autocommit mode.
-      */
-      Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, TRUE, TRUE, 0);
-      if (qinfo.write(&log_file))
-        goto err;
       DBUG_EXECUTE_IF("crash_before_writing_xid",
                       {
                         if ((write_error= write_cache(cache, false, true)))
@@ -3877,9 +3867,6 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
       if ((write_error= write_cache(cache, false, false)))
         goto err;
 
-      if (commit_event && commit_event->write(&log_file))
-        goto err;
-
       if (incident && write_incident(thd, FALSE))
         goto err;
 
@@ -3913,7 +3900,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++;
@@ -4349,54 +4336,55 @@ int THD::binlog_setup_trx_data()
       event, to include some extra events.
  */
 
-void
-THD::binlog_start_trans_and_stmt()
+void binlog_start_trans_and_stmt(THD *thd, uint16 cache_type)
 {
-  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);
+  DBUG_ASSERT(cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE ||
+              cache_type == Log_event::EVENT_STMT_CACHE ||
+              cache_type == Log_event::EVENT_IMMEDIATE_LOGGING);
+  
+  bool is_transactional= FALSE;
+
+  if (thd_get_ha_data(thd, binlog_hton) == NULL)
+    thd->binlog_setup_trx_data();
+
+  if (cache_type == Log_event::EVENT_IMMEDIATE_LOGGING)
+    DBUG_VOID_RETURN;
+
+  is_transactional= (cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE);
+  binlog_cache_mngr *cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
+  binlog_cache_data *cache= is_transactional ? &cache_mngr->trx_cache : &cache_mngr->stmt_cache;
+ 
+  if (cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF)
+  {
+    my_off_t pos= 0;
+    binlog_trans_log_savepos(thd, &pos);
+    cache_mngr->trx_cache.set_prev_position(pos);
+
+    if (thd->in_multi_stmt_transaction_mode())
+      trans_register_ha(thd, TRUE, binlog_hton);
+    trans_register_ha(thd, FALSE, binlog_hton);
+
+    thd->ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
+  }
+
+  if (cache->empty())
+  {
+    IO_CACHE *file=
+      cache_mngr->get_binlog_cache_log(is_transactional);
     /*
-      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.
+      Log "BEGIN" at the beginning of every transaction.  Here, a
+      transaction is either a BEGIN..COMMIT block or a single
+      statement in autocommit mode.
     */
-    ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
+    Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), is_transactional, FALSE, TRUE, 0);
+    qinfo.set_cache_type(cache_type);
+    qinfo.write(file);
   }
-  DBUG_VOID_RETURN;
-}
-
-void THD::binlog_set_stmt_begin() {
-  binlog_cache_mngr *cache_mngr=
-    (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
 
-  /*
-    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);
+  DBUG_VOID_RETURN;
 }
 
-
 /**
   This function writes a table map to the binary log. 
   Note that in order to keep the signature uniform with related methods,
@@ -4432,14 +4420,15 @@ 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, 
+    is_transactional ? Log_event::EVENT_TRANSACTIONAL_CACHE :
+                       Log_event::EVENT_STMT_CACHE);
 
   binlog_cache_mngr *const cache_mngr=
     (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
 
   IO_CACHE *file=
-    cache_mngr->get_binlog_cache_log(use_trans_cache(this, is_transactional));
+    cache_mngr->get_binlog_cache_log(is_transactional);
 
   if (binlog_rows_query && this->query())
   {
@@ -4483,7 +4472,7 @@ THD::binlog_get_pending_rows_event(bool
   if (cache_mngr)
   {
     binlog_cache_data *cache_data=
-      cache_mngr->get_binlog_cache_data(use_trans_cache(this, is_transactional));
+      cache_mngr->get_binlog_cache_data(is_transactional);
 
     rows= cache_data->pending();
   }
@@ -4503,16 +4492,13 @@ THD::binlog_get_pending_rows_event(bool
 void
 THD::binlog_set_pending_rows_event(Rows_log_event* ev, bool is_transactional)
 {
-  if (thd_get_ha_data(this, binlog_hton) == NULL)
-    binlog_setup_trx_data();
-
   binlog_cache_mngr *const cache_mngr=
     (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
 
   DBUG_ASSERT(cache_mngr);
 
   binlog_cache_data *cache_data=
-    cache_mngr->get_binlog_cache_data(use_trans_cache(this, is_transactional));
+    cache_mngr->get_binlog_cache_data(is_transactional);
 
   cache_data->set_pending(ev);
 }
@@ -4936,13 +4922,6 @@ THD::binlog_prepare_pending_rows_event(T
   /* Fetch the type code for the RowsEventT template parameter */
   int const type_code= RowsEventT::TYPE_CODE;
 
-  /*
-    There is no good place to set up the transactional data, so we
-    have to do it here.
-  */
-  if (binlog_setup_trx_data())
-    DBUG_RETURN(NULL);
-
   Rows_log_event* pending= binlog_get_pending_rows_event(is_transactional);
 
   if (unlikely(pending && !pending->is_valid()))

=== modified file 'sql/binlog.h'
--- a/sql/binlog.h	2011-01-05 05:21:07 +0000
+++ b/sql/binlog.h	2011-02-02 23:41:09 +0000
@@ -198,12 +198,13 @@ public:
   int new_file();
 
   bool write(Log_event* event_info); // binary log write
-  bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
-
-  bool write_incident(THD *thd, bool lock);
+  bool write(THD *thd, IO_CACHE *cache, bool incident, bool prepared);
   int  write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
+
   void set_write_error(THD *thd, bool is_transactional);
   bool check_write_error(THD *thd);
+  bool write_incident(THD *thd, bool lock);
+  bool write_incident(Incident_log_event *ev, bool lock);
 
   void start_union_events(THD *thd, query_id_t query_id_param);
   void stop_union_events(THD *thd);
@@ -284,7 +285,6 @@ extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG
 
 bool trans_has_updated_trans_table(const THD* thd);
 bool stmt_has_updated_trans_table(const THD *thd);
-bool use_trans_cache(const THD* thd, bool is_transactional);
 bool ending_trans(THD* thd, const bool all);
 bool ending_single_stmt_trans(THD* thd, const bool all);
 bool stmt_cannot_safely_rollback(const THD* thd);

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2011-01-28 14:49:41 +0000
+++ b/sql/log_event.cc	2011-02-02 23:41:09 +0000
@@ -918,7 +918,7 @@ my_bool Log_event::need_checksum()
   ret= (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) ?
     (checksum_alg != BINLOG_CHECKSUM_ALG_OFF) :
     ((binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF) &&
-     (cache_type == Log_event::EVENT_NO_CACHE))? binlog_checksum_options :
+     (cache_type == Log_event::EVENT_DIRECT_LOGGING))? binlog_checksum_options :
     FALSE;
 
   /*
@@ -959,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);
+              cache_type == Log_event::EVENT_DIRECT_LOGGING);
 
   DBUG_RETURN(ret);
 }
@@ -2704,7 +2704,7 @@ Query_log_event::Query_log_event()
 */
 Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
 				 ulong query_length, bool using_trans,
-				 bool direct, bool suppress_use, int errcode)
+				 bool immediate, bool suppress_use, int errcode)
 
   :Log_event(thd_arg,
              (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
@@ -2831,15 +2831,17 @@ Query_log_event::Query_log_event(THD* th
       break;
   }
 
-  if (!use_cache || direct)
+  if (!use_cache || immediate)
   {
-    cache_type= Log_event::EVENT_NO_CACHE;
+    cache_type= Log_event::EVENT_IMMEDIATE_LOGGING;
   }
   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))
+                                          thd->tx_isolation) ||
+           (!thd->variables.binlog_direct_non_trans_update &&
+             trans_has_updated_trans_table(thd)))
     cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
   else
     cache_type= Log_event::EVENT_STMT_CACHE;
@@ -5489,7 +5491,7 @@ 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;
+  cache_type= EVENT_IMMEDIATE_LOGGING;
   if (flags & DUP_NAME)
     new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
   if (flags & RELAY_LOG)
@@ -7326,9 +7328,9 @@ Execute_load_query_log_event(THD *thd_ar
                              ulong query_length_arg, uint fn_pos_start_arg,
                              uint fn_pos_end_arg,
                              enum_load_dup_handling dup_handling_arg,
-                             bool using_trans, bool direct, bool suppress_use,
+                             bool using_trans, bool immediate, bool suppress_use,
                              int errcode):
-  Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, direct,
+  Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, immediate,
                   suppress_use, errcode),
   file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
   fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2011-01-11 05:13:23 +0000
+++ b/sql/log_event.h	2011-02-02 23:41:09 +0000
@@ -936,10 +936,15 @@ public:
     */
     EVENT_TRANSACTIONAL_CACHE,
     /* 
+      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,
+    /* 
       The event must be written directly to the binary log without going
-      through a cache.
+      through any cache.
     */
-    EVENT_NO_CACHE,
+    EVENT_DIRECT_LOGGING,
     /**
        If there is a need for different types, introduce them before this.
     */
@@ -1130,17 +1135,17 @@ public:
   bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
   bool is_relay_log_event() const { return flags & LOG_EVENT_RELAY_LOG_F; }
   bool is_ignorable_event() const { return flags & LOG_EVENT_IGNORABLE_F; }
+  inline void set_cache_type(int16 cache_type_arg)
+  { 
+    cache_type= cache_type_arg;
+  }
   inline bool use_trans_cache() const
   { 
     return (cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE);
   }
-  inline void set_direct_logging()
-  {
-    cache_type = Log_event::EVENT_NO_CACHE;
-  }
-  inline bool use_direct_logging()
+  inline bool use_immediate_logging()
   {
-    return (cache_type == Log_event::EVENT_NO_CACHE);
+    return (cache_type == Log_event::EVENT_IMMEDIATE_LOGGING);
   }
   Log_event(const char* buf, const Format_description_log_event
             *description_event);
@@ -2482,7 +2487,7 @@ class Xid_log_event: public Log_event
 
 #ifdef MYSQL_SERVER
   Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg, 0, TRUE), xid(x)
-  { cache_type= EVENT_NO_CACHE; }
+  { }
 #ifdef HAVE_REPLICATION
   void pack_info(Protocol* protocol);
 #endif /* HAVE_REPLICATION */
@@ -4005,7 +4010,7 @@ public:
     DBUG_PRINT("enter", ("m_incident: %d", m_incident));
     m_message.str= NULL;                    /* Just as a precaution */
     m_message.length= 0;
-    set_direct_logging();
+    cache_type= Log_event::EVENT_DIRECT_LOGGING;
     DBUG_VOID_RETURN;
   }
 
@@ -4024,7 +4029,7 @@ public:
     }
     strmake(m_message.str, msg.str, msg.length);
     m_message.length= msg.length;
-    set_direct_logging();
+    cache_type= Log_event::EVENT_DIRECT_LOGGING;
     DBUG_VOID_RETURN;
   }
 #endif

=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc	2010-12-10 16:55:50 +0000
+++ b/sql/rpl_injector.cc	2011-02-02 23:41:09 +0000
@@ -242,15 +242,11 @@ void injector::new_trans(THD *thd, injec
 int injector::record_incident(THD *thd, Incident incident)
 {
   Incident_log_event ev(thd, incident);
-  if (int error= mysql_bin_log.write(&ev))
-    return error;
-  return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+  return (mysql_bin_log.write_incident(&ev, TRUE));
 }
 
 int injector::record_incident(THD *thd, Incident incident, LEX_STRING const message)
 {
   Incident_log_event ev(thd, incident, message);
-  if (int error= mysql_bin_log.write(&ev))
-    return error;
-  return mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+  return (mysql_bin_log.write_incident(&ev, TRUE));
 }

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-01-28 14:49:41 +0000
+++ b/sql/sql_class.h	2011-02-02 23:41:09 +0000
@@ -1642,8 +1642,6 @@ public:
   /*
     Public interface to write RBR events to the binlog
   */
-  void binlog_start_trans_and_stmt();
-  void binlog_set_stmt_begin();
   int binlog_write_table_map(TABLE *table, bool is_transactional,
                              bool binlog_rows_query);
   int binlog_write_row(TABLE* table, bool is_transactional,

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2011-01-28 14:49:41 +0000
+++ b/sql/sql_insert.cc	2011-02-02 23:41:09 +0000
@@ -3895,23 +3895,9 @@ select_create::prepare(List<Item> &value
 
   MY_HOOKS hooks(this, create_table, select_tables);
   hook_ptr= &hooks;
-
+  
   unit= u;
-
-  /*
-    Start a statement transaction before the create if we are using
-    row-based replication for the statement.  If we are creating a
-    temporary table, we need to start a statement transaction.
-  */
-  if ((thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) == 0 &&
-      thd->is_current_stmt_binlog_format_row() &&
-      mysql_bin_log.is_open())
-  {
-    thd->binlog_start_trans_and_stmt();
-  }
-
   DBUG_ASSERT(create_table->table == NULL);
-
   DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000););
 
   if (!(table= create_table_from_items(thd, create_info, create_table,

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2011-01-28 14:49:41 +0000
+++ b/sql/sql_parse.cc	2011-02-02 23:41:09 +0000
@@ -2816,8 +2816,7 @@ end_with_restore_list:
       if (incident)
       {
         Incident_log_event ev(thd, incident);
-        (void) mysql_bin_log.write(&ev);        /* error is ignored */
-        if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
+        if (mysql_bin_log.write_incident(&ev, TRUE))
         {
           res= 1;
           break;


Attachment: [text/bzr-bundle] bzr/alfranio.correia@oracle.com-20110202234109-1bdvij1pekgntl78.bundle
Thread
bzr commit into mysql-trunk branch (alfranio.correia:3564) WL#4832Alfranio Correia3 Feb