Commit 8ae26740 authored by Jan Lindström's avatar Jan Lindström

Fix InnoDB: Assertion failure in thread 2868898624 in file buf0lru.c line 1000

InnoDB: Failing assertion: mutex_own(&buf_pool->LRU_list_mutex)

and

InnoDB: Assertion failure in thread 2868898624 in file buf0lru.c line 1077
InnoDB: Failing assertion: mutex_own(&buf_pool->LRU_list_mutex)

Analysis: Function buf_LRU_free_block might release LRU_list_mutex on
same cases to avoid mutex order problems, we need to take it back 
before accessing list. 
parent be667b8c
......@@ -2566,6 +2566,11 @@ buf_page_get_gen(
|| mode == BUF_PEEK_IF_IN_POOL
|| mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
if (have_LRU_mutex) {
mutex_exit(&buf_pool->LRU_list_mutex);
have_LRU_mutex = FALSE;
}
return(NULL);
}
......@@ -2628,6 +2633,11 @@ buf_page_get_gen(
//buf_pool_mutex_exit(buf_pool);
mutex_exit(block_mutex);
if (have_LRU_mutex) {
mutex_exit(&buf_pool->LRU_list_mutex);
have_LRU_mutex = FALSE;
}
return(NULL);
}
......@@ -2635,6 +2645,12 @@ buf_page_get_gen(
srv_pass_corrupt_table <= 1)) {
mutex_exit(block_mutex);
if (have_LRU_mutex) {
mutex_exit(&buf_pool->LRU_list_mutex);
have_LRU_mutex = FALSE;
}
return(NULL);
}
......@@ -2843,6 +2859,11 @@ buf_page_get_gen(
insert buffer (change buffer) as much as possible. */
ulint page_no = buf_block_get_page_no(block);
if (!have_LRU_mutex) {
mutex_enter(&buf_pool->LRU_list_mutex);
have_LRU_mutex = TRUE;
}
if (buf_LRU_free_block(&block->page, (void *)block_mutex, TRUE, &have_LRU_mutex)) {
mutex_exit(block_mutex);
if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
......@@ -2867,6 +2888,12 @@ buf_page_get_gen(
fprintf(stderr,
"innodb_change_buffering_debug evict %u %u\n",
(unsigned) space, (unsigned) offset);
if (have_LRU_mutex){
mutex_exit(&buf_pool->LRU_list_mutex);
have_LRU_mutex = FALSE;
}
return(NULL);
} else if (UNIV_UNLIKELY(buf_block_get_state(block)
!= BUF_BLOCK_FILE_PAGE
......@@ -2995,6 +3022,11 @@ buf_page_get_gen(
_increment_page_get_statistics(block, trx);
}
if (have_LRU_mutex) {
mutex_exit(&buf_pool->LRU_list_mutex);
have_LRU_mutex = FALSE;
}
return(block);
}
......
......@@ -1013,6 +1013,10 @@ buf_LRU_free_from_unzip_LRU_list(
*have_LRU_mutex = FALSE;
}
return(TRUE);
} else if (!*have_LRU_mutex) {
*have_LRU_mutex = TRUE;
mutex_enter(&buf_pool->LRU_list_mutex);
taken_LRU_mutex = TRUE;
}
}
......@@ -1097,6 +1101,10 @@ buf_LRU_free_from_common_LRU_list(
}
return(TRUE);
} else if (!*have_LRU_mutex) {
mutex_enter(&buf_pool->LRU_list_mutex);
taken_LRU_mutex = TRUE;
*have_LRU_mutex = TRUE;
}
}
......@@ -1955,9 +1963,10 @@ buf_LRU_free_block(
mutex_exit((mutex_t*)block_mutex);
if (!*have_LRU_mutex) {
mutex_enter(&buf_pool->LRU_list_mutex); /* optimistic */
mutex_enter(&buf_pool->LRU_list_mutex);
*have_LRU_mutex = TRUE;
}
rw_lock_x_lock(&buf_pool->page_hash_latch);
mutex_enter((mutex_t*)block_mutex);
......@@ -1968,10 +1977,12 @@ buf_LRU_free_block(
if (b) {
buf_page_free_descriptor(b);
}
if (*have_LRU_mutex) {
mutex_exit(&buf_pool->LRU_list_mutex);
*have_LRU_mutex = FALSE;
}
rw_lock_x_unlock(&buf_pool->page_hash_latch);
return(FALSE);
} else if (zip || !bpage->zip.data) {
......@@ -2106,10 +2117,12 @@ buf_LRU_free_block(
}
//buf_pool_mutex_exit(buf_pool);
if (*have_LRU_mutex) {
mutex_exit(&buf_pool->LRU_list_mutex);
*have_LRU_mutex = FALSE;
}
rw_lock_x_unlock(&buf_pool->page_hash_latch);
mutex_exit((mutex_t*)block_mutex);
......@@ -2143,10 +2156,12 @@ buf_LRU_free_block(
}
//buf_pool_mutex_enter(buf_pool);
if (!*have_LRU_mutex) {
mutex_enter(&buf_pool->LRU_list_mutex);
*have_LRU_mutex = TRUE;
}
mutex_enter((mutex_t*)block_mutex);
if (b) {
......@@ -2161,7 +2176,6 @@ buf_LRU_free_block(
mutex_exit(&buf_pool->LRU_list_mutex);
*have_LRU_mutex = FALSE;
}
} else {
/* The block_mutex should have been released by
buf_LRU_block_remove_hashed_page() when it returns
......@@ -2173,6 +2187,7 @@ buf_LRU_free_block(
mutex_exit(&buf_pool->LRU_list_mutex);
*have_LRU_mutex = FALSE;
}
rw_lock_x_unlock(&buf_pool->page_hash_latch);
}
......
......@@ -1013,7 +1013,8 @@ sync_array_print_long_waits(
if (noticed) {
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
void* wait_object;
os_thread_id_t reserver=0;
os_thread_id_t reserver=ULINT_UNDEFINED;
ulint loop=0;
cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
......@@ -1030,7 +1031,7 @@ sync_array_print_long_waits(
noticed = TRUE;
/* Try to output cell information for writer recursive way */
while (reserver != 0) {
while (reserver != ULINT_UNDEFINED) {
sync_cell_t* reserver_wait;
reserver_wait = sync_array_find_thread(sync_primary_wait_array, reserver);
......@@ -1040,9 +1041,20 @@ sync_array_print_long_waits(
reserver_wait->waiting) {
fputs("InnoDB: Warning: Writer thread is waiting this semaphore:\n",
stderr);
reserver = ULINT_UNDEFINED;
sync_array_cell_print(stderr, reserver_wait, &reserver);
loop++;
if (reserver_wait->thread == reserver) {
reserver = ULINT_UNDEFINED;
}
} else {
reserver = 0;
reserver = ULINT_UNDEFINED;
}
/* This is protection against loop */
if (loop > 100) {
fputs("InnoDB: Warning: Too many waiting threads.\n", stderr);
break;
}
}
}
......
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