Skip to content
Permalink
Browse files
MDEV-15773 - trx_sys.mysql_trx_list -> trx_sys.trx_list
Replaced "list of transactions created for MySQL" with "list of all
transactions". This simplifies code and allows further removal of
trx_sys.m_views.
  • Loading branch information
Sergey Vojtovich committed Apr 4, 2018
1 parent 061c767 commit 0993d6b
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 185 deletions.
@@ -2760,9 +2760,9 @@ buf_pool_resize()
lock_mutex_enter();
mutex_enter(&trx_sys.mutex);
bool found = false;
for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys.mysql_trx_list);
for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys.trx_list);
trx != NULL;
trx = UT_LIST_GET_NEXT(mysql_trx_list, trx)) {
trx = UT_LIST_GET_NEXT(trx_list, trx)) {
if (trx->state != TRX_STATE_NOT_STARTED
&& trx->mysql_thd != NULL
&& ut_difftime(withdraw_started,
@@ -2741,7 +2741,7 @@ innobase_trx_allocate(
DBUG_ASSERT(thd != NULL);
DBUG_ASSERT(EQ_CURRENT_THD(thd));

trx = trx_allocate_for_mysql();
trx = trx_create();

trx->mysql_thd = thd;

@@ -808,20 +808,11 @@ class trx_sys_t
bool m_initialised;

public:
MY_ALIGNED(CACHE_LINE_SIZE) mutable
TrxSysMutex mutex; /*!< mutex protecting most fields in
this structure except when noted
otherwise */
MY_ALIGNED(CACHE_LINE_SIZE)
trx_ut_list_t mysql_trx_list; /*!< List of transactions created
for MySQL. All user transactions are
on mysql_trx_list. The rw_trx_hash
can contain system transactions and
recovered transactions that will not
be in the mysql_trx_list.
mysql_trx_list may additionally contain
transactions that have not yet been
started in InnoDB. */
/** Mutex protecting trx_list. */
MY_ALIGNED(CACHE_LINE_SIZE) mutable TrxSysMutex mutex;

/** List of all transactions. */
MY_ALIGNED(CACHE_LINE_SIZE) trx_ut_list_t trx_list;

MY_ALIGNED(CACHE_LINE_SIZE)
/** Temporary rollback segments */
@@ -82,12 +82,6 @@ const dict_index_t*
trx_get_error_info(
/*===============*/
const trx_t* trx); /*!< in: trx object */
/********************************************************************//**
Creates a transaction object for MySQL.
@return own: transaction object */
trx_t*
trx_allocate_for_mysql(void);
/*========================*/

/** @return a trx_t instance from trx_pools. */
trx_t *trx_create();
@@ -106,11 +100,6 @@ trx_free_at_shutdown(trx_t *trx);
void
trx_free_for_mysql(trx_t* trx);

/** Disconnect a transaction from MySQL.
@param[in,out] trx transaction */
void
trx_disconnect_plain(trx_t* trx);

/** Disconnect a prepared transaction from MySQL.
@param[in,out] trx transaction */
void
@@ -514,7 +503,7 @@ transaction pool.
/*******************************************************************//**
Assert that an autocommit non-locking select cannot be in the
rw_trx_hash and that it is a read-only transaction.
The tranasction must be in the mysql_trx_list. */
The transaction must have mysql_thd assigned. */
# define assert_trx_nonlocking_or_in_list(t) \
do { \
if (trx_is_autocommit_non_locking(t)) { \
@@ -532,7 +521,7 @@ The tranasction must be in the mysql_trx_list. */
/*******************************************************************//**
Assert that an autocommit non-locking slect cannot be in the
rw_trx_hash and that it is a read-only transaction.
The tranasction must be in the mysql_trx_list. */
The transaction must have mysql_thd assigned. */
# define assert_trx_nonlocking_or_in_list(trx) ((void)0)
#endif /* UNIV_DEBUG */

@@ -733,9 +722,8 @@ and lock_trx_release_locks() [invoked by trx_commit()].
* trx_print_low() may access transactions not associated with the current
thread. The caller must be holding lock_sys.mutex.
* When a transaction handle is in the trx_sys.mysql_trx_list or
trx_sys.trx_list, some of its fields must not be modified without
holding trx_sys.mutex exclusively.
* When a transaction handle is in the trx_sys.trx_list, some of its fields
must not be modified without holding trx->mutex.
* The locking code (in particular, lock_deadlock_recursive() and
lock_rec_convert_impl_to_expl()) will access transactions associated
@@ -854,8 +842,8 @@ struct trx_t {
do we remove it from the read-only list and put it on the read-write
list. During this switch we assign it a rollback segment.
When a transaction is NOT_STARTED, it can be in mysql_trx_list if
it is a user transaction. It cannot be in rw_trx_hash.
When a transaction is NOT_STARTED, it can be in trx_list. It cannot be
in rw_trx_hash.
ACTIVE->PREPARED->COMMITTED is only possible when trx is in rw_trx_hash.
The transition ACTIVE->PREPARED is protected by trx_sys.mutex.
@@ -973,9 +961,8 @@ struct trx_t {
statement uses, except those
in consistent read */
/*------------------------------*/
UT_LIST_NODE_T(trx_t)
mysql_trx_list; /*!< list of transactions created for
MySQL; protected by trx_sys.mutex */
UT_LIST_NODE_T(trx_t) trx_list; /*!< list of all transactions;
protected by trx_sys.mutex */
/*------------------------------*/
dberr_t error_state; /*!< 0 if no error, otherwise error
number; NOTE That ONLY the thread
@@ -4666,20 +4666,20 @@ lock_print_info_summary(
return(TRUE);
}

/** Functor to print not-started transaction from the mysql_trx_list. */
/** Functor to print not-started transaction from the trx_list. */

struct PrintNotStarted {

PrintNotStarted(FILE* file) : m_file(file) { }

void operator()(const trx_t* trx)
{
ut_ad(trx->mysql_thd);
ut_ad(mutex_own(&trx_sys.mutex));

/* See state transitions and locking rules in trx0trx.h */

if (trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {
if (trx->mysql_thd
&& trx_state_eq(trx, TRX_STATE_NOT_STARTED)) {

fputs("---", m_file);
trx_print_latched(m_file, trx, 600);
@@ -4806,7 +4806,7 @@ lock_print_info_all_transactions(

PrintNotStarted print_not_started(file);
mutex_enter(&trx_sys.mutex);
ut_list_map(trx_sys.mysql_trx_list, print_not_started);
ut_list_map(trx_sys.trx_list, print_not_started);
mutex_exit(&trx_sys.mutex);

trx_sys.rw_trx_hash.iterate_no_dups(
@@ -3728,7 +3728,7 @@ row_import_for_mysql(

trx_start_if_not_started(prebuilt->trx, true);

trx = trx_allocate_for_mysql();
trx = trx_create();

/* So that the table is not DROPped during recovery. */
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
@@ -2872,8 +2872,8 @@ innodb_shutdown()
if (log_sys) {
log_shutdown();
}
trx_sys.close();
purge_sys.close();
trx_sys.close();
if (buf_dblwr) {
buf_dblwr_free();
}
@@ -56,6 +56,8 @@ Created July 17, 2007 Vasil Dimov
#include "trx0sys.h"
#include "trx0trx.h"
#include "ut0mem.h"
#include "que0que.h"
#include "trx0purge.h"

/** Initial number of rows in the table cache */
#define TABLE_CACHE_INITIAL_ROWSNUM 1024
@@ -1275,17 +1277,6 @@ static void fetch_data_into_cache_low(trx_i_s_cache_t *cache, const trx_t *trx)
}


static my_bool fetch_data_into_cache_callback(
rw_trx_hash_element_t *element, trx_i_s_cache_t *cache)
{
mutex_enter(&element->mutex);
if (element->trx)
fetch_data_into_cache_low(cache, element->trx);
mutex_exit(&element->mutex);
return cache->is_truncated;
}


/**
Fetches the data needed to fill the 3 INFORMATION SCHEMA tables into the
table cache buffer. Cache must be locked for write.
@@ -1296,24 +1287,13 @@ static void fetch_data_into_cache(trx_i_s_cache_t *cache)
ut_ad(lock_mutex_own());
trx_i_s_cache_clear(cache);

/*
Capture the state of the read-write transactions. This includes
internal transactions too. They are not on mysql_trx_list
*/
trx_sys.rw_trx_hash.iterate_no_dups(reinterpret_cast<my_hash_walk_action>
(fetch_data_into_cache_callback), cache);

/* Capture the state of the read-only active transactions */
/* Capture the state of transactions */
mutex_enter(&trx_sys.mutex);
for (const trx_t *trx= UT_LIST_GET_FIRST(trx_sys.mysql_trx_list);
for (const trx_t *trx= UT_LIST_GET_FIRST(trx_sys.trx_list);
trx != NULL;
trx= UT_LIST_GET_NEXT(mysql_trx_list, trx))
trx= UT_LIST_GET_NEXT(trx_list, trx))
{
/*
Skip transactions that have trx->id > 0: they were added in previous
iteration. Although we may miss concurrently started transactions.
*/
if (trx_is_started(trx) && trx->id == 0)
if (trx_is_started(trx) && trx != purge_sys.query->trx)
{
fetch_data_into_cache_low(cache, trx);
if (cache->is_truncated)
@@ -759,14 +759,14 @@ trx_roll_must_shutdown()


static my_bool trx_rollback_recovered_callback(rw_trx_hash_element_t *element,
trx_ut_list_t *trx_list)
std::vector<trx_t*> *trx_list)
{
mutex_enter(&element->mutex);
if (trx_t *trx= element->trx)
{
mutex_enter(&trx->mutex);
if (trx->is_recovered && trx_state_eq(trx, TRX_STATE_ACTIVE))
UT_LIST_ADD_FIRST(*trx_list, trx);
trx_list->push_back(trx);
mutex_exit(&trx->mutex);
}
mutex_exit(&element->mutex);
@@ -791,10 +791,9 @@ static my_bool trx_rollback_recovered_callback(rw_trx_hash_element_t *element,

void trx_rollback_recovered(bool all)
{
trx_ut_list_t trx_list;
std::vector<trx_t*> trx_list;

ut_a(srv_force_recovery < SRV_FORCE_NO_TRX_UNDO);
UT_LIST_INIT(trx_list, &trx_t::mysql_trx_list);

/*
Collect list of recovered ACTIVE transaction ids first. Once collected, no
@@ -805,9 +804,10 @@ void trx_rollback_recovered(bool all)
(trx_rollback_recovered_callback),
&trx_list);

while (trx_t *trx= UT_LIST_GET_FIRST(trx_list))
while (!trx_list.empty())
{
UT_LIST_REMOVE(trx_list, trx);
trx_t *trx= trx_list.back();
trx_list.pop_back();

#ifdef UNIV_DEBUG
ut_ad(trx);
@@ -217,7 +217,7 @@ trx_sys_t::create()
ut_ad(!is_initialised());
m_initialised = true;
mutex_create(LATCH_ID_TRX_SYS, &mutex);
UT_LIST_INIT(mysql_trx_list, &trx_t::mysql_trx_list);
UT_LIST_INIT(trx_list, &trx_t::trx_list);
UT_LIST_INIT(m_views, &ReadView::m_view_list);
my_atomic_store32(&rseg_history_len, 0);

@@ -345,47 +345,26 @@ trx_sys_t::close()
}
}

ut_a(UT_LIST_GET_LEN(mysql_trx_list) == 0);
ut_a(UT_LIST_GET_LEN(trx_list) == 0);
ut_ad(UT_LIST_GET_LEN(m_views) == 0);
mutex_free(&mutex);
m_initialised = false;
}


static my_bool active_count_callback(rw_trx_hash_element_t *element,
uint32_t *count)
{
mutex_enter(&element->mutex);
if (trx_t *trx= element->trx)
{
mutex_enter(&trx->mutex);
if (trx_state_eq(trx, TRX_STATE_ACTIVE))
++*count;
mutex_exit(&trx->mutex);
}
mutex_exit(&element->mutex);
return 0;
}


/** @return total number of active (non-prepared) transactions */
ulint trx_sys_t::any_active_transactions()
{
uint32_t total_trx = 0;

trx_sys.rw_trx_hash.iterate_no_dups(
reinterpret_cast<my_hash_walk_action>
(active_count_callback), &total_trx);

mutex_enter(&mutex);
for (trx_t* trx = UT_LIST_GET_FIRST(trx_sys.mysql_trx_list);
trx != NULL;
trx = UT_LIST_GET_NEXT(mysql_trx_list, trx)) {
if (trx->state != TRX_STATE_NOT_STARTED && !trx->id) {
total_trx++;
}
}
mutex_exit(&mutex);
uint32_t total_trx= 0;

return(total_trx);
mutex_enter(&mutex);
for (trx_t* trx= UT_LIST_GET_FIRST(trx_sys.trx_list);
trx != NULL;
trx= UT_LIST_GET_NEXT(trx_list, trx))
{
if (trx->state == TRX_STATE_COMMITTED_IN_MEMORY ||
(trx->state == TRX_STATE_ACTIVE && trx->id))
total_trx++;
}
mutex_exit(&mutex);
return total_trx;
}

0 comments on commit 0993d6b

Please sign in to comment.