mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
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.
This commit is contained in:
parent
3f975a7fcf
commit
8504580ced
15 changed files with 701 additions and 249 deletions
mysql-test
extra/binlog_tests
suite/binlog
sql
129
mysql-test/extra/binlog_tests/binlog_cache_stat.test
Normal file
129
mysql-test/extra/binlog_tests/binlog_cache_stat.test
Normal file
|
@ -0,0 +1,129 @@
|
|||
# Embedded server doesn't support binlog
|
||||
-- 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.
|
||||
#
|
||||
# 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";
|
||||
|
||||
--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;
|
||||
}
|
||||
commit;
|
||||
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 );
|
||||
commit;
|
||||
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 );
|
||||
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;
|
|
@ -1,41 +0,0 @@
|
|||
# Embedded server doesn't support binlog
|
||||
-- source include/not_embedded.inc
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
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...
|
||||
let $1=2000;
|
||||
disable_query_log;
|
||||
begin;
|
||||
while ($1)
|
||||
{
|
||||
eval insert into t1 values( $1 );
|
||||
dec $1;
|
||||
}
|
||||
commit;
|
||||
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.
|
||||
begin;
|
||||
delete from t1;
|
||||
commit;
|
||||
show status like "binlog_cache_use";
|
||||
show status like "binlog_cache_disk_use";
|
||||
drop table t1;
|
|
@ -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
|
||||
|
|
|
@ -1,25 +0,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
|
||||
drop table if exists t1;
|
||||
create table t1 (a int) engine=innodb;
|
||||
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
|
||||
begin;
|
||||
delete from t1;
|
||||
commit;
|
||||
show status like "binlog_cache_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_use 4
|
||||
show status like "binlog_cache_disk_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_disk_use 1
|
||||
drop table t1;
|
120
mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result
Normal file
120
mysql-test/suite/binlog/r/binlog_mixed_cache_stat.result
Normal file
|
@ -0,0 +1,120 @@
|
|||
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
|
||||
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 );
|
||||
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;
|
||||
insert into t1 values( 1 );
|
||||
insert into t2 values( 1 );
|
||||
commit;
|
||||
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
|
||||
**** 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, t2;
|
120
mysql-test/suite/binlog/r/binlog_row_cache_stat.result
Normal file
120
mysql-test/suite/binlog/r/binlog_row_cache_stat.result
Normal file
|
@ -0,0 +1,120 @@
|
|||
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
|
||||
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 );
|
||||
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;
|
||||
insert into t1 values( 1 );
|
||||
insert into t2 values( 1 );
|
||||
commit;
|
||||
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
|
||||
**** 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, t2;
|
|
@ -1,25 +0,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
|
||||
drop table if exists t1;
|
||||
create table t1 (a int) engine=innodb;
|
||||
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
|
||||
begin;
|
||||
delete from t1;
|
||||
commit;
|
||||
show status like "binlog_cache_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_use 4
|
||||
show status like "binlog_cache_disk_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_disk_use 1
|
||||
drop table t1;
|
120
mysql-test/suite/binlog/r/binlog_stm_cache_stat.result
Normal file
120
mysql-test/suite/binlog/r/binlog_stm_cache_stat.result
Normal file
|
@ -0,0 +1,120 @@
|
|||
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
|
||||
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 );
|
||||
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;
|
||||
insert into t1 values( 1 );
|
||||
insert into t2 values( 1 );
|
||||
commit;
|
||||
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
|
||||
**** 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, t2;
|
|
@ -1,25 +0,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
|
||||
drop table if exists t1;
|
||||
create table t1 (a int) engine=innodb;
|
||||
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
|
||||
begin;
|
||||
delete from t1;
|
||||
commit;
|
||||
show status like "binlog_cache_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_use 4
|
||||
show status like "binlog_cache_disk_use";
|
||||
Variable_name Value
|
||||
Binlog_cache_disk_use 1
|
||||
drop table t1;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
308
sql/log.cc
308
sql/log.cc
|
@ -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,56 +1536,146 @@ static int binlog_close_connection(handlerton *hton, THD *thd)
|
|||
}
|
||||
|
||||
/**
|
||||
This function flushes a transactional cache upon commit/rollback.
|
||||
This function computes binlog cache and disk usage.
|
||||
|
||||
@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.
|
||||
@param cache_data Pointer to the cache where data is
|
||||
stored.
|
||||
*/
|
||||
static inline void
|
||||
binlog_compute_statistics(binlog_cache_data* cache_data)
|
||||
{
|
||||
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 flushes a cache upon commit/rollback.
|
||||
|
||||
@param thd The thread whose transaction should be flushed
|
||||
@param cache_data Pointer to the cache
|
||||
@param end_ev The end event either commit/rollback
|
||||
@param is_transactional The type of the cache: transactional or
|
||||
non-transactional
|
||||
|
||||
@return
|
||||
nonzero if an error pops up when flushing the transactional cache.
|
||||
nonzero if an error pops up when flushing the cache.
|
||||
*/
|
||||
static int
|
||||
binlog_flush_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr,
|
||||
Log_event *end_ev)
|
||||
static inline int
|
||||
binlog_flush_cache(THD *thd, binlog_cache_data* cache_data, Log_event *end_evt,
|
||||
bool is_transactional)
|
||||
{
|
||||
DBUG_ENTER("binlog_flush_trx_cache");
|
||||
int error=0;
|
||||
IO_CACHE *cache_log= &cache_mngr->trx_cache.cache_log;
|
||||
DBUG_ENTER("binlog_flush_cache");
|
||||
int error= 0;
|
||||
|
||||
/*
|
||||
This function handles transactional changes and as such
|
||||
this flag equals to true.
|
||||
*/
|
||||
bool const is_transactional= TRUE;
|
||||
|
||||
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_mngr->trx_cache.cache_log, end_ev,
|
||||
cache_mngr->trx_cache.has_incident());
|
||||
cache_mngr->reset_cache(&cache_mngr->trx_cache);
|
||||
|
||||
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.
|
||||
|
||||
DBUG_ASSERT(cache_mngr->trx_cache.empty());
|
||||
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_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, binlog_cache_mngr *cache_mngr, bool all)
|
|||
*/
|
||||
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
|
||||
|
@ -1619,51 +1742,6 @@ static int binlog_prepare(handlerton *hton, THD *thd, bool all)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
|
@ -1690,19 +1768,7 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
|
|||
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 *hton, THD *thd, bool all)
|
|||
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 *hton, THD *thd, bool all)
|
|||
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 *hton, THD *thd, bool all)
|
|||
. 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 *hton, THD *thd, bool all)
|
|||
(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 *hton, THD *thd, bool all)
|
|||
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)
|
||||
|
|
|
@ -2537,6 +2537,22 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
|||
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* thd_arg, const char* query_arg,
|
|||
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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue