summaryrefslogtreecommitdiff
path: root/storage/innobase/include/buf0dblwr.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/buf0dblwr.h')
-rw-r--r--storage/innobase/include/buf0dblwr.h187
1 files changed, 84 insertions, 103 deletions
diff --git a/storage/innobase/include/buf0dblwr.h b/storage/innobase/include/buf0dblwr.h
index fed64e0ee72..406e1f85846 100644
--- a/storage/innobase/include/buf0dblwr.h
+++ b/storage/innobase/include/buf0dblwr.h
@@ -24,101 +24,38 @@ Doublewrite buffer module
Created 2011/12/19 Inaam Rana
*******************************************************/
-#ifndef buf0dblwr_h
-#define buf0dblwr_h
+#pragma once
-#include "ut0byte.h"
-#include "log0log.h"
+#include "os0file.h"
#include "buf0types.h"
-#include "log0recv.h"
-
-/** Doublewrite system */
-extern buf_dblwr_t* buf_dblwr;
-
-/** Create the doublewrite buffer if the doublewrite buffer header
-is not present in the TRX_SYS page.
-@return whether the operation succeeded
-@retval true if the doublewrite buffer exists or was created
-@retval false if the creation failed (too small first data file) */
-MY_ATTRIBUTE((warn_unused_result))
-bool
-buf_dblwr_create();
-
-/**
-At database startup initializes the doublewrite buffer memory structure if
-we already have a doublewrite buffer created in the data files. If we are
-upgrading to an InnoDB version which supports multiple tablespaces, then this
-function performs the necessary update operations. If we are in a crash
-recovery, this function loads the pages from double write buffer into memory.
-@param[in] file File handle
-@param[in] path Path name of file
-@return DB_SUCCESS or error code */
-dberr_t
-buf_dblwr_init_or_load_pages(
- pfs_os_file_t file,
- const char* path);
-
-/** Process and remove the double write buffer pages for all tablespaces. */
-void
-buf_dblwr_process();
-
-/****************************************************************//**
-frees doublewrite buffer. */
-void
-buf_dblwr_free();
-
-/** Update the doublewrite buffer on write completion. */
-void buf_dblwr_update(const buf_page_t &bpage, bool single_page);
-/****************************************************************//**
-Determines if a page number is located inside the doublewrite buffer.
-@return TRUE if the location is inside the two blocks of the
-doublewrite buffer */
-ibool
-buf_dblwr_page_inside(
-/*==================*/
- ulint page_no); /*!< in: page number */
-
-/********************************************************************//**
-Flushes possible buffered writes from the doublewrite memory buffer to disk.
-It is very important to call this function after a batch of writes
-has been posted, and also when we may have to wait for a page latch!
-Otherwise a deadlock of threads can occur. */
-void
-buf_dblwr_flush_buffered_writes();
/** Doublewrite control struct */
-struct buf_dblwr_t{
- ib_mutex_t mutex; /*!< mutex protecting the first_free
- field and write_buf */
- ulint block1; /*!< the page number of the first
- doublewrite block (64 pages) */
- ulint block2; /*!< page number of the second block */
- ulint first_free;/*!< first free position in write_buf
- measured in units of srv_page_size */
- ulint b_reserved;/*!< number of slots currently reserved
- for batch flush. */
- os_event_t b_event;/*!< event where threads wait for a
- batch flush to end;
- os_event_set() and os_event_reset()
- are protected by buf_dblwr_t::mutex */
- ulint s_reserved;/*!< number of slots currently
- reserved for single page flushes. */
- os_event_t s_event;/*!< event where threads wait for a
- single page flush slot. Protected by mutex. */
- bool batch_running;/*!< set to TRUE if currently a batch
- is being written from the doublewrite
- buffer. */
- byte* write_buf;/*!< write buffer used in writing to the
- doublewrite buffer, aligned to an
- address divisible by srv_page_size
- (which is required by Windows aio) */
+class buf_dblwr_t
+{
+ /** the page number of the first doublewrite block (block_size() pages) */
+ page_id_t block1= page_id_t(0, 0);
+ /** the page number of the second doublewrite block (block_size() pages) */
+ page_id_t block2= page_id_t(0, 0);
+
+ /** mutex protecting the data members below */
+ mysql_mutex_t mutex;
+ /** condition variable for !batch_running */
+ mysql_cond_t cond;
+ /** whether a batch is being written from the doublewrite buffer */
+ bool batch_running;
+ /** first free position in write_buf measured in units of srv_page_size */
+ ulint first_free;
+ /** number of slots reserved for the current write batch */
+ ulint reserved;
+ /** the doublewrite buffer, aligned to srv_page_size */
+ byte *write_buf;
struct element
{
/** block descriptor */
buf_page_t *bpage;
- /** flush type */
- IORequest::flush_t flush;
+ /** true=buf_pool.flush_list, false=buf_pool.LRU */
+ bool lru;
/** payload size in bytes */
size_t size;
};
@@ -126,23 +63,67 @@ struct buf_dblwr_t{
/** buffer blocks to be written via write_buf */
element *buf_block_arr;
+ /** Initialize the doublewrite buffer data structure.
+ @param header doublewrite page header in the TRX_SYS page */
+ inline void init(const byte *header);
+
+ /** Flush possible buffered writes to persistent storage. */
+ bool flush_buffered_writes(const ulint size);
+
+public:
+ /** Create or restore the doublewrite buffer in the TRX_SYS page.
+ @return whether the operation succeeded */
+ bool create();
+ /** Free the doublewrite buffer. */
+ void close();
+
+ /** Initialize the doublewrite buffer memory structure on recovery.
+ If we are upgrading from a version before MySQL 4.1, then this
+ function performs the necessary update operations to support
+ innodb_file_per_table. If we are in a crash recovery, this function
+ loads the pages from double write buffer into memory.
+ @param file File handle
+ @param path Path name of file
+ @return DB_SUCCESS or error code */
+ dberr_t init_or_load_pages(pfs_os_file_t file, const char *path);
+
+ /** Process and remove the double write buffer pages for all tablespaces. */
+ void recover();
+
+ /** Update the doublewrite buffer on write completion. */
+ void write_completed();
+ /** Flush possible buffered writes to persistent storage.
+ It is very important to call this function after a batch of writes has been
+ posted, and also when we may have to wait for a page latch!
+ Otherwise a deadlock of threads can occur. */
+ void flush_buffered_writes();
+
+ /** Size of the doublewrite block in pages */
+ uint32_t block_size() const { return FSP_EXTENT_SIZE; }
+
/** Schedule a page write. If the doublewrite memory buffer is full,
- buf_dblwr_flush_buffered_writes() will be invoked to make space.
- @param bpage buffer pool page to be written
- @param flush type of flush
- @param size payload size in bytes */
- void add_to_batch(buf_page_t *bpage, IORequest::flush_t flush, size_t size);
- /** Write a page to the doublewrite buffer on disk, sync it, then write
- the page to the datafile and sync the datafile. This function is used
- for single page flushes. If all the buffers allocated for single page
- flushes in the doublewrite buffer are in use we wait here for one to
- become free. We are guaranteed that a slot will become free because any
- thread that is using a slot must also release the slot before leaving
- this function.
- @param bpage buffer pool page to be written
- @param sync whether synchronous operation is requested
- @param size payload size in bytes */
- void write_single_page(buf_page_t *bpage, bool sync, size_t size);
+ flush_buffered_writes() will be invoked to make space.
+ @param bpage buffer pool page to be written
+ @param lru true=buf_pool.LRU; false=buf_pool.flush_list
+ @param size payload size in bytes */
+ void add_to_batch(buf_page_t *bpage, bool lru, size_t size);
+
+ /** Determine whether the doublewrite buffer is initialized */
+ bool is_initialised() const
+ { return UNIV_LIKELY(block1 != page_id_t(0, 0)); }
+
+ /** @return whether a page identifier is part of the doublewrite buffer */
+ bool is_inside(const page_id_t id) const
+ {
+ if (!is_initialised())
+ return false;
+ ut_ad(block1 < block2);
+ if (id < block1)
+ return false;
+ const uint32_t size= block_size();
+ return id < block1 + size || (id >= block2 && id < block2 + size);
+ }
};
-#endif
+/** The doublewrite buffer */
+extern buf_dblwr_t buf_dblwr;