List:Commits« Previous MessageNext Message »
From:Luís Soares Date:October 14 2010 2:43pm
Subject:Re: bzr commit into mysql-5.5-bugfixing branch (alfranio.correia:3203)
Bug#56343
View as plain text  
Hi Alfranio,

  Nice Work. We're not there yet... but we're on the right
  track. Thanks.  Please find my review comments below.

STATUS
------

  Not approved.

REQUIRED CHANGES
----------------

  RC1. Please make it clear what happens for binlog_cache_disk_use

       See commit message:

       "
       (...)
       Note that binlog_cache_use is incremented for both types of
       cache, transactional and non-transactional and that the
       behavior presented in this patch also applies to the
       binlog_cache_disk_use.
       (...)
       "

  RC2. Please rewrite/make it more clear.

     @ sql/log_event.cc
        Introduced debug information to check if Query_log_event("BEGIN"),
        Query_log_event("COMMIT") and Query_log_event("ROLLBACK").

       What exactly does this mean?

  RC3. log.cc hunk: @@ -262,6 +265,14 @@

       The comment is still not clear to me.

       "Binlog_cache_disk_use

        The number of transactions that used the temporary binary
        log cache but that exceeded the value of
        binlog_cache_size and used a temporary file to store
        statements from the transaction."

       Why can't we set it to one and increment it on
       binlog_compute_statistics ? I guess that's because it can
       happen when calling reset on the binlog_cache_data (which
       truncates the cache), and that is after
       binlog_compute_statistics. Please improve the comment.

       Why is truncate setting the io_cache disk_writes ?


  RC4. Why all these flush functions? Can't we just use
       binlog_flush_cache directly?

       I think these can be removed and replaced by call to
       binlog_flush_cache:

       binlog_commit_flush_stmt_cache
       binlog_commit_flush_trx_cache
       binlog_rollback_flush_trx_cache
       binlog_commit_flush_trx_cache

  RC5. There are some places in the source code that the return
       value for binlog_..._flush_..._cache is disregarded and
       some where they are not. Eg, in binlog_rollback. Why ?
       Shouldn't we check for errors everywhere ?

  RC6. In sql/log_event.cc it would be better to add to the
       comment, how the test case benefits from this. Quite
       frankly, it's not obvious to me either.

  RC7. Given that there are some dependencies for code that is
       compiled in only in debug mode, should the test case(s)
       have:

       -- source include/have_debug.inc ?

  RC8. The assertions are quite loose, and vulnerable to result
       rewrites... Can you please rewrite them in some way
       similar to:

       let $expected= 1
       let $got= query_get_value(show status like "binlog_cache_disk_use", Value, 1);

       if (`SELECT $expected <> $got`)
       {
          -- echo "Fill your assertion failed message here"
          -- die
       }

REQUESTS
--------
 n/a

SUGGESTIONS
-----------

  S1. Please rewrite:

     @ sql/log_event.h
        Guaranteed Xid_log_event is always classified as a transactional event.

       I would suggest: Makes Xid_log_event to be always classified ...

DETAILS
-------
 n/a


On 10/06/2010 09:35 AM, Alfranio Correia wrote:
> #At
> file:///home/acorreia/workspace.sun/repository.mysql.new/bzrwork/bug-56343/mysql-5.5-bugfixing/
> based on revid:mats.kindahl@stripped
> 
>  3203 Alfranio Correia	2010-10-06
>       BUG#56343 binlog_cache_use status is bigger than expected
>       
>       The binlog_cache_use is incremented twice when changes to a transactional
> table
>       are committed, i.e. TC_LOG_BINLOG::log_xid calls is called. The problem
> happens
>       because log_xid calls both binlog_flush_stmt_cache and binlog_flush_trx_cache
>       without checking if such caches are empty thus unintentionally increasing the
>       binlog_cache_use value twice.
>       
>       To fix the problem we avoided incrementing the binlog_cache_use if the cache
> is
>       empty. We also decided to increment binlog_cache_use when the cache is
> truncated
>       as the cache is used although its content is discarded and is not written to
> the
>       binary log.
>       
>       Note that binlog_cache_use is incremented for both types of cache,
> transactional
>       and non-transactional and that the behavior presented in this patch also
> applies
>       to the binlog_cache_disk_use.
>       
>       Finally, we re-organized the code around the functions binlog_flush_trx_cache
> and
>       binlog_flush_stmt_cache.
>      @ mysql-test/extra/binlog_tests/binlog_cache_stat.test
>         Updated the test case with comments and additional tests to check both
>         transactional and non-transactional changes and what happens when a 
>         is transaction either committed or aborted.
>      @ mysql-test/suite/binlog/r/binlog_innodb.result
>         Updated the result file.
>      @ mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result
>         Updated the result file.
>      @ mysql-test/suite/binlog/r/binlog_row_cache_stat.result
>         Updated the result file.
>      @ mysql-test/suite/binlog/r/binlog_stm_cache_stat.result
>         Updated the result file.
>      @ mysql-test/suite/binlog/t/binlog_mixed_cache_stat.test
>         Updated the test case with a new source file.
>      @ mysql-test/suite/binlog/t/binlog_row_cache_stat.test
>         Updated the test case with a new source file.
>      @ mysql-test/suite/binlog/t/binlog_stm_cache_stat.test
>         Updated the test case with a new source file.
>      @ sql/log_event.cc
>         Introduced debug information to check if Query_log_event("BEGIN"),
>         Query_log_event("COMMIT") and Query_log_event("ROLLBACK").
>      @ sql/log_event.h
>         Guaranteed Xid_log_event is always classified as a transactional event.
> 
>     renamed:
>       mysql-test/extra/binlog_tests/innodb_stat.test =>
> mysql-test/extra/binlog_tests/binlog_cache_stat.test
>       mysql-test/suite/binlog/r/binlog_mix_innodb_stat.result =>
> mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result
>       mysql-test/suite/binlog/r/binlog_row_innodb_stat.result =>
> mysql-test/suite/binlog/r/binlog_row_cache_stat.result
>       mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result =>
> mysql-test/suite/binlog/r/binlog_stm_cache_stat.result
>       mysql-test/suite/binlog/t/binlog_mix_innodb_stat.test =>
> mysql-test/suite/binlog/t/binlog_mixed_cache_stat.test
>       mysql-test/suite/binlog/t/binlog_row_innodb_stat.test =>
> mysql-test/suite/binlog/t/binlog_row_cache_stat.test
>       mysql-test/suite/binlog/t/binlog_stm_innodb_stat.test =>
> mysql-test/suite/binlog/t/binlog_stm_cache_stat.test
>     modified:
>       mysql-test/suite/binlog/r/binlog_innodb.result
>       sql/log.cc
>       sql/log_event.cc
>       sql/log_event.h
>       mysql-test/extra/binlog_tests/binlog_cache_stat.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/binlog/t/binlog_mixed_cache_stat.test
>       mysql-test/suite/binlog/t/binlog_row_cache_stat.test
>       mysql-test/suite/binlog/t/binlog_stm_cache_stat.test
> === renamed file 'mysql-test/extra/binlog_tests/innodb_stat.test' =>
> 'mysql-test/extra/binlog_tests/binlog_cache_stat.test'
> --- a/mysql-test/extra/binlog_tests/innodb_stat.test	2008-09-22 19:15:52 +0000
> +++ b/mysql-test/extra/binlog_tests/binlog_cache_stat.test	2010-10-06 08:34:49 +0000
> @@ -2,22 +2,36 @@
>  -- source include/not_embedded.inc
>  -- source include/have_innodb.inc
>  
> +# Creating tables
> +--disable_warnings
> +drop table if exists t1, t2;
> +--enable_warnings
> +
> +create table t1 (a int) engine=innodb;
> +create table t2 (a int) engine=myisam;
> +
>  #
>  # Let us test binlog_cache_use and binlog_cache_disk_use status vars.
> -# Actually this test has nothing to do with innodb per se, it just requires
> -# transactional table. 
> +# Actually this test has nothing to do with innodb per se, it just
> +# requires transactional table.
> +#
> +# This test checks binlog_cache_use and binlog_cache_disk_use when
> +# transactions are committed and after when they are aborted.
> +#
> +
> +#
> +# Checking commit.
>  #
> +--echo **** Preparing the enviroment to check commit and its effect on
> +--echo **** the binlog_cache_use and binlog_cache_disk_use.
> +--echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
>  flush status;
>  show status like "binlog_cache_use";
>  show status like "binlog_cache_disk_use";
> ---disable_warnings
> -drop table if exists t1;
> ---enable_warnings
>  
> -create table t1 (a int) engine=innodb;
> -
> -# Now we are going to create transaction which is long enough so its 
> -# transaction binlog will be flushed to disk...
> +--echo **** Now we are going to create transactional changes which are long enough
> so
> +--echo **** they will be flushed to disk...
> +--echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
>  let $1=2000;
>  disable_query_log;
>  begin;
> @@ -31,11 +45,85 @@ enable_query_log;
>  show status like "binlog_cache_use";
>  show status like "binlog_cache_disk_use";
>  
> -# Transaction which should not be flushed to disk and so should not
> -# increase binlog_cache_disk_use.
> +--echo **** Transactional changes which should not be flushed to disk and so should
> not
> +--echo **** increase binlog_cache_disk_use.
> +--echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
>  begin;
> -delete from t1;
> +insert into t1 values( 1 );
>  commit;
>  show status like "binlog_cache_use";
>  show status like "binlog_cache_disk_use";
> -drop table t1;
> +
> +--echo **** Non-Transactional changes which should not be flushed to disk and so
> should not
> +--echo **** increase binlog_cache_disk_use.
> +--echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
> +begin;
> +insert into t2 values( 1 );
> +commit;
> +show status like "binlog_cache_use";
> +show status like "binlog_cache_disk_use";
> +
> +--echo **** Mixed changes which should not be flushed to disk and so should not
> +--echo **** increase binlog_cache_disk_use.
> +--echo **** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +insert into t2 values( 1 );
> +commit;
> +show status like "binlog_cache_use";
> +show status like "binlog_cache_disk_use";
> +
> +#
> +# Checking abort.
> +#
> +--echo **** Preparing the enviroment to check abort and its effect on
> +--echo **** the binlog_cache_use and binlog_cache_disk_use
> +--echo **** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
> +flush status;
> +show status like "binlog_cache_use";
> +show status like "binlog_cache_disk_use";
> +
> +--echo **** Now we are going to create transactional changes which are long enough
> so
> +--echo **** they will be flushed to disk...
> +--echo **** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
> +let $1=2000;
> +disable_query_log;
> +begin;
> +while ($1)
> +{
> + eval insert into t1 values( $1 );
> + dec $1;
> +}
> +rollback;
> +enable_query_log;
> +show status like "binlog_cache_use";
> +show status like "binlog_cache_disk_use";
> +
> +--echo **** Transactional changes which should not be flushed to disk and so should
> not
> +--echo **** increase binlog_cache_disk_use.
> +--echo **** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +rollback;
> +show status like "binlog_cache_use";
> +show status like "binlog_cache_disk_use";
> +
> +--echo **** Non-Transactional changes which should not be flushed to disk and so
> should not
> +--echo **** increase binlog_cache_disk_use.
> +--echo **** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
> +begin;
> +insert into t2 values( 1 );
> +rollback;
> +show status like "binlog_cache_use";
> +show status like "binlog_cache_disk_use";
> +
> +--echo **** Mixed changes which should not be flushed to disk and so should not
> +--echo **** increase binlog_cache_disk_use.
> +--echo **** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +insert into t2 values( 1 );
> +rollback;
> +show status like "binlog_cache_use";
> +show status like "binlog_cache_disk_use";
> +drop table t1, t2;
> 
> === modified file 'mysql-test/suite/binlog/r/binlog_innodb.result'
> --- a/mysql-test/suite/binlog/r/binlog_innodb.result	2010-06-17 13:31:51 +0000
> +++ b/mysql-test/suite/binlog/r/binlog_innodb.result	2010-10-06 08:34:49 +0000
> @@ -123,7 +123,7 @@ Binlog_cache_disk_use	0
>  create table t1 (a int) engine=innodb;
>  show status like "binlog_cache_use";
>  Variable_name	Value
> -Binlog_cache_use	2
> +Binlog_cache_use	1
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	1
> @@ -132,7 +132,7 @@ delete from t1;
>  commit;
>  show status like "binlog_cache_use";
>  Variable_name	Value
> -Binlog_cache_use	4
> +Binlog_cache_use	2
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	1
> 
> === renamed file 'mysql-test/suite/binlog/r/binlog_mix_innodb_stat.result' =>
> 'mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result'
> --- a/mysql-test/suite/binlog/r/binlog_mix_innodb_stat.result	2010-01-05 16:55:23
> +0000
> +++ b/mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result	2010-10-06 08:34:49
> +0000
> @@ -1,3 +1,9 @@
> +drop table if exists t1, t2;
> +create table t1 (a int) engine=innodb;
> +create table t2 (a int) engine=myisam;
> +**** Preparing the enviroment to check commit and its effect on
> +**** the binlog_cache_use and binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
>  flush status;
>  show status like "binlog_cache_use";
>  Variable_name	Value
> @@ -5,21 +11,110 @@ Binlog_cache_use	0
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	0
> -drop table if exists t1;
> -create table t1 (a int) engine=innodb;
> +**** Now we are going to create transactional changes which are long enough so
> +**** they will be flushed to disk...
> +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	1
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Transactional changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +commit;
>  show status like "binlog_cache_use";
>  Variable_name	Value
>  Binlog_cache_use	2
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	1
> +**** Non-Transactional changes which should not be flushed to disk and so should
> not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
> +begin;
> +insert into t2 values( 1 );
> +commit;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	3
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Mixed changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1.
>  begin;
> -delete from t1;
> +insert into t1 values( 1 );
> +insert into t2 values( 1 );
>  commit;
>  show status like "binlog_cache_use";
>  Variable_name	Value
> -Binlog_cache_use	4
> +Binlog_cache_use	5
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Preparing the enviroment to check abort and its effect on
> +**** the binlog_cache_use and binlog_cache_disk_use
> +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
> +flush status;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	0
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	0
> +**** Now we are going to create transactional changes which are long enough so
> +**** they will be flushed to disk...
> +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	1
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Transactional changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +rollback;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	2
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Non-Transactional changes which should not be flushed to disk and so should
> not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
> +begin;
> +insert into t2 values( 1 );
> +rollback;
> +Warnings:
> +Warning	1196	Some non-transactional changed tables couldn't be rolled back
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	3
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Mixed changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +insert into t2 values( 1 );
> +rollback;
> +Warnings:
> +Warning	1196	Some non-transactional changed tables couldn't be rolled back
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	5
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	1
> -drop table t1;
> +drop table t1, t2;
> 
> === renamed file 'mysql-test/suite/binlog/r/binlog_row_innodb_stat.result' =>
> 'mysql-test/suite/binlog/r/binlog_row_cache_stat.result'
> --- a/mysql-test/suite/binlog/r/binlog_row_innodb_stat.result	2010-01-05 16:55:23
> +0000
> +++ b/mysql-test/suite/binlog/r/binlog_row_cache_stat.result	2010-10-06 08:34:49
> +0000
> @@ -1,3 +1,9 @@
> +drop table if exists t1, t2;
> +create table t1 (a int) engine=innodb;
> +create table t2 (a int) engine=myisam;
> +**** Preparing the enviroment to check commit and its effect on
> +**** the binlog_cache_use and binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
>  flush status;
>  show status like "binlog_cache_use";
>  Variable_name	Value
> @@ -5,21 +11,110 @@ Binlog_cache_use	0
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	0
> -drop table if exists t1;
> -create table t1 (a int) engine=innodb;
> +**** Now we are going to create transactional changes which are long enough so
> +**** they will be flushed to disk...
> +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	1
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Transactional changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +commit;
>  show status like "binlog_cache_use";
>  Variable_name	Value
>  Binlog_cache_use	2
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	1
> +**** Non-Transactional changes which should not be flushed to disk and so should
> not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
> +begin;
> +insert into t2 values( 1 );
> +commit;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	3
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Mixed changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1.
>  begin;
> -delete from t1;
> +insert into t1 values( 1 );
> +insert into t2 values( 1 );
>  commit;
>  show status like "binlog_cache_use";
>  Variable_name	Value
> -Binlog_cache_use	4
> +Binlog_cache_use	5
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Preparing the enviroment to check abort and its effect on
> +**** the binlog_cache_use and binlog_cache_disk_use
> +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
> +flush status;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	0
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	0
> +**** Now we are going to create transactional changes which are long enough so
> +**** they will be flushed to disk...
> +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	1
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Transactional changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +rollback;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	2
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Non-Transactional changes which should not be flushed to disk and so should
> not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
> +begin;
> +insert into t2 values( 1 );
> +rollback;
> +Warnings:
> +Warning	1196	Some non-transactional changed tables couldn't be rolled back
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	3
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Mixed changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +insert into t2 values( 1 );
> +rollback;
> +Warnings:
> +Warning	1196	Some non-transactional changed tables couldn't be rolled back
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	5
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	1
> -drop table t1;
> +drop table t1, t2;
> 
> === renamed file 'mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result' =>
> 'mysql-test/suite/binlog/r/binlog_stm_cache_stat.result'
> --- a/mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result	2010-01-05 16:55:23
> +0000
> +++ b/mysql-test/suite/binlog/r/binlog_stm_cache_stat.result	2010-10-06 08:34:49
> +0000
> @@ -1,3 +1,9 @@
> +drop table if exists t1, t2;
> +create table t1 (a int) engine=innodb;
> +create table t2 (a int) engine=myisam;
> +**** Preparing the enviroment to check commit and its effect on
> +**** the binlog_cache_use and binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
>  flush status;
>  show status like "binlog_cache_use";
>  Variable_name	Value
> @@ -5,21 +11,110 @@ Binlog_cache_use	0
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	0
> -drop table if exists t1;
> -create table t1 (a int) engine=innodb;
> +**** Now we are going to create transactional changes which are long enough so
> +**** they will be flushed to disk...
> +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	1
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Transactional changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +commit;
>  show status like "binlog_cache_use";
>  Variable_name	Value
>  Binlog_cache_use	2
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	1
> +**** Non-Transactional changes which should not be flushed to disk and so should
> not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
> +begin;
> +insert into t2 values( 1 );
> +commit;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	3
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Mixed changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1.
>  begin;
> -delete from t1;
> +insert into t1 values( 1 );
> +insert into t2 values( 1 );
>  commit;
>  show status like "binlog_cache_use";
>  Variable_name	Value
> -Binlog_cache_use	4
> +Binlog_cache_use	5
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Preparing the enviroment to check abort and its effect on
> +**** the binlog_cache_use and binlog_cache_disk_use
> +**** Expected: binlog_cache_use = 0, binlog_cache_disk_use = 0.
> +flush status;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	0
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	0
> +**** Now we are going to create transactional changes which are long enough so
> +**** they will be flushed to disk...
> +**** Expected: binlog_cache_use = 1, binlog_cache_disk_use = 1.
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	1
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Transactional changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 2, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +rollback;
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	2
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Non-Transactional changes which should not be flushed to disk and so should
> not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 3, binlog_cache_disk_use = 1.
> +begin;
> +insert into t2 values( 1 );
> +rollback;
> +Warnings:
> +Warning	1196	Some non-transactional changed tables couldn't be rolled back
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	3
> +show status like "binlog_cache_disk_use";
> +Variable_name	Value
> +Binlog_cache_disk_use	1
> +**** Mixed changes which should not be flushed to disk and so should not
> +**** increase binlog_cache_disk_use.
> +**** Expected: binlog_cache_use = 5, binlog_cache_disk_use = 1.
> +begin;
> +insert into t1 values( 1 );
> +insert into t2 values( 1 );
> +rollback;
> +Warnings:
> +Warning	1196	Some non-transactional changed tables couldn't be rolled back
> +show status like "binlog_cache_use";
> +Variable_name	Value
> +Binlog_cache_use	5
>  show status like "binlog_cache_disk_use";
>  Variable_name	Value
>  Binlog_cache_disk_use	1
> -drop table t1;
> +drop table t1, t2;
> 
> === renamed file 'mysql-test/suite/binlog/t/binlog_mix_innodb_stat.test' =>
> 'mysql-test/suite/binlog/t/binlog_mixed_cache_stat.test'
> --- a/mysql-test/suite/binlog/t/binlog_mix_innodb_stat.test	2008-09-08 20:23:55
> +0000
> +++ b/mysql-test/suite/binlog/t/binlog_mixed_cache_stat.test	2010-10-06 08:34:49
> +0000
> @@ -2,4 +2,4 @@
>  # For both statement and row based bin logs 9/19/2005 [jbm]
>  
>  -- source include/have_binlog_format_mixed.inc
> --- source extra/binlog_tests/innodb_stat.test
> +-- source extra/binlog_tests/binlog_cache_stat.test
> 
> === renamed file 'mysql-test/suite/binlog/t/binlog_row_innodb_stat.test' =>
> 'mysql-test/suite/binlog/t/binlog_row_cache_stat.test'
> --- a/mysql-test/suite/binlog/t/binlog_row_innodb_stat.test	2007-06-27 12:28:02
> +0000
> +++ b/mysql-test/suite/binlog/t/binlog_row_cache_stat.test	2010-10-06 08:34:49 +0000
> @@ -2,4 +2,4 @@
>  # For both statement and row based bin logs 9/19/2005 [jbm]
>  
>  -- source include/have_binlog_format_row.inc
> --- source extra/binlog_tests/innodb_stat.test
> +-- source extra/binlog_tests/binlog_cache_stat.test
> 
> === renamed file 'mysql-test/suite/binlog/t/binlog_stm_innodb_stat.test' =>
> 'mysql-test/suite/binlog/t/binlog_stm_cache_stat.test'
> --- a/mysql-test/suite/binlog/t/binlog_stm_innodb_stat.test	2008-09-08 20:23:55
> +0000
> +++ b/mysql-test/suite/binlog/t/binlog_stm_cache_stat.test	2010-10-06 08:34:49 +0000
> @@ -2,4 +2,4 @@
>  # For both statement and row based bin logs 9/19/2005 [jbm]
>  
>  -- source include/have_binlog_format_statement.inc
> --- source extra/binlog_tests/innodb_stat.test
> +-- source extra/binlog_tests/binlog_cache_stat.test
> 
> === modified file 'sql/log.cc'
> --- a/sql/log.cc	2010-09-06 17:18:44 +0000
> +++ b/sql/log.cc	2010-10-06 08:34:49 +0000
> @@ -210,6 +210,9 @@ class binlog_cache_data
>  public:
>    binlog_cache_data(): m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF),
>    incident(FALSE), changes_to_non_trans_temp_table_flag(FALSE)
> +#ifndef DBUG_OFF
> +  , has_trans(FALSE)
> +#endif
>    {
>      cache_log.end_of_file= max_binlog_cache_size;
>    }
> @@ -262,6 +265,14 @@ public:
>      incident= FALSE;
>      before_stmt_pos= MY_OFF_T_UNDEF;
>      cache_log.end_of_file= max_binlog_cache_size;
> +    /*
> +      When a truncate is called there may be write activity and by consequence
> +      "disk_writes" is increased. This breaks the "disk_writes"' use by the
> +      binary log which aims to compute the ratio between in-memory cache usage
> +      and disk cache usage. To avoid this undesirable behavior, we reset the
> +      variable after truncating the cache.
> +    */
> +    cache_log.disk_writes= 0;
>      DBUG_ASSERT(empty());
>    }
>  
> @@ -292,6 +303,18 @@ public:
>        before_stmt_pos= MY_OFF_T_UNDEF;
>    }
>  
> +#ifndef DBUG_OFF
> +  bool is_transactional()
> +  {
> +    return(has_trans);
> +  }
> +
> +  void set_transactional(bool is_transactional)
> +  {
> +    has_trans= is_transactional;
> +  }
> +#endif
> +
>    /*
>      Cache to store data before copying it to the binary log.
>    */
> @@ -321,6 +344,13 @@ private:
>    */
>    bool changes_to_non_trans_temp_table_flag;
>  
> +#ifndef DBUG_OFF
> +  /*
> +    Defines the type of the cache either: transactional or non-transactional.
> +  */
> +  bool has_trans;
> +#endif
> +
>    /*
>      It truncates the cache to a certain position. This includes deleting the
>      pending event.
> @@ -1506,57 +1536,147 @@ static int binlog_close_connection(handl
>  }
>  
>  /**
> -  This function flushes a transactional cache upon commit/rollback.
> -
> -  @param thd        The thread whose transaction should be flushed
> -  @param cache_mngr Pointer to the cache data to be flushed
> -  @param end_ev     The end event either commit/rollback.
> +  This function computes binlog cache and disk usage.
>  
> -  @return
> -    nonzero if an error pops up when flushing the transactional cache.
> +  @param cache_data  Pointer to the cache where data is
> +                     stored.
>  */
> -static int
> -binlog_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr,
> -                       Log_event *end_ev)
> +static inline void
> +binlog_compute_statistics(binlog_cache_data* cache_data)
>  {
> -  DBUG_ENTER("binlog_flush_trx_cache");
> -  int error=0;
> -  IO_CACHE *cache_log= &cache_mngr->trx_cache.cache_log;
> +  if (!cache_data->empty())
> +  {
> +    statistic_increment(binlog_cache_use, &LOCK_status);
> +    if (cache_data->cache_log.disk_writes != 0)
> +      statistic_increment(binlog_cache_disk_use, &LOCK_status);
> +  }
> +}
>  
> -  /*
> -    This function handles transactional changes and as such
> -    this flag equals to true.
> -  */
> -  bool const is_transactional= TRUE;
> +/**
> +  This function flushes a cache upon commit/rollback.
>  
> -  if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional))
> -    DBUG_RETURN(1);
> -  /*
> -    Doing a commit or a rollback including non-transactional tables,
> -    i.e., ending a transaction where we might write the transaction
> -    cache to the binary log.
> +  @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
>  
> -    We can always end the statement when ending a transaction since
> -    transactions are not allowed inside stored functions. If they
> -    were, we would have to ensure that we're not ending a statement
> -    inside a stored function.
> -  */
> -  error= mysql_bin_log.write(thd, &cache_mngr->trx_cache.cache_log, end_ev,
> -                             cache_mngr->trx_cache.has_incident());
> -  cache_mngr->reset_cache(&cache_mngr->trx_cache);
> +  @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)
> +{
> +  DBUG_ENTER("binlog_flush_cache");
> +  int error= 0;
>  
> -  statistic_increment(binlog_cache_use, &LOCK_status);
> -  if (cache_log->disk_writes != 0)
> +  if (!cache_data->empty())
>    {
> -    statistic_increment(binlog_cache_disk_use, &LOCK_status);
> -    cache_log->disk_writes= 0;
> +#ifndef DBUG_OFF   
> +    DBUG_PRINT("info", ("is_transactional(%d), event(%d), cache_data(%d)",
> +               is_transactional, end_evt->use_trans_cache(),
> +               cache_data->is_transactional()));
> +    DBUG_ASSERT(is_transactional == end_evt->use_trans_cache() &&
> +                is_transactional == cache_data->is_transactional());
> +#endif
> +    if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional))
> +      DBUG_RETURN(1);
> +    /*
> +      Doing a commit or a rollback including non-transactional tables,
> +      i.e., ending a transaction where we might write the transaction
> +      cache to the binary log.
> +
> +      We can always end the statement when ending a transaction since
> +      transactions are not allowed inside stored functions. If they
> +      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());
>    }
> +  binlog_compute_statistics(cache_data);
> +  cache_data->reset();
>  
> -  DBUG_ASSERT(cache_mngr->trx_cache.empty());
> +  DBUG_ASSERT(cache_data->empty());
>    DBUG_RETURN(error);
>  }
>  
>  /**
> +  This function flushes the stmt-cache upon commit.
> +
> +  @param thd                The thread whose transaction should be flushed
> +  @param cache_mngr         Pointer to the cache manager
> +
> +  @return
> +    nonzero if an error pops up when flushing the cache.
> +*/
> +static inline int
> +binlog_commit_flush_stmt_cache(THD *thd,
> +                               binlog_cache_mngr *cache_mngr)
> +{
> +  Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"),
> +                          FALSE, FALSE, TRUE, 0);
> +  return (binlog_flush_cache(thd, &cache_mngr->stmt_cache, &end_evt,
> +                             FALSE));
> +}
> +
> +/**
> +  This function flushes the trx-cache upon commit.
> +
> +  @param thd                The thread whose transaction should be flushed
> +  @param cache_mngr         Pointer to the cache manager
> +
> +  @return
> +    nonzero if an error pops up when flushing the cache.
> +*/
> +static inline int
> +binlog_commit_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr)
> +{
> +  Query_log_event end_evt(thd, STRING_WITH_LEN("COMMIT"),
> +                          TRUE, FALSE, TRUE, 0);
> +  return (binlog_flush_cache(thd, &cache_mngr->trx_cache, &end_evt,
> +                             TRUE));
> +}
> +
> +/**
> +  This function flushes the trx-cache upon rollback.
> +
> +  @param thd                The thread whose transaction should be flushed
> +  @param cache_mngr         Pointer to the cache manager
> +
> +  @return
> +    nonzero if an error pops up when flushing the cache.
> +*/
> +static inline int
> +binlog_rollback_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr)
> +{
> +  Query_log_event end_evt(thd, STRING_WITH_LEN("ROLLBACK"),
> +                          TRUE, FALSE, TRUE, 0);
> +  return (binlog_flush_cache(thd, &cache_mngr->trx_cache, &end_evt,
> +                             TRUE));
> +}
> +
> +/**
> +  This function flushes the trx-cache upon commit.
> +
> +  @param thd                The thread whose transaction should be flushed
> +  @param cache_mngr         Pointer to the cache manager
> +  @param xid                Transaction Id
> +
> +  @return
> +    nonzero if an error pops up when flushing the cache.
> +*/
> +static inline int
> +binlog_commit_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr,
> +                              my_xid xid)
> +{
> +  Xid_log_event end_evt(thd, xid);
> +  return (binlog_flush_cache(thd, &cache_mngr->trx_cache, &end_evt,
> +                             TRUE));
> +}
> +
> +/**
>    This function truncates the transactional cache upon committing or rolling
>    back either a transaction or a statement.
>  
> @@ -1579,23 +1699,26 @@ binlog_truncate_trx_cache(THD *thd, binl
>    */
>    bool const is_transactional= TRUE;
>  
> -  DBUG_PRINT("info", ("thd->options={ %s%s}, transaction: %s",
> +  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);
>    /*
>      If rolling back an entire transaction or a single statement not
>      inside a transaction, we reset the transaction cache.
>    */
> -  thd->binlog_remove_pending_rows_event(TRUE, is_transactional);
>    if (ending_trans(thd, all))
>    {
>      if (cache_mngr->trx_cache.has_incident())
>        error= mysql_bin_log.write_incident(thd, TRUE);
>  
> -    cache_mngr->reset_cache(&cache_mngr->trx_cache);
> -
>      thd->clear_binlog_table_maps();
> +
> +    binlog_compute_statistics(&cache_mngr->trx_cache);
> +
> +    cache_mngr->reset_cache(&cache_mngr->trx_cache);
>    }
>    /*
>      If rolling back a statement in a transaction, we truncate the
> @@ -1620,51 +1743,6 @@ static int binlog_prepare(handlerton *ht
>  }
>  
>  /**
> -  This function flushes the non-transactional to the binary log upon
> -  committing or rolling back a statement.
> -
> -  @param thd        The thread whose transaction should be flushed
> -  @param cache_mngr Pointer to the cache data to be flushed
> -
> -  @return
> -    nonzero if an error pops up when flushing the non-transactional cache.
> -*/
> -static int
> -binlog_flush_stmt_cache(THD *thd, binlog_cache_mngr *cache_mngr)
> -{
> -  int error= 0;
> -  DBUG_ENTER("binlog_flush_stmt_cache");
> -  /*
> -    If we are flushing the statement cache, it means that the changes get
> -    through otherwise the cache is empty and this routine should not be called.
> -  */
> -  DBUG_ASSERT(cache_mngr->stmt_cache.has_incident() == FALSE);
> -  /*
> -    This function handles non-transactional changes and as such this flag equals
> -    to false.
> -  */
> -  bool const is_transactional= FALSE;
> -  IO_CACHE *cache_log= &cache_mngr->stmt_cache.cache_log;
> -
> -  if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional))
> -    DBUG_RETURN(1);
> -
> -  Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE, TRUE, 0);
> -  if ((error= mysql_bin_log.write(thd, cache_log, &qev,
> -                                  cache_mngr->stmt_cache.has_incident())))
> -    DBUG_RETURN(error);
> -  cache_mngr->reset_cache(&cache_mngr->stmt_cache);
> -
> -  statistic_increment(binlog_cache_use, &LOCK_status);
> -  if (cache_log->disk_writes != 0)
> -  {
> -    statistic_increment(binlog_cache_disk_use, &LOCK_status);
> -    cache_log->disk_writes= 0;
> -  }
> -  DBUG_RETURN(error);
> -}
> -
> -/**
>    This function is called once after each statement.
>  
>    It has the responsibility to flush the caches to the binary log on commits.
> @@ -1690,19 +1768,7 @@ static int binlog_commit(handlerton *hto
>                YESNO(thd->transaction.all.modified_non_trans_table),
>                YESNO(thd->transaction.stmt.modified_non_trans_table)));
>  
> -  if (!cache_mngr->stmt_cache.empty())
> -  {
> -    binlog_flush_stmt_cache(thd, cache_mngr);
> -  }
> -
> -  if (cache_mngr->trx_cache.empty())
> -  {
> -    /*
> -      we're here because cache_log was flushed in MYSQL_BIN_LOG::log_xid()
> -    */
> -    cache_mngr->reset_cache(&cache_mngr->trx_cache);
> -    DBUG_RETURN(0);
> -  }
> +  binlog_commit_flush_stmt_cache(thd, cache_mngr);
>  
>    /*
>      We commit the transaction if:
> @@ -1711,16 +1777,14 @@ static int binlog_commit(handlerton *hto
>      Otherwise, we accumulate the changes.
>    */
>    if (ending_trans(thd, all))
> -  {
> -    Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE, TRUE, 0);
> -    error= binlog_flush_trx_cache(thd, cache_mngr, &qev);
> -  }
> +    error= binlog_commit_flush_trx_cache(thd, cache_mngr);
>  
>    /*
>      This is part of the stmt rollback.
>    */
>    if (!all)
>      cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF);
> +
>    DBUG_RETURN(error);
>  }
>  
> @@ -1755,19 +1819,8 @@ static int binlog_rollback(handlerton *h
>      error= mysql_bin_log.write_incident(thd, TRUE);
>      cache_mngr->reset_cache(&cache_mngr->stmt_cache);
>    }
> -  else if (!cache_mngr->stmt_cache.empty())
> -  {
> -    binlog_flush_stmt_cache(thd, cache_mngr);
> -  }
> -
> -  if (cache_mngr->trx_cache.empty())
> -  {
> -    /* 
> -      we're here because cache_log was flushed in MYSQL_BIN_LOG::log_xid()
> -    */
> -    cache_mngr->reset_cache(&cache_mngr->trx_cache);
> -    DBUG_RETURN(0);
> -  }
> +  else
> +    binlog_commit_flush_stmt_cache(thd, cache_mngr);
>  
>    if (mysql_bin_log.check_write_error(thd))
>    {
> @@ -1796,7 +1849,6 @@ static int binlog_rollback(handlerton *h
>          . the format is MIXED, non-trans table was updated and
>            aborting a single statement transaction;
>      */
> -
>      if (ending_trans(thd, all) &&
>          ((thd->variables.option_bits & OPTION_KEEP_LOG) ||
>           (trans_has_updated_non_trans_table(thd) &&
> @@ -1806,10 +1858,7 @@ static int binlog_rollback(handlerton *h
>           (trans_has_updated_non_trans_table(thd) &&
>            ending_single_stmt_trans(thd,all) &&
>            thd->variables.binlog_format == BINLOG_FORMAT_MIXED)))
> -    {
> -      Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE, TRUE, 0);
> -      error= binlog_flush_trx_cache(thd, cache_mngr, &qev);
> -    }
> +      error= binlog_rollback_flush_trx_cache(thd, cache_mngr);
>      /*
>        Truncate the cache if:
>          . aborting a single or multi-statement transaction or;
> @@ -1832,7 +1881,8 @@ static int binlog_rollback(handlerton *h
>      This is part of the stmt rollback.
>    */
>    if (!all)
> -    cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF); 
> +    cache_mngr->trx_cache.set_prev_position(MY_OFF_T_UNDEF);
> +
>    DBUG_RETURN(error);
>  }
>  
> @@ -4364,6 +4414,11 @@ int THD::binlog_setup_trx_data()
>  
>    cache_mngr= new (thd_get_ha_data(this, binlog_hton)) binlog_cache_mngr;
>  
> +#ifndef DBUG_OFF
> +  cache_mngr->trx_cache.set_transactional(TRUE);
> +  cache_mngr->stmt_cache.set_transactional(FALSE);
> +#endif
> +
>    DBUG_RETURN(0);
>  }
>  
> @@ -6291,15 +6346,14 @@ void TC_LOG_BINLOG::close()
>  int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
>  {
>    DBUG_ENTER("TC_LOG_BINLOG::log");
> -  Xid_log_event xle(thd, xid);
>    binlog_cache_mngr *cache_mngr=
>      (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
>    /*
>      We always commit the entire transaction when writing an XID. Also
>      note that the return value is inverted.
>     */
> -  DBUG_RETURN(!binlog_flush_stmt_cache(thd, cache_mngr) &&
> -              !binlog_flush_trx_cache(thd, cache_mngr, &xle));
> +  DBUG_RETURN(!binlog_commit_flush_stmt_cache(thd, cache_mngr) &&
> +              !binlog_commit_flush_trx_cache(thd, cache_mngr, xid));
>  }
>  
>  void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
> 
> === modified file 'sql/log_event.cc'
> --- a/sql/log_event.cc	2010-08-23 22:31:12 +0000
> +++ b/sql/log_event.cc	2010-10-06 08:34:49 +0000
> @@ -2537,6 +2537,22 @@ Query_log_event::Query_log_event(THD* th
>    bool trx_cache= FALSE;
>    cache_type= Log_event::EVENT_INVALID_CACHE;
>  
> +#ifndef DBUG_OFF
> +  /*
> +    If debug is enabled, we make sure that begin, commit and rollback
> +    have the cache_type exclusively defined by the param using_trans.
> +    as this is important while checking if the correct cache is used.
> +
> +    Note this is the only way to accurately set the type of the cache
> +    when a begin, commit or rollback event is created because such
> +    events may be artificially produced to compose the binary log.
> +  */
> +  if (strncmp("BEGIN", query_arg, query_length) &&
> +      strncmp("COMMIT", query_arg, query_length) &&
> +      strncmp("ROLLBACK", query_arg, query_length))
> +  {  
> +#endif
> +
>    switch (lex->sql_command)
>    {
>      case SQLCOM_DROP_TABLE:
> @@ -2574,6 +2590,15 @@ Query_log_event::Query_log_event(THD* th
>      cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
>    else
>      cache_type= Log_event::EVENT_STMT_CACHE;
> +
> +#ifndef DBUG_OFF
> +  }
> +  else if (using_trans)
> +    cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
> +  else
> +    cache_type= Log_event::EVENT_STMT_CACHE;
> +#endif
> +
>    DBUG_ASSERT(cache_type != Log_event::EVENT_INVALID_CACHE);
>    DBUG_PRINT("info",("Query_log_event has flags2: %lu  sql_mode: %lu",
>                       (ulong) flags2, sql_mode));
> 
> === modified file 'sql/log_event.h'
> --- a/sql/log_event.h	2010-07-15 13:47:50 +0000
> +++ b/sql/log_event.h	2010-10-06 08:34:49 +0000
> @@ -2504,7 +2504,7 @@ 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,0), xid(x) {}
> +  Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg, 0, TRUE), xid(x) {}
>  #ifdef HAVE_REPLICATION
>    void pack_info(Protocol* protocol);
>  #endif /* HAVE_REPLICATION */
> 
> 
> 
> 
> 

Thread
bzr commit into mysql-5.5-bugfixing branch (alfranio.correia:3203) Bug#56343Alfranio Correia6 Oct
  • Re: bzr commit into mysql-5.5-bugfixing branch (alfranio.correia:3203)Bug#56343Luís Soares14 Oct
    • Re: bzr commit into mysql-5.5-bugfixing branch (alfranio.correia:3203)Bug#56343Alfranio Correia18 Oct
      • Re: bzr commit into mysql-5.5-bugfixing branch (alfranio.correia:3203)Bug#56343Luís Soares5 Nov
  • Re: bzr commit into mysql-5.5-bugfixing branch (alfranio.correia:3203)Bug#56343Alfranio Correia18 Oct