1 /*****************************************************************************
2
3 Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
4
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
16
17 *****************************************************************************/
18
19 /**************************************************//**
20 @file include/fsp0sysspace.h
21 Multi file, shared, system tablespace implementation.
22
23 Created 2013-7-26 by Kevin Lewis
24 *******************************************************/
25
26 #ifndef fsp0sysspace_h
27 #define fsp0sysspace_h
28
29 #include "fsp0space.h"
30
31 /** If the last data file is auto-extended, we add this many pages to it
32 at a time. We have to make this public because it is a config variable. */
33 extern uint sys_tablespace_auto_extend_increment;
34
35 /** Data structure that contains the information about shared tablespaces.
36 Currently this can be the system tablespace or a temporary table tablespace */
37 class SysTablespace : public Tablespace
38 {
39 public:
40
SysTablespace()41 SysTablespace()
42 :
43 m_auto_extend_last_file(),
44 m_last_file_size_max(),
45 m_created_new_raw(),
46 m_is_tablespace_full(false),
47 m_sanity_checks_done(false)
48 {
49 /* No op */
50 }
51
~SysTablespace()52 ~SysTablespace() override
53 {
54 shutdown();
55 }
56
57 /** Set tablespace full status
58 @param[in] is_full true if full */
set_tablespace_full_status(bool is_full)59 void set_tablespace_full_status(bool is_full)
60 {
61 m_is_tablespace_full = is_full;
62 }
63
64 /** Get tablespace full status
65 @return true if table is full */
get_tablespace_full_status()66 bool get_tablespace_full_status()
67 {
68 return(m_is_tablespace_full);
69 }
70
71 /** Set sanity check status
72 @param[in] status true if sanity checks are done */
set_sanity_check_status(bool status)73 void set_sanity_check_status(bool status)
74 {
75 m_sanity_checks_done = status;
76 }
77
78 /** Get sanity check status
79 @return true if sanity checks are done */
get_sanity_check_status()80 bool get_sanity_check_status()
81 {
82 return(m_sanity_checks_done);
83 }
84
85 /** Parse the input params and populate member variables.
86 @param filepath path to data files
87 @param supports_raw true if it supports raw devices
88 @return true on success parse */
89 bool parse_params(const char* filepath, bool supports_raw);
90
91 /** Check the data file specification.
92 @param[out] create_new_db true if a new database
93 is to be created
94 @param[in] min_expected_size expected tablespace
95 size in bytes
96 @return DB_SUCCESS if all OK else error code */
97 dberr_t check_file_spec(
98 bool* create_new_db,
99 ulint min_expected_tablespace_size);
100
101 /** Free the memory allocated by parse() */
102 void shutdown();
103
104 /** Normalize the file size, convert to extents. */
105 void normalize_size();
106
107 /**
108 @return true if a new raw device was created. */
created_new_raw()109 bool created_new_raw() const
110 {
111 return(m_created_new_raw);
112 }
113
114 /**
115 @return auto_extend value setting */
can_auto_extend_last_file()116 ulint can_auto_extend_last_file() const
117 {
118 return(m_auto_extend_last_file);
119 }
120
121 /** Set the last file size.
122 @param[in] size the size to set */
set_last_file_size(uint32_t size)123 void set_last_file_size(uint32_t size)
124 {
125 ut_ad(!m_files.empty());
126 m_files.back().m_size = size;
127 }
128
129 /** Get the size of the last data file in the tablespace
130 @return the size of the last data file in the array */
last_file_size()131 uint32_t last_file_size() const
132 {
133 ut_ad(!m_files.empty());
134 return(m_files.back().m_size);
135 }
136
137 /**
138 @return the autoextend increment in pages. */
get_autoextend_increment()139 uint32_t get_autoextend_increment() const
140 {
141 return sys_tablespace_auto_extend_increment
142 << (20 - srv_page_size_shift);
143 }
144
145 /**
146 @return next increment size */
147 uint32_t get_increment() const;
148
149 /** Open or create the data files
150 @param[in] is_temp whether this is a temporary tablespace
151 @param[in] create_new_db whether we are creating a new database
152 @param[out] sum_new_sizes sum of sizes of the new files added
153 @param[out] flush_lsn FIL_PAGE_FILE_FLUSH_LSN of first file
154 @return DB_SUCCESS or error code */
155 dberr_t open_or_create(
156 bool is_temp,
157 bool create_new_db,
158 ulint* sum_new_sizes,
159 lsn_t* flush_lsn)
160 MY_ATTRIBUTE((warn_unused_result));
161
162 private:
163 /** Check the tablespace header for this tablespace.
164 @param[out] flushed_lsn the value of FIL_PAGE_FILE_FLUSH_LSN
165 @return DB_SUCCESS or error code */
166 dberr_t read_lsn_and_check_flags(lsn_t* flushed_lsn);
167
168 /**
169 @return true if the last file size is valid. */
is_valid_size()170 bool is_valid_size() const
171 {
172 return(m_last_file_size_max >= last_file_size());
173 }
174
175 /**
176 @return true if configured to use raw devices */
177 bool has_raw_device();
178
179 /** Note that the data file was not found.
180 @param[in] file data file object
181 @param[out] create_new_db true if a new instance to be created
182 @return DB_SUCESS or error code */
183 dberr_t file_not_found(Datafile& file, bool* create_new_db);
184
185 /** Note that the data file was found.
186 @param[in,out] file data file object
187 @return true if a new instance to be created */
188 bool file_found(Datafile& file);
189
190 /** Create a data file.
191 @param[in,out] file data file object
192 @return DB_SUCCESS or error code */
193 dberr_t create(Datafile& file);
194
195 /** Create a data file.
196 @param[in,out] file data file object
197 @return DB_SUCCESS or error code */
198 dberr_t create_file(Datafile& file);
199
200 /** Open a data file.
201 @param[in,out] file data file object
202 @return DB_SUCCESS or error code */
203 dberr_t open_file(Datafile& file);
204
205 /** Set the size of the file.
206 @param[in,out] file data file object
207 @return DB_SUCCESS or error code */
208 dberr_t set_size(Datafile& file);
209
210 /** Convert a numeric string that optionally ends in G or M, to a
211 number containing megabytes.
212 @param[in] ptr string with a quantity in bytes
213 @param[out] megs the number in megabytes
214 @return next character in string */
215 static char* parse_units(char* ptr, ulint* megs);
216
217 private:
218 enum file_status_t {
219 FILE_STATUS_VOID = 0, /** status not set */
220 FILE_STATUS_RW_PERMISSION_ERROR,/** permission error */
221 FILE_STATUS_READ_WRITE_ERROR, /** not readable/writable */
222 FILE_STATUS_NOT_REGULAR_FILE_ERROR /** not a regular file */
223 };
224
225 /** Verify the size of the physical file
226 @param[in] file data file object
227 @return DB_SUCCESS if OK else error code. */
228 dberr_t check_size(Datafile& file);
229
230 /** Check if a file can be opened in the correct mode.
231 @param[in,out] file data file object
232 @param[out] reason exact reason if file_status check failed.
233 @return DB_SUCCESS or error code. */
234 dberr_t check_file_status(
235 const Datafile& file,
236 file_status_t& reason);
237
238 /* DATA MEMBERS */
239
240 /** if true, then we auto-extend the last data file */
241 bool m_auto_extend_last_file;
242
243 /** maximum size of the last data file (0=unlimited) */
244 ulint m_last_file_size_max;
245
246 /** If the following is true we do not allow
247 inserts etc. This protects the user from forgetting
248 the 'newraw' keyword to my.cnf */
249 bool m_created_new_raw;
250
251 /** Tablespace full status */
252 bool m_is_tablespace_full;
253
254 /** if false, then sanity checks are still pending */
255 bool m_sanity_checks_done;
256 };
257
258 /* GLOBAL OBJECTS */
259
260 /** The control info of the system tablespace. */
261 extern SysTablespace srv_sys_space;
262
263 /** The control info of a temporary table shared tablespace. */
264 extern SysTablespace srv_tmp_space;
265
266 /** Check if the space_id is for a system-tablespace (shared + temp).
267 @param[in] id Space ID to check
268 @return true if id is a system tablespace, false if not. */
269 UNIV_INLINE
270 bool
is_system_tablespace(ulint id)271 is_system_tablespace(ulint id)
272 {
273 return(id == TRX_SYS_SPACE || id == SRV_TMP_SPACE_ID);
274 }
275
276 /** Check if predefined shared tablespace.
277 @return true if predefined shared tablespace */
278 UNIV_INLINE
279 bool
is_predefined_tablespace(ulint id)280 is_predefined_tablespace(
281 ulint id)
282 {
283 ut_ad(srv_sys_space.space_id() == TRX_SYS_SPACE);
284 ut_ad(TRX_SYS_SPACE == 0);
285 return(id == TRX_SYS_SPACE
286 || id == SRV_TMP_SPACE_ID
287 || srv_is_undo_tablespace(id));
288 }
289 #endif /* fsp0sysspace_h */
290