1/*****************************************************************************
2
3Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2017, MariaDB Corporation.
5
6This program is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free Software
8Foundation; version 2 of the License.
9
10This program is distributed in the hope that it will be useful, but WITHOUT
11ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along with
15this program; if not, write to the Free Software Foundation, Inc.,
1651 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
18*****************************************************************************/
19
20/**************************************************//**
21@file include/buf0dblwr.h
22Doublewrite buffer module
23
24Created 2011/12/19 Inaam Rana
25*******************************************************/
26
27#ifndef buf0dblwr_h
28#define buf0dblwr_h
29
30#include "univ.i"
31#include "ut0byte.h"
32#include "log0log.h"
33#include "buf0types.h"
34#include "log0recv.h"
35
36/** Doublewrite system */
37extern buf_dblwr_t* buf_dblwr;
38/** Set to TRUE when the doublewrite buffer is being created */
39extern ibool buf_dblwr_being_created;
40
41/** Create the doublewrite buffer if the doublewrite buffer header
42is not present in the TRX_SYS page.
43@return whether the operation succeeded
44@retval true if the doublewrite buffer exists or was created
45@retval false if the creation failed (too small first data file) */
46MY_ATTRIBUTE((warn_unused_result))
47bool
48buf_dblwr_create();
49
50/**
51At database startup initializes the doublewrite buffer memory structure if
52we already have a doublewrite buffer created in the data files. If we are
53upgrading to an InnoDB version which supports multiple tablespaces, then this
54function performs the necessary update operations. If we are in a crash
55recovery, this function loads the pages from double write buffer into memory.
56@param[in] file File handle
57@param[in] path Path name of file
58@return DB_SUCCESS or error code */
59dberr_t
60buf_dblwr_init_or_load_pages(
61 pfs_os_file_t file,
62 const char* path);
63
64/** Process and remove the double write buffer pages for all tablespaces. */
65void
66buf_dblwr_process();
67
68/****************************************************************//**
69frees doublewrite buffer. */
70void
71buf_dblwr_free();
72
73/********************************************************************//**
74Updates the doublewrite buffer when an IO request is completed. */
75void
76buf_dblwr_update(
77/*=============*/
78 const buf_page_t* bpage, /*!< in: buffer block descriptor */
79 buf_flush_t flush_type);/*!< in: flush type */
80/****************************************************************//**
81Determines if a page number is located inside the doublewrite buffer.
82@return TRUE if the location is inside the two blocks of the
83doublewrite buffer */
84ibool
85buf_dblwr_page_inside(
86/*==================*/
87 ulint page_no); /*!< in: page number */
88/********************************************************************//**
89Posts a buffer page for writing. If the doublewrite memory buffer is
90full, calls buf_dblwr_flush_buffered_writes and waits for for free
91space to appear. */
92void
93buf_dblwr_add_to_batch(
94/*====================*/
95 buf_page_t* bpage); /*!< in: buffer block to write */
96
97/********************************************************************//**
98Flush a batch of writes to the datafiles that have already been
99written to the dblwr buffer on disk. */
100void
101buf_dblwr_sync_datafiles();
102
103/********************************************************************//**
104Flushes possible buffered writes from the doublewrite memory buffer to disk,
105and also wakes up the aio thread if simulated aio is used. It is very
106important to call this function after a batch of writes has been posted,
107and also when we may have to wait for a page latch! Otherwise a deadlock
108of threads can occur. */
109void
110buf_dblwr_flush_buffered_writes();
111
112/********************************************************************//**
113Writes a page to the doublewrite buffer on disk, sync it, then write
114the page to the datafile and sync the datafile. This function is used
115for single page flushes. If all the buffers allocated for single page
116flushes in the doublewrite buffer are in use we wait here for one to
117become free. We are guaranteed that a slot will become free because any
118thread that is using a slot must also release the slot before leaving
119this function. */
120void
121buf_dblwr_write_single_page(
122/*========================*/
123 buf_page_t* bpage, /*!< in: buffer block to write */
124 bool sync); /*!< in: true if sync IO requested */
125
126/** Doublewrite control struct */
127struct buf_dblwr_t{
128 ib_mutex_t mutex; /*!< mutex protecting the first_free
129 field and write_buf */
130 ulint block1; /*!< the page number of the first
131 doublewrite block (64 pages) */
132 ulint block2; /*!< page number of the second block */
133 ulint first_free;/*!< first free position in write_buf
134 measured in units of srv_page_size */
135 ulint b_reserved;/*!< number of slots currently reserved
136 for batch flush. */
137 os_event_t b_event;/*!< event where threads wait for a
138 batch flush to end;
139 os_event_set() and os_event_reset()
140 are protected by buf_dblwr_t::mutex */
141 ulint s_reserved;/*!< number of slots currently
142 reserved for single page flushes. */
143 os_event_t s_event;/*!< event where threads wait for a
144 single page flush slot. Protected by mutex. */
145 bool* in_use; /*!< flag used to indicate if a slot is
146 in use. Only used for single page
147 flushes. */
148 bool batch_running;/*!< set to TRUE if currently a batch
149 is being written from the doublewrite
150 buffer. */
151 byte* write_buf;/*!< write buffer used in writing to the
152 doublewrite buffer, aligned to an
153 address divisible by srv_page_size
154 (which is required by Windows aio) */
155 byte* write_buf_unaligned;/*!< pointer to write_buf,
156 but unaligned */
157 buf_page_t** buf_block_arr;/*!< array to store pointers to
158 the buffer blocks which have been
159 cached to write_buf */
160};
161
162#endif
163