MySQL  8.0.18
Source Code Documentation
row0merge.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 2005, 2019, 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, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 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 St, Fifth Floor, Boston, MA 02110-1301 USA
24 
25 *****************************************************************************/
26 
27 /** @file include/row0merge.h
28  Index build routines using a merge sort
29 
30  Created 13/06/2005 Jan Lindstrom
31  *******************************************************/
32 
33 #ifndef row0merge_h
34 #define row0merge_h
35 
36 #include "btr0types.h"
37 #include "data0data.h"
38 #include "dict0types.h"
39 #include "lock0types.h"
40 #include "mtr0mtr.h"
41 #include "que0types.h"
42 #include "rem0rec.h"
43 #include "rem0types.h"
44 #include "row0mysql.h"
45 #include "srv0srv.h"
46 #include "trx0types.h"
47 #include "univ.i"
48 #include "ut0stage.h"
49 
50 // Forward declaration
52 
53 /** @brief Block size for I/O operations in merge sort.
54 
55 The minimum is UNIV_PAGE_SIZE, or page_get_free_space_of_empty()
56 rounded to a power of 2.
57 
58 When not creating a PRIMARY KEY that contains column prefixes, this
59 can be set as small as UNIV_PAGE_SIZE / 2. */
60 typedef byte row_merge_block_t;
61 
62 /** @brief Secondary buffer for I/O operations of merge records.
63 
64 This buffer is used for writing or reading a record that spans two
65 row_merge_block_t. Thus, it must be able to hold one merge record,
66 whose maximum size is the same as the minimum size of
67 row_merge_block_t. */
68 typedef byte mrec_buf_t[UNIV_PAGE_SIZE_MAX];
69 
70 /** @brief Merge record in row_merge_block_t.
71 
72 The format is the same as a record in ROW_FORMAT=COMPACT with the
73 exception that the REC_N_NEW_EXTRA_BYTES are omitted. */
74 typedef byte mrec_t;
75 
76 /** Merge record in row_merge_buf_t */
77 struct mtuple_t {
78  dfield_t *fields; /*!< data fields */
79 };
80 
81 /** Buffer for sorting in main memory. */
83  mem_heap_t *heap; /*!< memory heap where allocated */
84  dict_index_t *index; /*!< the index the tuples belong to */
85  ulint total_size; /*!< total amount of data bytes */
86  ulint n_tuples; /*!< number of data tuples */
87  ulint max_tuples; /*!< maximum number of data tuples */
88  mtuple_t *tuples; /*!< array of data tuples */
89  mtuple_t *tmp_tuples; /*!< temporary copy of tuples,
90  for sorting */
91 };
92 
93 /** Information about temporary files used in merge sort */
94 struct merge_file_t {
95  int fd; /*!< file descriptor */
96  ulint offset; /*!< file offset (end of file) */
97  ib_uint64_t n_rec; /*!< number of records in the file */
98 };
99 
100 /** Index field definition */
102  ulint col_no; /*!< column offset */
103  ulint prefix_len; /*!< column prefix length, or 0
104  if indexing the whole column */
105  bool is_v_col; /*!< whether this is a virtual column */
106  bool is_multi_value; /*!< whether it has multi-value */
107  bool is_ascending; /*!< true=ASC, false=DESC */
108 };
109 
110 /** Definition of an index being created */
111 struct index_def_t {
112  const char *name; /*!< index name */
113  bool rebuild; /*!< whether the table is rebuilt */
114  ulint ind_type; /*!< 0, DICT_UNIQUE,
115  or DICT_CLUSTERED */
116  ulint key_number; /*!< MySQL key number,
117  or ULINT_UNDEFINED if none */
118  ulint n_fields; /*!< number of fields in index */
119  index_field_t *fields; /*!< field definitions */
120  st_mysql_ftparser *parser; /*!< fulltext parser plugin */
121  bool is_ngram; /*!< true if it's ngram parser */
122  bool srid_is_valid; /*!< true if we want to check SRID
123  while inserting to index */
124  uint32_t srid; /*!< SRID obtained from dd column */
125 };
126 
127 /** Structure for reporting duplicate records. */
129  dict_index_t *index; /*!< index being sorted */
130  struct TABLE *table; /*!< MySQL table object */
131  const ulint *col_map; /*!< mapping of column numbers
132  in table to the rebuilt table
133  (index->table), or NULL if not
134  rebuilding table */
135  ulint n_dup; /*!< number of duplicates */
136 };
137 
138 /** Report a duplicate key. */
140  row_merge_dup_t *dup, /*!< in/out: for reporting duplicates */
141  const dfield_t *entry); /*!< in: duplicate index entry */
142 /** Sets an exclusive lock on a table, for the duration of creating indexes.
143  @return error code or DB_SUCCESS */
144 dberr_t row_merge_lock_table(trx_t *trx, /*!< in/out: transaction */
145  dict_table_t *table, /*!< in: table to lock */
146  enum lock_mode mode) /*!< in: LOCK_X or LOCK_S */
147  MY_ATTRIBUTE((warn_unused_result));
148 /** Drop those indexes which were created before an error occurred.
149  The data dictionary must have been locked exclusively by the caller,
150  because the transaction will not be committed. */
152  trx_t *trx, /*!< in/out: transaction */
153  dict_table_t *table, /*!< in/out: table containing the indexes */
154  ibool locked); /*!< in: TRUE=table locked,
155  FALSE=may need to do a lazy drop */
156 
157 /**Create temporary merge files in the given paramater path, and if
158 UNIV_PFS_IO defined, register the file descriptor with Performance Schema.
159 @param[in] path location for creating temporary merge files.
160 @return File descriptor */
161 int row_merge_file_create_low(const char *path)
162  MY_ATTRIBUTE((warn_unused_result));
163 
164 /** Destroy a merge file. And de-register the file from Performance Schema
165  if UNIV_PFS_IO is defined. */
166 void row_merge_file_destroy_low(int fd); /*!< in: merge file descriptor */
167 
168 /** Provide a new pathname for a table that is being renamed if it belongs to
169  a file-per-table tablespace. The caller is responsible for freeing the
170  memory allocated for the return value.
171  @return new pathname of tablespace file, or NULL if space = 0 */
172 char *row_make_new_pathname(dict_table_t *table, /*!< in: table to be renamed */
173  const char *new_name); /*!< in: new name */
174 /** Rename the tables in the data dictionary. The data dictionary must
175  have been locked exclusively by the caller, because the transaction
176  will not be committed.
177  @return error code or DB_SUCCESS */
179  dict_table_t *old_table, /*!< in/out: old table, renamed to
180  tmp_name */
181  dict_table_t *new_table, /*!< in/out: new table, renamed to
182  old_table->name */
183  const char *tmp_name, /*!< in: new name for old_table */
184  trx_t *trx) /*!< in/out: dictionary transaction */
185  MY_ATTRIBUTE((warn_unused_result));
186 
187 /** Create the index and load in to the dictionary.
188 @param[in,out] trx trx (sets error_state)
189 @param[in,out] table the index is on this table
190 @param[in] index_def the index definition
191 @param[in] add_v new virtual columns added along with add
192  index call
193 @return index, or NULL on error */
195  const index_def_t *index_def,
196  const dict_add_v_col_t *add_v);
197 
198 /** Drop a table. The caller must have ensured that the background stats
199  thread is not processing the table. This can be done by calling
200  dict_stats_wait_bg_to_stop_using_table() after locking the dictionary and
201  before calling this function.
202  @return DB_SUCCESS or error code */
204  trx_t *trx, /*!< in: transaction */
205  dict_table_t *table); /*!< in: table instance to drop */
206 
207 /** Build indexes on a table by reading a clustered index, creating a temporary
208 file containing index entries, merge sorting these index entries and inserting
209 sorted index entries to indexes.
210 @param[in] trx transaction
211 @param[in] old_table table where rows are read from
212 @param[in] new_table table where indexes are created; identical to
213 old_table unless creating a PRIMARY KEY
214 @param[in] online true if creating indexes online
215 @param[in] indexes indexes to be created
216 @param[in] key_numbers MySQL key numbers
217 @param[in] n_indexes size of indexes[]
218 @param[in,out] table MySQL table, for reporting erroneous key value
219 if applicable
220 @param[in] add_cols default values of added columns, or NULL
221 @param[in] col_map mapping of old column numbers to new ones, or
222 NULL if old_table == new_table
223 @param[in] add_autoinc number of added AUTO_INCREMENT columns, or
224 ULINT_UNDEFINED if none is added
225 @param[in,out] sequence autoinc sequence
226 @param[in] skip_pk_sort whether the new PRIMARY KEY will follow
227 existing order
228 @param[in,out] stage performance schema accounting object, used by
229 ALTER TABLE. stage->begin_phase_read_pk() will be called at the beginning of
230 this function and it will be passed to other functions for further accounting.
231 @param[in] add_v new virtual columns added along with indexes
232 @param[in] eval_table mysql table used to evaluate virtual column
233  value, see innobase_get_computed_value().
234 @return DB_SUCCESS or error code */
236  trx_t *trx, dict_table_t *old_table, dict_table_t *new_table, bool online,
237  dict_index_t **indexes, const ulint *key_numbers, ulint n_indexes,
238  struct TABLE *table, const dtuple_t *add_cols, const ulint *col_map,
239  ulint add_autoinc, ib_sequence_t &sequence, bool skip_pk_sort,
240  ut_stage_alter_t *stage, const dict_add_v_col_t *add_v,
241  struct TABLE *eval_table) MY_ATTRIBUTE((warn_unused_result));
242 
243 /** Write a buffer to a block.
244 @param[in] buf sorted buffer
245 @param[in] of output file
246 @param[out] block buffer for writing to file */
247 void row_merge_buf_write(const row_merge_buf_t *buf, const merge_file_t *of,
248  row_merge_block_t *block);
249 
250 /** Sort a buffer. */
251 void row_merge_buf_sort(
252  row_merge_buf_t *buf, /*!< in/out: sort buffer */
253  row_merge_dup_t *dup); /*!< in/out: reporter of duplicates
254  (NULL if non-unique index) */
255 /** Write a merge block to the file system.
256  @return true if request was successful, false if fail */
257 ibool row_merge_write(int fd, /*!< in: file descriptor */
258  ulint offset, /*!< in: offset where to write,
259  in number of row_merge_block_t elements */
260  const void *buf); /*!< in: data */
261 /** Empty a sort buffer.
262  @return sort buffer */
264  row_merge_buf_t *buf) /*!< in,own: sort buffer */
265  MY_ATTRIBUTE((warn_unused_result));
266 
267 /** Create a merge file int the given location.
268 @param[out] merge_file merge file structure
269 @param[in] path location for creating temporary file
270 @return file descriptor, or -1 on failure */
271 int row_merge_file_create(merge_file_t *merge_file, const char *path);
272 
273 /** Merge disk files.
274 @param[in] trx transaction
275 @param[in] dup descriptor of index being created
276 @param[in,out] file file containing index entries
277 @param[in,out] block 3 buffers
278 @param[in,out] tmpfd temporary file handle
279 @param[in,out] stage performance schema accounting object, used by
280 ALTER TABLE. If not NULL, stage->begin_phase_sort() will be called initially
281 and then stage->inc() will be called for each record processed.
282 @return DB_SUCCESS or error code */
284  merge_file_t *file, row_merge_block_t *block, int *tmpfd,
285  ut_stage_alter_t *stage = NULL);
286 
287 /** Allocate a sort buffer.
288  @return own: sort buffer */
290  dict_index_t *index) /*!< in: secondary index */
291  MY_ATTRIBUTE((warn_unused_result, malloc));
292 /** Deallocate a sort buffer. */
293 void row_merge_buf_free(
294  row_merge_buf_t *buf); /*!< in,own: sort buffer to be freed */
295 /** Destroy a merge file. */
297  merge_file_t *merge_file); /*!< in/out: merge file structure */
298 /** Read a merge block from the file system.
299  @return true if request was successful, false if fail */
300 ibool row_merge_read(int fd, /*!< in: file descriptor */
301  ulint offset, /*!< in: offset where to read
302  in number of row_merge_block_t
303  elements */
304  row_merge_block_t *buf); /*!< out: data */
305 /** Read a merge record.
306  @return pointer to next record, or NULL on I/O error or end of list */
307 const byte *row_merge_read_rec(
308  row_merge_block_t *block, /*!< in/out: file buffer */
309  mrec_buf_t *buf, /*!< in/out: secondary buffer */
310  const byte *b, /*!< in: pointer to record */
311  const dict_index_t *index, /*!< in: index of the record */
312  int fd, /*!< in: file descriptor */
313  ulint *foffs, /*!< in/out: file offset */
314  const mrec_t **mrec, /*!< out: pointer to merge record,
315  or NULL on end of list
316  (non-NULL on I/O error) */
317  ulint *offsets) /*!< out: offsets of mrec */
318  MY_ATTRIBUTE((warn_unused_result));
319 #endif /* row0merge.h */
Record manager global types.
Information about temporary files used in merge sort.
Definition: row0merge.h:94
dberr_t row_merge_drop_table(trx_t *trx, dict_table_t *table)
Drop a table.
Definition: row0merge.cc:3572
Supplementary code to performance schema stage instrumentation.
Buffer for sorting in main memory.
Definition: row0merge.h:82
int row_merge_file_create_low(const char *path)
Create temporary merge files in the given paramater path, and if UNIV_PFS_IO defined, register the file descriptor with Performance Schema.
Definition: row0merge.cc:3346
bool is_multi_value
whether it has multi-value
Definition: row0merge.h:106
dict_index_t * index
index being sorted
Definition: row0merge.h:129
Definition: trx0trx.h:780
bool rebuild
whether the table is rebuilt
Definition: row0merge.h:113
bool is_ngram
true if it&#39;s ngram parser
Definition: row0merge.h:121
The transaction lock system global types.
#define malloc(A)
Definition: fts0ast.h:41
Data structure for a database table.
Definition: dict0mem.h:1529
Data structure for newly added virtual column in a table.
Definition: dict0mem.h:658
ulint ind_type
0, DICT_UNIQUE, or DICT_CLUSTERED
Definition: row0merge.h:114
Index field definition.
Definition: row0merge.h:101
void row_merge_drop_indexes(trx_t *trx, dict_table_t *table, ibool locked)
Drop those indexes which were created before an error occurred.
Definition: row0merge.cc:3169
Definition of an index being created.
Definition: row0merge.h:111
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:343
byte row_merge_block_t
Block size for I/O operations in merge sort.
Definition: row0merge.h:51
void row_merge_buf_write(const row_merge_buf_t *buf, const merge_file_t *of, row_merge_block_t *block)
Write a buffer to a block.
SQL data field and tuple.
Definition: table.h:1301
struct TABLE * table
MySQL table object.
Definition: row0merge.h:130
The server main program.
Query graph global types.
dberr_t row_merge_lock_table(trx_t *trx, dict_table_t *table, enum lock_mode mode)
Sets an exclusive lock on a table, for the duration of creating indexes.
Definition: row0merge.cc:3150
bool is_ascending
true=ASC, false=DESC
Definition: row0merge.h:107
ulint n_dup
number of duplicates
Definition: row0merge.h:135
Generate the next autoinc based on a snapshot of the session auto_increment_increment and auto_increm...
Definition: handler0alter.h:59
int fd
file descriptor
Definition: row0merge.h:95
ulint prefix_len
column prefix length, or 0 if indexing the whole column
Definition: row0merge.h:103
The index tree general types.
long long sequence(UDF_INIT *initid, UDF_ARGS *args, unsigned char *, unsigned char *)
Definition: udf_example.cc:565
char * index(const char *, int c)
Definition: mysql.cc:2862
Data dictionary global types.
ulint key_number
MySQL key number, or ULINT_UNDEFINED if none.
Definition: row0merge.h:116
uint32_t srid
SRID obtained from dd column.
Definition: row0merge.h:124
Interface between Innobase row operations and MySQL.
ibool row_merge_write(int fd, ulint offset, const void *buf)
Write a merge block to the file system.
Definition: row0merge.cc:1102
bool srid_is_valid
true if we want to check SRID while inserting to index
Definition: row0merge.h:122
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:714
index_field_t * fields
field definitions
Definition: row0merge.h:119
dberr_t row_merge_sort(trx_t *trx, const row_merge_dup_t *dup, merge_file_t *file, row_merge_block_t *block, int *tmpfd, ut_stage_alter_t *stage=NULL)
Merge disk files.
Definition: row0merge.cc:2848
bool is_v_col
whether this is a virtual column
Definition: row0merge.h:105
dberr_t
Definition: db0err.h:38
mtuple_t * tuples
array of data tuples
Definition: row0merge.h:88
ib_uint64_t n_rec
number of records in the file
Definition: row0merge.h:97
ulint n_fields
number of fields in index
Definition: row0merge.h:118
dberr_t row_merge_rename_tables_dict(dict_table_t *old_table, dict_table_t *new_table, const char *tmp_name, trx_t *trx)
Rename the tables in the data dictionary.
void row_merge_dup_report(row_merge_dup_t *dup, const dfield_t *entry)
Report a duplicate key.
Definition: row0merge.cc:879
static char * path
Definition: mysqldump.cc:125
dict_index_t * row_merge_create_index(trx_t *trx, dict_table_t *table, const index_def_t *index_def, const dict_add_v_col_t *add_v)
Create the index and load in to the dictionary.
Definition: row0merge.cc:3456
ulint max_tuples
maximum number of data tuples
Definition: row0merge.h:87
Structure for an SQL data field.
Definition: data0data.h:644
ulint col_no
column offset
Definition: row0merge.h:102
Transaction system global type definitions.
const byte * row_merge_read_rec(row_merge_block_t *block, mrec_buf_t *buf, const byte *b, const dict_index_t *index, int fd, ulint *foffs, const mrec_t **mrec, ulint *offsets)
Read a merge record.
Definition: row0merge.cc:1132
void row_merge_buf_free(row_merge_buf_t *buf)
Deallocate a sort buffer.
Definition: row0merge.cc:394
ulint total_size
total amount of data bytes
Definition: row0merge.h:85
ibool row_merge_read(int fd, ulint offset, row_merge_block_t *buf)
Read a merge block from the file system.
Definition: row0merge.cc:1067
Definition: plugin_ftparser.h:211
Structure for reporting duplicate records.
Definition: row0merge.h:128
void row_merge_file_destroy_low(int fd)
Destroy a merge file.
Definition: row0merge.cc:3402
mem_heap_t * heap
memory heap where allocated
Definition: row0merge.h:83
st_mysql_ftparser * parser
fulltext parser plugin
Definition: row0merge.h:120
char * row_make_new_pathname(dict_table_t *table, const char *new_name)
Provide a new pathname for a table that is being renamed if it belongs to a file-per-table tablespace...
Definition: row0merge.cc:3438
int row_merge_file_create(merge_file_t *merge_file, const char *path)
Create a merge file int the given location.
Definition: row0merge.cc:3387
row_merge_buf_t * row_merge_buf_create(dict_index_t *index)
Allocate a sort buffer.
Definition: row0merge.cc:350
handler * file
Definition: table.h:1303
Class used to report ALTER TABLE progress via performance_schema.
Definition: ut0stage.h:77
const char * name
index name
Definition: row0merge.h:112
dfield_t * fields
data fields
Definition: row0merge.h:78
byte mrec_t
Merge record in row_merge_block_t.
Definition: row0merge.h:74
const ulint * col_map
mapping of column numbers in table to the rebuilt table (index->table), or NULL if not rebuilding tab...
Definition: row0merge.h:131
void row_merge_buf_sort(row_merge_buf_t *buf, row_merge_dup_t *dup)
Sort a buffer.
Definition: row0merge.cc:991
byte mrec_buf_t[UNIV_PAGE_SIZE_MAX]
Secondary buffer for I/O operations of merge records.
Definition: row0merge.h:68
#define NULL
Definition: types.h:55
ulint offset
file offset (end of file)
Definition: row0merge.h:96
Merge record in row_merge_buf_t.
Definition: row0merge.h:77
row_merge_buf_t * row_merge_buf_empty(row_merge_buf_t *buf)
Empty a sort buffer.
Definition: row0merge.cc:372
Mini-transaction buffer.
ulint n_tuples
number of data tuples
Definition: row0merge.h:86
unsigned char byte
Blob class.
Definition: common.h:159
dberr_t row_merge_build_indexes(trx_t *trx, dict_table_t *old_table, dict_table_t *new_table, bool online, dict_index_t **indexes, const ulint *key_numbers, ulint n_indexes, struct TABLE *table, const dtuple_t *add_cols, const ulint *col_map, ulint add_autoinc, ib_sequence_t &sequence, bool skip_pk_sort, ut_stage_alter_t *stage, const dict_add_v_col_t *add_v, struct TABLE *eval_table)
Build indexes on a table by reading a clustered index, creating a temporary file containing index ent...
Definition: row0merge.cc:3629
lock_mode
Definition: lock0types.h:51
dict_index_t * index
the index the tuples belong to
Definition: row0merge.h:84
Definition: completion_hash.h:34
void row_merge_file_destroy(merge_file_t *merge_file)
Destroy a merge file.
Definition: row0merge.cc:3423
Record manager.
Data structure for an index.
Definition: dict0mem.h:875
mtuple_t * tmp_tuples
temporary copy of tuples, for sorting
Definition: row0merge.h:89