summaryrefslogtreecommitdiff
path: root/storage/innobase/include/buf0flu.h
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2016-08-12 11:17:45 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2016-09-02 13:22:28 +0300
commit2e814d4702d71a04388386a9f591d14a35980bfe (patch)
treef3f9b48d116a3738c5e71f3a360ca61f16cfb632 /storage/innobase/include/buf0flu.h
parent848d211c5c4df00b819cd84d7530cf7d29bb0524 (diff)
downloadmariadb-git-2e814d4702d71a04388386a9f591d14a35980bfe.tar.gz
Merge InnoDB 5.7 from mysql-5.7.9.
Contains also MDEV-10547: Test multi_update_innodb fails with InnoDB 5.7 The failure happened because 5.7 has changed the signature of the bool handler::primary_key_is_clustered() const virtual function ("const" was added). InnoDB was using the old signature which caused the function not to be used. MDEV-10550: Parallel replication lock waits/deadlock handling does not work with InnoDB 5.7 Fixed mutexing problem on lock_trx_handle_wait. Note that rpl_parallel and rpl_optimistic_parallel tests still fail. MDEV-10156 : Group commit tests fail on 10.2 InnoDB (branch bb-10.2-jan) Reason: incorrect merge MDEV-10550: Parallel replication can't sync with master in InnoDB 5.7 (branch bb-10.2-jan) Reason: incorrect merge
Diffstat (limited to 'storage/innobase/include/buf0flu.h')
-rw-r--r--storage/innobase/include/buf0flu.h258
1 files changed, 193 insertions, 65 deletions
diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h
index f1ca1039ccb..1d38c679f81 100644
--- a/storage/innobase/include/buf0flu.h
+++ b/storage/innobase/include/buf0flu.h
@@ -31,11 +31,15 @@ Created 11/5/1995 Heikki Tuuri
#include "ut0byte.h"
#include "log0log.h"
#ifndef UNIV_HOTBACKUP
-#include "mtr0types.h"
#include "buf0types.h"
/** Flag indicating if the page_cleaner is in active state. */
-extern ibool buf_page_cleaner_is_active;
+extern bool buf_page_cleaner_is_active;
+
+/** Event to synchronise with the flushing. */
+extern os_event_t buf_flush_event;
+
+class ut_stage_alter_t;
/** Event to synchronise with the flushing. */
extern os_event_t buf_flush_event;
@@ -50,7 +54,6 @@ struct flush_counters_t {
/********************************************************************//**
Remove a block from the flush list of modified blocks. */
-UNIV_INTERN
void
buf_flush_remove(
/*=============*/
@@ -59,7 +62,6 @@ buf_flush_remove(
Relocates a buffer control block on the flush_list.
Note that it is assumed that the contents of bpage has already been
copied to dpage. */
-UNIV_INTERN
void
buf_flush_relocate_on_flush_list(
/*=============================*/
@@ -67,22 +69,25 @@ buf_flush_relocate_on_flush_list(
buf_page_t* dpage); /*!< in/out: destination block */
/********************************************************************//**
Updates the flush system data structures when a write is completed. */
-UNIV_INTERN
void
buf_flush_write_complete(
/*=====================*/
buf_page_t* bpage); /*!< in: pointer to the block in question */
#endif /* !UNIV_HOTBACKUP */
-/********************************************************************//**
-Initializes a page for writing to the tablespace. */
-UNIV_INTERN
+/** Initialize a page for writing to the tablespace.
+@param[in] block buffer block; NULL if bypassing the buffer pool
+@param[in,out] page page frame
+@param[in,out] page_zip_ compressed page, or NULL if uncompressed
+@param[in] newest_lsn newest modification LSN to the page
+@param[in] skip_checksum whether to disable the page checksum */
void
buf_flush_init_for_writing(
-/*=======================*/
- byte* page, /*!< in/out: page */
- void* page_zip_, /*!< in/out: compressed page, or NULL */
- lsn_t newest_lsn); /*!< in: newest modification lsn
- to the page */
+ const buf_block_t* block,
+ byte* page,
+ void* page_zip_,
+ lsn_t newest_lsn,
+ bool skip_checksum);
+
#ifndef UNIV_HOTBACKUP
# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/********************************************************************//**
@@ -91,7 +96,6 @@ NOTE: buf_pool->mutex and block->mutex must be held upon entering this
function, and they will be released by this function after flushing.
This is loosely based on buf_flush_batch() and buf_flush_page().
@return TRUE if the page was flushed and the mutexes released */
-UNIV_INTERN
ibool
buf_flush_page_try(
/*===============*/
@@ -99,28 +103,46 @@ buf_flush_page_try(
buf_block_t* block) /*!< in/out: buffer control block */
MY_ATTRIBUTE((nonnull, warn_unused_result));
# endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
-/*******************************************************************//**
-This utility flushes dirty blocks from the end of the flush list of
-all buffer pool instances.
+/** Do flushing batch of a given type.
NOTE: The calling thread is not allowed to own any latches on pages!
+@param[in,out] buf_pool buffer pool instance
+@param[in] type flush type
+@param[in] min_n wished minimum mumber of blocks flushed
+(it is not guaranteed that the actual number is that big, though)
+@param[in] 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
+@param[out] n the number of pages which were processed is
+passed back to caller. Ignored if NULL
+@retval true if a batch was queued successfully.
+@retval false if another batch of same type was already running. */
+bool
+buf_flush_do_batch(
+ buf_pool_t* buf_pool,
+ buf_flush_t type,
+ ulint min_n,
+ lsn_t lsn_limit,
+ flush_counters_t* n);
+
+/** This utility flushes dirty blocks from the end of the flush list of all
+buffer pool instances.
+NOTE: The calling thread is not allowed to own any latches on pages!
+@param[in] min_n wished minimum mumber of blocks flushed (it is
+not guaranteed that the actual number is that big, though)
+@param[in] 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
+@param[out] n_processed the number of pages which were processed is
+passed back to caller. Ignored if NULL.
@return true if a batch was queued successfully for each buffer pool
instance. false if another batch of same type was already running in
at least one of the buffer pool instance */
-UNIV_INTERN
bool
-buf_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 */
+buf_flush_lists(
+ ulint min_n,
+ lsn_t lsn_limit,
+ ulint* n_processed);
+
/******************************************************************//**
This function picks up a single page from the tail of the LRU
list, flushes it (if it is dirty), removes it from page_hash and LRU
@@ -128,26 +150,31 @@ list and puts it on the free list. It is called from user threads when
they are unable to find a replaceable page at the tail of the LRU
list i.e.: when the background LRU flushing in the page_cleaner thread
is not fast enough to keep pace with the workload.
-@return TRUE if success. */
-UNIV_INTERN
-ibool
+@return true if success. */
+bool
buf_flush_single_page_from_LRU(
/*===========================*/
buf_pool_t* buf_pool); /*!< in/out: buffer pool instance */
/******************************************************************//**
Waits until a flush batch of the given type ends */
-UNIV_INTERN
void
buf_flush_wait_batch_end(
/*=====================*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
buf_flush_t type); /*!< in: BUF_FLUSH_LRU
or BUF_FLUSH_LIST */
+/**
+Waits until a flush batch of the given lsn ends
+@param[in] new_oldest target oldest_modified_lsn to wait for */
+
+void
+buf_flush_wait_flushed(
+ lsn_t new_oldest);
+
/******************************************************************//**
Waits until a flush batch of the given type ends. This is called by
a thread that only wants to wait for a flush to end but doesn't do
any flushing itself. */
-UNIV_INTERN
void
buf_flush_wait_batch_end_wait_only(
/*===============================*/
@@ -162,8 +189,13 @@ UNIV_INLINE
void
buf_flush_note_modification(
/*========================*/
- buf_block_t* block, /*!< in: block which is modified */
- mtr_t* mtr); /*!< in: mtr */
+ buf_block_t* block, /*!< in: block which is modified */
+ lsn_t start_lsn, /*!< in: start lsn of the first mtr in a
+ set of mtr's */
+ lsn_t end_lsn, /*!< in: end lsn of the last mtr in the
+ set of mtr's */
+ FlushObserver* observer); /*!< in: flush observer */
+
/********************************************************************//**
This function should be called when recovery has modified a buffer page. */
UNIV_INLINE
@@ -178,8 +210,7 @@ buf_flush_recv_note_modification(
/********************************************************************//**
Returns TRUE if the file page block is immediately suitable for replacement,
i.e., transition FILE_PAGE => NOT_USED allowed.
-@return TRUE if can replace immediately */
-UNIV_INTERN
+@return TRUE if can replace immediately */
ibool
buf_flush_ready_for_replace(
/*========================*/
@@ -187,14 +218,28 @@ buf_flush_ready_for_replace(
buf_page_in_file(bpage) and in the LRU list */
/******************************************************************//**
page_cleaner thread tasked with flushing dirty pages from the buffer
-pools. As of now we'll have only one instance of this thread.
+pools. As of now we'll have only one coordinator of this thread.
+@return a dummy parameter */
+extern "C"
+os_thread_ret_t
+DECLARE_THREAD(buf_flush_page_cleaner_coordinator)(
+/*===============================================*/
+ void* arg); /*!< in: a dummy parameter required by
+ os_thread_create */
+/******************************************************************//**
+Worker thread of page_cleaner.
@return a dummy parameter */
-extern "C" UNIV_INTERN
+extern "C"
os_thread_ret_t
-DECLARE_THREAD(buf_flush_page_cleaner_thread)(
+DECLARE_THREAD(buf_flush_page_cleaner_worker)(
/*==========================================*/
void* arg); /*!< in: a dummy parameter required by
os_thread_create */
+/******************************************************************//**
+Initialize page_cleaner. */
+void
+buf_flush_page_cleaner_init(void);
+/*=============================*/
/*********************************************************************//**
Clears up tail of the LRU lists:
* Put replaceable pages at the tail of LRU to the free list
@@ -202,13 +247,11 @@ Clears up tail of the LRU lists:
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_flush_LRU_tail(void);
-/*====================*/
+buf_flush_LRU_lists(void);
+/*=====================*/
/*********************************************************************//**
Wait for any possible LRU flushes that are in progress to end. */
-UNIV_INTERN
void
buf_flush_wait_LRU_batch_end(void);
/*==============================*/
@@ -216,8 +259,7 @@ buf_flush_wait_LRU_batch_end(void);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/******************************************************************//**
Validates the flush list.
-@return TRUE if ok */
-UNIV_INTERN
+@return TRUE if ok */
ibool
buf_flush_validate(
/*===============*/
@@ -228,14 +270,12 @@ buf_flush_validate(
Initialize the red-black tree to speed up insertions into the flush_list
during recovery process. Should be called at the start of recovery
process before any page has been read/written. */
-UNIV_INTERN
void
buf_flush_init_flush_rbt(void);
/*==========================*/
/********************************************************************//**
Frees up the red-black tree. */
-UNIV_INTERN
void
buf_flush_free_flush_rbt(void);
/*==========================*/
@@ -246,10 +286,9 @@ NOTE: in simulated aio we must call
os_aio_simulated_wake_handler_threads after we have posted a batch of
writes! NOTE: buf_pool->mutex and buf_page_get_mutex(bpage) must be
held upon entering this function, and they will be released by this
-function if it returns true.
-@return TRUE if the page was flushed */
-UNIV_INTERN
-bool
+function.
+@return TRUE if page was flushed */
+ibool
buf_flush_page(
/*===========*/
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
@@ -258,8 +297,7 @@ buf_flush_page(
bool sync); /*!< in: true if sync IO request */
/********************************************************************//**
Returns true if the block is modified and ready for flushing.
-@return true if can flush immediately */
-UNIV_INTERN
+@return true if can flush immediately */
bool
buf_flush_ready_for_flush(
/*======================*/
@@ -268,26 +306,116 @@ buf_flush_ready_for_flush(
buf_flush_t flush_type)/*!< in: type of flush */
MY_ATTRIBUTE((warn_unused_result));
-#ifdef UNIV_DEBUG
/******************************************************************//**
Check if there are any dirty pages that belong to a space id in the flush
list in a particular buffer pool.
-@return number of dirty pages present in a single buffer pool */
-UNIV_INTERN
+@return number of dirty pages present in a single buffer pool */
ulint
buf_pool_get_dirty_pages_count(
/*===========================*/
buf_pool_t* buf_pool, /*!< in: buffer pool */
- ulint id); /*!< in: space id to check */
+ ulint id, /*!< in: space id to check */
+ FlushObserver* observer); /*!< in: flush observer to check */
/******************************************************************//**
Check if there are any dirty pages that belong to a space id in the flush list.
-@return count of dirty pages present in all the buffer pools */
-UNIV_INTERN
+@return count of dirty pages present in all the buffer pools */
ulint
buf_flush_get_dirty_pages_count(
/*============================*/
- ulint id); /*!< in: space id to check */
-#endif /* UNIV_DEBUG */
+ ulint id, /*!< in: space id to check */
+ FlushObserver* observer); /*!< in: flush observer to check */
+
+/*******************************************************************//**
+Synchronously flush dirty blocks from the end of the flush list of all buffer
+pool instances.
+NOTE: The calling thread is not allowed to own any latches on pages! */
+void
+buf_flush_sync_all_buf_pools(void);
+/*==============================*/
+
+/** Request IO burst and wake page_cleaner up.
+@param[in] lsn_limit upper limit of LSN to be flushed */
+void
+buf_flush_request_force(
+ lsn_t lsn_limit);
+
+/** We use FlushObserver to track flushing of non-redo logged pages in bulk
+create index(BtrBulk.cc).Since we disable redo logging during a index build,
+we need to make sure that all dirty pages modifed by the index build are
+flushed to disk before any redo logged operations go to the index. */
+
+class FlushObserver {
+public:
+ /** Constructor
+ @param[in] space_id table space id
+ @param[in] trx trx instance
+ @param[in] stage performance schema accounting object,
+ used by ALTER TABLE. It is passed to log_preflush_pool_modified_pages()
+ for accounting. */
+ FlushObserver(ulint space_id, trx_t* trx, ut_stage_alter_t* stage);
+
+ /** Deconstructor */
+ ~FlushObserver();
+
+ /** Check pages have been flushed and removed from the flush list
+ in a buffer pool instance.
+ @pram[in] instance_no buffer pool instance no
+ @return true if the pages were removed from the flush list */
+ bool is_complete(ulint instance_no)
+ {
+ return(m_flushed->at(instance_no) == m_removed->at(instance_no)
+ || m_interrupted);
+ }
+
+ /** Interrupt observer not to wait. */
+ void interrupted()
+ {
+ m_interrupted = true;
+ }
+
+ /** Check whether trx is interrupted
+ @return true if trx is interrupted */
+ bool check_interrupted();
+
+ /** Flush dirty pages. */
+ void flush();
+
+ /** Notify observer of flushing a page
+ @param[in] buf_pool buffer pool instance
+ @param[in] bpage buffer page to flush */
+ void notify_flush(
+ buf_pool_t* buf_pool,
+ buf_page_t* bpage);
+
+ /** Notify observer of removing a page from flush list
+ @param[in] buf_pool buffer pool instance
+ @param[in] bpage buffer page flushed */
+ void notify_remove(
+ buf_pool_t* buf_pool,
+ buf_page_t* bpage);
+private:
+ /** Table space id */
+ ulint m_space_id;
+
+ /** Trx instance */
+ trx_t* m_trx;
+
+ /** Performance schema accounting object, used by ALTER TABLE.
+ If not NULL, then stage->begin_phase_flush() will be called initially,
+ specifying the number of pages to be attempted to be flushed and
+ subsequently, stage->inc() will be called for each page we attempt to
+ flush. */
+ ut_stage_alter_t* m_stage;
+
+ /* Flush request sent */
+ std::vector<ulint>* m_flushed;
+
+ /* Flush request finished */
+ std::vector<ulint>* m_removed;
+
+ /* True if the operation was interrupted. */
+ bool m_interrupted;
+};
#endif /* !UNIV_HOTBACKUP */