MySQL  8.0.21
Source Code Documentation
row0merge.cc File Reference

New index creation routines using a merge sort. More...

#include <fcntl.h>
#include <math.h>
#include <sys/types.h>
#include <sql_class.h>
#include "btr0bulk.h"
#include "dict0crea.h"
#include "dict0dd.h"
#include "fsp0sysspace.h"
#include "ha_prototypes.h"
#include "handler0alter.h"
#include "lob0lob.h"
#include "lock0lock.h"
#include "my_psi_config.h"
#include "pars0pars.h"
#include "row0ext.h"
#include "row0ftsort.h"
#include "row0import.h"
#include "row0ins.h"
#include "row0log.h"
#include "row0merge.h"
#include "row0sel.h"
#include "trx0purge.h"
#include "ut0new.h"
#include "ut0sort.h"
#include "ut0stage.h"
#include "my_dbug.h"
#include "sql/table.h"

Classes

class  index_tuple_info_t
 Class that caches index row tuples made from a single cluster index page scan, and then insert into corresponding index tree. More...
 

Macros

#define FTS_PENDING_DOC_MEMORY_LIMIT   1000000
 
#define row_merge_buf_redundant_convert(trx, index, row_field, field, len, page_size, is_sdi, heap)
 
#define row_merge_tuple_sort_ctx(tuples, aux, low, high)   row_merge_tuple_sort(index, n_uniq, n_field, dup, tuples, aux, low, high)
 Wrapper for row_merge_tuple_sort() to inject some more context to UT_SORT_FUNCTION_BODY(). More...
 
#define row_merge_tuple_cmp_ctx(a, b)   row_merge_tuple_cmp(index, n_uniq, n_field, a, b, dup)
 Wrapper for row_merge_tuple_cmp() to inject some more context to UT_SORT_FUNCTION_BODY(). More...
 
#define ROW_MERGE_WRITE_GET_NEXT_LOW(N, INDEX, AT_END)
 Write a record via buffer 2 and read the next record to buffer N. More...
 
#define ROW_MERGE_WRITE_GET_NEXT(N, INDEX, AT_END)
 
#define row_merge_copy_blobs(trx, index, mrec, offsets, page_size, tuple, is_sdi, heap)
 

Functions

static dberr_t row_merge_insert_index_tuples (trx_t *trx, dict_index_t *index, const dict_table_t *old_table, int fd, row_merge_block_t *block, const row_merge_buf_t *row_buf, BtrBulk *btr_bulk, ut_stage_alter_t *stage=nullptr)
 Insert sorted data tuples to the index. More...
 
static void row_merge_buf_encode (byte **b, const dict_index_t *index, const mtuple_t *entry, ulint n_fields)
 Encode an index record. More...
 
static row_merge_buf_trow_merge_buf_create_low (mem_heap_t *heap, dict_index_t *index, ulint max_tuples, ulint buf_size)
 Allocate a sort buffer. More...
 
row_merge_buf_trow_merge_buf_create (dict_index_t *index)
 Allocate a sort buffer. More...
 
row_merge_buf_trow_merge_buf_empty (row_merge_buf_t *buf)
 Empty a sort buffer. More...
 
void row_merge_buf_free (row_merge_buf_t *buf)
 Deallocate a sort buffer. More...
 
static void row_merge_buf_redundant_convert_func (trx_t *trx, const dict_index_t *clust_index, const dfield_t *row_field, dfield_t *field, ulint len, const page_size_t &page_size, bool is_sdi, mem_heap_t *heap)
 Convert the field data from compact to redundant format. More...
 
static ulint row_merge_buf_add (row_merge_buf_t *buf, dict_index_t *fts_index, const dict_table_t *old_table, const dict_table_t *new_table, fts_psort_t *psort_info, const dtuple_t *row, const row_ext_t *ext, doc_id_t *doc_id, mem_heap_t *conv_heap, dberr_t *err, mem_heap_t **v_heap, TABLE *my_table, trx_t *trx, ulint *multi_val_added)
 Insert a data tuple into a sort buffer. More...
 
void row_merge_dup_report (row_merge_dup_t *dup, const dfield_t *entry)
 Report a duplicate key. More...
 
static int row_merge_tuple_cmp (const dict_index_t *index, ulint n_uniq, ulint n_field, const mtuple_t &a, const mtuple_t &b, row_merge_dup_t *dup)
 Compare two tuples. More...
 
static void row_merge_tuple_sort (const dict_index_t *index, ulint n_uniq, ulint n_field, row_merge_dup_t *dup, mtuple_t *tuples, mtuple_t *aux, ulint low, ulint high)
 Merge sort the tuple buffer in main memory. More...
 
void row_merge_buf_sort (row_merge_buf_t *buf, row_merge_dup_t *dup)
 Sort a buffer. More...
 
void row_merge_buf_write (const row_merge_buf_t *buf, const merge_file_t *of UNIV_UNUSED, row_merge_block_t *block)
 Write a buffer to a block. More...
 
static mem_heap_trow_merge_heap_create (const dict_index_t *index, mrec_buf_t **buf, ulint **offsets1, ulint **offsets2)
 Create a memory heap and allocate space for row_merge_rec_offsets() and mrec_buf_t[3]. More...
 
ibool row_merge_read (int fd, ulint offset, row_merge_block_t *buf)
 Read a merge block from the file system. More...
 
ibool row_merge_write (int fd, ulint offset, const void *buf)
 Write a merge block to the file system. More...
 
const byterow_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. More...
 
static void row_merge_write_rec_low (byte *b, ulint e, ulint size, int fd, ulint foffs, const mrec_t *mrec, const ulint *offsets)
 Write a merge record. More...
 
static byterow_merge_write_rec (row_merge_block_t *block, mrec_buf_t *buf, byte *b, int fd, ulint *foffs, const mrec_t *mrec, const ulint *offsets)
 Write a merge record. More...
 
static byterow_merge_write_eof (row_merge_block_t *block, byte *b, int fd, ulint *foffs)
 Write an end-of-list marker. More...
 
static int row_merge_tmpfile_if_needed (int *tmpfd, const char *path)
 Create a temporary file if it has not been created already. More...
 
static int row_merge_file_create_if_needed (merge_file_t *file, int *tmpfd, ulint nrec, const char *path)
 Create a temporary file for merge sort if it was not created already. More...
 
static void row_mtuple_create (const mtuple_t *mtuple, mtuple_t *prev_mtuple, ulint n_unique, mem_heap_t *heap)
 Copy the merge data tuple from another merge data tuple. More...
 
static int row_mtuple_cmp (const mtuple_t *prev_mtuple, const mtuple_t *current_mtuple, row_merge_dup_t *dup)
 Compare two merge data tuples. More...
 
static dberr_t row_merge_spatial_rows (trx_id_t trx_id, index_tuple_info_t **sp_tuples, ulint num_spatial, mem_heap_t *row_heap, mem_heap_t *sp_heap, btr_pcur_t *pcur, mtr_t *mtr, bool *mtr_committed)
 Insert cached spatial index rows. More...
 
static bool row_geo_field_is_valid (const dtuple_t *row, dict_index_t *index)
 Check if the geometry field is valid. More...
 
static dberr_t row_merge_read_clustered_index (trx_t *trx, struct TABLE *table, const dict_table_t *old_table, dict_table_t *new_table, bool online, dict_index_t **index, dict_index_t *fts_sort_idx, fts_psort_t *psort_info, merge_file_t *files, const ulint *key_numbers, ulint n_index, const dtuple_t *add_cols, const dict_add_v_col_t *add_v, const ulint *col_map, ulint add_autoinc, ib_sequence_t &sequence, row_merge_block_t *block, bool skip_pk_sort, int *tmpfd, ut_stage_alter_t *stage, struct TABLE *eval_table)
 Reads clustered index of the table and create temporary files containing the index entries for the indexes to be built. More...
 
static dberr_t row_merge_blocks (const row_merge_dup_t *dup, const merge_file_t *file, row_merge_block_t *block, ulint *foffs0, ulint *foffs1, merge_file_t *of, ut_stage_alter_t *stage)
 Merge two blocks of records on disk and write a bigger block. More...
 
static ibool row_merge_blocks_copy (const dict_index_t *index, const merge_file_t *file, row_merge_block_t *block, ulint *foffs0, merge_file_t *of, ut_stage_alter_t *stage)
 Copy a block of index entries. More...
 
static dberr_t row_merge (trx_t *trx, const row_merge_dup_t *dup, merge_file_t *file, row_merge_block_t *block, int *tmpfd, ulint *num_run, ulint *run_offset, ut_stage_alter_t *stage)
 Merge disk files. More...
 
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)
 Merge disk files. More...
 
static void row_merge_copy_blobs_func (trx_t *trx, const dict_index_t *index, const mrec_t *mrec, const ulint *offsets, const page_size_t &page_size, dtuple_t *tuple, bool is_sdi, mem_heap_t *heap)
 Copy externally stored columns to the data tuple. More...
 
static void row_merge_mtuple_to_dtuple (dict_index_t *index, dtuple_t *dtuple, const mtuple_t *mtuple)
 Convert a merge record to a typed data tuple. More...
 
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. More...
 
void row_merge_drop_indexes (trx_t *trx, dict_table_t *table, ibool locked)
 Drop indexes that were created before an error occurred. More...
 
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. More...
 
int row_merge_file_create (merge_file_t *merge_file, const char *path)
 Create a merge file in the given location. More...
 
void row_merge_file_destroy_low (int fd)
 Destroy a merge file. More...
 
void row_merge_file_destroy (merge_file_t *merge_file)
 Destroy a merge file. More...
 
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. More...
 
dict_index_trow_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. More...
 
dberr_t row_merge_drop_table (trx_t *trx, dict_table_t *table)
 Drop a table. More...
 
static void row_merge_write_redo (const dict_index_t *index)
 Write an MLOG_INDEX_LOAD record to indicate in the redo-log that redo-logging of individual index pages was disabled, and the flushing of such pages to the data files was completed. More...
 
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 entries, merge sorting these index entries and inserting sorted index entries to indexes. More...
 

Variables

bool srv_disable_sort_file_cache
 

Detailed Description

New index creation routines using a merge sort.

Created 12/4/2005 Jan Lindstrom Completed by Sunny Bains and Marko Makela

Macro Definition Documentation

◆ FTS_PENDING_DOC_MEMORY_LIMIT

#define FTS_PENDING_DOC_MEMORY_LIMIT   1000000

◆ row_merge_buf_redundant_convert

#define row_merge_buf_redundant_convert (   trx,
  index,
  row_field,
  field,
  len,
  page_size,
  is_sdi,
  heap 
)
Value:
row_merge_buf_redundant_convert_func(trx, index, row_field, field, len, \
page_size, is_sdi, heap)
static void row_merge_buf_redundant_convert_func(trx_t *trx, const dict_index_t *clust_index, const dfield_t *row_field, dfield_t *field, ulint len, const page_size_t &page_size, bool is_sdi, mem_heap_t *heap)
Convert the field data from compact to redundant format.
Definition: row0merge.cc:430

◆ row_merge_copy_blobs

#define row_merge_copy_blobs (   trx,
  index,
  mrec,
  offsets,
  page_size,
  tuple,
  is_sdi,
  heap 
)
Value:
row_merge_copy_blobs_func(trx, index, mrec, offsets, page_size, tuple, \
is_sdi, heap)
static void row_merge_copy_blobs_func(trx_t *trx, const dict_index_t *index, const mrec_t *mrec, const ulint *offsets, const page_size_t &page_size, dtuple_t *tuple, bool is_sdi, mem_heap_t *heap)
Copy externally stored columns to the data tuple.
Definition: row0merge.cc:2933

◆ row_merge_tuple_cmp_ctx

#define row_merge_tuple_cmp_ctx (   a,
 
)    row_merge_tuple_cmp(index, n_uniq, n_field, a, b, dup)

Wrapper for row_merge_tuple_cmp() to inject some more context to UT_SORT_FUNCTION_BODY().

Parameters
afirst tuple to be compared
bsecond tuple to be compared
Returns
positive, 0, negative, if a is greater, equal, less, than b, respectively

◆ row_merge_tuple_sort_ctx

#define row_merge_tuple_sort_ctx (   tuples,
  aux,
  low,
  high 
)    row_merge_tuple_sort(index, n_uniq, n_field, dup, tuples, aux, low, high)

Wrapper for row_merge_tuple_sort() to inject some more context to UT_SORT_FUNCTION_BODY().

Parameters
tuplesarray of tuples that being sorted
auxwork area, same size as tuples[]
lowlower bound of the sorting area, inclusive
highupper bound of the sorting area, inclusive

◆ ROW_MERGE_WRITE_GET_NEXT

#define ROW_MERGE_WRITE_GET_NEXT (   N,
  INDEX,
  AT_END 
)
Value:
do { \
if (stage != NULL) { \
stage->inc(); \
} \
ROW_MERGE_WRITE_GET_NEXT_LOW(N, INDEX, AT_END); \
} while (0)
std::atomic< Type > N
Definition: ut0counter.h:224
const std::string INDEX("INDEX")
#define NULL
Definition: types.h:54

◆ ROW_MERGE_WRITE_GET_NEXT_LOW

#define ROW_MERGE_WRITE_GET_NEXT_LOW (   N,
  INDEX,
  AT_END 
)
Value:
do { \
b2 = row_merge_write_rec(&block[2 * srv_sort_buf_size], &buf[2], b2, \
of->fd, &of->offset, mrec##N, offsets##N); \
if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
goto corrupt; \
} \
b##N = \
row_merge_read_rec(&block[N * srv_sort_buf_size], &buf[N], b##N, \
INDEX, file->fd, foffs##N, &mrec##N, offsets##N); \
if (UNIV_UNLIKELY(!b##N)) { \
if (mrec##N) { \
goto corrupt; \
} \
AT_END; \
} \
} while (0)
ulong srv_sort_buf_size
Sort buffer size in index creation.
Definition: srv0srv.cc:194
std::atomic< Type > N
Definition: ut0counter.h:224
const std::string INDEX("INDEX")
Definition: os0file.h:85
static byte * row_merge_write_rec(row_merge_block_t *block, mrec_buf_t *buf, byte *b, int fd, ulint *foffs, const mrec_t *mrec, const ulint *offsets)
Write a merge record.
Definition: row0merge.cc:1326

Write a record via buffer 2 and read the next record to buffer N.

Parameters
Nnumber of the buffer (0 or 1)
INDEXrecord descriptor
AT_ENDstatement to execute at end of input

Function Documentation

◆ row_geo_field_is_valid()

static bool row_geo_field_is_valid ( const dtuple_t row,
dict_index_t index 
)
static

Check if the geometry field is valid.

Parameters
[in]rowthe row
[in]indexspatial index
Returns
true if it's valid, false if it's invalid.

◆ row_make_new_pathname()

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.

The caller is responsible for freeing the memory allocated for the return value.

Returns
new pathname of tablespace file, or NULL if space = 0
Parameters
tablein: table to be renamed
new_namein: new name

◆ row_merge()

static dberr_t row_merge ( trx_t trx,
const row_merge_dup_t dup,
merge_file_t file,
row_merge_block_t block,
int *  tmpfd,
ulint *  num_run,
ulint *  run_offset,
ut_stage_alter_t stage 
)
static

Merge disk files.

Parameters
[in]trxtransaction
[in]dupdescriptor of index being created
[in,out]filefile containing index entries
[in,out]block3 buffers
[in,out]tmpfdtemporary file handle
[in,out]num_runNumber of runs that remain to be merged
[in,out]run_offsetArray that contains the first offset number for each merge run
[in,out]stageperformance schema accounting object, used by ALTER TABLE. If not NULL stage->inc() will be called for each record processed.
Returns
DB_SUCCESS or error code

< first input offset

< second input offset

< error code

< output file

< half the input file

< num of runs generated from this merge

◆ row_merge_blocks()

static dberr_t row_merge_blocks ( const row_merge_dup_t dup,
const merge_file_t file,
row_merge_block_t block,
ulint *  foffs0,
ulint *  foffs1,
merge_file_t of,
ut_stage_alter_t stage 
)
static

Merge two blocks of records on disk and write a bigger block.

Parameters
[in]dupdescriptor of index being created
[in]filefile containing index entries
[in,out]block3 buffers
[in,out]foffs0offset of first source list in the file
[in,out]foffs1offset of second source list in the file
[in,out]ofoutput file
[in,out]stageperformance schema accounting object, used by ALTER TABLE. If not NULL stage->inc() will be called for each record processed.
Returns
DB_SUCCESS or error code

< memory heap for offsets0, offsets1

< buffer for handling split mrec in block[]

< pointer to block[0]

< pointer to block[srv_sort_buf_size]

< pointer to block[2 * srv_sort_buf_size]

< merge rec, points to block[0] or buf[0]

< merge rec, points to block[srv_sort_buf_size] or buf[1]

◆ row_merge_blocks_copy()

static ibool row_merge_blocks_copy ( const dict_index_t index,
const merge_file_t file,
row_merge_block_t block,
ulint *  foffs0,
merge_file_t of,
ut_stage_alter_t stage 
)
static

Copy a block of index entries.

Parameters
[in]indexindex being created
[in]fileinput file
[in,out]block3 buffers
[in,out]foffs0input file offset
[in,out]ofoutput file
[in,out]stageperformance schema accounting object, used by ALTER TABLE. If not NULL stage->inc() will be called for each record processed.
Returns
true on success, false on failure

< memory heap for offsets0, offsets1

< buffer for handling split mrec in block[]

< pointer to block[0]

< pointer to block[2 * srv_sort_buf_size]

< merge rec, points to block[0]

◆ row_merge_buf_add()

static ulint row_merge_buf_add ( row_merge_buf_t buf,
dict_index_t fts_index,
const dict_table_t old_table,
const dict_table_t new_table,
fts_psort_t psort_info,
const dtuple_t row,
const row_ext_t ext,
doc_id_t doc_id,
mem_heap_t conv_heap,
dberr_t err,
mem_heap_t **  v_heap,
TABLE my_table,
trx_t trx,
ulint *  multi_val_added 
)
static

Insert a data tuple into a sort buffer.

Parameters
[in,out]bufsort buffer
[in]fts_indexfts index to be created
[in]old_tableoriginal table
[in]new_tablenew table
[in,out]psort_infoparallel sort info
[in]rowtable row
[in]extcache of externally stored column prefixes, or NULL
[in,out]doc_idDoc ID if we are creating FTS index
[in,out]conv_heapmemory heap where to allocate data when converting to ROW_FORMAT=REDUNDANT, or NULL when not to invoke row_merge_buf_redundant_convert()
[in,out]errset if error occurs
[in,out]v_heapheap memory to process data for virtual column
[in,out]my_tablemysql table object
[in]trxtransaction object
[in,out]multi_val_addednon-zero indicates this number of multi-value data has been put to the buffer, and it should just continue from this point, otherwise, this is a new row to be added to buffer. For the output, non-zero means the new number of multi-value data which have been handled, while zero means this is a normal row or all data of the multi-value data in this row have been parsed
Returns
number of rows added, 0 if out of space, or UNIV_NO_INDEX_VALUE if this is a multi-value index and current row has nothing valid to be indexed

◆ row_merge_buf_create()

row_merge_buf_t* row_merge_buf_create ( dict_index_t index)

Allocate a sort buffer.

Returns
own: sort buffer
Parameters
indexin: secondary index

◆ row_merge_buf_create_low()

static row_merge_buf_t* row_merge_buf_create_low ( mem_heap_t heap,
dict_index_t index,
ulint  max_tuples,
ulint  buf_size 
)
static

Allocate a sort buffer.

Returns
own: sort buffer
Parameters
heapin: heap where allocated
indexin: secondary index
max_tuplesin: maximum number of data tuples
buf_sizein: size of the buffer, in bytes

◆ row_merge_buf_empty()

row_merge_buf_t* row_merge_buf_empty ( row_merge_buf_t buf)

Empty a sort buffer.

Returns
sort buffer
Parameters
bufin,own: sort buffer

◆ row_merge_buf_encode()

static void row_merge_buf_encode ( byte **  b,
const dict_index_t index,
const mtuple_t entry,
ulint  n_fields 
)
static

Encode an index record.

Parameters
bin/out: pointer to current end of output buffer
indexin: index
entryin: index fields of the record to encode
n_fieldsin: number of fields in the entry

◆ row_merge_buf_free()

void row_merge_buf_free ( row_merge_buf_t buf)

Deallocate a sort buffer.

Parameters
bufin,own: sort buffer to be freed

◆ row_merge_buf_redundant_convert_func()

static void row_merge_buf_redundant_convert_func ( trx_t trx,
const dict_index_t clust_index,
const dfield_t row_field,
dfield_t field,
ulint  len,
const page_size_t page_size,
bool  is_sdi,
mem_heap_t heap 
)
static

Convert the field data from compact to redundant format.

Parameters
[in]trxcurrent transaction
[in]clust_indexclustered index being built
[in]row_fieldfield to copy from
[out]fieldfield to copy to
[in]lenlength of the field data
[in]page_sizecompressed BLOB page size, zero for uncompressed BLOBs
[in]is_sditrue for SDI indexes
[in,out]heapmemory heap where to allocate data when converting to ROW_FORMAT=REDUNDANT, or NULL when not to invoke row_merge_buf_redundant_convert().

◆ row_merge_buf_sort()

void row_merge_buf_sort ( row_merge_buf_t buf,
row_merge_dup_t dup 
)

Sort a buffer.

Parameters
bufin/out: sort buffer
dupin/out: reporter of duplicates (NULL if non-unique index)

◆ row_merge_buf_write()

void row_merge_buf_write ( const row_merge_buf_t buf,
const merge_file_t *of  UNIV_UNUSED,
row_merge_block_t block 
)

Write a buffer to a block.

Parameters
bufin: sorted buffer
UNIV_UNUSEDin: output file
blockout: buffer for writing to file

◆ row_merge_build_indexes()

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 entries, merge sorting these index entries and inserting sorted index entries to indexes.

Parameters
[in]trxtransaction
[in]old_tabletable where rows are read from
[in]new_tabletable where indexes are created; identical to old_table unless creating a PRIMARY KEY
[in]onlinetrue if creating indexes online
[in]indexesindexes to be created
[in]key_numbersMySQL key numbers
[in]n_indexessize of indexes[]
[in,out]tableMySQL table, for reporting erroneous key value if applicable
[in]add_colsdefault values of added columns, or NULL
[in]col_mapmapping of old column numbers to new ones, or NULL if old_table == new_table
[in]add_autoincnumber of added AUTO_INCREMENT columns, or ULINT_UNDEFINED if none is added
[in,out]sequenceautoinc sequence
[in]skip_pk_sortwhether the new PRIMARY KEY will follow existing order
[in,out]stageperformance schema accounting object, used by ALTER TABLE. stage->begin_phase_read_pk() will be called at the beginning of this function and it will be passed to other functions for further accounting.
[in]add_vnew virtual columns added along with indexes
[in]eval_tablemysql table used to evaluate virtual column value, see innobase_get_computed_value().
Returns
DB_SUCCESS or error code

◆ row_merge_copy_blobs_func()

static void row_merge_copy_blobs_func ( trx_t trx,
const dict_index_t index,
const mrec_t mrec,
const ulint *  offsets,
const page_size_t page_size,
dtuple_t tuple,
bool  is_sdi,
mem_heap_t heap 
)
static

Copy externally stored columns to the data tuple.

Parameters
[in]trxcurrent transaction
[in]indexindex dictionary object.
[in]mrecrecord containing BLOB pointers, or NULL to use tuple instead
[in]offsetsoffsets of mrec
[in]page_sizecompressed page size in bytes, or 0
[in,out]tupledata tuple
[in]is_sditrue for SDI Indexes
[in,out]heapmemory heap

◆ row_merge_create_index()

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.

Parameters
[in,out]trxtrx (sets error_state)
[in,out]tablethe index is on this table
[in]index_defthe index definition
[in]add_vnew virtual columns added along with add index call
Returns
index, or NULL on error

◆ row_merge_drop_indexes()

void row_merge_drop_indexes ( trx_t trx,
dict_table_t table,
ibool  locked 
)

Drop indexes that were created before an error occurred.

Drop those indexes which were created before an error occurred.

The data dictionary must have been locked exclusively by the caller, because the transaction will not be committed.

Parameters
trxin/out: dictionary transaction
tablein/out: table containing the indexes
lockedin: TRUE=table locked, FALSE=may need to do a lazy drop

◆ row_merge_drop_table()

dberr_t row_merge_drop_table ( trx_t trx,
dict_table_t table 
)

Drop a table.

The caller must have ensured that the background stats thread is not processing the table. This can be done by calling dict_stats_wait_bg_to_stop_using_table() after locking the dictionary and before calling this function.

Returns
DB_SUCCESS or error code
Parameters
trxin: transaction
tablein: table to drop

◆ row_merge_dup_report()

void row_merge_dup_report ( row_merge_dup_t dup,
const dfield_t entry 
)

Report a duplicate key.

Parameters
dupin/out: for reporting duplicates
entryin: duplicate index entry

◆ row_merge_file_create()

int row_merge_file_create ( merge_file_t merge_file,
const char *  path 
)

Create a merge file in the given location.

Create a merge file int the given location.

Parameters
[out]merge_filemerge file structure
[in]pathlocation for creating temporary file
Returns
file descriptor, or -1 on failure

◆ row_merge_file_create_if_needed()

static int row_merge_file_create_if_needed ( merge_file_t file,
int *  tmpfd,
ulint  nrec,
const char *  path 
)
static

Create a temporary file for merge sort if it was not created already.

Parameters
[in,out]filemerge file structure
[in]tmpfdtemporary file handle
[in]nrecnumber of records in the file
[in]pathlocation for creating temporary file
Returns
file descriptor, or -1 on failure

◆ row_merge_file_create_low()

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.

Parameters
[in]pathlocation for creating temporary merge files.
Returns
File descriptor

◆ row_merge_file_destroy()

void row_merge_file_destroy ( merge_file_t merge_file)

Destroy a merge file.

Parameters
merge_filein/out: merge file structure

◆ row_merge_file_destroy_low()

void row_merge_file_destroy_low ( int  fd)

Destroy a merge file.

And de-register the file from Performance Schema if UNIV_PFS_IO is defined.

Parameters
fdin: merge file descriptor

◆ row_merge_heap_create()

static mem_heap_t* row_merge_heap_create ( const dict_index_t index,
mrec_buf_t **  buf,
ulint **  offsets1,
ulint **  offsets2 
)
static

Create a memory heap and allocate space for row_merge_rec_offsets() and mrec_buf_t[3].

Returns
memory heap
Parameters
indexin: record descriptor
bufout: 3 buffers
offsets1out: offsets
offsets2out: offsets

◆ row_merge_insert_index_tuples()

static dberr_t row_merge_insert_index_tuples ( trx_t trx,
dict_index_t index,
const dict_table_t old_table,
int  fd,
row_merge_block_t block,
const row_merge_buf_t row_buf,
BtrBulk btr_bulk,
ut_stage_alter_t stage = nullptr 
)
static

Insert sorted data tuples to the index.

Parameters
[in]trxcurrent transaction
[in]indexindex to be inserted
[in]old_tableold table
[in]fdfile descriptor
[in,out]blockfile buffer
[in]row_bufrow_buf the sorted data tuples, or NULL if fd, block will be used instead
[in,out]btr_bulkbtr bulk instance
[in,out]stageperformance schema accounting object, used by ALTER TABLE. If not NULL stage->begin_phase_insert() will be called initially and then stage->inc() will be called for each record that is processed.
Returns
DB_SUCCESS or error number

◆ row_merge_lock_table()

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.

Returns
error code or DB_SUCCESS
Parameters
trxin/out: transaction
tablein: table to lock
modein: LOCK_X or LOCK_S

◆ row_merge_mtuple_to_dtuple()

static void row_merge_mtuple_to_dtuple ( dict_index_t index,
dtuple_t dtuple,
const mtuple_t mtuple 
)
static

Convert a merge record to a typed data tuple.

Note that externally stored fields are not copied to heap.

Parameters
[in,out]indexindex on the table
[in]mtuplemerge record
[in]dtupledata tuple of records

◆ row_merge_read()

ibool row_merge_read ( int  fd,
ulint  offset,
row_merge_block_t buf 
)

Read a merge block from the file system.

Returns
true if request was successful, false if fail
Parameters
fdin: file descriptor
offsetin: offset where to read in number of row_merge_block_t elements
bufout: data

◆ row_merge_read_clustered_index()

static dberr_t row_merge_read_clustered_index ( trx_t trx,
struct TABLE table,
const dict_table_t old_table,
dict_table_t new_table,
bool  online,
dict_index_t **  index,
dict_index_t fts_sort_idx,
fts_psort_t psort_info,
merge_file_t files,
const ulint *  key_numbers,
ulint  n_index,
const dtuple_t add_cols,
const dict_add_v_col_t add_v,
const ulint *  col_map,
ulint  add_autoinc,
ib_sequence_t sequence,
row_merge_block_t block,
bool  skip_pk_sort,
int *  tmpfd,
ut_stage_alter_t stage,
struct TABLE eval_table 
)
static

Reads clustered index of the table and create temporary files containing the index entries for the indexes to be built.

Parameters
[in]trxtransaction
[in,out]tableMySQL table object, for reporting erroneous records
[in]old_tabletable where rows are read from
[in]new_tabletable where indexes are created; identical to old_table unless creating a PRIMARY KEY
[in]onlinetrue if creating indexes online
[in]indexindexes to be created
[in]fts_sort_idxfull-text index to be created, or NULL
[in]psort_infoparallel sort info for fts_sort_idx creation, or NULL
[in]filestemporary files
[in]key_numbersMySQL key numbers to create
[in]n_indexnumber of indexes to create
[in]add_colsdefault values of added columns, or NULL
[in]add_vnewly added virtual columns along with indexes
[in]col_mapmapping of old column numbers to new ones, or NULL if old_table == new_table
[in]add_autoincnumber of added AUTO_INCREMENT columns, or ULINT_UNDEFINED if none is added
[in,out]sequenceautoinc sequence
[in,out]blockfile buffer
[in]skip_pk_sortwhether the new PRIMARY KEY will follow existing order
[in,out]tmpfdtemporary file handle
[in,out]stageperformance schema accounting object, used by ALTER TABLE. stage->n_pk_recs_inc() will be called for each record read and stage->inc() will be called for each page read.
[in]eval_tablemysql table used to evaluate virtual column value, see innobase_get_computed_value().
Returns
DB_SUCCESS or error

◆ row_merge_read_rec()

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.

Returns
pointer to next record, or NULL on I/O error or end of list
Parameters
blockin/out: file buffer
bufin/out: secondary buffer
bin: pointer to record
indexin: index of the record
fdin: file descriptor
foffsin/out: file offset
mrecout: pointer to merge record, or NULL on end of list (non-NULL on I/O error)
offsetsout: offsets of mrec

◆ row_merge_sort()

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 
)

Merge disk files.

Parameters
[in]trxtransaction
[in]dupdescriptor of index being created
[in,out]filefile containing index entries
[in,out]block3 buffers
[in,out]tmpfdtemporary file handle
[in,out]stageperformance schema accounting object, used by ALTER TABLE. If not NULL, stage->begin_phase_sort() will be called initially and then stage->inc() will be called for each record processed.
Returns
DB_SUCCESS or error code

◆ row_merge_spatial_rows()

static dberr_t row_merge_spatial_rows ( trx_id_t  trx_id,
index_tuple_info_t **  sp_tuples,
ulint  num_spatial,
mem_heap_t row_heap,
mem_heap_t sp_heap,
btr_pcur_t pcur,
mtr_t mtr,
bool mtr_committed 
)
static

Insert cached spatial index rows.

Parameters
[in]trx_idtransaction id
[in]sp_tuplescached spatial rows
[in]num_spatialnumber of spatial indexes
[in,out]row_heapheap for insert
[in,out]sp_heapheap for tuples
[in,out]pcurcluster index cursor
[in,out]mtrmini transaction
[in,out]mtr_committedwhether scan_mtr got committed
Returns
DB_SUCCESS or error number

◆ row_merge_tmpfile_if_needed()

static int row_merge_tmpfile_if_needed ( int *  tmpfd,
const char *  path 
)
static

Create a temporary file if it has not been created already.

Parameters
[in,out]tmpfdtemporary file handle
[in]pathlocation for creating temporary file
Returns
file descriptor, or -1 on failure

◆ row_merge_tuple_cmp()

static int row_merge_tuple_cmp ( const dict_index_t index,
ulint  n_uniq,
ulint  n_field,
const mtuple_t a,
const mtuple_t b,
row_merge_dup_t dup 
)
static

Compare two tuples.

Parameters
[in]indexindex tree
[in]n_uniqnumber of unique fields
[in]n_fieldnumber of fields
[in]afirst tuple to be compared
[in]bsecond tuple to be compared
[in,out]dupfor reporting duplicates, NULL if non-unique index
Returns
positive, 0, negative if a is greater, equal, less, than b, respectively

◆ row_merge_tuple_sort()

static void row_merge_tuple_sort ( const dict_index_t index,
ulint  n_uniq,
ulint  n_field,
row_merge_dup_t dup,
mtuple_t tuples,
mtuple_t aux,
ulint  low,
ulint  high 
)
static

Merge sort the tuple buffer in main memory.

Parameters
indexin: index tree
n_uniqin: number of unique fields
n_fieldin: number of fields
dupin/out: reporter of duplicates (NULL if non-unique index)
tuplesin/out: tuples
auxin/out: work area
lowin: lower bound of the sorting area, inclusive
highin: upper bound of the sorting area, exclusive

◆ row_merge_write()

ibool row_merge_write ( int  fd,
ulint  offset,
const void *  buf 
)

Write a merge block to the file system.

Returns
true if request was successful, false if fail
Parameters
fdin: file descriptor
offsetin: offset where to write, in number of row_merge_block_t elements
bufin: data

◆ row_merge_write_eof()

static byte* row_merge_write_eof ( row_merge_block_t block,
byte b,
int  fd,
ulint *  foffs 
)
static

Write an end-of-list marker.

Returns
pointer to end of block, or NULL on error
Parameters
blockin/out: file buffer
bin: pointer to end of block
fdin: file descriptor
foffsin/out: file offset

◆ row_merge_write_rec()

static byte* row_merge_write_rec ( row_merge_block_t block,
mrec_buf_t buf,
byte b,
int  fd,
ulint *  foffs,
const mrec_t mrec,
const ulint *  offsets 
)
static

Write a merge record.

Returns
pointer to end of block, or NULL on error
Parameters
blockin/out: file buffer
bufin/out: secondary buffer
bin: pointer to end of block
fdin: file descriptor
foffsin/out: file offset
mrecin: record to write
offsetsin: offsets of mrec

◆ row_merge_write_rec_low()

static void row_merge_write_rec_low ( byte b,
ulint  e,
ulint  size,
int  fd,
ulint  foffs,
const mrec_t mrec,
const ulint *  offsets 
)
static

Write a merge record.

Parameters
bout: buffer
ein: encoded extra_size
sizein: total size to write
fdin: file descriptor
foffsin: file offset
mrecin: record to write
offsetsin: offsets of mrec

◆ row_merge_write_redo()

static void row_merge_write_redo ( const dict_index_t index)
static

Write an MLOG_INDEX_LOAD record to indicate in the redo-log that redo-logging of individual index pages was disabled, and the flushing of such pages to the data files was completed.

Parameters
[in]indexan index tree on which redo logging was disabled

◆ row_mtuple_cmp()

static int row_mtuple_cmp ( const mtuple_t prev_mtuple,
const mtuple_t current_mtuple,
row_merge_dup_t dup 
)
static

Compare two merge data tuples.

Parameters
[in]prev_mtuplemerge data tuple
[in]current_mtuplemerge data tuple
[in,out]dupreporter of duplicates
Return values
positive,0,negativeif current_mtuple is greater, equal, less, than last_mtuple.

◆ row_mtuple_create()

static void row_mtuple_create ( const mtuple_t mtuple,
mtuple_t prev_mtuple,
ulint  n_unique,
mem_heap_t heap 
)
static

Copy the merge data tuple from another merge data tuple.

Parameters
[in]mtuplesource merge data tuple
[in,out]prev_mtupledestination merge data tuple
[in]n_uniquenumber of unique fields exist in the mtuple
[in,out]heapmemory heap where last_mtuple allocated

Variable Documentation

◆ srv_disable_sort_file_cache

bool srv_disable_sort_file_cache