summaryrefslogtreecommitdiff
path: root/storage/xtradb/buf
diff options
context:
space:
mode:
authorJan Lindström <jplindst@mariadb.org>2014-02-28 08:53:09 +0200
committerJan Lindström <jplindst@mariadb.org>2014-02-28 08:53:09 +0200
commitc88a0d48c6624466d058282bf7e2e8279660564e (patch)
tree96f0a63360e5d7b69920815c3e66b8a1b944c421 /storage/xtradb/buf
parentb620e7368f05af52f3fa1a759bc446140baf7b56 (diff)
downloadmariadb-git-c88a0d48c6624466d058282bf7e2e8279660564e.tar.gz
Temporal fix for flush thread hang.
Added option to disable multi-threaded flush with innodb_use_mtflush = 0 option, by default multi-threaded flush is used. Updated innochecksum tool, still it does not support new checksums.
Diffstat (limited to 'storage/xtradb/buf')
-rw-r--r--storage/xtradb/buf/buf0mtflu.cc34
1 files changed, 27 insertions, 7 deletions
diff --git a/storage/xtradb/buf/buf0mtflu.cc b/storage/xtradb/buf/buf0mtflu.cc
index eeb9bf36c86..f7da4c1c7a9 100644
--- a/storage/xtradb/buf/buf0mtflu.cc
+++ b/storage/xtradb/buf/buf0mtflu.cc
@@ -134,6 +134,7 @@ typedef struct thread_sync
static int mtflush_work_initialized = -1;
static os_fast_mutex_t mtflush_mtx;
+static os_fast_mutex_t mtflush_mtx_wait;
static thread_sync_t* mtflush_ctx=NULL;
/******************************************************************//**
@@ -182,7 +183,9 @@ buf_mtflu_flush_pool_instance(
pools based on the assumption that it will
help in the retry which will follow the
failure. */
+#ifdef UNIV_DEBUG
fprintf(stderr, "InnoDB: Note: buf flush start failed there is already active flush for this buffer pool.\n");
+#endif
return 0;
}
@@ -228,12 +231,16 @@ mtflush_service_io(
mtflush_io->wt_status = WTHR_SIG_WAITING;
+ /* TODO: Temporal fix for the hang bug. This needs a real fix. */
+ os_fast_mutex_lock(&mtflush_mtx_wait);
work_item = (wrk_t *)ib_wqueue_nowait(mtflush_io->wq);
if (work_item == NULL) {
work_item = (wrk_t *)ib_wqueue_timedwait(mtflush_io->wq, MT_WAIT_IN_USECS);
}
+ os_fast_mutex_unlock(&mtflush_mtx_wait);
+
if (work_item) {
mtflush_io->wt_status = WTHR_RUNNING;
} else {
@@ -242,6 +249,10 @@ mtflush_service_io(
return;
}
+ if (work_item->wi_status != WRK_ITEM_EXIT) {
+ work_item->wi_status = WRK_ITEM_SET;
+ }
+
work_item->id_usr = os_thread_get_curr_id();
/* This works as a producer/consumer model, where in tasks are
@@ -258,7 +269,7 @@ mtflush_service_io(
work_item->wi_status = WRK_ITEM_EXIT;
ib_wqueue_add(mtflush_io->wr_cq, work_item, work_item->wheap);
mtflush_io->wt_status = WTHR_KILL_IT;
- return;
+ break;
case MT_WRK_WRITE:
ut_a(work_item->wi_status == WRK_ITEM_SET);
@@ -278,9 +289,9 @@ mtflush_service_io(
default:
/* None other than Write/Read handling planned */
ut_a(0);
+ break;
}
- mtflush_io->wt_status = WTHR_NO_WORK;
}
/******************************************************************//**
@@ -302,13 +313,16 @@ DECLARE_THREAD(mtflush_io_thread)(
#endif
while (TRUE) {
+#ifdef UNIV_DEBUG
fprintf(stderr, "InnoDB: Note. Thread %lu work queue len %lu return queue len %lu\n",
os_thread_get_curr_id(),
ib_wqueue_len(mtflush_io->wq),
ib_wqueue_len(mtflush_io->wr_cq));
+#endif /* UNIV_DEBUG */
mtflush_service_io(mtflush_io);
+#ifdef UNIV_DEBUG
if (mtflush_io->wt_status == WTHR_NO_WORK) {
n_timeout++;
@@ -323,6 +337,7 @@ DECLARE_THREAD(mtflush_io_thread)(
} else {
n_timeout = 0;
}
+#endif /* UNIV_DEBUG */
if (mtflush_io->wt_status == WTHR_KILL_IT) {
break;
@@ -405,6 +420,7 @@ buf_mtflu_io_thread_exit(void)
ib_wqueue_free(mtflush_io->rd_cq);
os_fast_mutex_free(&mtflush_mtx);
+ os_fast_mutex_free(&mtflush_mtx_wait);
/* Free heap */
mem_heap_free(mtflush_io->wheap);
@@ -426,6 +442,7 @@ buf_mtflu_handler_init(
ib_wqueue_t* mtflush_read_comp_queue;
os_fast_mutex_init(PFS_NOT_INSTRUMENTED, &mtflush_mtx);
+ os_fast_mutex_init(PFS_NOT_INSTRUMENTED, &mtflush_mtx_wait);
/* Create heap, work queue, write completion queue, read
completion queue for multi-threaded flush, and init
@@ -491,16 +508,15 @@ buf_mtflu_flush_work_items(
node items areallocated */
work_heap = mem_heap_create(0);
work_item = (wrk_t*)mem_heap_alloc(work_heap, sizeof(wrk_t)*buf_pool_inst);
+ memset(work_item, 0, sizeof(wrk_t)*buf_pool_inst);
for(i=0;i<buf_pool_inst; i++) {
work_item[i].tsk = MT_WRK_WRITE;
- work_item[i].rd.page_pool = NULL;
work_item[i].wr.buf_pool = buf_pool_from_array(i);
work_item[i].wr.flush_type = flush_type;
work_item[i].wr.min = min_n;
work_item[i].wr.lsn_limit = lsn_limit;
- work_item[i].id_usr = -1;
- work_item[i].wi_status = WRK_ITEM_SET;
+ work_item[i].wi_status = WRK_ITEM_UNSET;
work_item[i].wheap = work_heap;
ib_wqueue_add(mtflush_ctx->wq,
@@ -516,14 +532,18 @@ buf_mtflu_flush_work_items(
if (done_wi != NULL) {
per_pool_pages_flushed[i] = done_wi->n_flushed;
- if((int)done_wi->id_usr == -1 &&
- done_wi->wi_status == WRK_ITEM_SET ) {
+#ifdef UNIV_DEBUG
+ /* TODO: Temporal fix for hang. This is really a bug. */
+ if((int)done_wi->id_usr == 0 &&
+ (done_wi->wi_status == WRK_ITEM_SET ||
+ done_wi->wi_status == WRK_ITEM_UNSET)) {
fprintf(stderr,
"**Set/Unused work_item[%lu] flush_type=%d\n",
i,
done_wi->wr.flush_type);
ut_a(0);
}
+#endif
n_flushed+= done_wi->n_flushed;
i++;