mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
MW-28, codership/mysql-wsrep#28 Fix sync_thread_levels debug assert
Introduced a new wsrep_trx_print_locking() which may be called under lock_sys->mutex if the trx has locks. Signed-off-by: Sachin Setiya <sachin.setiya@mariadb.com>
This commit is contained in:
parent
836727c971
commit
cdd1dc829b
6 changed files with 262 additions and 12 deletions
|
|
@ -334,6 +334,23 @@ trx_print_latched(
|
|||
or 0 to use the default max length */
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction.
|
||||
Transaction information may be retrieved without having trx_sys->mutex acquired
|
||||
so it may not be completely accurate. The caller must own lock_sys->mutex
|
||||
and the trx must have some locks to make sure that it does not escape
|
||||
without locking lock_sys->mutex. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
wsrep_trx_print_locking(
|
||||
/*==============*/
|
||||
FILE* f, /*!< in: output stream */
|
||||
const trx_t* trx, /*!< in: transaction */
|
||||
ulint max_query_len) /*!< in: max query length to print,
|
||||
or 0 to use the default max length */
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
#endif /* WITH_WSREP */
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction.
|
||||
Acquires and releases lock_sys->mutex and trx_sys->mutex. */
|
||||
|
|
|
|||
|
|
@ -1752,7 +1752,6 @@ wsrep_kill_victim(
|
|||
is in the queue*/
|
||||
} else if (lock->trx != trx) {
|
||||
if (wsrep_log_conflicts) {
|
||||
mutex_enter(&trx_sys->mutex);
|
||||
if (bf_this) {
|
||||
fputs("\n*** Priority TRANSACTION:\n",
|
||||
stderr);
|
||||
|
|
@ -1761,7 +1760,7 @@ wsrep_kill_victim(
|
|||
stderr);
|
||||
}
|
||||
|
||||
trx_print_latched(stderr, trx, 3000);
|
||||
wsrep_trx_print_locking(stderr, trx, 3000);
|
||||
|
||||
if (bf_other) {
|
||||
fputs("\n*** Priority TRANSACTION:\n",
|
||||
|
|
@ -1770,10 +1769,7 @@ wsrep_kill_victim(
|
|||
fputs("\n*** Victim TRANSACTION:\n",
|
||||
stderr);
|
||||
}
|
||||
|
||||
trx_print_latched(stderr, lock->trx, 3000);
|
||||
|
||||
mutex_exit(&trx_sys->mutex);
|
||||
wsrep_trx_print_locking(stderr, lock->trx, 3000);
|
||||
|
||||
fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
|
||||
stderr);
|
||||
|
|
|
|||
|
|
@ -1885,6 +1885,118 @@ trx_print_latched(
|
|||
mem_heap_get_size(trx->lock.lock_heap));
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction.
|
||||
Transaction information may be retrieved without having trx_sys->mutex acquired
|
||||
so it may not be completely accurate. The caller must own lock_sys->mutex
|
||||
and the trx must have some locks to make sure that it does not escape
|
||||
without locking lock_sys->mutex. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
wsrep_trx_print_locking(
|
||||
/*==========*/
|
||||
FILE* f,
|
||||
/*!< in: output stream */
|
||||
const trx_t* trx,
|
||||
/*!< in: transaction */
|
||||
ulint max_query_len)
|
||||
/*!< in: max query length to print,
|
||||
or 0 to use the default max length */
|
||||
{
|
||||
ibool newline;
|
||||
const char* op_info;
|
||||
|
||||
ut_ad(lock_mutex_own());
|
||||
ut_ad(trx->lock.trx_locks.count > 0);
|
||||
|
||||
fprintf(f, "TRANSACTION " TRX_ID_FMT, trx->id);
|
||||
|
||||
/* trx->state may change since trx_sys->mutex is not required */
|
||||
switch (trx->state) {
|
||||
case TRX_STATE_NOT_STARTED:
|
||||
fputs(", not started", f);
|
||||
goto state_ok;
|
||||
case TRX_STATE_ACTIVE:
|
||||
fprintf(f, ", ACTIVE %lu sec",
|
||||
(ulong) difftime(time(NULL), trx->start_time));
|
||||
goto state_ok;
|
||||
case TRX_STATE_PREPARED:
|
||||
fprintf(f, ", ACTIVE (PREPARED) %lu sec",
|
||||
(ulong) difftime(time(NULL), trx->start_time));
|
||||
goto state_ok;
|
||||
case TRX_STATE_COMMITTED_IN_MEMORY:
|
||||
fputs(", COMMITTED IN MEMORY", f);
|
||||
goto state_ok;
|
||||
}
|
||||
fprintf(f, ", state %lu", (ulong) trx->state);
|
||||
ut_ad(0);
|
||||
state_ok:
|
||||
|
||||
/* prevent a race condition */
|
||||
op_info = trx->op_info;
|
||||
|
||||
if (*op_info) {
|
||||
putc(' ', f);
|
||||
fputs(op_info, f);
|
||||
}
|
||||
|
||||
if (trx->is_recovered) {
|
||||
fputs(" recovered trx", f);
|
||||
}
|
||||
|
||||
if (trx->declared_to_be_inside_innodb) {
|
||||
fprintf(f, ", thread declared inside InnoDB %lu",
|
||||
(ulong) trx->n_tickets_to_enter_innodb);
|
||||
}
|
||||
|
||||
putc('\n', f);
|
||||
|
||||
if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) {
|
||||
fprintf(f, "mysql tables in use %lu, locked %lu\n",
|
||||
(ulong) trx->n_mysql_tables_in_use,
|
||||
(ulong) trx->mysql_n_tables_locked);
|
||||
}
|
||||
|
||||
newline = TRUE;
|
||||
|
||||
/* trx->lock.que_state of an ACTIVE transaction may change
|
||||
while we are not holding trx->mutex. We perform a dirty read
|
||||
for performance reasons. */
|
||||
|
||||
switch (trx->lock.que_state) {
|
||||
case TRX_QUE_RUNNING:
|
||||
newline = FALSE; break;
|
||||
case TRX_QUE_LOCK_WAIT:
|
||||
fputs("LOCK WAIT ", f); break;
|
||||
case TRX_QUE_ROLLING_BACK:
|
||||
fputs("ROLLING BACK ", f); break;
|
||||
case TRX_QUE_COMMITTING:
|
||||
fputs("COMMITTING ", f); break;
|
||||
default:
|
||||
fprintf(f, "que state %lu ", (ulong) trx->lock.que_state);
|
||||
}
|
||||
|
||||
if (trx->has_search_latch) {
|
||||
newline = TRUE;
|
||||
fputs(", holds adaptive hash latch", f);
|
||||
}
|
||||
|
||||
if (trx->undo_no != 0) {
|
||||
newline = TRUE;
|
||||
fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no);
|
||||
}
|
||||
|
||||
if (newline) {
|
||||
putc('\n', f);
|
||||
}
|
||||
|
||||
if (trx->mysql_thd != NULL) {
|
||||
innobase_mysql_print_thd(
|
||||
f, trx->mysql_thd, static_cast<uint>(max_query_len));
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction.
|
||||
Acquires and releases lock_sys->mutex and trx_sys->mutex. */
|
||||
|
|
|
|||
|
|
@ -348,6 +348,23 @@ trx_print_latched(
|
|||
or 0 to use the default max length */
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction.
|
||||
Transaction information may be retrieved without having trx_sys->mutex acquired
|
||||
so it may not be completely accurate. The caller must own lock_sys->mutex
|
||||
and the trx must have some locks to make sure that it does not escape
|
||||
without locking lock_sys->mutex. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
wsrep_trx_print_locking(
|
||||
/*==============*/
|
||||
FILE* f, /*!< in: output stream */
|
||||
const trx_t* trx, /*!< in: transaction */
|
||||
ulint max_query_len) /*!< in: max query length to print,
|
||||
or 0 to use the default max length */
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
#endif /* WITH_WSREP */
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction.
|
||||
Acquires and releases lock_sys->mutex and trx_sys->mutex. */
|
||||
|
|
|
|||
|
|
@ -1762,7 +1762,6 @@ wsrep_kill_victim(
|
|||
is in the queue*/
|
||||
} else if (lock->trx != trx) {
|
||||
if (wsrep_log_conflicts) {
|
||||
mutex_enter(&trx_sys->mutex);
|
||||
if (bf_this) {
|
||||
fputs("\n*** Priority TRANSACTION:\n",
|
||||
stderr);
|
||||
|
|
@ -1771,7 +1770,7 @@ wsrep_kill_victim(
|
|||
stderr);
|
||||
}
|
||||
|
||||
trx_print_latched(stderr, trx, 3000);
|
||||
wsrep_trx_print_locking(stderr, trx, 3000);
|
||||
|
||||
if (bf_other) {
|
||||
fputs("\n*** Priority TRANSACTION:\n",
|
||||
|
|
@ -1780,10 +1779,7 @@ wsrep_kill_victim(
|
|||
fputs("\n*** Victim TRANSACTION:\n",
|
||||
stderr);
|
||||
}
|
||||
|
||||
trx_print_latched(stderr, lock->trx, 3000);
|
||||
|
||||
mutex_exit(&trx_sys->mutex);
|
||||
wsrep_trx_print_locking(stderr, lock->trx, 3000);
|
||||
|
||||
fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
|
||||
stderr);
|
||||
|
|
|
|||
|
|
@ -2161,6 +2161,118 @@ trx_print_latched(
|
|||
mem_heap_get_size(trx->lock.lock_heap));
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction.
|
||||
Transaction information may be retrieved without having trx_sys->mutex acquired
|
||||
so it may not be completely accurate. The caller must own lock_sys->mutex
|
||||
and the trx must have some locks to make sure that it does not escape
|
||||
without locking lock_sys->mutex. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
wsrep_trx_print_locking(
|
||||
/*==========*/
|
||||
FILE* f,
|
||||
/*!< in: output stream */
|
||||
const trx_t* trx,
|
||||
/*!< in: transaction */
|
||||
ulint max_query_len)
|
||||
/*!< in: max query length to print,
|
||||
or 0 to use the default max length */
|
||||
{
|
||||
ibool newline;
|
||||
const char* op_info;
|
||||
|
||||
ut_ad(lock_mutex_own());
|
||||
ut_ad(trx->lock.trx_locks.count > 0);
|
||||
|
||||
fprintf(f, "TRANSACTION " TRX_ID_FMT, trx->id);
|
||||
|
||||
/* trx->state may change since trx_sys->mutex is not required */
|
||||
switch (trx->state) {
|
||||
case TRX_STATE_NOT_STARTED:
|
||||
fputs(", not started", f);
|
||||
goto state_ok;
|
||||
case TRX_STATE_ACTIVE:
|
||||
fprintf(f, ", ACTIVE %lu sec",
|
||||
(ulong) difftime(time(NULL), trx->start_time));
|
||||
goto state_ok;
|
||||
case TRX_STATE_PREPARED:
|
||||
fprintf(f, ", ACTIVE (PREPARED) %lu sec",
|
||||
(ulong) difftime(time(NULL), trx->start_time));
|
||||
goto state_ok;
|
||||
case TRX_STATE_COMMITTED_IN_MEMORY:
|
||||
fputs(", COMMITTED IN MEMORY", f);
|
||||
goto state_ok;
|
||||
}
|
||||
fprintf(f, ", state %lu", (ulong) trx->state);
|
||||
ut_ad(0);
|
||||
state_ok:
|
||||
|
||||
/* prevent a race condition */
|
||||
op_info = trx->op_info;
|
||||
|
||||
if (*op_info) {
|
||||
putc(' ', f);
|
||||
fputs(op_info, f);
|
||||
}
|
||||
|
||||
if (trx->is_recovered) {
|
||||
fputs(" recovered trx", f);
|
||||
}
|
||||
|
||||
if (trx->declared_to_be_inside_innodb) {
|
||||
fprintf(f, ", thread declared inside InnoDB %lu",
|
||||
(ulong) trx->n_tickets_to_enter_innodb);
|
||||
}
|
||||
|
||||
putc('\n', f);
|
||||
|
||||
if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) {
|
||||
fprintf(f, "mysql tables in use %lu, locked %lu\n",
|
||||
(ulong) trx->n_mysql_tables_in_use,
|
||||
(ulong) trx->mysql_n_tables_locked);
|
||||
}
|
||||
|
||||
newline = TRUE;
|
||||
|
||||
/* trx->lock.que_state of an ACTIVE transaction may change
|
||||
while we are not holding trx->mutex. We perform a dirty read
|
||||
for performance reasons. */
|
||||
|
||||
switch (trx->lock.que_state) {
|
||||
case TRX_QUE_RUNNING:
|
||||
newline = FALSE; break;
|
||||
case TRX_QUE_LOCK_WAIT:
|
||||
fputs("LOCK WAIT ", f); break;
|
||||
case TRX_QUE_ROLLING_BACK:
|
||||
fputs("ROLLING BACK ", f); break;
|
||||
case TRX_QUE_COMMITTING:
|
||||
fputs("COMMITTING ", f); break;
|
||||
default:
|
||||
fprintf(f, "que state %lu ", (ulong) trx->lock.que_state);
|
||||
}
|
||||
|
||||
if (trx->has_search_latch) {
|
||||
newline = TRUE;
|
||||
fputs(", holds adaptive hash latch", f);
|
||||
}
|
||||
|
||||
if (trx->undo_no != 0) {
|
||||
newline = TRUE;
|
||||
fprintf(f, ", undo log entries " TRX_ID_FMT, trx->undo_no);
|
||||
}
|
||||
|
||||
if (newline) {
|
||||
putc('\n', f);
|
||||
}
|
||||
|
||||
if (trx->mysql_thd != NULL) {
|
||||
innobase_mysql_print_thd(
|
||||
f, trx->mysql_thd, static_cast<uint>(max_query_len));
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
/**********************************************************************//**
|
||||
Prints info about a transaction.
|
||||
Acquires and releases lock_sys->mutex and trx_sys->mutex. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue