From 690d8cc6ba993ad7364c966437a7f4b2d3fdfea3 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 20 Mar 2012 16:04:50 +0200 Subject: [PATCH] Fixed lp:947474 "Assertion `table->file->stats.records > 0 || error' failed in join_read_const_table on concurrent SELECT and ALTER, constant Aria table" Remove Aria state history for drop/rename mysql-test/suite/maria/r/maria-recovery2.result: Updated old (wrong) test result sql/handler.cc: Fixed wrong argument to implict_commit storage/maria/ha_maria.cc: Ensure that we don't use file->trn if THD_TRN is 0. (This means that implict_commit() has been called and the trn object is not ours anymore) storage/maria/ma_extra.c: Remove Aria state history for drop/rename storage/maria/ma_rename.c: Remove Aria state history for rename storage/maria/ma_state.c: More DBUG_PRINT --- mysql-test/suite/maria/r/maria-recovery2.result | 3 ++- sql/handler.cc | 2 +- storage/maria/ha_maria.cc | 17 +++++++++++++++-- storage/maria/ma_extra.c | 2 ++ storage/maria/ma_rename.c | 1 + storage/maria/ma_state.c | 14 ++++++++++---- 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/maria/r/maria-recovery2.result b/mysql-test/suite/maria/r/maria-recovery2.result index 2c92bb8dace..149ce5a01af 100644 --- a/mysql-test/suite/maria/r/maria-recovery2.result +++ b/mysql-test/suite/maria/r/maria-recovery2.result @@ -84,10 +84,11 @@ Table Op Msg_type Msg_text mysqltest.t1 check status OK * testing that checksum after recovery is as expected Checksum-check -ok +failure use mysqltest; select * from t1; a +1 3 drop table t1; * TEST of recovery when crash before bulk-insert-with-repair is committed diff --git a/sql/handler.cc b/sql/handler.cc index 0310180759c..cdc367bbb18 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1185,7 +1185,7 @@ int ha_commit_trans(THD *thd, bool all) } #ifdef WITH_ARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, FALSE); + ha_maria::implicit_commit(thd, TRUE); #endif if (!ha_info) diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 7205a1042ef..aeeb994667e 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2463,18 +2463,26 @@ int ha_maria::extra(enum ha_extra_function operation) without calling commit/rollback in between. If file->trn is not set we can't remove file->share from the transaction list in the extra() call. + We also ensure that we set file->trn to 0 if THD_TRN is 0 as in + this case we have already freed the trn. This can happen when one + implicit_commit() is called as part of alter table. + table->in_use is not set in the case this is a done as part of closefrm() as part of drop table. */ - if (file->s->now_transactional && !file->trn && table->in_use && + if (file->s->now_transactional && table->in_use && (operation == HA_EXTRA_PREPARE_FOR_DROP || - operation == HA_EXTRA_PREPARE_FOR_RENAME)) + operation == HA_EXTRA_PREPARE_FOR_RENAME || + operation == HA_EXTRA_PREPARE_FOR_FORCED_CLOSE)) { THD *thd= table->in_use; TRN *trn= THD_TRN; _ma_set_trn_for_table(file, trn); } + DBUG_ASSERT(file->s->base.born_transactional || file->trn == 0 || + file->trn == &dummy_transaction_object); + tmp= maria_extra(file, operation, 0); file->trn= old_trn; // Reset trn if was used return tmp; @@ -2767,6 +2775,11 @@ int ha_maria::implicit_commit(THD *thd, bool new_trn) error= 1; if (!new_trn) { + /* + To be extra safe, we should also reset file->trn for all open + tables as some calls, like extra() may access it. We take care + of this in extra() by resetting file->trn if THD_TRN is 0. + */ THD_TRN= NULL; goto end; } diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c index c8b969363fa..0847f3c729c 100644 --- a/storage/maria/ma_extra.c +++ b/storage/maria/ma_extra.c @@ -348,6 +348,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function, /* Ensure we don't point to the deleted data in trn */ info->state= info->state_start= &share->state.state; } + /* Remove history for table */ + _ma_reset_state(info); type= do_flush ? FLUSH_RELEASE : FLUSH_IGNORE_CHANGED; save_global_changed= share->global_changed; diff --git a/storage/maria/ma_rename.c b/storage/maria/ma_rename.c index 7db397617d4..2f798a95dc5 100644 --- a/storage/maria/ma_rename.c +++ b/storage/maria/ma_rename.c @@ -103,6 +103,7 @@ int maria_rename(const char *old_name, const char *new_name) } } + _ma_reset_state(info); maria_close(info); fn_format(from,old_name,"",MARIA_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c index ca698bc7245..1f4a7504c56 100644 --- a/storage/maria/ma_state.c +++ b/storage/maria/ma_state.c @@ -229,13 +229,14 @@ void _ma_remove_not_visible_states_with_lock(MARIA_SHARE *share, to current state. @notes - Used after repair as then all rows are visible for everyone + Used after repair/rename/drop as then all rows are visible for everyone */ void _ma_reset_state(MARIA_HA *info) { MARIA_SHARE *share= info->s; MARIA_STATE_HISTORY *history= share->state_history; + DBUG_ENTER("_ma_reset_state"); if (history) { @@ -253,6 +254,7 @@ void _ma_reset_state(MARIA_HA *info) share->state_history->next= 0; share->state_history->trid= 0; /* Visibile for all */ } + DBUG_VOID_RETURN; } @@ -433,6 +435,7 @@ my_bool _ma_trnman_end_trans_hook(TRN *trn, my_bool commit, my_bool error= 0; MARIA_USED_TABLES *tables, *next; DBUG_ENTER("_ma_trnman_end_trans_hook"); + DBUG_PRINT("enter", ("trn: %p used_tables: %p", trn, trn->used_tables)); for (tables= (MARIA_USED_TABLES*) trn->used_tables; tables; @@ -547,8 +550,8 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn) { MARIA_USED_TABLES *tables, **prev; DBUG_ENTER("_ma_remove_table_from_trnman"); - DBUG_PRINT("enter", ("share: 0x%lx in_trans: %d", - (ulong) share, share->in_trans)); + DBUG_PRINT("enter", ("trn: %p used_tables: %p share: %p in_trans: %d", + trn, trn->used_tables, share, share->in_trans)); mysql_mutex_assert_owner(&share->intern_lock); @@ -560,7 +563,6 @@ void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn) { *prev= tables->next; share->in_trans--; - DBUG_PRINT("info", ("in_trans: %d", share->in_trans)); my_free(tables); break; } @@ -730,6 +732,10 @@ void _ma_copy_nontrans_state_information(MARIA_HA *info) info->s->state.state.checksum= info->state->checksum; } +/** + Reset history + This is only called during repair when we the only one using the table. +*/ void _ma_reset_history(MARIA_SHARE *share) {