summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jplindst@mariadb.org>2014-07-25 10:30:16 +0300
committerJan Lindström <jplindst@mariadb.org>2014-07-25 10:30:16 +0300
commita3acd725704c99dcb8a7a0d0c7c47e43c33a6cd7 (patch)
treeb980bdd63882167d23c4e03efff065af615cd88a
parent6192f0bffa798c01acc85db9f427ed02234aead4 (diff)
downloadmariadb-git-a3acd725704c99dcb8a7a0d0c7c47e43c33a6cd7.tar.gz
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.
-rw-r--r--mysql-test/include/mtr_warnings.sql1
-rw-r--r--storage/innobase/btr/btr0cur.cc1
-rw-r--r--storage/innobase/buf/buf0lru.cc18
-rw-r--r--storage/innobase/page/page0zip.cc4
-rw-r--r--storage/innobase/sync/sync0arr.cc120
-rw-r--r--storage/xtradb/buf/buf0lru.cc22
-rw-r--r--storage/xtradb/page/page0zip.cc4
-rw-r--r--storage/xtradb/sync/sync0arr.cc120
8 files changed, 223 insertions, 67 deletions
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index 0ad1079cd92..9d97d23897c 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -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
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 1d2f313a07c..a165c9c47f4 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -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(
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index ec30c063a72..64409e1993d 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -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"
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 3b80236eb47..4b19a35925e 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -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,
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc
index 8e1b8180eb1..82eac41cef9 100644
--- a/storage/innobase/sync/sync0arr.cc
+++ b/storage/innobase/sync/sync0arr.cc
@@ -182,6 +182,33 @@ sync_array_get_nth_cell(
}
/******************************************************************//**
+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
void
@@ -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);
}
}
}
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index d0904f4b8ad..3449982b1dd 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -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);
diff --git a/storage/xtradb/page/page0zip.cc b/storage/xtradb/page/page0zip.cc
index 923684964ae..c4c8354aa1e 100644
--- a/storage/xtradb/page/page0zip.cc
+++ b/storage/xtradb/page/page0zip.cc
@@ -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,
diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc
index 880f47237d6..764d57b2cad 100644
--- a/storage/xtradb/sync/sync0arr.cc
+++ b/storage/xtradb/sync/sync0arr.cc
@@ -184,6 +184,33 @@ sync_array_get_nth_cell(
}
/******************************************************************//**
+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
void
@@ -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);
}
}
}