2680 Mats Kindahl 2008-09-03
BUG#32709: Assertion failed: trx_data->empty(), file log.cc
Incremental fixes: updating a comment and fixing a result file.
modified:
mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result
sql/sql_class.h
2679 Mats Kindahl 2008-09-03
Bug #32709: Assertion failed: trx_data->empty(), file log.cc
The assertion indicates that some data was left in the transaction
cache when the server was shut down, which means that a previous
statement did not commit or rollback correctly.
What happened was that a bug in the rollback of a transactional
table caused the transaction cache to be emptied, but not reset.
The error can be triggered by having a failing UPDATE or INSERT,
on a transactional table, causing an implicit rollback.
Fixed by always flushing the pending event to reset the state
properly.
modified:
mysql-test/extra/rpl_tests/rpl_row_basic.test
mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result
mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result
sql/log.cc
sql/log.h
sql/sql_class.cc
sql/sql_class.h
2678 Andrei Elkin 2008-09-03 [merge]
merging with 5.1.29.
modified:
mysql-test/r/default.result
mysql-test/t/default.test
sql/item.cc
=== modified file 'mysql-test/extra/rpl_tests/rpl_row_basic.test'
--- a/mysql-test/extra/rpl_tests/rpl_row_basic.test 2008-08-14 08:27:28 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test 2008-09-03 20:04:07 +0000
@@ -451,3 +451,23 @@ connection master;
drop table t1, t2, t3, t4, t5, t6, t7;
sync_slave_with_master;
+#
+# BUG#32709: Assertion failed: trx_data->empty(), file .\log.cc, line 1293
+#
+
+connection master;
+eval CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=$type;
+
+INSERT INTO t1 VALUES (1), (2), (3);
+--error ER_DUP_ENTRY
+UPDATE t1 SET a = 10;
+INSERT INTO t1 VALUES (4);
+sync_slave_with_master;
+
+let $diff_table_1=master:test.t1;
+let $diff_table_2=slave:test.t1;
+source include/diff_tables.inc;
+
+connection master;
+drop table t1;
+sync_slave_with_master;
=== modified file 'mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result'
--- a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result 2008-08-12 09:09:36 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result 2008-09-03 20:04:07 +0000
@@ -520,3 +520,10 @@ INSERT INTO t7 VALUES (1, "", 1);
INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
Comparing tables master:test.t7 and slave:test.t7
drop table t1, t2, t3, t4, t5, t6, t7;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE='MYISAM' ;
+INSERT INTO t1 VALUES (1), (2), (3);
+UPDATE t1 SET a = 10;
+ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
+INSERT INTO t1 VALUES (4);
+Comparing tables master:test.t1 and slave:test.t1
+drop table t1;
=== modified file 'mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result'
--- a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result 2008-08-12 09:09:36 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result 2008-09-03 20:04:07 +0000
@@ -520,3 +520,10 @@ INSERT INTO t7 VALUES (1, "", 1);
INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
Comparing tables master:test.t7 and slave:test.t7
drop table t1, t2, t3, t4, t5, t6, t7;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE='INNODB' ;
+INSERT INTO t1 VALUES (1), (2), (3);
+UPDATE t1 SET a = 10;
+ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
+INSERT INTO t1 VALUES (4);
+Comparing tables master:test.t1 and slave:test.t1
+drop table t1;
=== modified file 'mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result'
--- a/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result 2008-08-12 09:09:36 +0000
+++ b/mysql-test/suite/rpl_ndb/r/rpl_row_basic_7ndb.result 2008-09-03 20:52:54 +0000
@@ -520,3 +520,10 @@ INSERT INTO t7 VALUES (1, "", 1);
INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
Comparing tables master:test.t7 and slave:test.t7
drop table t1, t2, t3, t4, t5, t6, t7;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE='NDB' ;
+INSERT INTO t1 VALUES (1), (2), (3);
+UPDATE t1 SET a = 10;
+ERROR 23000: Duplicate entry '10' for key 'PRIMARY'
+INSERT INTO t1 VALUES (4);
+Comparing tables master:test.t1 and slave:test.t1
+drop table t1;
=== modified file 'sql/log.cc'
--- a/sql/log.cc 2008-07-22 10:41:55 +0000
+++ b/sql/log.cc 2008-09-03 20:04:07 +0000
@@ -1421,6 +1421,7 @@ binlog_end_trans(THD *thd, binlog_trx_da
If rolling back a statement in a transaction, we truncate the
transaction cache to remove the statement.
*/
+ thd->binlog_remove_pending_rows_event(TRUE);
if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT)))
trx_data->reset();
else // ...statement
@@ -3769,6 +3770,31 @@ THD::binlog_set_pending_rows_event(Rows_
}
+/**
+ Remove the pending rows event, discarding any outstanding rows.
+
+ If there is no pending rows event available, this is effectively a
+ no-op.
+ */
+int
+MYSQL_BIN_LOG::remove_pending_rows_event(THD *thd)
+{
+ DBUG_ENTER(__FUNCTION__);
+
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
+
+ DBUG_ASSERT(trx_data);
+
+ if (Rows_log_event* pending= trx_data->pending())
+ {
+ delete pending;
+ trx_data->set_pending(NULL);
+ }
+
+ DBUG_RETURN(0);
+}
+
/*
Moves the last bunch of rows from the pending Rows event to the binlog
(either cached binlog if transaction, or disk binlog). Sets a new pending
=== modified file 'sql/log.h'
--- a/sql/log.h 2007-10-30 08:03:34 +0000
+++ b/sql/log.h 2008-09-03 20:04:07 +0000
@@ -307,6 +307,7 @@ public:
void update_table_map_version() { ++m_table_map_version; }
int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event);
+ int remove_pending_rows_event(THD *thd);
#endif /* !defined(MYSQL_CLIENT) */
void reset_bytes_written()
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2008-08-26 10:07:56 +0000
+++ b/sql/sql_class.cc 2008-09-03 20:04:07 +0000
@@ -3502,6 +3502,21 @@ int THD::binlog_delete_row(TABLE* table,
}
+int THD::binlog_remove_pending_rows_event(bool clear_maps)
+{
+ DBUG_ENTER(__FUNCTION__);
+
+ if (!mysql_bin_log.is_open())
+ DBUG_RETURN(0);
+
+ mysql_bin_log.remove_pending_rows_event(this);
+
+ if (clear_maps)
+ binlog_table_maps= 0;
+
+ DBUG_RETURN(0);
+}
+
int THD::binlog_flush_pending_rows_event(bool stmt_end)
{
DBUG_ENTER("THD::binlog_flush_pending_rows_event");
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2008-08-26 10:01:49 +0000
+++ b/sql/sql_class.h 2008-09-03 20:52:54 +0000
@@ -1360,9 +1360,14 @@ public:
Rows_log_event* binlog_get_pending_rows_event() const;
void binlog_set_pending_rows_event(Rows_log_event* ev);
int binlog_flush_pending_rows_event(bool stmt_end);
+ int binlog_remove_pending_rows_event(bool clear_maps);
private:
- uint binlog_table_maps; // Number of table maps currently in the binlog
+ /*
+ Number of outstanding table maps, i.e., table maps in the
+ transaction cache.
+ */
+ uint binlog_table_maps;
enum enum_binlog_flag {
BINLOG_FLAG_UNSAFE_STMT_PRINTED,
| Thread |
|---|
| • bzr push into mysql-5.1 branch (mats:2678 to 2680) Bug#32709 | Mats Kindahl | 4 Sep |