diff options
Diffstat (limited to 'storage/innobase/include/buf0dblwr.h')
-rw-r--r-- | storage/innobase/include/buf0dblwr.h | 187 |
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; |