Commit 4d096730 authored by unknown's avatar unknown
Browse files

Fix crash in BDB from improper cleanup of transactions, and avoid problem

in NDB that the fix would cause due to improper registration of a transaction
that isn't meant to be seen by the handler layer. (Bug #14212)

Thanks to Sergei Golubchik for helping with this.


mysql-test/r/bdb.result:
  Add new result
mysql-test/t/bdb.test:
  Add new regression test
sql/ha_ndbcluster.cc:
  Don't register transaction if transactions are "disabled".
sql/handler.cc:
  Commit statement before trying to end transaction.
parent bb2f4b81
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1895,3 +1895,8 @@ t1 CREATE TABLE `t1` (
) ENGINE=BerkeleyDB DEFAULT CHARSET=latin1
drop table t1;
set storage_engine=MyISAM;
set autocommit=0;
create table t1 (a int) engine=bdb;
commit;
alter table t1 add primary key(a);
drop table t1;
+11 −0
Original line number Diff line number Diff line
@@ -973,3 +973,14 @@ drop table t1;

# End varchar test
eval set storage_engine=$default;

#
# Bug #14212: Server crash after COMMIT + ALTER TABLE
#
set autocommit=0;
create table t1 (a int) engine=bdb;
commit;
alter table t1 add primary key(a);
drop table t1;

# End of 5.0 tests
+8 −6
Original line number Diff line number Diff line
@@ -3221,6 +3221,10 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
  if (lock_type != F_UNLCK)
  {
    DBUG_PRINT("info", ("lock_type != F_UNLCK"));
    if (!thd->transaction.on)
      m_transaction_on= FALSE;
    else
      m_transaction_on= thd->variables.ndb_use_transactions;
    if (!thd_ndb->lock_count++)
    {
      PRINT_OPTION_FLAGS(thd);
@@ -3235,6 +3239,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
          ERR_RETURN(ndb->getNdbError());
        no_uncommitted_rows_reset(thd);
        thd_ndb->stmt= trans;
        if (m_transaction_on)
          trans_register_ha(thd, FALSE, &ndbcluster_hton);
      } 
      else 
@@ -3250,6 +3255,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
            ERR_RETURN(ndb->getNdbError());
          no_uncommitted_rows_reset(thd);
          thd_ndb->all= trans; 
          if (m_transaction_on)
            trans_register_ha(thd, TRUE, &ndbcluster_hton);

          /*
@@ -3284,10 +3290,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
    m_ha_not_exact_count= !thd->variables.ndb_use_exact_count;
    m_autoincrement_prefetch= 
      (ha_rows) thd->variables.ndb_autoincrement_prefetch_sz;
    if (!thd->transaction.on)
      m_transaction_on= FALSE;
    else
      m_transaction_on= thd->variables.ndb_use_transactions;

    m_active_trans= thd_ndb->all ? thd_ndb->all : thd_ndb->stmt;
    DBUG_ASSERT(m_active_trans);
+2 −1
Original line number Diff line number Diff line
@@ -1910,6 +1910,7 @@ int ha_enable_transaction(THD *thd, bool on)
      is an optimization hint that storage engine is free to ignore.
      So, let's commit an open transaction (if any) now.
    */
    if (!(error= ha_commit_stmt(thd)))
      error= end_trans(thd, COMMIT);
  }
  DBUG_RETURN(error);