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