1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. |
4 | Copyright (c) 2017, MariaDB Corporation. |
5 | |
6 | This program is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free Software |
8 | Foundation; version 2 of the License. |
9 | |
10 | This program is distributed in the hope that it will be useful, but WITHOUT |
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License along with |
15 | this program; if not, write to the Free Software Foundation, Inc., |
16 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
17 | |
18 | *****************************************************************************/ |
19 | |
20 | /**************************************************//** |
21 | @file include/buf0dblwr.h |
22 | Doublewrite buffer module |
23 | |
24 | Created 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 */ |
37 | extern buf_dblwr_t* buf_dblwr; |
38 | /** Set to TRUE when the doublewrite buffer is being created */ |
39 | extern ibool buf_dblwr_being_created; |
40 | |
41 | /** Create the doublewrite buffer if the doublewrite buffer header |
42 | is 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) */ |
46 | MY_ATTRIBUTE((warn_unused_result)) |
47 | bool |
48 | buf_dblwr_create(); |
49 | |
50 | /** |
51 | At database startup initializes the doublewrite buffer memory structure if |
52 | we already have a doublewrite buffer created in the data files. If we are |
53 | upgrading to an InnoDB version which supports multiple tablespaces, then this |
54 | function performs the necessary update operations. If we are in a crash |
55 | recovery, 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 */ |
59 | dberr_t |
60 | buf_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. */ |
65 | void |
66 | buf_dblwr_process(); |
67 | |
68 | /****************************************************************//** |
69 | frees doublewrite buffer. */ |
70 | void |
71 | buf_dblwr_free(); |
72 | |
73 | /********************************************************************//** |
74 | Updates the doublewrite buffer when an IO request is completed. */ |
75 | void |
76 | buf_dblwr_update( |
77 | /*=============*/ |
78 | const buf_page_t* bpage, /*!< in: buffer block descriptor */ |
79 | buf_flush_t flush_type);/*!< in: flush type */ |
80 | /****************************************************************//** |
81 | Determines if a page number is located inside the doublewrite buffer. |
82 | @return TRUE if the location is inside the two blocks of the |
83 | doublewrite buffer */ |
84 | ibool |
85 | buf_dblwr_page_inside( |
86 | /*==================*/ |
87 | ulint page_no); /*!< in: page number */ |
88 | /********************************************************************//** |
89 | Posts a buffer page for writing. If the doublewrite memory buffer is |
90 | full, calls buf_dblwr_flush_buffered_writes and waits for for free |
91 | space to appear. */ |
92 | void |
93 | buf_dblwr_add_to_batch( |
94 | /*====================*/ |
95 | buf_page_t* bpage); /*!< in: buffer block to write */ |
96 | |
97 | /********************************************************************//** |
98 | Flush a batch of writes to the datafiles that have already been |
99 | written to the dblwr buffer on disk. */ |
100 | void |
101 | buf_dblwr_sync_datafiles(); |
102 | |
103 | /********************************************************************//** |
104 | Flushes possible buffered writes from the doublewrite memory buffer to disk, |
105 | and also wakes up the aio thread if simulated aio is used. It is very |
106 | important to call this function after a batch of writes has been posted, |
107 | and also when we may have to wait for a page latch! Otherwise a deadlock |
108 | of threads can occur. */ |
109 | void |
110 | buf_dblwr_flush_buffered_writes(); |
111 | |
112 | /********************************************************************//** |
113 | Writes a page to the doublewrite buffer on disk, sync it, then write |
114 | the page to the datafile and sync the datafile. This function is used |
115 | for single page flushes. If all the buffers allocated for single page |
116 | flushes in the doublewrite buffer are in use we wait here for one to |
117 | become free. We are guaranteed that a slot will become free because any |
118 | thread that is using a slot must also release the slot before leaving |
119 | this function. */ |
120 | void |
121 | buf_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 */ |
127 | struct 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 | |