diff options
author | Jan Lindström <jplindst@mariadb.org> | 2014-02-28 08:53:09 +0200 |
---|---|---|
committer | Jan Lindström <jplindst@mariadb.org> | 2014-02-28 08:53:09 +0200 |
commit | c88a0d48c6624466d058282bf7e2e8279660564e (patch) | |
tree | 96f0a63360e5d7b69920815c3e66b8a1b944c421 /storage/xtradb/buf | |
parent | b620e7368f05af52f3fa1a759bc446140baf7b56 (diff) | |
download | mariadb-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.cc | 34 |
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++; |