mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
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.
This commit is contained in:
parent
fb454deccd
commit
cd7d82f2e3
3 changed files with 82 additions and 14 deletions
|
@ -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)) {
|
||||
|
|
|
@ -958,12 +958,62 @@ sync_thread_levels_contain(
|
|||
}
|
||||
|
||||
/******************************************************************//**
|
||||
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, ...)*/
|
||||
{
|
||||
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 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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
|
|
Loading…
Reference in a new issue