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