diff options
Diffstat (limited to 'storage/innobase/buf/buf0mtflu.cc')
-rw-r--r-- | storage/innobase/buf/buf0mtflu.cc | 736 |
1 files changed, 0 insertions, 736 deletions
diff --git a/storage/innobase/buf/buf0mtflu.cc b/storage/innobase/buf/buf0mtflu.cc deleted file mode 100644 index aae90e48168..00000000000 --- a/storage/innobase/buf/buf0mtflu.cc +++ /dev/null @@ -1,736 +0,0 @@ -/***************************************************************************** - -Copyright (C) 2013, 2014, Fusion-io. All Rights Reserved. -Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/******************************************************************//** -@file buf/buf0mtflu.cc -Multi-threaded flush method implementation - -Created 06/11/2013 Dhananjoy Das DDas@fusionio.com -Modified 12/12/2013 Jan Lindström jan.lindstrom@skysql.com -Modified 03/02/2014 Dhananjoy Das DDas@fusionio.com -Modified 06/02/2014 Jan Lindström jan.lindstrom@skysql.com -***********************************************************************/ - -#include "buf0buf.h" -#include "buf0flu.h" -#include "buf0mtflu.h" -#include "buf0checksum.h" -#include "srv0start.h" -#include "srv0srv.h" -#include "page0zip.h" -#include "ut0byte.h" -#include "ut0lst.h" -#include "page0page.h" -#include "fil0fil.h" -#include "buf0lru.h" -#include "buf0rea.h" -#include "ibuf0ibuf.h" -#include "log0log.h" -#include "os0file.h" -#include "trx0sys.h" -#include "srv0mon.h" -#include "mysql/plugin.h" -#include "mysql/service_thd_wait.h" -#include "fil0pagecompress.h" - -#define MT_COMP_WATER_MARK 50 -/** Time to wait for a message. */ -#define MT_WAIT_IN_USECS 5000000 - -/* Work item status */ -typedef enum wrk_status { - WRK_ITEM_UNSET=0, /*!< Work item is not set */ - WRK_ITEM_START=1, /*!< Processing of work item has started */ - WRK_ITEM_DONE=2, /*!< Processing is done usually set to - SUCCESS/FAILED */ - WRK_ITEM_SUCCESS=2, /*!< Work item successfully processed */ - WRK_ITEM_FAILED=3, /*!< Work item process failed */ - WRK_ITEM_EXIT=4, /*!< Exiting */ - WRK_ITEM_SET=5, /*!< Work item is set */ - WRK_ITEM_STATUS_UNDEFINED -} wrk_status_t; - -/* Work item task type */ -typedef enum mt_wrk_tsk { - MT_WRK_NONE=0, /*!< Exit queue-wait */ - MT_WRK_WRITE=1, /*!< Flush operation */ - MT_WRK_READ=2, /*!< Read operation */ - MT_WRK_UNDEFINED -} mt_wrk_tsk_t; - -/* Work thread status */ -typedef enum wthr_status { - WTHR_NOT_INIT=0, /*!< Work thread not initialized */ - WTHR_INITIALIZED=1, /*!< Work thread initialized */ - WTHR_SIG_WAITING=2, /*!< Work thread wating signal */ - WTHR_RUNNING=3, /*!< Work thread running */ - WTHR_NO_WORK=4, /*!< Work thread has no work */ - WTHR_KILL_IT=5, /*!< Work thread should exit */ - WTHR_STATUS_UNDEFINED -} wthr_status_t; - -/* Write work task */ -typedef struct wr_tsk { - buf_pool_t *buf_pool; /*!< buffer-pool instance */ - buf_flush_t flush_type; /*!< flush-type for buffer-pool - flush operation */ - ulint min; /*!< minimum number of pages - requested to be flushed */ - lsn_t lsn_limit; /*!< lsn limit for the buffer-pool - flush operation */ -} wr_tsk_t; - -/* Read work task */ -typedef struct rd_tsk { - buf_pool_t *page_pool; /*!< list of pages to decompress; */ -} rd_tsk_t; - -/* Work item */ -typedef struct wrk_itm -{ - mt_wrk_tsk_t tsk; /*!< Task type. Based on task-type - one of the entries wr_tsk/rd_tsk - will be used */ - wr_tsk_t wr; /*!< Flush page list */ - rd_tsk_t rd; /*!< Decompress page list */ - ulint n_flushed; /*!< Number of flushed pages */ - ulint n_evicted; /*!< Number of evicted pages */ - os_thread_id_t id_usr; /*!< Thread-id currently working */ - wrk_status_t wi_status; /*!< Work item status */ - mem_heap_t *wheap; /*!< Heap were to allocate memory - for queue nodes */ - mem_heap_t *rheap; -} wrk_t; - -struct thread_data_t -{ - os_thread_id_t wthread_id; /*!< Identifier */ - wthr_status_t wt_status; /*!< Worker thread status */ -}; - -/** Flush dirty pages when multi-threaded flush is used. */ -extern "C" UNIV_INTERN -os_thread_ret_t -DECLARE_THREAD(mtflush_io_thread)(void* arg); - -/** Thread syncronization data */ -struct thread_sync_t -{ - /** Constructor */ - thread_sync_t(ulint n_threads, mem_heap_t* wheap, mem_heap_t* rheap) : - thread_global_mtx(), n_threads(n_threads), - wq(ib_wqueue_create()), - wr_cq(ib_wqueue_create()), - rd_cq(ib_wqueue_create()), - wheap(wheap), rheap(rheap), gwt_status(), - thread_data(static_cast<thread_data_t*>( - mem_heap_zalloc(wheap, n_threads - * sizeof *thread_data))) - { - ut_a(wq); - ut_a(wr_cq); - ut_a(rd_cq); - ut_a(thread_data); - - mutex_create(LATCH_ID_MTFLUSH_THREAD_MUTEX, - &thread_global_mtx); - - /* Create threads for page-compression-flush */ - for(ulint i = 0; i < n_threads; i++) { - thread_data[i].wt_status = WTHR_INITIALIZED; - os_thread_create(mtflush_io_thread, this, - &thread_data[i].wthread_id); - } - } - - /** Destructor */ - ~thread_sync_t() - { - ut_a(ib_wqueue_is_empty(wq)); - ut_a(ib_wqueue_is_empty(wr_cq)); - ut_a(ib_wqueue_is_empty(rd_cq)); - - /* Free all queues */ - ib_wqueue_free(wq); - ib_wqueue_free(wr_cq); - ib_wqueue_free(rd_cq); - - mutex_free(&thread_global_mtx); - - mem_heap_free(rheap); - mem_heap_free(wheap); - } - - /* Global variables used by all threads */ - ib_mutex_t thread_global_mtx; /*!< Mutex used protecting below - variables */ - ulint n_threads; /*!< Number of threads */ - ib_wqueue_t *wq; /*!< Work Queue */ - ib_wqueue_t *wr_cq; /*!< Write Completion Queue */ - ib_wqueue_t *rd_cq; /*!< Read Completion Queue */ - mem_heap_t* wheap; /*!< Work heap where memory - is allocated */ - mem_heap_t* rheap; /*!< Work heap where memory - is allocated */ - wthr_status_t gwt_status; /*!< Global thread status */ - - /* Variables used by only one thread at a time */ - thread_data_t* thread_data; /*!< Thread specific data */ -}; - -static thread_sync_t* mtflush_ctx; -static ib_mutex_t mtflush_mtx; - -/******************************************************************//** -Return true if multi-threaded flush is initialized -@return true if initialized */ -bool -buf_mtflu_init_done(void) -/*=====================*/ -{ - return(mtflush_ctx != NULL); -} - -/******************************************************************//** -Fush buffer pool instance. -@return number of flushed pages, or 0 if error happened -*/ -static -ulint -buf_mtflu_flush_pool_instance( -/*==========================*/ - wrk_t *work_item) /*!< inout: work item to be flushed */ -{ - flush_counters_t n; - ut_a(work_item != NULL); - ut_a(work_item->wr.buf_pool != NULL); - - if (!buf_flush_start(work_item->wr.buf_pool, work_item->wr.flush_type)) { - /* We have two choices here. If lsn_limit was - specified then skipping an instance of buffer - pool means we cannot guarantee that all pages - up to lsn_limit has been flushed. We can - return right now with failure or we can try - to flush remaining buffer pools up to the - lsn_limit. We attempt to flush other buffer - pools based on the assumption that it will - help in the retry which will follow the - failure. */ -#ifdef UNIV_MTFLUSH_DEBUG - fprintf(stderr, "InnoDB: Note: buf flush start failed there is already active flush for this buffer pool.\n"); -#endif - return 0; - } - - memset(&n, 0, sizeof(flush_counters_t)); - - if (work_item->wr.flush_type == BUF_FLUSH_LRU) { - /* srv_LRU_scan_depth can be arbitrarily large value. - * We cap it with current LRU size. - */ - buf_pool_mutex_enter(work_item->wr.buf_pool); - work_item->wr.min = UT_LIST_GET_LEN(work_item->wr.buf_pool->LRU); - buf_pool_mutex_exit(work_item->wr.buf_pool); - work_item->wr.min = ut_min((ulint)srv_LRU_scan_depth,(ulint)work_item->wr.min); - } - - buf_flush_batch(work_item->wr.buf_pool, - work_item->wr.flush_type, - work_item->wr.min, - work_item->wr.lsn_limit, - &n); - - buf_flush_end(work_item->wr.buf_pool, work_item->wr.flush_type); - buf_flush_common(work_item->wr.flush_type, n.flushed); - work_item->n_flushed = n.flushed; - work_item->n_evicted = n.evicted; - - return work_item->n_flushed; -} - -/******************************************************************//** -Worker function to wait for work items and processing them and -sending reply back. -*/ -static -void -mtflush_service_io( -/*===============*/ - thread_sync_t* mtflush_io, /*!< inout: multi-threaded flush - syncronization data */ - thread_data_t* thread_data) /* Thread status data */ -{ - wrk_t *work_item = NULL; - ulint n_flushed=0; - - ut_a(mtflush_io != NULL); - ut_a(thread_data != NULL); - - thread_data->wt_status = WTHR_SIG_WAITING; - - work_item = (wrk_t *)ib_wqueue_nowait(mtflush_io->wq); - - if (work_item == NULL) { - work_item = (wrk_t *)ib_wqueue_wait(mtflush_io->wq); - } - - if (work_item) { - thread_data->wt_status = WTHR_RUNNING; - } else { - /* Thread did not get any work */ - thread_data->wt_status = WTHR_NO_WORK; - return; - } - - if (work_item->wi_status != WRK_ITEM_EXIT) { - work_item->wi_status = WRK_ITEM_SET; - } - -#ifdef UNIV_MTFLUSH_DEBUG - ut_a(work_item->id_usr == 0); -#endif - work_item->id_usr = os_thread_get_curr_id(); - - /* This works as a producer/consumer model, where in tasks are - * inserted into the work-queue (wq) and completions are based - * on the type of operations performed and as a result the WRITE/ - * compression/flush operation completions get posted to wr_cq. - * And READ/decompress operations completions get posted to rd_cq. - * in future we may have others. - */ - - switch(work_item->tsk) { - case MT_WRK_NONE: - ut_a(work_item->wi_status == WRK_ITEM_EXIT); - work_item->wi_status = WRK_ITEM_EXIT; - ib_wqueue_add(mtflush_io->wr_cq, work_item, work_item->rheap); - thread_data->wt_status = WTHR_KILL_IT; - break; - - case MT_WRK_WRITE: - ut_a(work_item->wi_status == WRK_ITEM_SET); - work_item->wi_status = WRK_ITEM_START; - /* Process work item */ - if (0 == (n_flushed = buf_mtflu_flush_pool_instance(work_item))) { - work_item->wi_status = WRK_ITEM_FAILED; - } - work_item->wi_status = WRK_ITEM_SUCCESS; - ib_wqueue_add(mtflush_io->wr_cq, work_item, work_item->rheap); - break; - - case MT_WRK_READ: - ut_a(0); - break; - - default: - /* None other than Write/Read handling planned */ - ut_a(0); - break; - } -} - -/** Flush dirty pages when multi-threaded flush is used. */ -extern "C" UNIV_INTERN -os_thread_ret_t -DECLARE_THREAD(mtflush_io_thread)(void* arg) -{ - thread_sync_t *mtflush_io = ((thread_sync_t *)arg); - thread_data_t *this_thread_data = NULL; - ulint i; - - /* Find correct slot for this thread */ - mutex_enter(&(mtflush_io->thread_global_mtx)); - for(i=0; i < mtflush_io->n_threads; i ++) { - if (mtflush_io->thread_data[i].wthread_id == os_thread_get_curr_id()) { - break; - } - } - - ut_a(i <= mtflush_io->n_threads); - this_thread_data = &mtflush_io->thread_data[i]; - mutex_exit(&(mtflush_io->thread_global_mtx)); - - while (TRUE) { - -#ifdef UNIV_MTFLUSH_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_MTFLUSH_DEBUG */ - - mtflush_service_io(mtflush_io, this_thread_data); - - - if (this_thread_data->wt_status == WTHR_KILL_IT) { - break; - } - } - - os_thread_exit(); - OS_THREAD_DUMMY_RETURN; -} - -/******************************************************************//** -Add exit work item to work queue to signal multi-threded flush -threads that they should exit. -*/ -void -buf_mtflu_io_thread_exit(void) -/*==========================*/ -{ - ulint i; - thread_sync_t* mtflush_io = mtflush_ctx; - wrk_t* work_item = NULL; - - ut_a(mtflush_io != NULL); - - /* Allocate work items for shutdown message */ - work_item = (wrk_t*)mem_heap_alloc(mtflush_io->wheap, sizeof(wrk_t)*srv_mtflush_threads); - - /* Confirm if the io-thread KILL is in progress, bailout */ - if (mtflush_io->gwt_status == WTHR_KILL_IT) { - return; - } - - mtflush_io->gwt_status = WTHR_KILL_IT; - - /* This lock is to safequard against timing bug: flush request take - this mutex before sending work items to be processed by flush - threads. Inside flush thread we assume that work queue contains only - a constant number of items. Thus, we may not install new work items - below before all previous ones are processed. This mutex is released - by flush request after all work items sent to flush threads have - been processed. Thus, we can get this mutex if and only if work - queue is empty. */ - - mutex_enter(&mtflush_mtx); - - /* Make sure the work queue is empty */ - ut_a(ib_wqueue_is_empty(mtflush_io->wq)); - - /* Send one exit work item/thread */ - for (i=0; i < (ulint)srv_mtflush_threads; i++) { - work_item[i].tsk = MT_WRK_NONE; - work_item[i].wi_status = WRK_ITEM_EXIT; - work_item[i].wheap = mtflush_io->wheap; - work_item[i].rheap = mtflush_io->rheap; - work_item[i].id_usr = 0; - - ib_wqueue_add(mtflush_io->wq, - (void *)&(work_item[i]), - mtflush_io->wheap); - } - - /* Requests sent */ - mutex_exit(&mtflush_mtx); - - /* Wait until all work items on a work queue are processed */ - while(!ib_wqueue_is_empty(mtflush_io->wq)) { - /* Wait */ - os_thread_sleep(MT_WAIT_IN_USECS); - } - - ut_a(ib_wqueue_is_empty(mtflush_io->wq)); - - /* Collect all work done items */ - for (i=0; i < (ulint)srv_mtflush_threads;) { - wrk_t* work_item = NULL; - - work_item = (wrk_t *)ib_wqueue_timedwait(mtflush_io->wr_cq, MT_WAIT_IN_USECS); - - /* If we receive reply to work item and it's status is exit, - thead has processed this message and existed */ - if (work_item && work_item->wi_status == WRK_ITEM_EXIT) { - i++; - } - } - - /* Wait about 1/2 sec to allow threads really exit */ - os_thread_sleep(MT_WAIT_IN_USECS); - - /* Make sure that work queue is empty */ - while(!ib_wqueue_is_empty(mtflush_io->wq)) - { - ib_wqueue_nowait(mtflush_io->wq); - } - - mtflush_ctx->~thread_sync_t(); - mtflush_ctx = NULL; - - mutex_free(&mtflush_mtx); -} - -/******************************************************************//** -Initialize multi-threaded flush thread syncronization data. -@return Initialized multi-threaded flush thread syncroniztion data. */ -void* -buf_mtflu_handler_init( -/*===================*/ - ulint n_threads, /*!< in: Number of threads to create */ - ulint wrk_cnt) /*!< in: Number of work items */ -{ - mem_heap_t* mtflush_heap; - mem_heap_t* mtflush_heap2; - - /* Create heap, work queue, write completion queue, read - completion queue for multi-threaded flush, and init - handler. */ - mtflush_heap = mem_heap_create(0); - ut_a(mtflush_heap != NULL); - mtflush_heap2 = mem_heap_create(0); - ut_a(mtflush_heap2 != NULL); - - mutex_create(LATCH_ID_MTFLUSH_MUTEX, &mtflush_mtx); - - mtflush_ctx = new (mem_heap_zalloc(mtflush_heap, sizeof *mtflush_ctx)) - thread_sync_t(n_threads, mtflush_heap, mtflush_heap2); - - return((void *)mtflush_ctx); -} - -/******************************************************************//** -Flush buffer pool instances. -@return number of pages flushed. */ -ulint -buf_mtflu_flush_work_items( -/*=======================*/ - ulint buf_pool_inst, /*!< in: Number of buffer pool instances */ - flush_counters_t *per_pool_cnt, /*!< out: Number of pages - flushed or evicted /instance */ - buf_flush_t flush_type, /*!< in: Type of flush */ - ulint min_n, /*!< in: Wished minimum number of - blocks to be flushed */ - lsn_t lsn_limit) /*!< in: All blocks whose - oldest_modification is smaller than - this should be flushed (if their - number does not exceed min_n) */ -{ - ulint n_flushed=0, i; - mem_heap_t* work_heap; - mem_heap_t* reply_heap; - wrk_t work_item[MTFLUSH_MAX_WORKER]; - - if (mtflush_ctx->gwt_status == WTHR_KILL_IT) { - return 0; - } - - /* Allocate heap where all work items used and queue - node items areallocated */ - work_heap = mem_heap_create(0); - reply_heap = mem_heap_create(0); - - - for(i=0;i<buf_pool_inst; i++) { - work_item[i].tsk = MT_WRK_WRITE; - 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].wi_status = WRK_ITEM_UNSET; - work_item[i].wheap = work_heap; - work_item[i].rheap = reply_heap; - work_item[i].n_flushed = 0; - work_item[i].n_evicted = 0; - work_item[i].id_usr = 0; - - ib_wqueue_add(mtflush_ctx->wq, - (void *)(work_item + i), - work_heap); - } - - /* wait on the completion to arrive */ - for(i=0; i< buf_pool_inst;) { - wrk_t *done_wi = NULL; - done_wi = (wrk_t *)ib_wqueue_wait(mtflush_ctx->wr_cq); - - if (done_wi != NULL) { - per_pool_cnt[i].flushed = done_wi->n_flushed; - per_pool_cnt[i].evicted = done_wi->n_evicted; - -#ifdef UNIV_MTFLUSH_DEBUG - 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+done_wi->n_evicted; - i++; - } - } - - /* Release used work_items and queue nodes */ - mem_heap_free(work_heap); - mem_heap_free(reply_heap); - - return(n_flushed); -} - -/*******************************************************************//** -Multi-threaded version of buf_flush_list -*/ -bool -buf_mtflu_flush_list( -/*=================*/ - ulint min_n, /*!< in: wished minimum mumber of blocks - flushed (it is not guaranteed that the - actual number is that big, though) */ - lsn_t lsn_limit, /*!< in the case BUF_FLUSH_LIST all - blocks whose oldest_modification is - smaller than this should be flushed - (if their number does not exceed - min_n), otherwise ignored */ - ulint* n_processed) /*!< out: the number of pages - which were processed is passed - back to caller. Ignored if NULL */ - -{ - ulint i; - bool success = true; - flush_counters_t cnt[MTFLUSH_MAX_WORKER]; - - if (n_processed) { - *n_processed = 0; - } - - if (min_n != ULINT_MAX) { - /* Ensure that flushing is spread evenly amongst the - buffer pool instances. When min_n is ULINT_MAX - we need to flush everything up to the lsn limit - so no limit here. */ - min_n = (min_n + srv_buf_pool_instances - 1) - / srv_buf_pool_instances; - } - - /* This lock is to safequard against re-entry if any. */ - mutex_enter(&mtflush_mtx); - buf_mtflu_flush_work_items(srv_buf_pool_instances, - cnt, BUF_FLUSH_LIST, - min_n, lsn_limit); - mutex_exit(&mtflush_mtx); - - for (i = 0; i < srv_buf_pool_instances; i++) { - if (n_processed) { - *n_processed += cnt[i].flushed+cnt[i].evicted; - } - - if (cnt[i].flushed) { - MONITOR_INC_VALUE_CUMULATIVE( - MONITOR_FLUSH_BATCH_TOTAL_PAGE, - MONITOR_FLUSH_BATCH_COUNT, - MONITOR_FLUSH_BATCH_PAGES, - cnt[i].flushed); - } - - if(cnt[i].evicted) { - MONITOR_INC_VALUE_CUMULATIVE( - MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE, - MONITOR_LRU_BATCH_EVICT_COUNT, - MONITOR_LRU_BATCH_EVICT_PAGES, - cnt[i].evicted); - } - } -#ifdef UNIV_MTFLUSH_DEBUG - fprintf(stderr, "%s: [1] [*n_processed: (min:%lu)%lu ]\n", - __FUNCTION__, (min_n * srv_buf_pool_instances), *n_processed); -#endif - return(success); -} - -/*********************************************************************//** -Clears up tail of the LRU lists: -* Put replaceable pages at the tail of LRU to the free list -* Flush dirty pages at the tail of LRU to the disk -The depth to which we scan each buffer pool is controlled by dynamic -config parameter innodb_LRU_scan_depth. -@return total pages flushed */ -UNIV_INTERN -ulint -buf_mtflu_flush_LRU_tail(void) -/*==========================*/ -{ - ulint total_flushed=0, i; - flush_counters_t cnt[MTFLUSH_MAX_WORKER]; - - ut_a(buf_mtflu_init_done()); - - /* At shutdown do not send requests anymore */ - if (!mtflush_ctx || mtflush_ctx->gwt_status == WTHR_KILL_IT) { - return (total_flushed); - } - - /* This lock is to safeguard against re-entry if any */ - mutex_enter(&mtflush_mtx); - buf_mtflu_flush_work_items(srv_buf_pool_instances, - cnt, BUF_FLUSH_LRU, srv_LRU_scan_depth, 0); - mutex_exit(&mtflush_mtx); - - for (i = 0; i < srv_buf_pool_instances; i++) { - total_flushed += cnt[i].flushed+cnt[i].evicted; - - if (cnt[i].flushed) { - MONITOR_INC_VALUE_CUMULATIVE( - MONITOR_LRU_BATCH_FLUSH_TOTAL_PAGE, - MONITOR_LRU_BATCH_FLUSH_COUNT, - MONITOR_LRU_BATCH_FLUSH_PAGES, - cnt[i].flushed); - } - - if(cnt[i].evicted) { - MONITOR_INC_VALUE_CUMULATIVE( - MONITOR_LRU_BATCH_EVICT_TOTAL_PAGE, - MONITOR_LRU_BATCH_EVICT_COUNT, - MONITOR_LRU_BATCH_EVICT_PAGES, - cnt[i].evicted); - } - } - -#if UNIV_MTFLUSH_DEBUG - fprintf(stderr, "[1] [*n_processed: (min:%lu)%lu ]\n", ( - srv_LRU_scan_depth * srv_buf_pool_instances), total_flushed); -#endif - - return(total_flushed); -} - -/*********************************************************************//** -Set correct thread identifiers to io thread array based on -information we have. */ -void -buf_mtflu_set_thread_ids( -/*=====================*/ - ulint n_threads, /*!<in: Number of threads to fill */ - void* ctx, /*!<in: thread context */ - os_thread_id_t* thread_ids) /*!<in: thread id array */ -{ - thread_sync_t *mtflush_io = ((thread_sync_t *)ctx); - ulint i; - ut_a(mtflush_io != NULL); - ut_a(thread_ids != NULL); - - for(i = 0; i < n_threads; i++) { - thread_ids[i] = mtflush_io->thread_data[i].wthread_id; - } -} |