diff --git a/innobase/mem/mem0dbg.c b/innobase/mem/mem0dbg.c index 07f348ab82f..52a08e6faf1 100644 --- a/innobase/mem/mem0dbg.c +++ b/innobase/mem/mem0dbg.c @@ -20,7 +20,7 @@ Protected by mem_hash_mutex above. */ static ulint mem_n_created_heaps = 0; static ulint mem_n_allocations = 0; static ulint mem_total_allocated_memory = 0; -static ulint mem_current_allocated_memory = 0; +ulint mem_current_allocated_memory = 0; static ulint mem_max_allocated_memory = 0; /* Size of the hash table for memory management tracking */ diff --git a/mysql-test/r/bdb-crash.result b/mysql-test/r/bdb-crash.result index 5079368ea21..16e51c61504 100644 --- a/mysql-test/r/bdb-crash.result +++ b/mysql-test/r/bdb-crash.result @@ -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; diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 093633d5f5a..859d9d4cab0 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -546,3 +546,11 @@ CREATE TABLE t1 (a INT, b INT); SET @id=0; UPDATE t1 SET a=0 ORDER BY (a=@id), b; DROP TABLE t1; +create table t1(id int not null auto_increment primary key, t char(12)); +explain select id,t from t1 order by id; +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 1000 Using filesort +explain select id,t from t1 force index (primary) order by id; +table type possible_keys key key_len ref rows Extra +t1 index NULL PRIMARY 4 NULL 1000 +drop table t1; diff --git a/mysql-test/t/bdb-crash.test b/mysql-test/t/bdb-crash.test index 4575a612728..98b542bf4c3 100644 --- a/mysql-test/t/bdb-crash.test +++ b/mysql-test/t/bdb-crash.test @@ -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; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 8215ec84ae3..86ecc4aa70d 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -352,4 +352,15 @@ CREATE TABLE t1 (a INT, b INT); SET @id=0; UPDATE t1 SET a=0 ORDER BY (a=@id), b; DROP TABLE t1; - +create table t1(id int not null auto_increment primary key, t char(12)); +disable_query_log; +let $1 = 1000; +while ($1) + { + eval insert into t1(t) values ('$1'); + dec $1; + } +enable_query_log; +explain select id,t from t1 order by id; +explain select id,t from t1 force index (primary) order by id; +drop table t1; \ No newline at end of file diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 35e731f20da..3522aadf349 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -2099,6 +2099,53 @@ 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; + + /* + Original bdb documentation says: + "The DB->stat method cannot be transaction-protected. + For this reason, it should be called in a thread of + control that has no open cursors or active transactions." + So, let's check if there are any changes have been done since + the beginning of the transaction.. + */ + + /* + 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++) { diff --git a/sql/handler.h b/sql/handler.h index ead0ed106c7..ac00050b777 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -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 diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 87812414881..057f0bd9483 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6021,7 +6021,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, /* check if we can use a key to resolve the group */ /* Tables using JT_NEXT are handled here */ uint nr; - key_map keys=usable_keys; + key_map keys_to_use=~0,keys=usable_keys; /* If not used with LIMIT, only use keys if the whole query can be @@ -6029,7 +6029,17 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, retrieving all rows through an index. */ if (select_limit >= table->file->records) - keys&= (table->used_keys | table->file->keys_to_use_for_scanning()); + keys_to_use= (table->used_keys |table->file->keys_to_use_for_scanning()); + + /* + We are adding here also the index speified in FORCE INDEX clause, + if any. + This is to allow users to use index in ORDER BY. + */ + + if (table->force_index) + keys_to_use|= table->keys_in_use_for_query; + keys&= keys_to_use; for (nr=0; keys ; keys>>=1, nr++) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 48151ef55b9..7507ab16968 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -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");