Commit a3acd725 authored by Jan Lindström's avatar Jan Lindström

Merge InnoDB fixes from 5.5 revisions 4229, 4230, 4233, 4237 and 4238 i.e.

4229: MDEV-5670: Assertion failure in file buf0lru.c line 2355
      Add more status information if repeatable.

4230: MDEV-5673: Crash while parallel dropping multiple tables under heavy load
      Improve long semaphore wait output to include all semaphore waits
      and try to find out if there is a sequence of waiters.

4233: Fix compiler errors on product build.

4237: Fix too agressive long semaphore wait output and add guard against introducing
      compression failures on insert buffer.

4238: Fix test failure caused by simulated compression failure on
      IBUF_DUMMY table.
parent 6192f0bf
......@@ -159,6 +159,7 @@ INSERT INTO global_suppressions VALUES
("InnoDB: Error: in ALTER TABLE `test`.`t[123]`"),
("InnoDB: Error: in RENAME TABLE table `test`.`t1`"),
("InnoDB: Error: table `test`.`t[123]` .*does not exist in the InnoDB internal"),
("InnoDB: Warning: semaphore wait:"),
/*
BUG#32080 - Excessive warnings on Solaris: setrlimit could not
......
......@@ -271,6 +271,7 @@ btr_cur_latch_leaves(
case BTR_MODIFY_TREE:
/* x-latch also brothers from left to right */
left_page_no = btr_page_get_prev(page, mtr);
mode = latch_mode;
if (left_page_no != FIL_NULL) {
get_block = btr_block_get(
......
......@@ -2263,6 +2263,24 @@ buf_LRU_block_remove_hashed(
" in the hash table\n",
(ulong) bpage->space,
(ulong) bpage->offset);
#ifdef UNIV_DEBUG
fprintf(stderr,
"InnoDB: in_page_hash %lu in_zip_hash %lu\n"
" in_free_list %lu in_flush_list %lu in_LRU_list %lu\n"
" zip.data %p zip_size %lu page_state %d\n",
bpage->in_page_hash, bpage->in_zip_hash,
bpage->in_free_list, bpage->in_flush_list,
bpage->in_LRU_list, bpage->zip.data,
buf_page_get_zip_size(bpage),
buf_page_get_state(bpage));
#else
fprintf(stderr,
"InnoDB: zip.data %p zip_size %lu page_state %d\n",
bpage->zip.data,
buf_page_get_zip_size(bpage),
buf_page_get_state(bpage));
#endif
if (hashed_bpage) {
fprintf(stderr,
"InnoDB: In hash table we find block"
......
......@@ -1314,8 +1314,10 @@ page_zip_compress(
records. */
if (srv_simulate_comp_failures
&& !dict_index_is_ibuf(index)
&& page_get_n_recs(page) >= 2
&& ((ulint)(rand() % 100) < srv_simulate_comp_failures)) {
&& ((ulint)(rand() % 100) < srv_simulate_comp_failures)
&& strcasecmp(index->table_name, "IBUF_DUMMY") != 0) {
#ifdef UNIV_DEBUG
fprintf(stderr,
......
......@@ -181,6 +181,33 @@ sync_array_get_nth_cell(
return(arr->array + n);
}
/******************************************************************//**
Looks for a cell with the given thread id.
@return pointer to cell or NULL if not found */
static
sync_cell_t*
sync_array_find_thread(
/*===================*/
sync_array_t* arr, /*!< in: wait array */
os_thread_id_t thread) /*!< in: thread id */
{
ulint i;
sync_cell_t* cell;
for (i = 0; i < arr->n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
if (cell->wait_object != NULL
&& os_thread_eq(cell->thread, thread)) {
return(cell); /* Found */
}
}
return(NULL); /* Not found */
}
/******************************************************************//**
Reserves the mutex semaphore protecting a sync array. */
static
......@@ -432,8 +459,10 @@ static
void
sync_array_cell_print(
/*==================*/
FILE* file, /*!< in: file where to print */
sync_cell_t* cell) /*!< in: sync cell */
FILE* file, /*!< in: file where to print */
sync_cell_t* cell, /*!< in: sync cell */
os_thread_id_t* reserver) /*!< out: write reserver or
0 */
{
ib_mutex_t* mutex;
rw_lock_t* rwlock;
......@@ -494,6 +523,7 @@ sync_array_cell_print(
writer == RW_LOCK_EX
? " exclusive\n"
: " wait exclusive\n");
*reserver = rwlock->writer_thread;
}
fprintf(file,
......@@ -519,32 +549,6 @@ sync_array_cell_print(
}
#ifdef UNIV_SYNC_DEBUG
/******************************************************************//**
Looks for a cell with the given thread id.
@return pointer to cell or NULL if not found */
static
sync_cell_t*
sync_array_find_thread(
/*===================*/
sync_array_t* arr, /*!< in: wait array */
os_thread_id_t thread) /*!< in: thread id */
{
ulint i;
sync_cell_t* cell;
for (i = 0; i < arr->n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
if (cell->wait_object != NULL
&& os_thread_eq(cell->thread, thread)) {
return(cell); /* Found */
}
}
return(NULL); /* Not found */
}
/******************************************************************//**
Recursion step for deadlock detection.
......@@ -606,6 +610,7 @@ sync_array_detect_deadlock(
os_thread_id_t thread;
ibool ret;
rw_lock_debug_t*debug;
os_thread_id_t reserver=0;
ut_a(arr);
ut_a(start);
......@@ -641,10 +646,10 @@ sync_array_detect_deadlock(
depth);
if (ret) {
fprintf(stderr,
"Mutex %p owned by thread %lu file %s line %lu\n",
"Mutex %p owned by thread %lu file %s line %lu\n",
mutex, (ulong) os_thread_pf(mutex->thread_id),
mutex->file_name, (ulong) mutex->line);
sync_array_cell_print(stderr, cell);
sync_array_cell_print(stderr, cell, &reserver);
return(TRUE);
}
......@@ -682,7 +687,7 @@ sync_array_detect_deadlock(
print:
fprintf(stderr, "rw-lock %p ",
(void*) lock);
sync_array_cell_print(stderr, cell);
sync_array_cell_print(stderr, cell, &reserver);
rw_lock_debug_print(stderr, debug);
return(TRUE);
}
......@@ -925,6 +930,7 @@ sync_array_print_long_waits_low(
double diff;
sync_cell_t* cell;
void* wait_object;
os_thread_id_t reserver=0;
cell = sync_array_get_nth_cell(arr, i);
......@@ -940,7 +946,7 @@ sync_array_print_long_waits_low(
if (diff > SYNC_ARRAY_TIMEOUT) {
fputs("InnoDB: Warning: a long semaphore wait:\n",
stderr);
sync_array_cell_print(stderr, cell);
sync_array_cell_print(stderr, cell, &reserver);
*noticed = TRUE;
}
......@@ -955,6 +961,53 @@ sync_array_print_long_waits_low(
}
}
/* We found a long semaphore wait, wait all threads that are
waiting for a semaphore. */
if (*noticed) {
for (i = 0; i < arr->n_cells; i++) {
void* wait_object;
os_thread_id_t reserver=0;
sync_cell_t* cell;
ulint loop = 0;
cell = sync_array_get_nth_cell(arr, i);
wait_object = cell->wait_object;
if (wait_object == NULL || !cell->waiting) {
continue;
}
fputs("InnoDB: Warning: semaphore wait:\n",
stderr);
sync_array_cell_print(stderr, cell, &reserver);
/* Try to output cell information for writer recursive way */
while (reserver != 0) {
sync_cell_t* reserver_wait;
reserver_wait = sync_array_find_thread(arr, reserver);
if (reserver_wait &&
reserver_wait->wait_object != NULL &&
reserver_wait->waiting) {
fputs("InnoDB: Warning: Writer thread is waiting this semaphore:\n",
stderr);
sync_array_cell_print(stderr, reserver_wait, &reserver);
} else {
reserver = 0;
}
/* This is protection against loop */
if (loop > 100) {
fputs("InnoDB: Warning: Too many waiting threads.\n", stderr);
break;
}
}
}
}
#undef SYNC_ARRAY_TIMEOUT
return(fatal);
......@@ -1034,6 +1087,7 @@ sync_array_print_info_low(
{
ulint i;
ulint count = 0;
os_thread_id_t r = 0;
fprintf(file,
"OS WAIT ARRAY INFO: reservation count %ld\n",
......@@ -1046,7 +1100,7 @@ sync_array_print_info_low(
if (cell->wait_object != NULL) {
count++;
sync_array_cell_print(file, cell);
sync_array_cell_print(file, cell, &r);
}
}
}
......
......@@ -2429,6 +2429,25 @@ buf_LRU_block_remove_hashed(
" in the hash table\n",
(ulong) bpage->space,
(ulong) bpage->offset);
#ifdef UNIV_DEBUG
fprintf(stderr,
"InnoDB: in_page_hash %lu in_zip_hash %lu\n"
" in_free_list %lu in_flush_list %lu in_LRU_list %lu\n"
" zip.data %p zip_size %lu page_state %d\n",
bpage->in_page_hash, bpage->in_zip_hash,
bpage->in_free_list, bpage->in_flush_list,
bpage->in_LRU_list, bpage->zip.data,
buf_page_get_zip_size(bpage),
buf_page_get_state(bpage));
#else
fprintf(stderr,
"InnoDB: zip.data %p zip_size %lu page_state %d\n",
bpage->zip.data,
buf_page_get_zip_size(bpage),
buf_page_get_state(bpage));
#endif
if (hashed_bpage) {
fprintf(stderr,
"InnoDB: In hash table we find block"
......@@ -2439,6 +2458,9 @@ buf_LRU_block_remove_hashed(
(const void*) bpage);
}
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
ut_a(bpage->buf_fix_count == 0);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
mutex_exit(buf_page_get_mutex(bpage));
rw_lock_x_unlock(hash_lock);
......
......@@ -1319,8 +1319,10 @@ page_zip_compress(
records. */
if (srv_simulate_comp_failures
&& !dict_index_is_ibuf(index)
&& page_get_n_recs(page) >= 2
&& ((ulint)(rand() % 100) < srv_simulate_comp_failures)) {
&& ((ulint)(rand() % 100) < srv_simulate_comp_failures)
&& strcasecmp(index->table_name, "IBUF_DUMMY") != 0) {
#ifdef UNIV_DEBUG
fprintf(stderr,
......
......@@ -183,6 +183,33 @@ sync_array_get_nth_cell(
return(arr->array + n);
}
/******************************************************************//**
Looks for a cell with the given thread id.
@return pointer to cell or NULL if not found */
static
sync_cell_t*
sync_array_find_thread(
/*===================*/
sync_array_t* arr, /*!< in: wait array */
os_thread_id_t thread) /*!< in: thread id */
{
ulint i;
sync_cell_t* cell;
for (i = 0; i < arr->n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
if (cell->wait_object != NULL
&& os_thread_eq(cell->thread, thread)) {
return(cell); /* Found */
}
}
return(NULL); /* Not found */
}
/******************************************************************//**
Reserves the mutex semaphore protecting a sync array. */
static
......@@ -442,8 +469,10 @@ static
void
sync_array_cell_print(
/*==================*/
FILE* file, /*!< in: file where to print */
sync_cell_t* cell) /*!< in: sync cell */
FILE* file, /*!< in: file where to print */
sync_cell_t* cell, /*!< in: sync cell */
os_thread_id_t* reserver) /*!< out: write reserver or
0 */
{
ib_mutex_t* mutex;
ib_prio_mutex_t* prio_mutex;
......@@ -549,6 +578,8 @@ sync_array_cell_print(
writer == RW_LOCK_EX
? " exclusive\n"
: " wait exclusive\n");
*reserver = rwlock->writer_thread;
}
fprintf(file,
......@@ -594,32 +625,6 @@ sync_array_cell_print(
}
#ifdef UNIV_SYNC_DEBUG
/******************************************************************//**
Looks for a cell with the given thread id.
@return pointer to cell or NULL if not found */
static
sync_cell_t*
sync_array_find_thread(
/*===================*/
sync_array_t* arr, /*!< in: wait array */
os_thread_id_t thread) /*!< in: thread id */
{
ulint i;
sync_cell_t* cell;
for (i = 0; i < arr->n_cells; i++) {
cell = sync_array_get_nth_cell(arr, i);
if (cell->wait_object != NULL
&& os_thread_eq(cell->thread, thread)) {
return(cell); /* Found */
}
}
return(NULL); /* Not found */
}
/******************************************************************//**
Recursion step for deadlock detection.
......@@ -681,6 +686,7 @@ sync_array_detect_deadlock(
os_thread_id_t thread;
ibool ret;
rw_lock_debug_t*debug;
os_thread_id_t r = 0;
ut_a(arr);
ut_a(start);
......@@ -725,7 +731,7 @@ sync_array_detect_deadlock(
"Mutex %p owned by thread %lu file %s line %lu\n",
mutex, (ulong) os_thread_pf(mutex->thread_id),
mutex->file_name, (ulong) mutex->line);
sync_array_cell_print(stderr, cell);
sync_array_cell_print(stderr, cell, &r);
return(TRUE);
}
......@@ -764,7 +770,7 @@ sync_array_detect_deadlock(
print:
fprintf(stderr, "rw-lock %p ",
(void*) lock);
sync_array_cell_print(stderr, cell);
sync_array_cell_print(stderr, cell, &r);
rw_lock_debug_print(stderr, debug);
return(TRUE);
}
......@@ -1019,6 +1025,7 @@ sync_array_print_long_waits_low(
double diff;
sync_cell_t* cell;
void* wait_object;
os_thread_id_t reserver=0;
cell = sync_array_get_nth_cell(arr, i);
......@@ -1034,7 +1041,7 @@ sync_array_print_long_waits_low(
if (diff > SYNC_ARRAY_TIMEOUT) {
fputs("InnoDB: Warning: a long semaphore wait:\n",
stderr);
sync_array_cell_print(stderr, cell);
sync_array_cell_print(stderr, cell, &reserver);
*noticed = TRUE;
}
......@@ -1049,6 +1056,54 @@ sync_array_print_long_waits_low(
}
}
/* We found a long semaphore wait, wait all threads that are
waiting for a semaphore. */
if (*noticed) {
for (i = 0; i < arr->n_cells; i++) {
void* wait_object;
sync_cell_t* cell;
os_thread_id_t reserver=0;
ulint loop=0;
cell = sync_array_get_nth_cell(arr, i);
wait_object = cell->wait_object;
if (wait_object == NULL || !cell->waiting) {
continue;
}
fputs("InnoDB: Warning: semaphore wait:\n",
stderr);
sync_array_cell_print(stderr, cell, &reserver);
/* Try to output cell information for writer recursive way */
while (reserver != 0) {
sync_cell_t* reserver_wait;
reserver_wait = sync_array_find_thread(arr, reserver);
if (reserver_wait &&
reserver_wait->wait_object != NULL &&
reserver_wait->waiting) {
fputs("InnoDB: Warning: Writer thread is waiting this semaphore:\n",
stderr);
sync_array_cell_print(stderr, reserver_wait, &reserver);
loop++;
} else {
reserver = 0;
}
/* This is protection against loop */
if (loop > 100) {
fputs("InnoDB: Warning: Too many waiting threads.\n", stderr);
break;
}
}
}
}
#undef SYNC_ARRAY_TIMEOUT
return(fatal);
......@@ -1135,12 +1190,13 @@ sync_array_print_info_low(
for (i = 0; count < arr->n_reserved; ++i) {
sync_cell_t* cell;
os_thread_id_t r = 0;
cell = sync_array_get_nth_cell(arr, i);
if (cell->wait_object != NULL) {
count++;
sync_array_cell_print(file, cell);
sync_array_cell_print(file, cell, &r);
}
}
}
......
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