Skip to content

Commit

Permalink
Fix InnoDB: Assertion failure in thread 2868898624 in file buf0lru.c …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
Jan Lindström committed Jul 26, 2014
1 parent be667b8 commit 8ae2674
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 5 deletions.
32 changes: 32 additions & 0 deletions storage/xtradb/buf/buf0buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -2628,13 +2633,24 @@ 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);
}

if (UNIV_UNLIKELY(block->page.is_corrupt &&
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);
}

Expand Down Expand Up @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down
19 changes: 17 additions & 2 deletions storage/xtradb/buf/buf0lru.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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;
}
}

Expand Down Expand Up @@ -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);

Expand All @@ -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) {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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) {
Expand All @@ -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
Expand All @@ -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);
}

Expand Down
18 changes: 15 additions & 3 deletions storage/xtradb/sync/sync0arr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
Expand All @@ -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;
}
}
}
Expand Down

0 comments on commit 8ae2674

Please sign in to comment.