MySQL  8.0.22
Source Code Documentation
row0merge.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 2005, 2020, Oracle and/or its affiliates.
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.
139 @param[in,out] dup For reporting duplicates
140 @param[in] entry Duplicate index entry */
142 
143 /** Sets an exclusive lock on a table, for the duration of creating indexes.
144  @return error code or DB_SUCCESS */
145 dberr_t row_merge_lock_table(trx_t *trx, /*!< in/out: transaction */
146  dict_table_t *table, /*!< in: table to lock */
147  enum lock_mode mode) /*!< in: LOCK_X or LOCK_S */
148  MY_ATTRIBUTE((warn_unused_result));
149 /** Drop those indexes which were created before an error occurred.
150  The data dictionary must have been locked exclusively by the caller,
151  because the transaction will not be committed. */
153  trx_t *trx, /*!< in/out: transaction */
154  dict_table_t *table, /*!< in/out: table containing the indexes */
155  ibool locked); /*!< in: TRUE=table locked,
156  FALSE=may need to do a lazy drop */
157 
158 /**Create temporary merge files in the given paramater path, and if
159 UNIV_PFS_IO defined, register the file descriptor with Performance Schema.
160 @param[in] path location for creating temporary merge files.
161 @return File descriptor */
162 int row_merge_file_create_low(const char *path)
163  MY_ATTRIBUTE((warn_unused_result));
164 
165 /** Destroy a merge file. And de-register the file from Performance Schema
166  if UNIV_PFS_IO is defined. */
167 void row_merge_file_destroy_low(int fd); /*!< in: merge file descriptor */
168 
169 /** Provide a new pathname for a table that is being renamed if it belongs to
170  a file-per-table tablespace. The caller is responsible for freeing the
171  memory allocated for the return value.
172  @return new pathname of tablespace file, or NULL if space = 0 */
173 char *row_make_new_pathname(dict_table_t *table, /*!< in: table to be renamed */
174  const char *new_name); /*!< in: new name */
175 /** Rename the tables in the data dictionary. The data dictionary must
176  have been locked exclusively by the caller, because the transaction
177  will not be committed.
178  @return error code or DB_SUCCESS */
180  dict_table_t *old_table, /*!< in/out: old table, renamed to
181  tmp_name */
182  dict_table_t *new_table, /*!< in/out: new table, renamed to
183  old_table->name */
184  const char *tmp_name, /*!< in: new name for old_table */
185  trx_t *trx) /*!< in/out: dictionary transaction */
186  MY_ATTRIBUTE((warn_unused_result));
187 
188 /** Create the index and load in to the dictionary.
189 @param[in,out] trx trx (sets error_state)
190 @param[in,out] table the index is on this table
191 @param[in] index_def the index definition
192 @param[in] add_v new virtual columns added along with add
193  index call
194 @return index, or NULL on error */
196  const index_def_t *index_def,
197  const dict_add_v_col_t *add_v);
198 
199 /** Drop a table. The caller must have ensured that the background stats
200  thread is not processing the table. This can be done by calling
201  dict_stats_wait_bg_to_stop_using_table() after locking the dictionary and
202  before calling this function.
203  @return DB_SUCCESS or error code */
205  trx_t *trx, /*!< in: transaction */
206  dict_table_t *table); /*!< in: table instance to drop */
207 
208 /** Build indexes on a table by reading a clustered index, creating a temporary
209 file containing index entries, merge sorting these index entries and inserting
210 sorted index entries to indexes.
211 @param[in] trx transaction
212 @param[in] old_table table where rows are read from
213 @param[in] new_table table where indexes are created; identical to
214 old_table unless creating a PRIMARY KEY
215 @param[in] online true if creating indexes online
216 @param[in] indexes indexes to be created
217 @param[in] key_numbers MySQL key numbers
218 @param[in] n_indexes size of indexes[]
219 @param[in,out] table MySQL table, for reporting erroneous key value
220 if applicable
221 @param[in] add_cols default values of added columns, or NULL
222 @param[in] col_map mapping of old column numbers to new ones, or
223 NULL if old_table == new_table
224 @param[in] add_autoinc number of added AUTO_INCREMENT columns, or
225 ULINT_UNDEFINED if none is added
226 @param[in,out] sequence autoinc sequence
227 @param[in] skip_pk_sort whether the new PRIMARY KEY will follow
228 existing order
229 @param[in,out] stage performance schema accounting object, used by
230 ALTER TABLE. stage->begin_phase_read_pk() will be called at the beginning of
231 this function and it will be passed to other functions for further accounting.
232 @param[in] add_v new virtual columns added along with indexes
233 @param[in] eval_table mysql table used to evaluate virtual column
234  value, see innobase_get_computed_value().
235 @return DB_SUCCESS or error code */
237  trx_t *trx, dict_table_t *old_table, dict_table_t *new_table, bool online,
238  dict_index_t **indexes, const ulint *key_numbers, ulint n_indexes,
239  struct TABLE *table, const dtuple_t *add_cols, const ulint *col_map,
240  ulint add_autoinc, ib_sequence_t &sequence, bool skip_pk_sort,
241  ut_stage_alter_t *stage, const dict_add_v_col_t *add_v,
242  struct TABLE *eval_table) MY_ATTRIBUTE((warn_unused_result));
243 
244 /** Write a buffer to a block.
245 @param[in] buf sorted buffer
246 @param[in] of output file
247 @param[out] block buffer for writing to file */
248 void row_merge_buf_write(const row_merge_buf_t *buf, const merge_file_t *of,
249  row_merge_block_t *block);
250 
251 /** Sort a buffer.
252 @param[in,out] buf Sort buffer
253 @param[in,out] dup Reporter of duplicates (null if non-unique index) */
255 
256 /** Write a merge block to the file system.
257  @return true if request was successful, false if fail */
258 ibool row_merge_write(int fd, /*!< in: file descriptor */
259  ulint offset, /*!< in: offset where to write,
260  in number of row_merge_block_t elements */
261  const void *buf); /*!< in: data */
262 /** Empty a sort buffer.
263  @return sort buffer */
265  row_merge_buf_t *buf) /*!< in,own: sort buffer */
266  MY_ATTRIBUTE((warn_unused_result));
267 
268 /** Create a merge file in the given location.
269 @param[out] merge_file merge file structure
270 @param[in] path location for creating temporary file
271 @return file descriptor, or -1 on failure */
272 int row_merge_file_create(merge_file_t *merge_file, const char *path);
273 
274 /** Merge disk files.
275 @param[in] trx transaction
276 @param[in] dup descriptor of index being created
277 @param[in,out] file file containing index entries
278 @param[in,out] block 3 buffers
279 @param[in,out] tmpfd temporary file handle
280 @param[in,out] stage performance schema accounting object, used by
281 ALTER TABLE. If not NULL, stage->begin_phase_sort() will be called initially
282 and then stage->inc() will be called for each record processed.
283 @return DB_SUCCESS or error code */
285  merge_file_t *file, row_merge_block_t *block, int *tmpfd,
286  ut_stage_alter_t *stage = nullptr);
287 
288 /** Allocate a sort buffer.
289  @return own: sort buffer */
291  dict_index_t *index) /*!< in: secondary index */
292  MY_ATTRIBUTE((warn_unused_result, malloc));
293 /** Deallocate a sort buffer. */
294 void row_merge_buf_free(
295  row_merge_buf_t *buf); /*!< in,own: sort buffer to be freed */
296 /** Destroy a merge file. */
298  merge_file_t *merge_file); /*!< in/out: merge file structure */
299 /** Read a merge block from the file system.
300  @return true if request was successful, false if fail */
301 ibool row_merge_read(int fd, /*!< in: file descriptor */
302  ulint offset, /*!< in: offset where to read
303  in number of row_merge_block_t
304  elements */
305  row_merge_block_t *buf); /*!< out: data */
306 /** Read a merge record.
307  @return pointer to next record, or NULL on I/O error or end of list */
308 const byte *row_merge_read_rec(
309  row_merge_block_t *block, /*!< in/out: file buffer */
310  mrec_buf_t *buf, /*!< in/out: secondary buffer */
311  const byte *b, /*!< in: pointer to record */
312  const dict_index_t *index, /*!< in: index of the record */
313  int fd, /*!< in: file descriptor */
314  ulint *foffs, /*!< in/out: file offset */
315  const mrec_t **mrec, /*!< out: pointer to merge record,
316  or NULL on end of list
317  (non-NULL on I/O error) */
318  ulint *offsets) /*!< out: offsets of mrec */
319  MY_ATTRIBUTE((warn_unused_result));
320 #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:3579
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:3353
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:833
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.
mode
Definition: file_handle.h:59
#define malloc(A)
Definition: fts0ast.h:41
Data structure for a database table.
Definition: dict0mem.h:1532
Data structure for newly added virtual column in a table.
Definition: dict0mem.h:669
ulint ind_type
0, DICT_UNIQUE, or DICT_CLUSTERED
Definition: row0merge.h:114
Definition: buf0block_hint.cc:29
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:3176
Definition of an index being created.
Definition: row0merge.h:111
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:349
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:1363
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:3157
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:65
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:567
Data dictionary global types.
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=nullptr)
Merge disk files.
Definition: row0merge.cc:2856
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:1103
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:711
index_field_t * fields
field definitions
Definition: row0merge.h:119
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:885
static char * path
Definition: mysqldump.cc:131
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:3463
ulint max_tuples
maximum number of data tuples
Definition: row0merge.h:87
Structure for an SQL data field.
Definition: data0data.h:639
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:1133
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:1068
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:3409
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:3445
int row_merge_file_create(merge_file_t *merge_file, const char *path)
Create a merge file in the given location.
Definition: row0merge.cc:3394
row_merge_buf_t * row_merge_buf_create(dict_index_t *index)
Allocate a sort buffer.
Definition: row0merge.cc:350
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:996
byte mrec_buf_t[UNIV_PAGE_SIZE_MAX]
Secondary buffer for I/O operations of merge records.
Definition: row0merge.h:68
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.
Definition: os0file.h:85
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:3637
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:3430
Record manager.
Data structure for an index.
Definition: dict0mem.h:886
mtuple_t * tmp_tuples
temporary copy of tuples, for sorting
Definition: row0merge.h:89