mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
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.
This commit is contained in:
@@ -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
|
||||
@@ -433,7 +460,9 @@ void
|
||||
sync_array_cell_print(
|
||||
/*==================*/
|
||||
FILE* file, /*!< in: file where to print */
|
||||
sync_cell_t* cell) /*!< in: sync cell */
|
||||
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);
|
||||
@@ -644,7 +649,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, &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
|
||||
@@ -443,7 +470,9 @@ void
|
||||
sync_array_cell_print(
|
||||
/*==================*/
|
||||
FILE* file, /*!< in: file where to print */
|
||||
sync_cell_t* cell) /*!< in: sync cell */
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user