Commit 16925618 authored by Sergey Vojtovich's avatar Sergey Vojtovich

Applying InnoDB snapshot

Detailed revision comments:

r6449 | marko | 2010-01-13 22:38:53 +0200 (Wed, 13 Jan 2010) | 18 lines
branches/zip: lock_rec_validate_page(): Only validate the record
queues when the thread is not holding a space->latch.

When UNIV_DEBUG is defined while UNIV_SYNC_DEBUG is not,
latching order violations will still occur and deadlocks will be possible.

sync_thread_levels_nonempty_gen(): Renamed from
sync_thread_levels_empty_gen().  Return the violating latch or NULL
instead of FALSE or TRUE, except that there will be a ut_error before
the non-NULL return.

sync_thread_levels_empty_gen(): A macro that negates the return value of
sync_thread_levels_nonempty_gen().

sync_thread_levels_contains(): New function, based on
sync_thread_levels_nonempty_gen().

This should fix Issue #441.
parent 55cc8f1f
......@@ -238,16 +238,27 @@ ibool
sync_thread_levels_empty(void);
/*==========================*/
/******************************************************************//**
Checks that the level array for the current thread is empty.
@return TRUE if empty except the exceptions specified below */
Checks if the level array for the current thread contains a
mutex or rw-latch at the specified level.
@return a matching latch, or NULL if not found */
UNIV_INTERN
ibool
sync_thread_levels_empty_gen(
/*=========================*/
void*
sync_thread_levels_contains(
/*========================*/
ulint level); /*!< in: latching order level
(SYNC_DICT, ...)*/
/******************************************************************//**
Checks if the level array for the current thread is empty.
@return a latch, or NULL if empty except the exceptions specified below */
UNIV_INTERN
void*
sync_thread_levels_nonempty_gen(
/*============================*/
ibool dict_mutex_allowed); /*!< in: TRUE if dictionary mutex is
allowed to be owned by the thread,
also purge_is_running mutex is
allowed */
#define sync_thread_levels_empty_gen(d) (!sync_thread_levels_nonempty_gen(d))
/******************************************************************//**
Gets the debug information for a reserved mutex. */
UNIV_INTERN
......
......@@ -4766,6 +4766,13 @@ loop:
|| lock->trx->conc_state == TRX_PREPARED
|| lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY);
# ifdef UNIV_SYNC_DEBUG
/* Only validate the record queues when this thread is not
holding a space->latch. Deadlocks are possible due to
latching order violation when UNIV_DEBUG is defined while
UNIV_SYNC_DEBUG is not. */
if (!sync_thread_levels_contains(SYNC_FSP))
# endif /* UNIV_SYNC_DEBUG */
for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) {
if (i == 1 || lock_rec_get_nth_bit(lock, i)) {
......
......@@ -957,13 +957,63 @@ sync_thread_levels_contain(
return(FALSE);
}
/******************************************************************//**
Checks if the level array for the current thread contains a
mutex or rw-latch at the specified level.
@return a matching latch, or NULL if not found */
UNIV_INTERN
void*
sync_thread_levels_contains(
/*========================*/
ulint level) /*!< in: latching order level
(SYNC_DICT, ...)*/
{
sync_level_t* arr;
sync_thread_t* thread_slot;
sync_level_t* slot;
ulint i;
if (!sync_order_checks_on) {
return(NULL);
}
mutex_enter(&sync_thread_mutex);
thread_slot = sync_thread_level_arrays_find_slot();
if (thread_slot == NULL) {
mutex_exit(&sync_thread_mutex);
return(NULL);
}
arr = thread_slot->levels;
for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
slot = sync_thread_levels_get_nth(arr, i);
if (slot->latch != NULL && slot->level == level) {
mutex_exit(&sync_thread_mutex);
return(slot->latch);
}
}
mutex_exit(&sync_thread_mutex);
return(NULL);
}
/******************************************************************//**
Checks that the level array for the current thread is empty.
@return TRUE if empty except the exceptions specified below */
@return a latch, or NULL if empty except the exceptions specified below */
UNIV_INTERN
ibool
sync_thread_levels_empty_gen(
/*=========================*/
void*
sync_thread_levels_nonempty_gen(
/*============================*/
ibool dict_mutex_allowed) /*!< in: TRUE if dictionary mutex is
allowed to be owned by the thread,
also purge_is_running mutex is
......@@ -976,7 +1026,7 @@ sync_thread_levels_empty_gen(
if (!sync_order_checks_on) {
return(TRUE);
return(NULL);
}
mutex_enter(&sync_thread_mutex);
......@@ -987,7 +1037,7 @@ sync_thread_levels_empty_gen(
mutex_exit(&sync_thread_mutex);
return(TRUE);
return(NULL);
}
arr = thread_slot->levels;
......@@ -1004,13 +1054,13 @@ sync_thread_levels_empty_gen(
mutex_exit(&sync_thread_mutex);
ut_error;
return(FALSE);
return(slot->latch);
}
}
mutex_exit(&sync_thread_mutex);
return(TRUE);
return(NULL);
}
/******************************************************************//**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment