mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
Applying InnoDB snapshot, fixes BUG#49001
Detailed revision comments: r6545 | jyang | 2010-02-03 03:57:32 +0200 (Wed, 03 Feb 2010) | 8 lines branches/5.1: Fix bug #49001, "SHOW INNODB STATUS deadlock info incorrect when deadlock detection aborts". Print the correct lock owner when recursive function lock_deadlock_recursive() exceeds its maximum depth LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK. rb://217, approved by Marko.
This commit is contained in:
parent
6d4e34cabb
commit
167888c6c3
1 changed files with 63 additions and 35 deletions
|
@ -306,6 +306,7 @@ FILE* lock_latest_err_file;
|
|||
/* Flags for recursive deadlock search */
|
||||
#define LOCK_VICTIM_IS_START 1
|
||||
#define LOCK_VICTIM_IS_OTHER 2
|
||||
#define LOCK_EXCEED_MAX_DEPTH 3
|
||||
|
||||
/************************************************************************
|
||||
Checks if a lock request results in a deadlock. */
|
||||
|
@ -332,16 +333,18 @@ lock_deadlock_recursive(
|
|||
was found and we chose some other trx as a
|
||||
victim: we must do the search again in this
|
||||
last case because there may be another
|
||||
deadlock! */
|
||||
deadlock!
|
||||
LOCK_EXCEED_MAX_DEPTH if the lock search
|
||||
exceeds max steps and/or max depth. */
|
||||
trx_t* start, /* in: recursion starting point */
|
||||
trx_t* trx, /* in: a transaction waiting for a lock */
|
||||
lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
|
||||
ulint* cost, /* in/out: number of calculation steps thus
|
||||
far: if this exceeds LOCK_MAX_N_STEPS_...
|
||||
we return LOCK_VICTIM_IS_START */
|
||||
we return LOCK_EXCEED_MAX_DEPTH */
|
||||
ulint depth); /* in: recursion depth: if this exceeds
|
||||
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
|
||||
return LOCK_VICTIM_IS_START */
|
||||
return LOCK_EXCEED_MAX_DEPTH */
|
||||
|
||||
/*************************************************************************
|
||||
Gets the nth bit of a record lock. */
|
||||
|
@ -3084,8 +3087,6 @@ lock_deadlock_occurs(
|
|||
lock_t* lock, /* in: lock the transaction is requesting */
|
||||
trx_t* trx) /* in: transaction */
|
||||
{
|
||||
dict_table_t* table;
|
||||
dict_index_t* index;
|
||||
trx_t* mark_trx;
|
||||
ulint ret;
|
||||
ulint cost = 0;
|
||||
|
@ -3107,31 +3108,50 @@ retry:
|
|||
|
||||
ret = lock_deadlock_recursive(trx, trx, lock, &cost, 0);
|
||||
|
||||
if (ret == LOCK_VICTIM_IS_OTHER) {
|
||||
switch (ret) {
|
||||
case LOCK_VICTIM_IS_OTHER:
|
||||
/* We chose some other trx as a victim: retry if there still
|
||||
is a deadlock */
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (ret == LOCK_VICTIM_IS_START) {
|
||||
if (lock_get_type(lock) & LOCK_TABLE) {
|
||||
table = lock->un_member.tab_lock.table;
|
||||
index = NULL;
|
||||
} else {
|
||||
index = lock->index;
|
||||
table = index->table;
|
||||
}
|
||||
case LOCK_EXCEED_MAX_DEPTH:
|
||||
/* If the lock search exceeds the max step
|
||||
or the max depth, the current trx will be
|
||||
the victim. Print its information. */
|
||||
rewind(lock_latest_err_file);
|
||||
ut_print_timestamp(lock_latest_err_file);
|
||||
|
||||
lock_deadlock_found = TRUE;
|
||||
|
||||
fputs("*** WE ROLL BACK TRANSACTION (2)\n",
|
||||
fputs("TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
|
||||
" WAITS-FOR GRAPH, WE WILL ROLL BACK"
|
||||
" FOLLOWING TRANSACTION \n",
|
||||
lock_latest_err_file);
|
||||
|
||||
return(TRUE);
|
||||
fputs("\n*** TRANSACTION:\n", lock_latest_err_file);
|
||||
trx_print(lock_latest_err_file, trx, 3000);
|
||||
|
||||
fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
|
||||
lock_latest_err_file);
|
||||
|
||||
if (lock_get_type(lock) == LOCK_REC) {
|
||||
lock_rec_print(lock_latest_err_file, lock);
|
||||
} else {
|
||||
lock_table_print(lock_latest_err_file, lock);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOCK_VICTIM_IS_START:
|
||||
fputs("*** WE ROLL BACK TRANSACTION (2)\n",
|
||||
lock_latest_err_file);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* No deadlock detected*/
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
lock_deadlock_found = TRUE;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -3147,16 +3167,18 @@ lock_deadlock_recursive(
|
|||
was found and we chose some other trx as a
|
||||
victim: we must do the search again in this
|
||||
last case because there may be another
|
||||
deadlock! */
|
||||
deadlock!
|
||||
LOCK_EXCEED_MAX_DEPTH if the lock search
|
||||
exceeds max steps and/or max depth. */
|
||||
trx_t* start, /* in: recursion starting point */
|
||||
trx_t* trx, /* in: a transaction waiting for a lock */
|
||||
lock_t* wait_lock, /* in: the lock trx is waiting to be granted */
|
||||
ulint* cost, /* in/out: number of calculation steps thus
|
||||
far: if this exceeds LOCK_MAX_N_STEPS_...
|
||||
we return LOCK_VICTIM_IS_START */
|
||||
we return LOCK_EXCEED_MAX_DEPTH */
|
||||
ulint depth) /* in: recursion depth: if this exceeds
|
||||
LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we
|
||||
return LOCK_VICTIM_IS_START */
|
||||
return LOCK_EXCEED_MAX_DEPTH */
|
||||
{
|
||||
lock_t* lock;
|
||||
ulint bit_no = ULINT_UNDEFINED;
|
||||
|
@ -3215,7 +3237,7 @@ lock_deadlock_recursive(
|
|||
|
||||
lock_trx = lock->trx;
|
||||
|
||||
if (lock_trx == start || too_far) {
|
||||
if (lock_trx == start) {
|
||||
|
||||
/* We came back to the recursion starting
|
||||
point: a deadlock detected; or we have
|
||||
|
@ -3262,19 +3284,10 @@ lock_deadlock_recursive(
|
|||
}
|
||||
#ifdef UNIV_DEBUG
|
||||
if (lock_print_waits) {
|
||||
fputs("Deadlock detected"
|
||||
" or too long search\n",
|
||||
fputs("Deadlock detected\n",
|
||||
stderr);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
if (too_far) {
|
||||
|
||||
fputs("TOO DEEP OR LONG SEARCH"
|
||||
" IN THE LOCK TABLE"
|
||||
" WAITS-FOR GRAPH\n", ef);
|
||||
|
||||
return(LOCK_VICTIM_IS_START);
|
||||
}
|
||||
|
||||
if (trx_weight_cmp(wait_lock->trx,
|
||||
start) >= 0) {
|
||||
|
@ -3310,6 +3323,21 @@ lock_deadlock_recursive(
|
|||
return(LOCK_VICTIM_IS_OTHER);
|
||||
}
|
||||
|
||||
if (too_far) {
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (lock_print_waits) {
|
||||
fputs("Deadlock search exceeds"
|
||||
" max steps or depth.\n",
|
||||
stderr);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
/* The information about transaction/lock
|
||||
to be rolled back is available in the top
|
||||
level. Do not print anything here. */
|
||||
return(LOCK_EXCEED_MAX_DEPTH);
|
||||
}
|
||||
|
||||
if (lock_trx->que_state == TRX_QUE_LOCK_WAIT) {
|
||||
|
||||
/* Another trx ahead has requested lock in an
|
||||
|
|
Loading…
Reference in a new issue