1/*****************************************************************************
2
3Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2018, 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/row0trunc.h
22TRUNCATE implementation
23
24Created 2013-04-25 Krunal Bauskar
25*******************************************************/
26
27#ifndef row0trunc_h
28#define row0trunc_h
29
30#include "row0mysql.h"
31#include "dict0boot.h"
32#include "fil0fil.h"
33#include "srv0start.h"
34#include "ut0new.h"
35
36#include <vector>
37
38/** The information of TRUNCATE log record.
39This class handles the recovery stage of TRUNCATE table. */
40class truncate_t {
41
42public:
43 /**
44 Constructor
45
46 @param old_table_id old table id assigned to table before truncate
47 @param new_table_id new table id that will be assigned to table
48 after truncate
49 @param dir_path directory path */
50 truncate_t(
51 table_id_t old_table_id,
52 table_id_t new_table_id,
53 const char* dir_path);
54
55 /**
56 Constructor
57
58 @param log_file_name parse the log file during recovery to populate
59 information related to table to truncate */
60 truncate_t(const char* log_file_name);
61
62 /**
63 Consturctor
64
65 @param space_id space in which table reisde
66 @param name table name
67 @param tablespace_flags tablespace flags use for recreating tablespace
68 @param log_flags page format flag
69 @param recv_lsn lsn of redo log record. */
70 truncate_t(
71 ulint space_id,
72 const char* name,
73 ulint tablespace_flags,
74 ulint log_flags,
75 lsn_t recv_lsn);
76
77 /** Destructor */
78 ~truncate_t();
79
80 /** The index information of MLOG_FILE_TRUNCATE redo record */
81 struct index_t {
82
83 /* Default copy constructor and destructor should be OK. */
84
85 index_t();
86
87 /**
88 Set the truncate log values for a compressed table.
89 @return DB_CORRUPTION or error code */
90 dberr_t set(const dict_index_t* index);
91
92 typedef std::vector<byte, ut_allocator<byte> > fields_t;
93
94 /** Index id */
95 index_id_t m_id;
96
97 /** Index type */
98 ulint m_type;
99
100 /** Root Page Number */
101 ulint m_root_page_no;
102
103 /** New Root Page Number.
104 Note: This field is not persisted to TRUNCATE log but used
105 during truncate table fix-up for updating SYS_XXXX tables. */
106 ulint m_new_root_page_no;
107
108 /** Number of index fields */
109 ulint m_n_fields;
110
111 /** DATA_TRX_ID column position. */
112 ulint m_trx_id_pos;
113
114 /** Compressed table field meta data, encode by
115 page_zip_fields_encode. Empty for non-compressed tables.
116 Should be NUL terminated. */
117 fields_t m_fields;
118 };
119
120 /**
121 @return the directory path, can be NULL */
122 const char* get_dir_path() const
123 {
124 return(m_dir_path);
125 }
126
127 /**
128 Register index information
129
130 @param index index information logged as part of truncate log. */
131 void add(index_t& index)
132 {
133 m_indexes.push_back(index);
134 }
135
136 /**
137 Add table to truncate post recovery.
138
139 @param ptr table information need to complete truncate of table. */
140 static void add(truncate_t* ptr)
141 {
142 s_tables.push_back(ptr);
143 }
144
145 /**
146 Clear registered index vector */
147 void clear()
148 {
149 m_indexes.clear();
150 }
151
152 /**
153 @return old table id of the table to truncate */
154 table_id_t old_table_id() const
155 {
156 return(m_old_table_id);
157 }
158
159 /**
160 @return new table id of the table to truncate */
161 table_id_t new_table_id() const
162 {
163 return(m_new_table_id);
164 }
165
166 /**
167 Update root page number in SYS_XXXX tables.
168
169 @param trx transaction object
170 @param table_id table id for which information needs to
171 be updated.
172 @param reserve_dict_mutex if TRUE, acquire/release
173 dict_sys->mutex around call to pars_sql.
174 @param mark_index_corrupted if true, then mark index corrupted
175 @return DB_SUCCESS or error code */
176 dberr_t update_root_page_no(
177 trx_t* trx,
178 table_id_t table_id,
179 ibool reserve_dict_mutex,
180 bool mark_index_corrupted) const;
181
182 /** Create an index for a table.
183 @param[in] table_name table name, for which to create
184 the index
185 @param[in,out] space tablespace
186 @param[in] index_type type of index to truncate
187 @param[in] index_id id of index to truncate
188 @param[in] btr_redo_create_info control info for ::btr_create()
189 @param[in,out] mtr mini-transaction covering the
190 create index
191 @return root page no or FIL_NULL on failure */
192 inline ulint create_index(
193 const char* table_name,
194 fil_space_t* space,
195 ulint index_type,
196 index_id_t index_id,
197 const btr_create_t& btr_redo_create_info,
198 mtr_t* mtr) const;
199
200 /** Create the indexes for a table
201 @param[in] table_name table name, for which to create the
202 indexes
203 @param[in,out] space tablespace
204 @param[in] format_flags page format flags
205 @return DB_SUCCESS or error code. */
206 inline dberr_t create_indexes(
207 const char* table_name,
208 fil_space_t* space,
209 ulint format_flags);
210
211 /** Check if index has been modified since TRUNCATE log snapshot
212 was recorded.
213 @param[in] space tablespace
214 @param[in] root_page_no index root page number
215 @return true if modified else false */
216 inline bool is_index_modified_since_logged(
217 const fil_space_t* space,
218 ulint root_page_no) const;
219
220 /** Drop indexes for a table.
221 @param[in,out] space tablespace
222 @return DB_SUCCESS or error code. */
223 void drop_indexes(fil_space_t* space) const;
224
225 /**
226 Parses log record during recovery
227 @param start_ptr buffer containing log body to parse
228 @param end_ptr buffer end
229
230 @return DB_SUCCESS or error code */
231 dberr_t parse(
232 byte* start_ptr,
233 const byte* end_ptr);
234
235 /** Parse MLOG_TRUNCATE log record from REDO log file during recovery.
236 @param[in,out] start_ptr buffer containing log body to parse
237 @param[in] end_ptr buffer end
238 @param[in] space_id tablespace identifier
239 @return parsed upto or NULL. */
240 static byte* parse_redo_entry(
241 byte* start_ptr,
242 const byte* end_ptr,
243 ulint space_id);
244
245 /**
246 Write a log record for truncating a single-table tablespace.
247
248 @param start_ptr buffer to write log record
249 @param end_ptr buffer end
250 @param space_id space id
251 @param tablename the table name in the usual
252 databasename/tablename format of InnoDB
253 @param flags tablespace flags
254 @param format_flags page format
255 @param lsn lsn while logging */
256 dberr_t write(
257 byte* start_ptr,
258 byte* end_ptr,
259 ulint space_id,
260 const char* tablename,
261 ulint flags,
262 ulint format_flags,
263 lsn_t lsn) const;
264
265 /**
266 @return number of indexes parsed from the truncate log record */
267 size_t indexes() const;
268
269 /**
270 Truncate a single-table tablespace. The tablespace must be cached
271 in the memory cache.
272
273 Note: This is defined in fil0fil.cc because it needs to access some
274 types that are local to that file.
275
276 @param space_id space id
277 @param dir_path directory path
278 @param tablename the table name in the usual
279 databasename/tablename format of InnoDB
280 @param flags tablespace flags
281 @param default_size if true, truncate to default size if tablespace
282 is being newly re-initialized.
283 @return DB_SUCCESS or error */
284 static dberr_t truncate(
285 ulint space_id,
286 const char* dir_path,
287 const char* tablename,
288 ulint flags,
289 bool default_size);
290
291 /**
292 Fix the table truncate by applying information parsed from TRUNCATE log.
293 Fix-up includes re-creating table (drop and re-create indexes)
294 @return error code or DB_SUCCESS */
295 static dberr_t fixup_tables_in_system_tablespace();
296
297 /**
298 Fix the table truncate by applying information parsed from TRUNCATE log.
299 Fix-up includes re-creating tablespace.
300 @return error code or DB_SUCCESS */
301 static dberr_t fixup_tables_in_non_system_tablespace();
302
303 /**
304 Check whether a tablespace was truncated during recovery
305 @param space_id tablespace id to check
306 @return true if the tablespace was truncated */
307 static bool is_tablespace_truncated(ulint space_id);
308
309 /** Was tablespace truncated (on crash before checkpoint).
310 If the MLOG_TRUNCATE redo-record is still available then tablespace
311 was truncated and checkpoint is yet to happen.
312 @param[in] space_id tablespace id to check.
313 @return true if tablespace was truncated. */
314 static bool was_tablespace_truncated(ulint space_id);
315
316 /** Get the lsn associated with space.
317 @param[in] space_id tablespace id to check.
318 @return associated lsn. */
319 static lsn_t get_truncated_tablespace_init_lsn(ulint space_id);
320
321private:
322 typedef std::vector<index_t, ut_allocator<index_t> > indexes_t;
323
324 /** Space ID of tablespace */
325 ulint m_space_id;
326
327 /** ID of table that is being truncated. */
328 table_id_t m_old_table_id;
329
330 /** New ID that will be assigned to table on truncation. */
331 table_id_t m_new_table_id;
332
333 /** Data dir path of tablespace */
334 char* m_dir_path;
335
336 /** Table name */
337 char* m_tablename;
338
339 /** Tablespace Flags */
340 ulint m_tablespace_flags;
341
342 /** Format flags (log flags; stored in page-no field of header) */
343 ulint m_format_flags;
344
345 /** Index meta-data */
346 indexes_t m_indexes;
347
348 /** LSN of TRUNCATE log record. */
349 lsn_t m_log_lsn;
350
351 /** Log file name. */
352 char* m_log_file_name;
353
354 /** Encryption information of the table */
355 fil_encryption_t m_encryption;
356 uint32_t m_key_id;
357
358 /** Vector of tables to truncate. */
359 typedef std::vector<truncate_t*, ut_allocator<truncate_t*> >
360 tables_t;
361
362 /** Information about tables to truncate post recovery */
363 static tables_t s_tables;
364
365 /** Information about truncated table
366 This is case when truncate is complete but checkpoint hasn't. */
367 typedef std::map<ulint, lsn_t> truncated_tables_t;
368 static truncated_tables_t s_truncated_tables;
369
370public:
371 /** If true then fix-up of table is active and so while creating
372 index instead of grabbing information from dict_index_t, grab it
373 from parsed truncate log record. */
374 static bool s_fix_up_active;
375};
376
377/**
378Parse truncate log file. */
379class TruncateLogParser {
380
381public:
382
383 /**
384 Scan and Parse truncate log files.
385
386 @param dir_path look for log directory in following path
387 @return DB_SUCCESS or error code. */
388 static dberr_t scan_and_parse(
389 const char* dir_path);
390
391private:
392 typedef std::vector<char*, ut_allocator<char*> >
393 trunc_log_files_t;
394
395private:
396 /**
397 Scan to find out truncate log file from the given directory path.
398
399 @param dir_path look for log directory in following path.
400 @param log_files cache to hold truncate log file name found.
401 @return DB_SUCCESS or error code. */
402 static dberr_t scan(
403 const char* dir_path,
404 trunc_log_files_t& log_files);
405
406 /**
407 Parse the log file and populate table to truncate information.
408 (Add this table to truncate information to central vector that is then
409 used by truncate fix-up routine to fix-up truncate action of the table.)
410
411 @param log_file_name log file to parse
412 @return DB_SUCCESS or error code. */
413 static dberr_t parse(
414 const char* log_file_name);
415};
416
417
418/**
419Truncates a table for MySQL.
420@param table table being truncated
421@param trx transaction covering the truncate
422@return error code or DB_SUCCESS */
423dberr_t
424row_truncate_table_for_mysql(dict_table_t* table, trx_t* trx);
425
426#endif /* row0trunc_h */
427
428