List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:September 4 2008 9:52am
Subject:bzr push into mysql-5.1 branch (mats:2678 to 2680) Bug#32709
View as plain text  
 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#32709Mats Kindahl4 Sep