summaryrefslogtreecommitdiff
path: root/storage/xtradb/buf/buf0buf.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/buf/buf0buf.c')
-rw-r--r--storage/xtradb/buf/buf0buf.c194
1 files changed, 98 insertions, 96 deletions
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index bbc1042ca78..5bcfb0f51b9 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -66,9 +66,7 @@ _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
byte block_hash_offset;
ut_ad(block);
-
- if (!innobase_get_slow_log() || !trx || !trx->take_stats)
- return;
+ ut_ad(trx && trx->take_stats);
if (!trx->distinct_page_access_hash) {
trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
@@ -279,7 +277,7 @@ the read requests for the whole area.
#ifndef UNIV_HOTBACKUP
/** Value in microseconds */
-static const int WAIT_FOR_READ = 5000;
+static const int WAIT_FOR_READ = 100;
/** Number of attemtps made to read in a page in the buffer pool */
static const ulint BUF_PAGE_READ_MAX_RETRIES = 100;
@@ -412,6 +410,33 @@ buf_get_total_list_len(
}
/********************************************************************//**
+Get total list size in bytes from all buffer pools. */
+UNIV_INTERN
+void
+buf_get_total_list_size_in_bytes(
+/*=============================*/
+ buf_pools_list_size_t* buf_pools_list_size) /*!< out: list sizes
+ in all buffer pools */
+{
+ ulint i;
+ ut_ad(buf_pools_list_size);
+ memset(buf_pools_list_size, 0, sizeof(*buf_pools_list_size));
+
+ for (i = 0; i < srv_buf_pool_instances; i++) {
+ buf_pool_t* buf_pool;
+
+ buf_pool = buf_pool_from_array(i);
+ /* We don't need mutex protection since this is
+ for statistics purpose */
+ buf_pools_list_size->LRU_bytes += buf_pool->stat.LRU_bytes;
+ buf_pools_list_size->unzip_LRU_bytes +=
+ UT_LIST_GET_LEN(buf_pool->unzip_LRU) * UNIV_PAGE_SIZE;
+ buf_pools_list_size->flush_list_bytes +=
+ buf_pool->stat.flush_list_bytes;
+ }
+}
+
+/********************************************************************//**
Get total buffer pool statistics. */
UNIV_INTERN
void
@@ -1807,40 +1832,24 @@ buf_page_make_young(
}
/********************************************************************//**
-Sets the time of the first access of a page and moves a page to the
-start of the buffer pool LRU list if it is too old. This high-level
-function can be used to prevent an important page from slipping
-out of the buffer pool. */
+Moves a page to the start of the buffer pool LRU list if it is too old.
+This high-level function can be used to prevent an important page from
+slipping out of the buffer pool. */
static
void
-buf_page_set_accessed_make_young(
-/*=============================*/
- buf_page_t* bpage, /*!< in/out: buffer block of a
+buf_page_make_young_if_needed(
+/*==========================*/
+ buf_page_t* bpage) /*!< in/out: buffer block of a
file page */
- unsigned access_time) /*!< in: bpage->access_time
- read under mutex protection,
- or 0 if unknown */
{
+#ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
-
ut_ad(!buf_pool_mutex_own(buf_pool));
+#endif /* UNIV_DEBUG */
ut_a(buf_page_in_file(bpage));
if (buf_page_peek_if_too_old(bpage)) {
- //buf_pool_mutex_enter(buf_pool);
- mutex_enter(&buf_pool->LRU_list_mutex);
- buf_LRU_make_block_young(bpage);
- //buf_pool_mutex_exit(buf_pool);
- mutex_exit(&buf_pool->LRU_list_mutex);
- } else if (!access_time) {
- ulint time_ms = ut_time_ms();
- mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
- //buf_pool_mutex_enter(buf_pool);
- if (block_mutex) {
- buf_page_set_accessed(bpage, time_ms);
- mutex_exit(block_mutex);
- }
- //buf_pool_mutex_exit(buf_pool);
+ buf_page_make_young(bpage);
}
}
@@ -1959,7 +1968,6 @@ buf_page_get_zip(
buf_page_t* bpage;
mutex_t* block_mutex;
ibool must_read;
- unsigned access_time;
trx_t* trx = NULL;
ulint sec;
ulint ms;
@@ -1967,7 +1975,7 @@ buf_page_get_zip(
ib_uint64_t finish_time;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(innobase_get_slow_log())) {
trx = innobase_get_trx();
}
buf_pool->stat.n_page_gets++;
@@ -2089,13 +2097,14 @@ err_exit:
got_block:
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
- access_time = buf_page_is_accessed(bpage);
//buf_pool_mutex_exit(buf_pool);
+ buf_page_set_accessed(bpage);
+
mutex_exit(block_mutex);
- buf_page_set_accessed_make_young(bpage, access_time);
+ buf_page_make_young_if_needed(bpage);
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!bpage->file_page_was_freed);
@@ -2111,7 +2120,7 @@ got_block:
/* Let us wait until the read operation
completes */
- if (innobase_get_slow_log() && trx && trx->take_stats)
+ if (UNIV_UNLIKELY(trx && trx->take_stats))
{
ut_usectime(&sec, &ms);
start_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2132,7 +2141,7 @@ got_block:
break;
}
}
- if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ if (UNIV_UNLIKELY(start_time != 0))
{
ut_usectime(&sec, &ms);
finish_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2487,7 +2496,7 @@ buf_page_get_gen(
|| ibuf_page_low(space, zip_size, offset,
FALSE, file, line, NULL));
#endif
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(innobase_get_slow_log())) {
trx = innobase_get_trx();
}
buf_pool->stat.n_page_gets++;
@@ -2774,6 +2783,8 @@ wait_until_unfixed:
UNIV_MEM_INVALID(bpage, sizeof *bpage);
+ access_time = buf_page_is_accessed(&block->page);
+
mutex_exit(block_mutex);
mutex_exit(&buf_pool->zip_mutex);
@@ -2781,18 +2792,22 @@ wait_until_unfixed:
buf_pool->n_pend_unzip++;
buf_pool_mutex_exit(buf_pool);
- //buf_pool_mutex_exit(buf_pool);
-
buf_page_free_descriptor(bpage);
- /* Decompress the page and apply buffered operations
- while not holding buf_pool->mutex or block->mutex. */
+ /* Decompress the page while not holding
+ buf_pool->mutex or block->mutex. */
success = buf_zip_decompress(block, srv_use_checksums);
ut_a(success);
if (UNIV_LIKELY(!recv_no_ibuf_operations)) {
- ibuf_merge_or_delete_for_page(block, space, offset,
- zip_size, TRUE);
+ if (access_time) {
+#ifdef UNIV_IBUF_COUNT_DEBUG
+ ut_a(ibuf_count_get(space, offset) == 0);
+#endif /* UNIV_IBUF_COUNT_DEBUG */
+ } else {
+ ibuf_merge_or_delete_for_page(
+ block, space, offset, zip_size, TRUE);
+ }
}
/* Unfix and unlatch the block. */
@@ -2888,17 +2903,16 @@ wait_until_unfixed:
ut_a(mode == BUF_GET_POSSIBLY_FREED
|| !block->page.file_page_was_freed);
#endif
- //mutex_exit(&block->mutex);
/* Check if this is the first access to the page */
-
access_time = buf_page_is_accessed(&block->page);
- //buf_pool_mutex_exit(buf_pool);
- mutex_exit(block_mutex);
+ buf_page_set_accessed(&block->page);
+
+ mutex_exit(&block->mutex);
- if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
- buf_page_set_accessed_make_young(&block->page, access_time);
+ if (mode != BUF_PEEK_IF_IN_POOL) {
+ buf_page_make_young_if_needed(&block->page);
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
@@ -2913,7 +2927,7 @@ wait_until_unfixed:
/* Let us wait until the read operation
completes */
- if (innobase_get_slow_log() && trx && trx->take_stats)
+ if (UNIV_UNLIKELY(trx && trx->take_stats))
{
ut_usectime(&sec, &ms);
start_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2928,13 +2942,14 @@ wait_until_unfixed:
mutex_exit(&block->mutex);
if (io_fix == BUF_IO_READ) {
-
- os_thread_sleep(WAIT_FOR_READ);
+ /* wait by temporaly s-latch */
+ rw_lock_s_lock(&(block->lock));
+ rw_lock_s_unlock(&(block->lock));
} else {
break;
}
}
- if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ if (UNIV_UNLIKELY(start_time != 0))
{
ut_usectime(&sec, &ms);
finish_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2961,7 +2976,7 @@ wait_until_unfixed:
mtr_memo_push(mtr, block, fix_type);
- if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) {
+ if (mode != BUF_PEEK_IF_IN_POOL && !access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
@@ -2973,7 +2988,7 @@ wait_until_unfixed:
ut_a(ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0);
#endif
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(trx && trx->take_stats)) {
_increment_page_get_statistics(block, trx);
}
@@ -3018,15 +3033,13 @@ buf_page_optimistic_get(
buf_block_buf_fix_inc(block, file, line);
- mutex_exit(&block->mutex);
+ access_time = buf_page_is_accessed(&block->page);
- /* Check if this is the first access to the page.
- We do a dirty read on purpose, to avoid mutex contention.
- This field is only used for heuristic purposes; it does not
- affect correctness. */
+ buf_page_set_accessed(&block->page);
- access_time = buf_page_is_accessed(&block->page);
- buf_page_set_accessed_make_young(&block->page, access_time);
+ mutex_exit(&block->mutex);
+
+ buf_page_make_young_if_needed(&block->page);
ut_ad(!ibuf_inside(mtr)
|| ibuf_page(buf_block_get_space(block),
@@ -3078,11 +3091,11 @@ buf_page_optimistic_get(
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(innobase_get_slow_log())) {
trx = innobase_get_trx();
}
- if (UNIV_UNLIKELY(!access_time)) {
+ if (!access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
@@ -3099,7 +3112,7 @@ buf_page_optimistic_get(
buf_pool = buf_pool_from_block(block);
buf_pool->stat.n_page_gets++;
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(trx && trx->take_stats)) {
_increment_page_get_statistics(block, trx);
}
return(TRUE);
@@ -3149,28 +3162,14 @@ buf_page_get_known_nowait(
buf_block_buf_fix_inc(block, file, line);
+ buf_page_set_accessed(&block->page);
+
mutex_exit(&block->mutex);
buf_pool = buf_pool_from_block(block);
- if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
- //buf_pool_mutex_enter(buf_pool);
- mutex_enter(&buf_pool->LRU_list_mutex);
- buf_LRU_make_block_young(&block->page);
- //buf_pool_mutex_exit(buf_pool);
- mutex_exit(&buf_pool->LRU_list_mutex);
- } else if (!buf_page_is_accessed(&block->page)) {
- /* Above, we do a dirty read on purpose, to avoid
- mutex contention. The field buf_page_t::access_time
- is only used for heuristic purposes. Writes to the
- field must be protected by mutex, however. */
- ulint time_ms = ut_time_ms();
-
- //buf_pool_mutex_enter(buf_pool);
- mutex_enter(&block->mutex);
- buf_page_set_accessed(&block->page, time_ms);
- //buf_pool_mutex_exit(buf_pool);
- mutex_exit(&block->mutex);
+ if (mode == BUF_MAKE_YOUNG) {
+ buf_page_make_young_if_needed(&block->page);
}
ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
@@ -3211,9 +3210,13 @@ buf_page_get_known_nowait(
#endif
buf_pool->stat.n_page_gets++;
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(innobase_get_slow_log())) {
+
trx = innobase_get_trx();
- _increment_page_get_statistics(block, trx);
+ if (trx != NULL && trx->take_stats) {
+
+ _increment_page_get_statistics(block, trx);
+ }
}
return(TRUE);
@@ -3342,6 +3345,7 @@ buf_page_init(
ulint offset, /*!< in: offset of the page within space
in units of a page */
ulint fold, /*!< in: buf_page_address_fold(space,offset) */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
buf_block_t* block) /*!< in/out: block to init */
{
buf_page_t* hash_page;
@@ -3411,6 +3415,9 @@ buf_page_init(
ut_d(block->page.in_page_hash = TRUE);
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
fold, &block->page);
+ if (zip_size) {
+ page_zip_set_size(&block->page.zip, zip_size);
+ }
}
/********************************************************************//**
@@ -3537,7 +3544,7 @@ err_exit:
ut_ad(buf_pool_from_bpage(bpage) == buf_pool);
- buf_page_init(buf_pool, space, offset, fold, block);
+ buf_page_init(buf_pool, space, offset, fold, zip_size, block);
rw_lock_x_unlock(&buf_pool->page_hash_latch);
@@ -3557,8 +3564,6 @@ err_exit:
buf_page_set_io_fix(bpage, BUF_IO_READ);
if (UNIV_UNLIKELY(zip_size)) {
- page_zip_set_size(&block->page.zip, zip_size);
-
/* buf_pool->mutex may be released and
reacquired by buf_buddy_alloc(). Thus, we
must release block->mutex in order not to
@@ -3658,7 +3663,8 @@ err_exit:
rw_lock_x_unlock(&buf_pool->page_hash_latch);
- /* The block must be put to the LRU list, to the old blocks */
+ /* The block must be put to the LRU list, to the old blocks
+ The zip_size is already set into the page zip */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
@@ -3706,7 +3712,6 @@ buf_page_create(
buf_block_t* block;
ulint fold;
buf_block_t* free_block = NULL;
- ulint time_ms = ut_time_ms();
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mtr);
@@ -3774,7 +3779,7 @@ retry:
mutex_enter(&block->mutex);
- buf_page_init(buf_pool, space, offset, fold, block);
+ buf_page_init(buf_pool, space, offset, fold, zip_size,block);
rw_lock_x_unlock(&buf_pool->page_hash_latch);
/* The block must be put to the LRU list */
@@ -3793,8 +3798,6 @@ retry:
buf_page_set_io_fix(&block->page, BUF_IO_READ);
rw_lock_x_lock(&block->lock);
-
- page_zip_set_size(&block->page.zip, zip_size);
mutex_exit(&block->mutex);
/* buf_pool->mutex may be released and reacquired by
buf_buddy_alloc(). Thus, we must release block->mutex
@@ -3818,13 +3821,12 @@ retry:
rw_lock_x_unlock(&block->lock);
}
- buf_page_set_accessed(&block->page, time_ms);
-
- //buf_pool_mutex_exit(buf_pool);
mutex_exit(&buf_pool->LRU_list_mutex);
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
+ buf_page_set_accessed(&block->page);
+
mutex_exit(&block->mutex);
/* Delete possible entries for the page from the insert buffer:
@@ -3937,7 +3939,7 @@ buf_page_io_complete(
ensures that this is the only thread that handles the i/o for this
block. */
- io_type = buf_page_get_io_fix(bpage);
+ io_type = buf_page_get_io_fix_unlocked(bpage);
ut_ad(io_type == BUF_IO_READ || io_type == BUF_IO_WRITE);
if (io_type == BUF_IO_READ) {