Commit aab1e50e authored by unknown's avatar unknown
Browse files

fixed bug #2342

"Running ANALYZE TABLE on bdb table inside a transaction hangs server thread"

1. added new status HA_ADMIN_REJECT and processing of it in mysql_admin_table
2. got ha_berkley::analyze to return HA_ADMIN_REJECT if there are any 
 transactions with the table.. 


mysql-test/r/bdb-crash.result:
  added test for bug #2342 
  "Running ANALYZE TABLE on bdb table inside a transaction hangs server thread"
mysql-test/t/bdb-crash.test:
  added test for bug #2342 
  "Running ANALYZE TABLE on bdb table inside a transaction hangs server thread"
sql/ha_berkeley.cc:
  fixed bug #2342 
  "Running ANALYZE TABLE on bdb table inside a transaction hangs server thread"
  
  we have to return new status "HA_ADMIN_REJECT" for ha_berkley::analyze 
  if there are any transaction for this table 
  so as bdb documentation says:
  "The DB->stat method cannot be transaction protected"
sql/handler.h:
  added new status of table info "HA_ADMIN_REJECT"
  
  We have to return this status for bdb tables which 
  have any active transactions so as bdb-documentation says:
  "The DB->stat method cannot be transaction-protected"
sql/sql_table.cc:
  added processing of the new status HA_ADMIN_REJECT in mysql_admin_table
  (reason to add this status is explained in comment 
  for commit on sql/handler.h)
parent 8a6ae839
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -30,3 +30,10 @@ ChargeID ServiceID ChargeDate ChargeAmount FedTaxes ProvTaxes ChargeStatus Charg
1	1	2001-03-01	1.00	1.00	1.00	New	blablabla	NULL	now
2	1	2001-03-01	1.00	1.00	1.00	New	NULL	NULL	now
drop table t1;
create table t1 (a int) engine=bdb;
set autocommit=0;
insert into t1 values(1);
analyze table t1;
Table	Op	Msg_type	Msg_text
test.t1	analyze	status	Operation need committed state
drop table t1;
+12 −0
Original line number Diff line number Diff line
@@ -34,3 +34,15 @@ INSERT INTO t1
VALUES(NULL,1,'2001-03-01',1,1,1,'New',NULL,NULL,'now');
select * from t1;
drop table t1;

#
# Test for bug #2342 "Running ANALYZE TABLE on bdb table 
#                      inside a transaction hangs server thread"
#

create table t1 (a int) engine=bdb;

set autocommit=0;
insert into t1 values(1);
analyze table t1;
drop table t1;
 No newline at end of file
+38 −0
Original line number Diff line number Diff line
@@ -2099,6 +2099,44 @@ int ha_berkeley::analyze(THD* thd, HA_CHECK_OPT* check_opt)
{
  DB_BTREE_STAT *stat=0;
  uint i;
  DB_TXN_STAT *txn_stat_ptr= 0;

  /*
    If it's a merge conflict here (4.0->4.1), please ignore it!

    The reason of the conflict is the difference between versions of bdb:
    mysql-4.0 uses bdb 3.2.9
    mysql-4.1 uses bdb 4.1.24
    Older one has global functions txn_stat and txn_id but
    newer one has DB_ENV->txn_stat and DB_TXN->id
  */
  if (!txn_stat(db_env, &txn_stat_ptr, 0) &&
      txn_stat_ptr && txn_stat_ptr->st_nactive>=2)
  {
    DB_TXN_ACTIVE *atxn_stmt= 0, *atxn_all= 0;
    
    DB_TXN *txn_all= (DB_TXN*) thd->transaction.all.bdb_tid;
    u_int32_t all_id= txn_id(txn_all);
    
    DB_TXN *txn_stmt= (DB_TXN*) thd->transaction.stmt.bdb_tid;
    u_int32_t stmt_id= txn_id(txn_stmt);
    
    DB_TXN_ACTIVE *cur= txn_stat_ptr->st_txnarray;
    DB_TXN_ACTIVE *end= cur + txn_stat_ptr->st_nactive;
    for (; cur!=end && (!atxn_stmt || !atxn_all); cur++)
    {
      if (cur->txnid==all_id) atxn_all= cur;
      if (cur->txnid==stmt_id) atxn_stmt= cur;
    }
    
    if (atxn_stmt && atxn_all &&
	log_compare(&atxn_stmt->lsn,&atxn_all->lsn))
    {
      free(txn_stat_ptr);
      return HA_ADMIN_REJECT;
    }
    free(txn_stat_ptr);
  }

  for (i=0 ; i < table->keys ; i++)
  {
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#define HA_ADMIN_CORRUPT         -3
#define HA_ADMIN_INTERNAL_ERROR  -4
#define HA_ADMIN_INVALID         -5
#define HA_ADMIN_REJECT          -6

/* Bits in table_flags() to show what database can do */
#define HA_READ_RND_SAME	1	/* Read RND-record to KEY-record
+6 −0
Original line number Diff line number Diff line
@@ -1330,6 +1330,12 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
      net_store_data(packet, "Operation failed");
      break;

    case HA_ADMIN_REJECT:
      net_store_data(packet,"status");
      net_store_data(packet,"Operation need committed state");
      open_for_modify= false;
      break;

    case HA_ADMIN_ALREADY_DONE:
      net_store_data(packet, "status");
      net_store_data(packet, "Table is already up to date");