Bug#54453: Failing assertion: trx->active_trans when renaming a

table with active trx

Essentially, the problem is that InnoDB does a implicit commit
when a cursor (table handler) is unlocked/closed, creating
a dissonance between the transaction state within the server
layer and the storage engine layer. Theoretically, a statement
transaction can encompass several table instances in a similar
manner to a multiple statement transaction, hence it does not
make sense to limit a statement transaction to the lifetime of
the table instances (cursors) used within it.

Since this particular instance of the problem is only triggerable
on 5.1 and is masked on 5.5 due 2PC being skipped (assertion is in
the prepare phase of a 2PC), the solution (which is less risky) is
to explicitly end the transaction before the cached table is unlock
on rename table.

The patch is to be null merged into trunk.

mysql-test/include/commit.inc:
  Fix counters, the binlog engine does not get involved anymore.
mysql-test/suite/innodb_plugin/r/innodb_bug54453.result:
  Add test case result for Bug#54453
mysql-test/suite/innodb_plugin/t/innodb_bug54453.test:
  Add test case for Bug#54453
sql/sql_table.cc:
  End transaction as otherwise InnoDB will end it behind our backs.
This commit is contained in:
Davi Arnaut 2010-07-20 14:36:15 -03:00
parent dfaf73a987
commit b0035c76d4
5 changed files with 36 additions and 4 deletions

View file

@ -725,9 +725,9 @@ call p_verify_status_increment(4, 4, 4, 4);
alter table t3 add column (b int);
call p_verify_status_increment(2, 0, 2, 0);
alter table t3 rename t4;
call p_verify_status_increment(2, 2, 2, 2);
call p_verify_status_increment(1, 0, 1, 0);
rename table t4 to t3;
call p_verify_status_increment(2, 2, 2, 2);
call p_verify_status_increment(1, 0, 1, 0);
truncate table t3;
call p_verify_status_increment(4, 4, 4, 4);
create view v1 as select * from t2;

View file

@ -841,11 +841,11 @@ call p_verify_status_increment(2, 0, 2, 0);
SUCCESS
alter table t3 rename t4;
call p_verify_status_increment(2, 2, 2, 2);
call p_verify_status_increment(1, 0, 1, 0);
SUCCESS
rename table t4 to t3;
call p_verify_status_increment(2, 2, 2, 2);
call p_verify_status_increment(1, 0, 1, 0);
SUCCESS
truncate table t3;

View file

@ -0,0 +1,9 @@
#
# Bug#54453: Failing assertion: trx->active_trans when renaming a table with active trx
#
DROP TABLE IF EXISTS bug54453;
CREATE TABLE bug54453(a INT) ENGINE=InnoDB;
ALTER TABLE bug54453 RENAME TO bug54453_2;
SELECT * FROM bug54453_2;
a
DROP TABLE bug54453_2;

View file

@ -0,0 +1,15 @@
--source include/have_innodb_plugin.inc
--source include/have_log_bin.inc
--echo #
--echo # Bug#54453: Failing assertion: trx->active_trans when renaming a table with active trx
--echo #
--disable_warnings
DROP TABLE IF EXISTS bug54453;
--enable_warnings
CREATE TABLE bug54453(a INT) ENGINE=InnoDB;
ALTER TABLE bug54453 RENAME TO bug54453_2;
SELECT * FROM bug54453_2;
DROP TABLE bug54453_2;

View file

@ -6848,6 +6848,14 @@ view_err:
if (!error && (new_name != table_name || new_db != db))
{
thd_proc_info(thd, "rename");
/*
Workaround InnoDB ending the transaction when the table instance
is unlocked/closed (close_cached_table below), otherwise the trx
state will differ between the server and storage engine layers.
*/
ha_autocommit_or_rollback(thd, 0);
/*
Then do a 'simple' rename of the table. First we need to close all
instances of 'source' table.