summaryrefslogtreecommitdiff
path: root/storage/innobase/include/buf0buf.ic
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/buf0buf.ic')
-rw-r--r--storage/innobase/include/buf0buf.ic242
1 files changed, 193 insertions, 49 deletions
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
index 917ee5dda84..88c29ab5603 100644
--- a/storage/innobase/include/buf0buf.ic
+++ b/storage/innobase/include/buf0buf.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -35,6 +35,16 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0lru.h"
#include "buf0rea.h"
+#ifndef UNIV_HOTBACKUP
+/** A chunk of buffers. The buffer pool is allocated in chunks. */
+struct buf_chunk_struct{
+ ulint mem_size; /*!< allocated size of the chunk */
+ ulint size; /*!< size of frames[] and blocks[] */
+ void* mem; /*!< pointer to the memory area which
+ was allocated for the frames */
+ buf_block_t* blocks; /*!< array of buffer control blocks */
+};
+
/*********************************************************************//**
Gets the current size of buffer buf_pool in bytes.
@return size in bytes */
@@ -160,7 +170,7 @@ buf_page_peek_if_too_old(
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
- if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
+ if (buf_pool->freed_page_clock == 0) {
/* If eviction has not started yet, do not update the
statistics or move blocks in the LRU list. This is
either the warm-up phase or an in-memory workload. */
@@ -180,6 +190,7 @@ buf_page_peek_if_too_old(
return(!buf_page_peek_if_young(bpage));
}
}
+#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Gets the state of a block.
@@ -361,11 +372,11 @@ buf_page_get_flush_type(
#ifdef UNIV_DEBUG
switch (flush_type) {
case BUF_FLUSH_LRU:
- case BUF_FLUSH_SINGLE_PAGE:
case BUF_FLUSH_LIST:
+ case BUF_FLUSH_SINGLE_PAGE:
return(flush_type);
case BUF_FLUSH_N_TYPES:
- break;
+ ut_error;
}
ut_error;
#endif /* UNIV_DEBUG */
@@ -628,7 +639,7 @@ buf_page_get_block(
/*===============*/
buf_page_t* bpage) /*!< in: control block, or NULL */
{
- if (UNIV_LIKELY(bpage != NULL)) {
+ if (bpage != NULL) {
ut_ad(buf_page_in_file(bpage));
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
@@ -719,6 +730,23 @@ buf_page_get_page_no(
return(bpage->offset);
}
+/***********************************************************************
+FIXME_FTS Gets the frame the pointer is pointing to. */
+UNIV_INLINE
+buf_frame_t*
+buf_frame_align(
+/*============*/
+ /* out: pointer to frame */
+ byte* ptr) /* in: pointer to a frame */
+{
+ buf_frame_t* frame;
+
+ ut_ad(ptr);
+
+ frame = (buf_frame_t*) ut_align_down(ptr, UNIV_PAGE_SIZE);
+
+ return(frame);
+}
/*********************************************************************//**
Gets the page number of a block.
@@ -744,7 +772,8 @@ buf_page_get_zip_size(
/*==================*/
const buf_page_t* bpage) /*!< in: pointer to the control block */
{
- return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
+ return(bpage->zip.ssize
+ ? (UNIV_ZIP_SIZE_MIN >> 1) << bpage->zip.ssize : 0);
}
/*********************************************************************//**
@@ -756,7 +785,8 @@ buf_block_get_zip_size(
/*===================*/
const buf_block_t* block) /*!< in: pointer to the control block */
{
- return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
+ return(block->page.zip.ssize
+ ? (UNIV_ZIP_SIZE_MIN >> 1) << block->page.zip.ssize : 0);
}
#ifndef UNIV_HOTBACKUP
@@ -852,7 +882,7 @@ buf_block_free(
/*===========*/
buf_block_t* block) /*!< in, own: block to be freed */
{
- buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
+ buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*) block);
buf_pool_mutex_enter(buf_pool);
@@ -905,13 +935,13 @@ Gets the youngest modification log sequence number for a frame.
Returns zero if not file page or no modification occurred yet.
@return newest modification to page */
UNIV_INLINE
-ib_uint64_t
+lsn_t
buf_page_get_newest_modification(
/*=============================*/
const buf_page_t* bpage) /*!< in: block containing the
page frame */
{
- ib_uint64_t lsn;
+ lsn_t lsn;
mutex_t* block_mutex = buf_page_get_mutex(bpage);
mutex_enter(block_mutex);
@@ -938,7 +968,7 @@ buf_block_modify_clock_inc(
buf_block_t* block) /*!< in: block */
{
#ifdef UNIV_SYNC_DEBUG
- buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
+ buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*) block);
ut_ad((buf_pool_mutex_own(buf_pool)
&& (block->page.buf_fix_count == 0))
@@ -1047,18 +1077,24 @@ UNIV_INLINE
buf_page_t*
buf_page_hash_get_low(
/*==================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint space, /*!< in: space id */
- ulint offset, /*!< in: offset of the page
- within space */
- ulint fold) /*!< in: buf_page_address_fold(
- space, offset) */
+ buf_pool_t* buf_pool,/*!< buffer pool instance */
+ ulint space, /*!< in: space id */
+ ulint offset, /*!< in: offset of the page within space */
+ ulint fold) /*!< in: buf_page_address_fold(space, offset) */
{
buf_page_t* bpage;
- ut_ad(buf_pool);
- ut_ad(buf_pool_mutex_own(buf_pool));
- ut_ad(fold == buf_page_address_fold(space, offset));
+#ifdef UNIV_SYNC_DEBUG
+ ulint hash_fold;
+ rw_lock_t* hash_lock;
+
+ hash_fold = buf_page_address_fold(space, offset);
+ ut_ad(hash_fold == fold);
+
+ hash_lock = hash_get_lock(buf_pool->page_hash, fold);
+ ut_ad(rw_lock_own(hash_lock, RW_LOCK_EX)
+ || rw_lock_own(hash_lock, RW_LOCK_SHARED));
+#endif /* UNIV_SYNC_DEBUG */
/* Look for the page in the hash table */
@@ -1083,46 +1119,145 @@ buf_page_hash_get_low(
/******************************************************************//**
Returns the control block of a file page, NULL if not found.
-@return block, NULL if not found or not a real control block */
+If the block is found and lock is not NULL then the appropriate
+page_hash lock is acquired in the specified lock mode. Otherwise,
+mode value is ignored. It is up to the caller to release the
+lock. If the block is found and the lock is NULL then the page_hash
+lock is released by this function.
+@return block, NULL if not found */
UNIV_INLINE
buf_page_t*
-buf_page_hash_get(
-/*==============*/
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
+buf_page_hash_get_locked(
+/*=====================*/
+ /*!< out: pointer to the bpage,
+ or NULL; if NULL, hash_lock
+ is also NULL. */
+ buf_pool_t* buf_pool, /*!< buffer pool instance */
ulint space, /*!< in: space id */
- ulint offset) /*!< in: offset of the page
- within space */
+ ulint offset, /*!< in: page number */
+ rw_lock_t** lock, /*!< in/out: lock of the page
+ hash acquired if bpage is
+ found. NULL otherwise. If NULL
+ is passed then the hash_lock
+ is released by this function */
+ ulint lock_mode) /*!< in: RW_LOCK_EX or
+ RW_LOCK_SHARED. Ignored if
+ lock == NULL */
{
- buf_page_t* bpage;
- ulint fold = buf_page_address_fold(space, offset);
+ buf_page_t* bpage = NULL;
+ ulint fold;
+ rw_lock_t* hash_lock;
+ ulint mode = RW_LOCK_SHARED;
+
+ if (lock != NULL) {
+ *lock = NULL;
+ ut_ad(lock_mode == RW_LOCK_EX
+ || lock_mode == RW_LOCK_SHARED);
+ mode = lock_mode;
+ }
+
+ fold = buf_page_address_fold(space, offset);
+ hash_lock = hash_get_lock(buf_pool->page_hash, fold);
+
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX)
+ && !rw_lock_own(hash_lock, RW_LOCK_SHARED));
+#endif /* UNIV_SYNC_DEBUG */
+
+ if (mode == RW_LOCK_SHARED) {
+ rw_lock_s_lock(hash_lock);
+ } else {
+ rw_lock_x_lock(hash_lock);
+ }
- bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
+ bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
- if (bpage && buf_pool_watch_is_sentinel(buf_pool, bpage)) {
+ if (!bpage || buf_pool_watch_is_sentinel(buf_pool, bpage)) {
bpage = NULL;
+ goto unlock_and_exit;
}
+ ut_ad(buf_page_in_file(bpage));
+ ut_ad(offset == bpage->offset);
+ ut_ad(space == bpage->space);
+
+ if (lock == NULL) {
+ /* The caller wants us to release the page_hash lock */
+ goto unlock_and_exit;
+ } else {
+ /* To be released by the caller */
+ *lock = hash_lock;
+ goto exit;
+ }
+
+unlock_and_exit:
+ if (mode == RW_LOCK_SHARED) {
+ rw_lock_s_unlock(hash_lock);
+ } else {
+ rw_lock_x_unlock(hash_lock);
+ }
+exit:
return(bpage);
}
/******************************************************************//**
-Returns the control block of a file page, NULL if not found
-or an uncompressed page frame does not exist.
+Returns the control block of a file page, NULL if not found.
+If the block is found and lock is not NULL then the appropriate
+page_hash lock is acquired in the specified lock mode. Otherwise,
+mode value is ignored. It is up to the caller to release the
+lock. If the block is found and the lock is NULL then the page_hash
+lock is released by this function.
@return block, NULL if not found */
UNIV_INLINE
buf_block_t*
-buf_block_hash_get(
-/*===============*/
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
+buf_block_hash_get_locked(
+/*=====================*/
+ /*!< out: pointer to the bpage,
+ or NULL; if NULL, hash_lock
+ is also NULL. */
+ buf_pool_t* buf_pool, /*!< buffer pool instance */
ulint space, /*!< in: space id */
- ulint offset) /*!< in: offset of the page
- within space */
+ ulint offset, /*!< in: page number */
+ rw_lock_t** lock, /*!< in/out: lock of the page
+ hash acquired if bpage is
+ found. NULL otherwise. If NULL
+ is passed then the hash_lock
+ is released by this function */
+ ulint lock_mode) /*!< in: RW_LOCK_EX or
+ RW_LOCK_SHARED. Ignored if
+ lock == NULL */
{
- buf_block_t* block;
+ buf_page_t* bpage = buf_page_hash_get_locked(buf_pool,
+ space,
+ offset,
+ lock,
+ lock_mode);
+ buf_block_t* block = buf_page_get_block(bpage);
+
+ if (block) {
+ ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(!lock || rw_lock_own(*lock, lock_mode));
+#endif /* UNIV_SYNC_DEBUG */
+ return(block);
+ } else if (bpage) {
+ /* It is not a block. Just a bpage */
+ ut_ad(buf_page_in_file(bpage));
- block = buf_page_get_block(buf_page_hash_get(buf_pool, space, offset));
+ if (lock) {
+ if (lock_mode == RW_LOCK_SHARED) {
+ rw_lock_s_unlock(*lock);
+ } else {
+ rw_lock_x_unlock(*lock);
+ }
+ }
+ *lock = NULL;
+ return(NULL);
+ }
- return(block);
+ ut_ad(!bpage);
+ ut_ad(lock == NULL ||*lock == NULL);
+ return(NULL);
}
/********************************************************************//**
@@ -1139,16 +1274,9 @@ buf_page_peek(
ulint space, /*!< in: space id */
ulint offset) /*!< in: page number */
{
- const buf_page_t* bpage;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
- buf_pool_mutex_enter(buf_pool);
-
- bpage = buf_page_hash_get(buf_pool, space, offset);
-
- buf_pool_mutex_exit(buf_pool);
-
- return(bpage != NULL);
+ return(buf_page_hash_get(buf_pool, space, offset) != NULL);
}
/********************************************************************//**
@@ -1189,7 +1317,6 @@ buf_page_release_zip(
break;
}
-
ut_error;
}
@@ -1274,4 +1401,21 @@ buf_pool_mutex_exit_all(void)
buf_pool_mutex_exit(buf_pool);
}
}
+/*********************************************************************//**
+Get the nth chunk's buffer block in the specified buffer pool.
+@return the nth chunk's buffer block. */
+UNIV_INLINE
+buf_block_t*
+buf_get_nth_chunk_block(
+/*====================*/
+ const buf_pool_t* buf_pool, /*!< in: buffer pool instance */
+ ulint n, /*!< in: nth chunk in the buffer pool */
+ ulint* chunk_size) /*!< in: chunk size */
+{
+ const buf_chunk_t* chunk;
+
+ chunk = buf_pool->chunks + n;
+ *chunk_size = chunk->size;
+ return(chunk->blocks);
+}
#endif /* !UNIV_HOTBACKUP */