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