diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-05-07 12:28:04 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-05-07 12:28:04 +0300 |
commit | d11b5ae6474db09bf3e4a2b27adb5e75488fc61c (patch) | |
tree | 2c9f9654b602c2fc5cf12c33e4eb706513992661 | |
parent | 4a79e8e482a9dbb8ebde97d23b3856eebfcf4570 (diff) | |
download | mariadb-git-d11b5ae6474db09bf3e4a2b27adb5e75488fc61c.tar.gz |
MDEV-25594: Improve debug checks
trx_t::will_lock: Changed the type to bool.
trx:t::is_autocommit_non_locking(): Replaces trx_is_autocommit_non_locking().
trx_is_ac_nl_ro(): Remove (replaced with equivalent assertion expressions).
assert_trx_nonlocking_or_in_list(): Remove.
Replaced with at least as strict checks in each place.
check_trx_state(): Moved to a static function; partially replaced with
individual debug assertions implementing equivalent or stricter checks.
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 48 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 3 | ||||
-rw-r--r-- | storage/innobase/include/trx0i_s.h | 4 | ||||
-rw-r--r-- | storage/innobase/include/trx0sys.h | 2 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 73 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.ic | 10 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 36 | ||||
-rw-r--r-- | storage/innobase/read/read0read.cc | 4 | ||||
-rw-r--r-- | storage/innobase/trx/trx0i_s.cc | 21 | ||||
-rw-r--r-- | storage/innobase/trx/trx0roll.cc | 34 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 48 |
11 files changed, 128 insertions, 155 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 48cb81ce2c0..a800c9a8481 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -4123,7 +4123,7 @@ innobase_commit_low( if (trx_is_started(trx)) { trx_commit_for_mysql(trx); } else { - trx->will_lock = 0; + trx->will_lock = false; #ifdef WITH_WSREP trx->wsrep = false; #endif /* WITH_WSREP */ @@ -7604,7 +7604,7 @@ ha_innobase::write_row( ut_a(m_prebuilt->trx == trx); if (!trx_is_started(trx)) { - ++trx->will_lock; + trx->will_lock = true; } ins_mode_t vers_set_fields; @@ -8363,7 +8363,7 @@ ha_innobase::update_row( ib_senderrf(ha_thd(), IB_LOG_LEVEL_WARN, ER_READ_ONLY_MODE); DBUG_RETURN(HA_ERR_TABLE_READONLY); } else if (!trx_is_started(trx)) { - ++trx->will_lock; + trx->will_lock = true; } if (m_upd_buf == NULL) { @@ -8534,7 +8534,7 @@ ha_innobase::delete_row( ib_senderrf(ha_thd(), IB_LOG_LEVEL_WARN, ER_READ_ONLY_MODE); DBUG_RETURN(HA_ERR_TABLE_READONLY); } else if (!trx_is_started(trx)) { - ++trx->will_lock; + trx->will_lock = true; } if (!m_prebuilt->upd_node) { @@ -9371,7 +9371,7 @@ ha_innobase::ft_init() them as regular read only transactions for now. */ if (!trx_is_started(trx)) { - ++trx->will_lock; + trx->will_lock = true; } DBUG_RETURN(rnd_init(false)); @@ -9437,7 +9437,7 @@ ha_innobase::ft_init_ext( them as regular read only transactions for now. */ if (!trx_is_started(trx)) { - ++trx->will_lock; + trx->will_lock = true; } dict_table_t* ft_table = m_prebuilt->table; @@ -12966,7 +12966,7 @@ create_table_info_t::allocate_trx() { m_trx = innobase_trx_allocate(m_thd); - m_trx->will_lock++; + m_trx->will_lock = true; m_trx->ddl = true; } @@ -13290,13 +13290,7 @@ inline int ha_innobase::delete_table(const char* name, enum_sql_command sqlcom) ut_a(name_len < 1000); - /* Either the transaction is already flagged as a locking transaction - or it hasn't been started yet. */ - - ut_a(!trx_is_started(trx) || trx->will_lock > 0); - - /* We are doing a DDL operation. */ - ++trx->will_lock; + trx->will_lock = true; /* Drop the table in InnoDB */ @@ -13475,14 +13469,7 @@ innobase_drop_database( #endif /* _WIN32 */ trx_t* trx = innobase_trx_allocate(thd); - - /* Either the transaction is already flagged as a locking transaction - or it hasn't been started yet. */ - - ut_a(!trx_is_started(trx) || trx->will_lock > 0); - - /* We are doing a DDL operation. */ - ++trx->will_lock; + trx->will_lock = true; ulint dummy; @@ -13526,7 +13513,7 @@ inline dberr_t innobase_rename_table(trx_t *trx, const char *from, DEBUG_SYNC_C("innodb_rename_table_ready"); trx_start_if_not_started(trx, true); - ut_ad(trx->will_lock > 0); + ut_ad(trx->will_lock); if (commit) { /* Serialize data dictionary operations with dictionary mutex: @@ -13636,8 +13623,7 @@ int ha_innobase::truncate() heap, ib_table->name.m_name, ib_table->id); const char* name = mem_heap_strdup(heap, ib_table->name.m_name); trx_t* trx = innobase_trx_allocate(m_user_thd); - - ++trx->will_lock; + trx->will_lock = true; trx_set_dict_operation(trx, TRX_DICT_OP_TABLE); row_mysql_lock_data_dictionary(trx); dict_stats_wait_bg_to_stop_using_table(ib_table, trx); @@ -13722,9 +13708,7 @@ ha_innobase::rename_table( } trx_t* trx = innobase_trx_allocate(thd); - - /* We are doing a DDL operation. */ - ++trx->will_lock; + trx->will_lock = true; trx_set_dict_operation(trx, TRX_DICT_OP_INDEX); dberr_t error = innobase_rename_table(trx, from, to, true); @@ -15596,7 +15580,7 @@ ha_innobase::start_stmt( innobase_register_trx(ht, thd, trx); if (!trx_is_started(trx)) { - ++trx->will_lock; + trx->will_lock = true; } DBUG_RETURN(0); @@ -15822,7 +15806,7 @@ ha_innobase::external_lock( && (m_prebuilt->select_lock_type != LOCK_NONE || m_prebuilt->stored_select_lock_type != LOCK_NONE)) { - ++trx->will_lock; + trx->will_lock = true; } DBUG_RETURN(0); @@ -15861,7 +15845,7 @@ ha_innobase::external_lock( && (m_prebuilt->select_lock_type != LOCK_NONE || m_prebuilt->stored_select_lock_type != LOCK_NONE)) { - ++trx->will_lock; + trx->will_lock = true; } DBUG_RETURN(0); @@ -16534,7 +16518,7 @@ ha_innobase::store_lock( && (m_prebuilt->select_lock_type != LOCK_NONE || m_prebuilt->stored_select_lock_type != LOCK_NONE)) { - ++trx->will_lock; + trx->will_lock = true; } return(to); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 03dd51ea0c9..9d94aa5b062 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2352,7 +2352,7 @@ innodb_instant_alter_column_allowed_reason: } } - m_prebuilt->trx->will_lock++; + m_prebuilt->trx->will_lock = true; /* When changing a NULL column to NOT NULL and specifying a DEFAULT value, ensure that the DEFAULT expression is a constant. @@ -11458,7 +11458,6 @@ foreign_fail: m_prebuilt = ctx->prebuilt; } trx_start_if_not_started(user_trx, true); - user_trx->will_lock++; m_prebuilt->trx = user_trx; } DBUG_INJECT_CRASH("ib_commit_inplace_crash", diff --git a/storage/innobase/include/trx0i_s.h b/storage/innobase/include/trx0i_s.h index 98b84fe0985..40160ce4362 100644 --- a/storage/innobase/include/trx0i_s.h +++ b/storage/innobase/include/trx0i_s.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -151,7 +151,7 @@ struct i_s_trx_row_t { bool trx_is_read_only; /*!< trx_t::read_only */ bool trx_is_autocommit_non_locking; - /*!< trx_is_autocommit_non_locking(trx) + /*!< trx:t::is_autocommit_non_locking() */ }; diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index 752b3fcee0e..424e4447b41 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -513,7 +513,7 @@ class rw_trx_hash_t static void validate_element(trx_t *trx) { ut_ad(!trx->read_only || !trx->rsegs.m_redo.rseg); - ut_ad(!trx_is_autocommit_non_locking(trx)); + ut_ad(!trx->is_autocommit_non_locking()); /* trx->state can be anything except TRX_STATE_NOT_STARTED */ mutex_enter(&trx->mutex); ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE) || diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index f1a13e6ea59..92d148688e9 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -393,64 +393,6 @@ from innodb_lock_wait_timeout via trx_t::mysql_thd. ? thd_lock_wait_timeout((t)->mysql_thd) \ : 0) -/** -Determine if the transaction is a non-locking autocommit select -(implied read-only). -@param t transaction -@return true if non-locking autocommit select transaction. */ -#define trx_is_autocommit_non_locking(t) \ -((t)->auto_commit && (t)->will_lock == 0) - -/** -Determine if the transaction is a non-locking autocommit select -with an explicit check for the read-only status. -@param t transaction -@return true if non-locking autocommit read-only transaction. */ -#define trx_is_ac_nl_ro(t) \ -((t)->read_only && trx_is_autocommit_non_locking((t))) - -/** -Check transaction state */ -#define check_trx_state(t) do { \ - ut_ad(!trx_is_autocommit_non_locking((t))); \ - switch ((t)->state) { \ - case TRX_STATE_PREPARED: \ - case TRX_STATE_PREPARED_RECOVERED: \ - case TRX_STATE_ACTIVE: \ - case TRX_STATE_COMMITTED_IN_MEMORY: \ - continue; \ - case TRX_STATE_NOT_STARTED: \ - break; \ - } \ - ut_error; \ -} while (0) - -#ifdef UNIV_DEBUG -/*******************************************************************//** -Assert that an autocommit non-locking select cannot be in the -rw_trx_hash and that it is a read-only transaction. -The transaction must have mysql_thd assigned. */ -# define assert_trx_nonlocking_or_in_list(t) \ - do { \ - if (trx_is_autocommit_non_locking(t)) { \ - trx_state_t t_state = (t)->state; \ - ut_ad((t)->read_only); \ - ut_ad(!(t)->is_recovered); \ - ut_ad((t)->mysql_thd); \ - ut_ad(t_state == TRX_STATE_NOT_STARTED \ - || t_state == TRX_STATE_ACTIVE); \ - } else { \ - check_trx_state(t); \ - } \ - } while (0) -#else /* UNIV_DEBUG */ -/*******************************************************************//** -Assert that an autocommit non-locking slect cannot be in the -rw_trx_hash and that it is a read-only transaction. -The transaction must have mysql_thd assigned. */ -# define assert_trx_nonlocking_or_in_list(trx) ((void)0) -#endif /* UNIV_DEBUG */ - typedef std::vector<ib_lock_t*, ut_allocator<ib_lock_t*> > lock_list; /*******************************************************************//** @@ -947,16 +889,15 @@ public: /*------------------------------*/ bool read_only; /*!< true if transaction is flagged as a READ-ONLY transaction. - if auto_commit && will_lock == 0 + if auto_commit && !will_lock then it will be handled as a AC-NL-RO-SELECT (Auto Commit Non-Locking Read Only Select). A read only transaction will not be assigned an UNDO log. */ bool auto_commit; /*!< true if it is an autocommit */ - ib_uint32_t will_lock; /*!< Will acquire some locks. Increment - each time we determine that a lock will - be acquired by the MySQL layer. */ + bool will_lock; /*!< set to inform trx_start_low() that + the transaction may acquire locks */ /*------------------------------*/ fts_trx_t* fts_trx; /*!< FTS information, or NULL if transaction hasn't modified tables @@ -1099,11 +1040,13 @@ public: ut_ad(dict_operation == TRX_DICT_OP_NONE); } + /** @return whether this is a non-locking autocommit transaction */ + bool is_autocommit_non_locking() const { return auto_commit && !will_lock; } private: - /** Assign a rollback segment for modifying temporary tables. - @return the assigned rollback segment */ - trx_rseg_t* assign_temp_rseg(); + /** Assign a rollback segment for modifying temporary tables. + @return the assigned rollback segment */ + trx_rseg_t *assign_temp_rseg(); }; /** diff --git a/storage/innobase/include/trx0trx.ic b/storage/innobase/include/trx0trx.ic index 9fa4136f743..93c9591e0c2 100644 --- a/storage/innobase/include/trx0trx.ic +++ b/storage/innobase/include/trx0trx.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2019, MariaDB Corporation. +Copyright (c) 2016, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -49,11 +49,15 @@ trx_state_eq( case TRX_STATE_PREPARED: case TRX_STATE_PREPARED_RECOVERED: case TRX_STATE_COMMITTED_IN_MEMORY: - ut_ad(!trx_is_autocommit_non_locking(trx)); + ut_ad(!trx->is_autocommit_non_locking()); return(trx->state == state); case TRX_STATE_ACTIVE: - assert_trx_nonlocking_or_in_list(trx); + if (trx->is_autocommit_non_locking()) { + ut_ad(!trx->is_recovered); + ut_ad(trx->read_only); + ut_ad(trx->mysql_thd); + } return(state == trx->state); case TRX_STATE_NOT_STARTED: diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 43e5249a349..e124607617c 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1240,6 +1240,19 @@ wsrep_print_wait_locks( } #endif /* WITH_WSREP */ +#ifdef UNIV_DEBUG +/** Check transaction state */ +static void check_trx_state(const trx_t *trx) +{ + ut_ad(!trx->auto_commit || trx->will_lock); + const auto state= trx->state; + ut_ad(state == TRX_STATE_ACTIVE || + state == TRX_STATE_PREPARED_RECOVERED || + state == TRX_STATE_PREPARED || + state == TRX_STATE_COMMITTED_IN_MEMORY); +} +#endif + /** Create a new record lock and inserts it to the lock queue, without checking for deadlocks or conflicts. @param[in] type_mode lock mode and wait flag; type will be replaced @@ -3346,8 +3359,8 @@ lock_table_create( ut_ad(table && trx); ut_ad(lock_mutex_own()); ut_ad(trx_mutex_own(trx)); - - check_trx_state(trx); + ut_ad(trx->is_recovered || trx->state == TRX_STATE_ACTIVE); + ut_ad(!trx->auto_commit || trx->will_lock); if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) { ++table->n_waiting_or_granted_auto_inc_locks; @@ -4708,7 +4721,8 @@ lock_rec_queue_validate( ut_ad(!index || lock->index == index); trx_mutex_enter(lock->trx); - ut_ad(!trx_is_ac_nl_ro(lock->trx)); + ut_ad(!lock->trx->read_only + || !lock->trx->is_autocommit_non_locking()); ut_ad(trx_state_eq(lock->trx, TRX_STATE_COMMITTED_IN_MEMORY) || !lock_get_wait(lock) @@ -4794,8 +4808,8 @@ func_exit: for (lock = lock_rec_get_first(&lock_sys.rec_hash, block, heap_no); lock != NULL; lock = lock_rec_get_next_const(heap_no, lock)) { - - ut_ad(!trx_is_ac_nl_ro(lock->trx)); + ut_ad(!lock->trx->read_only + || !lock->trx->is_autocommit_non_locking()); ut_ad(!page_rec_is_metadata(rec)); if (index) { @@ -4881,7 +4895,8 @@ loop: } } - ut_ad(!trx_is_ac_nl_ro(lock->trx)); + ut_ad(!lock->trx->read_only + || !lock->trx->is_autocommit_non_locking()); /* Only validate the record queues when this thread is not holding a space->latch. */ @@ -4946,7 +4961,8 @@ lock_rec_validate( lock != NULL; lock = static_cast<const lock_t*>(HASH_GET_NEXT(hash, lock))) { - ut_ad(!trx_is_ac_nl_ro(lock->trx)); + ut_ad(!lock->trx->read_only + || !lock->trx->is_autocommit_non_locking()); ut_ad(lock_get_type(lock) == LOCK_REC); page_id_t current(lock->un_member.rec_lock.page_id); @@ -6514,7 +6530,8 @@ DeadlockChecker::search() ut_ad(m_start != NULL); ut_ad(m_wait_lock != NULL); - check_trx_state(m_wait_lock->trx); + ut_ad(!m_wait_lock->trx->auto_commit || m_wait_lock->trx->will_lock); + ut_d(check_trx_state(m_wait_lock->trx)); ut_ad(m_mark_start <= s_lock_mark_counter); /* Look at the locks ahead of wait_lock in the lock queue. */ @@ -6679,7 +6696,8 @@ DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx) { ut_ad(lock_mutex_own()); ut_ad(trx_mutex_own(trx)); - check_trx_state(trx); + ut_ad(trx->state == TRX_STATE_ACTIVE); + ut_ad(!trx->auto_commit || trx->will_lock); ut_ad(!srv_read_only_mode); if (!innobase_deadlock_detect) { diff --git a/storage/innobase/read/read0read.cc b/storage/innobase/read/read0read.cc index 92504546130..9047618d01c 100644 --- a/storage/innobase/read/read0read.cc +++ b/storage/innobase/read/read0read.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, 2019, MariaDB Corporation. +Copyright (c) 2018, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -221,7 +221,7 @@ void ReadView::open(trx_t *trx) else if (likely(!srv_read_only_mode)) { m_creator_trx_id= trx->id; - if (trx_is_autocommit_non_locking(trx) && empty() && + if (trx->is_autocommit_non_locking() && empty() && low_limit_id() == trx_sys.get_max_trx_id()) m_open.store(true, std::memory_order_relaxed); else diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index d49fcb4f52d..d043c3d86c0 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -518,7 +518,7 @@ thd_done: row->trx_is_read_only = trx->read_only; - row->trx_is_autocommit_non_locking = trx_is_autocommit_non_locking(trx); + row->trx_is_autocommit_non_locking = trx->is_autocommit_non_locking(); return(TRUE); } @@ -1175,7 +1175,24 @@ static void fetch_data_into_cache_low(trx_i_s_cache_t *cache, const trx_t *trx) { i_s_locks_row_t *requested_lock_row; - assert_trx_nonlocking_or_in_list(trx); +#ifdef UNIV_DEBUG + { + const auto state= trx->state; + + if (trx->is_autocommit_non_locking()) + { + ut_ad(trx->read_only); + ut_ad(!trx->is_recovered); + ut_ad(trx->mysql_thd); + ut_ad(state == TRX_STATE_NOT_STARTED || state == TRX_STATE_ACTIVE); + } + else + ut_ad(state == TRX_STATE_ACTIVE || + state == TRX_STATE_PREPARED || + state == TRX_STATE_PREPARED_RECOVERED || + state == TRX_STATE_COMMITTED_IN_MEMORY); + } +#endif /* UNIV_DEBUG */ if (add_trx_relevant_locks_to_cache(cache, trx, &requested_lock_row)) { diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index dc3dd51bb89..1fcfbfda7d6 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2020, MariaDB Corporation. +Copyright (c) 2016, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -101,10 +101,21 @@ inline void trx_t::rollback_low(trx_savept_t *savept) roll_node_t *roll_node= roll_node_create(heap); roll_node->savept= savept; - if (savept) - check_trx_state(this); - else - assert_trx_nonlocking_or_in_list(this); + ut_ad(!in_rollback); +#ifdef UNIV_DEBUG + { + const auto s= state; + ut_ad(s == TRX_STATE_ACTIVE || + s == TRX_STATE_PREPARED || + s == TRX_STATE_PREPARED_RECOVERED); + if (savept) + { + ut_ad(s == TRX_STATE_ACTIVE); + ut_ad(mysql_thd); + ut_ad(!is_recovered); + } + } +#endif error_state = DB_SUCCESS; @@ -203,7 +214,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx) switch (trx->state) { case TRX_STATE_NOT_STARTED: - trx->will_lock = 0; + trx->will_lock = false; ut_ad(trx->mysql_thd); #ifdef WITH_WSREP trx->wsrep= false; @@ -213,12 +224,13 @@ dberr_t trx_rollback_for_mysql(trx_t* trx) case TRX_STATE_ACTIVE: ut_ad(trx->mysql_thd); - assert_trx_nonlocking_or_in_list(trx); + ut_ad(!trx->is_recovered); + ut_ad(!trx->is_autocommit_non_locking() || trx->read_only); return(trx_rollback_for_mysql_low(trx)); case TRX_STATE_PREPARED: case TRX_STATE_PREPARED_RECOVERED: - ut_ad(!trx_is_autocommit_non_locking(trx)); + ut_ad(!trx->is_autocommit_non_locking()); if (trx->rsegs.m_redo.undo || trx->rsegs.m_redo.old_insert) { /* The XA ROLLBACK of a XA PREPARE transaction will consist of multiple mini-transactions. @@ -265,7 +277,7 @@ dberr_t trx_rollback_for_mysql(trx_t* trx) return(trx_rollback_for_mysql_low(trx)); case TRX_STATE_COMMITTED_IN_MEMORY: - check_trx_state(trx); + ut_ad(!trx->is_autocommit_non_locking()); break; } @@ -294,7 +306,9 @@ trx_rollback_last_sql_stat_for_mysql( return(DB_SUCCESS); case TRX_STATE_ACTIVE: - assert_trx_nonlocking_or_in_list(trx); + ut_ad(trx->mysql_thd); + ut_ad(!trx->is_recovered); + ut_ad(!trx->is_autocommit_non_locking() || trx->read_only); trx->op_info = "rollback of SQL statement"; diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index a48ab780960..e2f37bf9f07 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -137,7 +137,7 @@ trx_init( trx->auto_commit = false; - trx->will_lock = 0; + trx->will_lock = false; trx->ddl = false; @@ -353,7 +353,7 @@ trx_t *trx_create() ib_alloc_t* alloc; /* We just got trx from pool, it should be non locking */ - ut_ad(trx->will_lock == 0); + ut_ad(!trx->will_lock); ut_ad(!trx->rw_trx_hash_pins); DBUG_LOG("trx", "Create: " << trx); @@ -564,7 +564,7 @@ void trx_disconnect_prepared(trx_t *trx) trx->is_recovered= true; trx->mysql_thd= NULL; /* todo/fixme: suggest to do it at innodb prepare */ - trx->will_lock= 0; + trx->will_lock= false; trx_sys.rw_trx_hash.put_pins(trx); } @@ -911,11 +911,10 @@ static trx_rseg_t* trx_assign_rseg_low() /** Assign a rollback segment for modifying temporary tables. @return the assigned rollback segment */ -trx_rseg_t* -trx_t::assign_temp_rseg() +trx_rseg_t *trx_t::assign_temp_rseg() { ut_ad(!rsegs.m_noredo.rseg); - ut_ad(!trx_is_autocommit_non_locking(this)); + ut_ad(!is_autocommit_non_locking()); compile_time_assert(ut_is_2pow(TRX_SYS_N_RSEGS)); /* Choose a temporary rollback segment between 0 and 127 @@ -962,8 +961,8 @@ trx_start_low( && thd_trx_is_read_only(trx->mysql_thd)); if (!trx->auto_commit) { - ++trx->will_lock; - } else if (trx->will_lock == 0) { + trx->will_lock = true; + } else if (!trx->will_lock) { trx->read_only = true; } @@ -1001,7 +1000,7 @@ trx_start_low( trx_sys.register_rw(trx); } else { - if (!trx_is_autocommit_non_locking(trx)) { + if (!trx->is_autocommit_non_locking()) { /* If this is a read-only transaction that is writing to a temporary table then it needs a transaction id @@ -1302,12 +1301,15 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr) must_flush_log_later= false; read_view.close(); - if (trx_is_autocommit_non_locking(this)) + if (is_autocommit_non_locking()) { ut_ad(id == 0); ut_ad(read_only); + ut_ad(!will_lock); ut_a(!is_recovered); ut_ad(!rsegs.m_redo.rseg); + ut_ad(mysql_thd); + ut_ad(state == TRX_STATE_ACTIVE); /* Note: We are asserting without holding the lock mutex. But that is OK because this transaction is not waiting and cannot @@ -1321,12 +1323,11 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr) However, the freezing of trx_sys.trx_list will protect the trx_t instance and it cannot be removed from the trx_list and freed without first unfreezing trx_list. */ - ut_ad(trx_state_eq(this, TRX_STATE_ACTIVE)); + state= TRX_STATE_NOT_STARTED; MONITOR_INC(MONITOR_TRX_NL_RO_COMMIT); DBUG_LOG("trx", "Autocommit in memory: " << this); - state= TRX_STATE_NOT_STARTED; } else { @@ -1477,8 +1478,6 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr) @param mtr mini-transaction (if there are any persistent modifications) */ void trx_t::commit_low(mtr_t *mtr) { - assert_trx_nonlocking_or_in_list(this); - ut_ad(!trx_state_eq(this, TRX_STATE_COMMITTED_IN_MEMORY)); ut_ad(!mtr || mtr->is_active()); ut_d(bool aborted = in_rollback && error_state == DB_DEADLOCK); ut_ad(!mtr == (aborted || !has_logged_or_recovered())); @@ -1487,13 +1486,13 @@ void trx_t::commit_low(mtr_t *mtr) /* undo_no is non-zero if we're doing the final commit. */ if (fts_trx && undo_no) { - ut_a(!trx_is_autocommit_non_locking(this)); - dberr_t error= fts_commit(this); + ut_a(!is_autocommit_non_locking()); /* FTS-FIXME: Temporarily tolerate DB_DUPLICATE_KEY instead of dying. This is a possible scenario if there is a crash between insert to DELETED table committing and transaction committing. The fix would be able to return error from this function */ - ut_a(error == DB_SUCCESS || error == DB_DUPLICATE_KEY); + if (dberr_t error= fts_commit(this)) + ut_a(error == DB_DUPLICATE_KEY); } #ifndef DBUG_OFF @@ -1753,8 +1752,6 @@ trx_print_low( /*!< in: mem_heap_get_size(trx->lock.lock_heap) */ { ibool newline; - const char* op_info; - fprintf(f, "TRANSACTION " TRX_ID_FMT, trx_get_id_for_print(trx)); switch (trx->state) { @@ -1778,10 +1775,7 @@ trx_print_low( ut_ad(0); state_ok: - /* prevent a race condition */ - op_info = trx->op_info; - - if (*op_info) { + if (const char *op_info = trx->op_info) { putc(' ', f); fputs(op_info, f); } @@ -2245,7 +2239,7 @@ trx_start_internal_low( /* Ensure it is not flagged as an auto-commit-non-locking transaction. */ - trx->will_lock = 1; + trx->will_lock = true; trx->internal = true; @@ -2261,7 +2255,7 @@ trx_start_internal_read_only_low( /* Ensure it is not flagged as an auto-commit-non-locking transaction. */ - trx->will_lock = 1; + trx->will_lock = true; trx->internal = true; @@ -2285,7 +2279,7 @@ trx_start_for_ddl_low( /* Ensure it is not flagged as an auto-commit-non-locking transation. */ - trx->will_lock = 1; + trx->will_lock = true; trx->ddl= true; @@ -2315,7 +2309,7 @@ trx_set_rw_mode( trx_t* trx) /*!< in/out: transaction that is RW */ { ut_ad(trx->rsegs.m_redo.rseg == 0); - ut_ad(!trx_is_autocommit_non_locking(trx)); + ut_ad(!trx->is_autocommit_non_locking()); ut_ad(!trx->read_only); ut_ad(trx->id == 0); |