summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-05-07 12:28:04 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-05-07 12:28:04 +0300
commitd11b5ae6474db09bf3e4a2b27adb5e75488fc61c (patch)
tree2c9f9654b602c2fc5cf12c33e4eb706513992661
parent4a79e8e482a9dbb8ebde97d23b3856eebfcf4570 (diff)
downloadmariadb-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.cc48
-rw-r--r--storage/innobase/handler/handler0alter.cc3
-rw-r--r--storage/innobase/include/trx0i_s.h4
-rw-r--r--storage/innobase/include/trx0sys.h2
-rw-r--r--storage/innobase/include/trx0trx.h73
-rw-r--r--storage/innobase/include/trx0trx.ic10
-rw-r--r--storage/innobase/lock/lock0lock.cc36
-rw-r--r--storage/innobase/read/read0read.cc4
-rw-r--r--storage/innobase/trx/trx0i_s.cc21
-rw-r--r--storage/innobase/trx/trx0roll.cc34
-rw-r--r--storage/innobase/trx/trx0trx.cc48
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);