44 # define posix_fadvise(fd, offset, len, advice)  
   51 static ibool    row_merge_print_read;
 
   53 static ibool    row_merge_print_write;
 
   56 static ibool    row_merge_print_block;
 
   58 static ibool    row_merge_print_block_read;
 
   60 static ibool    row_merge_print_block_write;
 
   65 UNIV_INTERN 
char        srv_disable_sort_file_cache;
 
   70 static __attribute__((nonnull))
 
   72 row_merge_tuple_print(
 
   80         for (j = 0; j < n_fields; j++) {
 
   81                 const dfield_t* field = &entry->fields[j];
 
   87                         ulint   len             = 
ut_min(field_len, 20);
 
   94                         if (len != field_len) {
 
   95                                 fprintf(f, 
" (total %lu bytes)", field_len);
 
  105 static __attribute__((nonnull))
 
  107 row_merge_buf_encode(
 
  121                 index, entry->
fields, n_fields, &extra_size);
 
  122         ut_ad(size >= extra_size);
 
  125         if (extra_size + 1 < 0x80) {
 
  126                 *(*b)++ = (byte) (extra_size + 1);
 
  128                 ut_ad((extra_size + 1) < 0x8000);
 
  129                 *(*b)++ = (byte) (0x80 | ((extra_size + 1) >> 8));
 
  130                 *(*b)++ = (byte) (extra_size + 1);
 
  142 static __attribute__((malloc, nonnull))
 
  144 row_merge_buf_create_low(
 
  155         ut_ad(max_tuples > 0);
 
  187         buf_size = (
sizeof *
buf);
 
  191         buf = row_merge_buf_create_low(heap, index, max_tuples, buf_size);
 
  205         ulint           buf_size        = 
sizeof *
buf;
 
  262         ulint                   n_row_added = 0;
 
  263         DBUG_ENTER(
"row_merge_buf_add");
 
  270                 "ib_row_merge_buf_add_two",
 
  271                 if (buf->
n_tuples >= 2) DBUG_RETURN(0););
 
  273         UNIV_PREFETCH_R(row->
fields);
 
  289         ifield = dict_index_get_nth_field(index, 0);
 
  291         for (i = 0; i < n_fields; i++, field++, ifield++) {
 
  313                                 field, &write_doc_id, 
sizeof(write_doc_id));
 
  315                         field->type.mtype = ifield->
col->
mtype;
 
  316                         field->type.prtype = ifield->
col->
prtype;
 
  317                         field->type.mbminmaxlen = DATA_MBMINMAXLEN(0, 0);
 
  318                         field->type.len = ifield->
col->
len;
 
  320                         row_field = dtuple_get_nth_field(row, col_no);
 
  325                         if (index->
type & DICT_FTS) {
 
  337                                         doc_field = dtuple_get_nth_field(
 
  342                                                 dfield_get_data(doc_field)));
 
  346                                                         "FTS Doc ID is zero. " 
  362                                 value = 
static_cast<byte*
>(
 
  364                                 memcpy(value, field->data, field->len);
 
  367                                 doc_item->
field = field;
 
  368                                 doc_item->
doc_id = *doc_id;
 
  374                                         psort_info[bucket].fts_doc_list,
 
  391                         if (UNIV_LIKELY_NULL(buf)) {
 
  403                         if (UNIV_LIKELY_NULL(buf)) {
 
  417                                 static_cast<char*>(dfield_get_data(field)));
 
  421                 ut_ad(len <= col->len || col->
mtype == DATA_BLOB);
 
  441                         ut_ad(len <= fixed_len);
 
  442                         ut_ad(!mbmaxlen || len >= mbminlen
 
  443                               * (fixed_len / mbmaxlen));
 
  450                            || (col->
len < 256 && col->
mtype != DATA_BLOB)) {
 
  464         if (index->
type & DICT_FTS) {
 
  465                 DBUG_RETURN(n_row_added);
 
  474                         index, entry->
fields, n_fields, &extra);
 
  476                 ut_ad(data_size + extra_size == size);
 
  477                 ut_ad(extra_size == extra);
 
  485         data_size += (extra_size + 1) + ((extra_size + 1) >= 0x80);
 
  494         buf->total_size += data_size;
 
  504         } 
while (--n_fields);
 
  506         DBUG_RETURN(n_row_added);
 
  528 static __attribute__((warn_unused_result))
 
  545         ut_ad(n_uniq <= n_field);
 
  552         } 
while (!cmp && --n);
 
  563                 for (
const dfield_t* df = a.fields; df != af; df++) {
 
  575         for (n = n_field - n_uniq + 1; --
n; ) {
 
  595 #define row_merge_tuple_sort_ctx(tuples, aux, low, high)                \ 
  596         row_merge_tuple_sort(n_uniq, n_field, dup, tuples, aux, low, high) 
  602 #define row_merge_tuple_cmp_ctx(a,b)                    \ 
  603         row_merge_tuple_cmp(n_uniq, n_field, a, b, dup) 
  607 static __attribute__((nonnull(4,5)))
 
  609 row_merge_tuple_sort(
 
  623         ut_ad(n_uniq <= n_field);
 
  626                               tuples, aux, low, high, row_merge_tuple_cmp_ctx);
 
  660         for (ulint i = 0; i < buf->
n_tuples; i++) {
 
  663                 row_merge_buf_encode(&b, index, entry, n_fields);
 
  666                 if (row_merge_print_write) {
 
  667                         fprintf(stderr, 
"row_merge_buf_write %p,%d,%lu %lu",
 
  668                                 (
void*) b, of->fd, (ulong) of->offset,
 
  670                         row_merge_tuple_print(stderr, entry, n_fields);
 
  679 #ifdef UNIV_DEBUG_VALGRIND 
  685         if (row_merge_print_write) {
 
  686                 fprintf(stderr, 
"row_merge_buf_write %p,%d,%lu EOF\n",
 
  687                         (
void*) b, of->fd, (ulong) of->offset);
 
  698 row_merge_heap_create(
 
  705         ulint           i       = 1 + REC_OFFS_HEADER_SIZE
 
  712         *offsets1 = 
static_cast<ulint*
>(
 
  714         *offsets2 = 
static_cast<ulint*
>(
 
  717         (*offsets1)[0] = (*offsets2)[0] = 
i;
 
  739         DBUG_EXECUTE_IF(
"row_merge_read_failure", 
return(FALSE););
 
  742         if (row_merge_print_block_read) {
 
  743                 fprintf(stderr, 
"row_merge_read fd=%d ofs=%lu\n",
 
  749         if (row_merge_print_block_read) {
 
  750                 fprintf(stderr, 
"row_merge_read fd=%d ofs=%lu\n",
 
  757 #ifdef POSIX_FADV_DONTNEED 
  762         if (UNIV_UNLIKELY(!success)) {
 
  765                         "  InnoDB: failed to read merge block at "UINT64PF
"\n",
 
  769         return(UNIV_LIKELY(success));
 
  788         DBUG_EXECUTE_IF(
"row_merge_write_failure", 
return(FALSE););
 
  790         ret = os_file_write(
"(merge)", 
OS_FILE_FROM_FD(fd), buf, ofs, buf_len);
 
  793         if (row_merge_print_block_write) {
 
  794                 fprintf(stderr, 
"row_merge_write fd=%d ofs=%lu\n",
 
  799 #ifdef POSIX_FADV_DONTNEED 
  802         posix_fadvise(fd, ofs, buf_len, POSIX_FADV_DONTNEED);
 
  805         return(UNIV_LIKELY(ret));
 
  832         ut_ad(b >= &block[0]);
 
  839         ut_ad(*offsets == 1 + REC_OFFS_HEADER_SIZE
 
  844         if (UNIV_UNLIKELY(!extra_size)) {
 
  848                 if (row_merge_print_read) {
 
  849                         fprintf(stderr, 
"row_merge_read %p,%p,%d,%lu EOF\n",
 
  850                                 (
const void*) b, (
const void*) block,
 
  857         if (extra_size >= 0x80) {
 
  872                 extra_size = (extra_size & 0x7f) << 8;
 
  881         if (UNIV_UNLIKELY(b + extra_size >= &block[srv_sort_buf_size])) {
 
  887                 ut_ad(avail_size < 
sizeof *buf);
 
  888                 memcpy(*buf, b, avail_size);
 
  899                 memcpy(*buf + avail_size, b, extra_size - avail_size);
 
  900                 b += extra_size - avail_size;
 
  902                 *mrec = *buf + extra_size;
 
  911                 ut_a(extra_size + data_size < 
sizeof *buf);
 
  912                 ut_a(b + data_size < &block[srv_sort_buf_size]);
 
  915                 memcpy(*buf + extra_size, b, data_size);
 
  921         *mrec = b + extra_size;
 
  926         ut_ad(extra_size + data_size < 
sizeof *buf);
 
  928         b += extra_size + data_size;
 
  930         if (UNIV_LIKELY(b < &block[srv_sort_buf_size])) {
 
  938         b -= extra_size + data_size;
 
  940         memcpy(*buf, b, avail_size);
 
  941         *mrec = *buf + extra_size;
 
  947         offsets[2] = (ulint) *mrec;
 
  948         offsets[3] = (ulint) index;
 
  960         memcpy(*buf + avail_size, b, extra_size + data_size - avail_size);
 
  961         b += extra_size + data_size - avail_size;
 
  965         if (row_merge_print_read) {
 
  966                 fprintf(stderr, 
"row_merge_read %p,%p,%d,%lu ",
 
  967                         (
const void*) b, (
const void*) block,
 
  981 row_merge_write_rec_low(
 
  991         const ulint*    offsets)
 
  993 # define row_merge_write_rec_low(b, e, size, fd, foffs, mrec, offsets)  \ 
  994         row_merge_write_rec_low(b, e, mrec, offsets) 
  998         const byte* 
const end = b + 
size;
 
 1001         if (row_merge_print_write) {
 
 1002                 fprintf(stderr, 
"row_merge_write %p,%d,%lu ",
 
 1003                         (
void*) b, fd, (ulong) foffs);
 
 1012                 *b++ = (byte) (0x80 | (e >> 8));
 
 1025 row_merge_write_rec(
 
 1033         const ulint*            offsets)
 
 1041         ut_ad(b >= &block[0]);
 
 1042         ut_ad(b < &block[srv_sort_buf_size]);
 
 1045         ut_ad(mrec < &block[0] || mrec > &block[srv_sort_buf_size]);
 
 1046         ut_ad(mrec < buf[0] || mrec > buf[1]);
 
 1051         size = extra_size + (extra_size >= 0x80)
 
 1054         if (UNIV_UNLIKELY(b + size >= &block[srv_sort_buf_size])) {
 
 1059                 row_merge_write_rec_low(buf[0],
 
 1060                                         extra_size, size, fd, *foffs,
 
 1066                 memcpy(b, buf[0], avail_size);
 
 1072                 UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
 
 1076                 memcpy(b, buf[0] + avail_size, size - avail_size);
 
 1077                 b += size - avail_size;
 
 1079                 row_merge_write_rec_low(b, extra_size, size, fd, *foffs,
 
 1092 row_merge_write_eof(
 
 1100         ut_ad(b >= &block[0]);
 
 1101         ut_ad(b < &block[srv_sort_buf_size]);
 
 1104         if (row_merge_print_write) {
 
 1105                 fprintf(stderr, 
"row_merge_write %p,%p,%d,%lu EOF\n",
 
 1106                         (
void*) b, (
void*) block, fd, (ulong) *foffs);
 
 1111         UNIV_MEM_ASSERT_RW(&block[0], b - &block[0]);
 
 1112         UNIV_MEM_ASSERT_W(&block[0], srv_sort_buf_size);
 
 1113 #ifdef UNIV_DEBUG_VALGRIND 
 1116         memset(b, 0xff, &block[srv_sort_buf_size] - b);
 
 1123         UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
 
 1131 static __attribute__((nonnull(1,2,3,4,6,9,10,16), warn_unused_result))
 
 1133 row_merge_read_clustered_index(
 
 1153         const ulint*            key_numbers,
 
 1159         const ulint*            col_map,
 
 1177         ulint                   n_nonnull = 0;  
 
 1179         ulint*                  nonnull = NULL; 
 
 1183         ibool                   add_doc_id = FALSE;
 
 1185         ibool                   fts_pll_sort = FALSE;
 
 1186         ib_int64_t              sig_count = 0;
 
 1187         DBUG_ENTER(
"row_merge_read_clustered_index");
 
 1189         ut_ad((old_table == new_table) == !col_map);
 
 1190         ut_ad(!add_cols || col_map);
 
 1192         trx->op_info = 
"reading clustered index";
 
 1194 #ifdef FTS_INTERNAL_DIAG_PRINT 
 1195         DEBUG_FTS_SORT_PRINT(
"FTS_SORT: Start Create Index\n");
 
 1201                 mem_alloc(n_index * 
sizeof *merge_buf));
 
 1203         for (ulint i = 0; i < n_index; i++) {
 
 1204                 if (index[i]->
type & DICT_FTS) {
 
 1210                         fts_index = index[
i];
 
 1214                         add_doc_id = DICT_TF2_FLAG_IS_SET(
 
 1226                         fts_pll_sort = TRUE;
 
 1228                         fts_parallel_sort_event =
 
 1229                                  psort_info[0].psort_common->sort_event;
 
 1240         clust_index = dict_table_get_first_index(old_table);
 
 1245         if (old_table != new_table) {
 
 1251                 nonnull = 
static_cast<ulint*
>(
 
 1253                                   * 
sizeof *nonnull));
 
 1256                         if (dict_table_get_nth_col(old_table, i)->prtype
 
 1261                         const ulint j = col_map[
i];
 
 1263                         if (j == ULINT_UNDEFINED) {
 
 1268                         if (dict_table_get_nth_col(new_table, j)->prtype
 
 1270                                 nonnull[n_nonnull++] = j;
 
 1288                 page_cur_t*     cur     = btr_pcur_get_page_cur(&pcur);
 
 1294                                 err = DB_INTERRUPTED;
 
 1295                                 trx->error_key_num = 0;
 
 1299                         if (online && old_table != new_table) {
 
 1301                                 if (err != DB_SUCCESS) {
 
 1302                                         trx->error_key_num = 0;
 
 1307 # define dbug_run_purge false 
 1309                         bool    dbug_run_purge = 
false;
 
 1312                                 "ib_purge_on_create_index_page_switch",
 
 1313                                 dbug_run_purge = 
true;);
 
 1332                                               btr_pcur_get_block(&pcur))
 
 1333                                       == clust_index->
page);
 
 1338                                 if (dbug_run_purge) {
 
 1357                                 btr_pcur_restore_position(
 
 1377                                         page_cur_get_page(cur), &mtr);
 
 1383                                 block = page_cur_get_block(cur);
 
 1399                 rec = page_cur_get_rec(cur);
 
 1401                 offsets = rec_get_offsets(rec, clust_index, NULL,
 
 1402                                           ULINT_UNDEFINED, &row_heap);
 
 1424                         ut_ad(trx->read_view);
 
 1429                                             rec, clust_index, offsets))) {
 
 1433                                         rec, &mtr, clust_index, &offsets,
 
 1434                                         trx->read_view, &row_heap,
 
 1435                                         row_heap, &old_vers);
 
 1475                 row = 
row_build(ROW_COPY_POINTERS, clust_index,
 
 1476                                 rec, offsets, new_table,
 
 1477                                 add_cols, col_map, &ext, row_heap);
 
 1480                 for (ulint i = 0; i < n_nonnull; i++) {
 
 1483                         ut_ad(dfield_get_type(field)->prtype & DATA_NOT_NULL);
 
 1487                                 trx->error_key_num = 0;
 
 1499                 if (add_autoinc != ULINT_UNDEFINED) {
 
 1506                         dfield = dtuple_get_nth_field(row, add_autoinc);
 
 1511                         const dtype_t*  dtype = dfield_get_type(dfield);
 
 1512                         byte*   b = 
static_cast<byte*
>(dfield_get_data(dfield));
 
 1514                         if (sequence.eof()) {
 
 1516                                 trx->error_key_num = 0;
 
 1518                                 ib_errf(trx->mysql_thd, IB_LOG_LEVEL_ERROR,
 
 1519                                         ER_AUTOINC_READ_FAILED, 
"[NULL]");
 
 1524                         ulonglong       value = sequence++;
 
 1539                                         b, static_cast<float>(value));
 
 1544                                         b, static_cast<double>(value));
 
 1556                 for (ulint i = 0; i < n_index; i++) {
 
 1559                         ulint                   rows_added = 0;
 
 1562                             (row && (rows_added = row_merge_buf_add(
 
 1563                                         buf, fts_index, old_table,
 
 1564                                         psort_info, row, ext, &doc_id)))) {
 
 1569                                 file->
n_rec += rows_added;
 
 1570                                 if (doc_id > max_doc_id) {
 
 1571                                         max_doc_id = doc_id;
 
 1578                             && (!row || !doc_id)) {
 
 1600                                                 err = DB_DUPLICATE_KEY;
 
 1608                         } 
else if (online && new_table == old_table) {
 
 1637                                 err = DB_OUT_OF_FILE_SPACE;
 
 1638                                 trx->error_key_num = 
i;
 
 1642                         UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
 
 1645                         if (UNIV_LIKELY(row != NULL)) {
 
 1651                                     (!(rows_added = row_merge_buf_add(
 
 1652                                                 buf, fts_index, old_table,
 
 1653                                                 psort_info, row, ext,
 
 1660                                 file->
n_rec += rows_added;
 
 1668                 if (err != DB_SUCCESS) {
 
 1684 #ifdef FTS_INTERNAL_DIAG_PRINT 
 1685         DEBUG_FTS_SORT_PRINT(
"FTS_SORT: Complete Scan Table\n");
 
 1688                 bool    all_exit = 
false;
 
 1689                 ulint   trial_count = 0;
 
 1690                 const ulint max_trial_count = 10000;
 
 1699                                        1000000, sig_count);
 
 1702                         if (psort_info[i].child_status != FTS_CHILD_COMPLETE
 
 1703                             && psort_info[i].child_status != FTS_CHILD_EXITING) {
 
 1705                                         fts_parallel_sort_event);
 
 1717                                 if (psort_info[j].child_status
 
 1718                                     != FTS_CHILD_EXITING) {
 
 1725                 } 
while (!all_exit && trial_count < max_trial_count);
 
 1730                                 "Not all child sort threads exited" 
 1731                                 " when creating FTS index '%s'",
 
 1732                                 fts_sort_idx->name);
 
 1736 #ifdef FTS_INTERNAL_DIAG_PRINT 
 1737         DEBUG_FTS_SORT_PRINT(
"FTS_SORT: Complete Tokenization\n");
 
 1739         for (ulint i = 0; i < n_index; i++) {
 
 1753                         0, new_table, old_table->name, max_doc_id);
 
 1765 #define ROW_MERGE_WRITE_GET_NEXT(N, INDEX, AT_END)                      \ 
 1767                 b2 = row_merge_write_rec(&block[2 * srv_sort_buf_size], \ 
 1769                                          of->fd, &of->offset,           \ 
 1770                                          mrec##N, offsets##N);          \ 
 1771                 if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) {  \ 
 1774                 b##N = row_merge_read_rec(&block[N * srv_sort_buf_size],\ 
 1775                                           &buf[N], b##N, INDEX,         \ 
 1776                                           file->fd, foffs##N,           \ 
 1777                                           &mrec##N, offsets##N);        \ 
 1778                 if (UNIV_UNLIKELY(!b##N)) {                             \ 
 1789 static __attribute__((nonnull, warn_unused_result))
 
 1818         if (row_merge_print_block) {
 
 1820                         "row_merge_blocks fd=%d ofs=%lu + fd=%d ofs=%lu" 
 1821                         " = fd=%d ofs=%lu\n",
 
 1822                         file->fd, (ulong) *foffs0,
 
 1823                         file->fd, (ulong) *foffs1,
 
 1824                         of->fd, (ulong) of->offset);
 
 1828         heap = row_merge_heap_create(dup->index, &buf, &offsets0, &offsets1);
 
 1834             || !
row_merge_read(file->fd, *foffs1, &block[srv_sort_buf_size])) {
 
 1845                 &block[0], &buf[0], b0, dup->index,
 
 1846                 file->fd, foffs0, &mrec0, offsets0);
 
 1848                 &block[srv_sort_buf_size],
 
 1849                 &buf[srv_sort_buf_size], b1, dup->index,
 
 1850                 file->fd, foffs1, &mrec1, offsets1);
 
 1851         if (UNIV_UNLIKELY(!b0 && mrec0)
 
 1852             || UNIV_UNLIKELY(!b1 && mrec1)) {
 
 1857         while (mrec0 && mrec1) {
 
 1859                                 mrec0, mrec1, offsets0, offsets1,
 
 1860                                 dup->index, dup->table)) {
 
 1863                         return(DB_DUPLICATE_KEY);
 
 1865                         ROW_MERGE_WRITE_GET_NEXT(0, dup->index, 
goto merged);
 
 1868                         ROW_MERGE_WRITE_GET_NEXT(1, dup->index, 
goto merged);
 
 1879                         ROW_MERGE_WRITE_GET_NEXT(0, dup->index, 
goto done0);
 
 1886                         ROW_MERGE_WRITE_GET_NEXT(1, dup->index, 
goto done1);
 
 1892         b2 = row_merge_write_eof(&block[2 * srv_sort_buf_size],
 
 1893                                  b2, of->fd, &of->offset);
 
 1900 static __attribute__((nonnull, warn_unused_result))
 
 1902 row_merge_blocks_copy(
 
 1921         if (row_merge_print_block) {
 
 1923                         "row_merge_blocks_copy fd=%d ofs=%lu" 
 1924                         " = fd=%d ofs=%lu\n",
 
 1925                         file->fd, (ulong) foffs0,
 
 1926                         of->fd, (ulong) of->offset);
 
 1930         heap = row_merge_heap_create(index, &buf, &offsets0, &offsets1);
 
 1946                                 file->fd, foffs0, &mrec0, offsets0);
 
 1947         if (UNIV_UNLIKELY(!b0 && mrec0)) {
 
 1955                         ROW_MERGE_WRITE_GET_NEXT(0, index, 
goto done0);
 
 1965         return(row_merge_write_eof(&block[2 * srv_sort_buf_size],
 
 1966                                    b2, of->fd, &of->offset)
 
 1973 static __attribute__((nonnull))
 
 1994         const ulint     ihalf   = run_offset[*num_run / 2];
 
 1999         UNIV_MEM_ASSERT_W(&block[0], 3 * srv_sort_buf_size);
 
 2001         ut_ad(ihalf < file->offset);
 
 2007 #ifdef POSIX_FADV_SEQUENTIAL 
 2011         posix_fadvise(file->fd, 0, 0,
 
 2012                       POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
 
 2019         UNIV_MEM_INVALID(run_offset, *num_run * 
sizeof *run_offset);
 
 2021         for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
 
 2024                         return(DB_INTERRUPTED);
 
 2028                 run_offset[n_run++] = of.
offset;
 
 2030                 error = row_merge_blocks(dup, file, block,
 
 2031                                          &foffs0, &foffs1, &of);
 
 2033                 if (error != DB_SUCCESS) {
 
 2041         while (foffs0 < ihalf) {
 
 2043                         return(DB_INTERRUPTED);
 
 2047                 run_offset[n_run++] = of.
offset;
 
 2049                 if (!row_merge_blocks_copy(dup->index, file, block,
 
 2055         ut_ad(foffs0 == ihalf);
 
 2057         while (foffs1 < file->offset) {
 
 2059                         return(DB_INTERRUPTED);
 
 2063                 run_offset[n_run++] = of.
offset;
 
 2065                 if (!row_merge_blocks_copy(dup->index, file, block,
 
 2071         ut_ad(foffs1 == file->offset);
 
 2073         if (UNIV_UNLIKELY(of.
n_rec != file->n_rec)) {
 
 2077         ut_ad(n_run <= *num_run);
 
 2085         ut_ad((*num_run) <= file->offset);
 
 2095         UNIV_MEM_INVALID(&block[0], 3 * srv_sort_buf_size);
 
 2115         const ulint     half    = file->
offset / 2;
 
 2119         DBUG_ENTER(
"row_merge_sort");
 
 2125         if (num_runs <= 1) {
 
 2130         run_offset = (ulint*) mem_alloc(file->
offset * 
sizeof(ulint));
 
 2134         run_offset[half] = half;
 
 2142                 error = row_merge(trx, dup, file, block, tmpfd,
 
 2143                                   &num_runs, run_offset);
 
 2145                 if (error != DB_SUCCESS) {
 
 2149                 UNIV_MEM_ASSERT_RW(run_offset, num_runs * 
sizeof *run_offset);
 
 2150         } 
while (num_runs > 1);
 
 2159 static __attribute__((nonnull))
 
 2161 row_merge_copy_blobs(
 
 2164         const ulint*    offsets,
 
 2174                 dfield_t*       field = dtuple_get_nth_field(tuple, i);
 
 2189                         mrec, offsets, zip_size, i, &len, heap);
 
 2204 static __attribute__((nonnull, warn_unused_result))
 
 2206 row_merge_insert_index_tuples(
 
 2222         DBUG_ENTER(
"row_merge_insert_index_tuples");
 
 2225         ut_ad(!(index->type & DICT_FTS));
 
 2231                 ulint i = 1 + REC_OFFS_HEADER_SIZE
 
 2235                 offsets = 
static_cast<ulint*
>(
 
 2259                                                fd, &foffs, &mrec, offsets);
 
 2260                         if (UNIV_UNLIKELY(!b)) {
 
 2269                                 = dict_table_get_first_index(old_table);
 
 2274                                 if (error != DB_SUCCESS) {
 
 2280                                 mrec, index, offsets, &n_ext, tuple_heap);
 
 2305                                 row_merge_copy_blobs(
 
 2308                                         dtuple, tuple_heap);
 
 2311                         ut_ad(dtuple_validate(dtuple));
 
 2316                         btr_cur_open_at_index_side(
 
 2321                                 btr_cur_get_block(&cursor),
 
 2322                                 btr_cur_get_page_cur(&cursor));
 
 2326                         rec = btr_cur_get_rec(&cursor);
 
 2329                                 ulint*  rec_offsets = rec_get_offsets(
 
 2330                                         rec, index, offsets,
 
 2331                                         ULINT_UNDEFINED, &tuple_heap);
 
 2336                         ulint*  ins_offsets = NULL;
 
 2341                                 &cursor, &ins_offsets, &ins_heap,
 
 2342                                 dtuple, &rec, &big_rec, 0, NULL, &mtr);
 
 2344                         if (error == DB_FAIL) {
 
 2348                                 btr_cur_open_at_index_side(
 
 2354                                         btr_cur_get_block(&cursor),
 
 2355                                         btr_cur_get_page_cur(&cursor));
 
 2361                                         &cursor, &ins_offsets, &ins_heap,
 
 2362                                         dtuple, &rec, &big_rec, 0, NULL, &mtr);
 
 2367                                         btr_cur_get_block(&cursor),
 
 2374                         if (UNIV_LIKELY_NULL(big_rec)) {
 
 2383                                 ut_ad(error == DB_SUCCESS);
 
 2384                                 error = row_ins_index_entry_big_rec(
 
 2386                                         ins_offsets, &ins_heap,
 
 2387                                         index, NULL, __FILE__, __LINE__);
 
 2389                                         index, dtuple, big_rec);
 
 2392                         if (error != DB_SUCCESS) {
 
 2418         enum lock_mode  
mode)           
 
 2426         ut_ad(mode == LOCK_X || mode == LOCK_S);
 
 2430         trx->
op_info = 
"setting table lock for creating or dropping index";
 
 2453         if (UNIV_LIKELY(err == DB_SUCCESS)) {
 
 2458                 if (err != DB_QUE_THR_SUSPENDED) {
 
 2462                                 &err, trx, thr, NULL);
 
 2464                         if (was_lock_wait) {
 
 2474                                 static_cast<que_fork_t*>(parent));
 
 2476                         ut_a(run_thr == thr);
 
 2498 row_merge_drop_index_dict(
 
 2501         index_id_t      index_id)
 
 2503         static const char sql[] =
 
 2504                 "PROCEDURE DROP_INDEX_PROC () IS\n" 
 2506                 "DELETE FROM SYS_FIELDS WHERE INDEX_ID=:indexid;\n" 
 2507                 "DELETE FROM SYS_INDEXES WHERE ID=:indexid;\n" 
 2516 #ifdef UNIV_SYNC_DEBUG 
 2522         trx->
op_info = 
"dropping index from dictionary";
 
 2525         if (error != DB_SUCCESS) {
 
 2532                 fprintf(stderr, 
" InnoDB: Error: row_merge_drop_index_dict " 
 2533                         "failed with error code: %u.\n", (
unsigned) error);
 
 2548         table_id_t      table_id)
 
 2550         static const char sql[] =
 
 2551                 "PROCEDURE DROP_INDEXES_PROC () IS\n" 
 2555                 "DECLARE CURSOR index_cur IS\n" 
 2556                 " SELECT ID FROM SYS_INDEXES\n" 
 2557                 " WHERE TABLE_ID=:tableid AND\n" 
 2564                 "WHILE found = 1 LOOP\n" 
 2565                 "  FETCH index_cur INTO ixid;\n" 
 2566                 "  IF (SQL % NOTFOUND) THEN\n" 
 2569                 "    DELETE FROM SYS_FIELDS WHERE INDEX_ID=ixid;\n" 
 2570                 "    DELETE FROM SYS_INDEXES WHERE CURRENT OF index_cur;\n" 
 2573                 "CLOSE index_cur;\n" 
 2583 #ifdef UNIV_SYNC_DEBUG 
 2596         trx->
op_info = 
"dropping indexes";
 
 2599         if (error != DB_SUCCESS) {
 
 2606                 fprintf(stderr, 
" InnoDB: Error: row_merge_drop_indexes_dict " 
 2607                         "failed with error code: %u.\n", (
unsigned) error);
 
 2633 #ifdef UNIV_SYNC_DEBUG 
 2637         index = dict_table_get_first_index(table);
 
 2660                 while ((index = dict_table_get_next_index(index)) != NULL) {
 
 2670                                 } 
else if (index->
type & DICT_FTS) {
 
 2725                                 DEBUG_SYNC_C(
"merge_drop_index_after_abort");
 
 2734                                 row_merge_drop_index_dict(trx, index->
id);
 
 2756         next_index = dict_table_get_next_index(index);
 
 2758         while ((index = next_index) != NULL) {
 
 2760                 next_index = dict_table_get_next_index(index);
 
 2767                         if (index->
type & DICT_FTS) {
 
 2790                                 MONITOR_DEC(MONITOR_BACKGROUND_DROP_INDEX);
 
 2798         ut_d(dict_table_check_for_dup_indexes(table, CHECK_ALL_COMPLETE));
 
 2808         static const char sql[] =
 
 2809                 "PROCEDURE DROP_TEMP_INDEXES_PROC () IS\n" 
 2813                 "DECLARE CURSOR index_cur IS\n" 
 2814                 " SELECT ID FROM SYS_INDEXES\n" 
 2821                 "WHILE found = 1 LOOP\n" 
 2822                 "  FETCH index_cur INTO ixid;\n" 
 2823                 "  IF (SQL % NOTFOUND) THEN\n" 
 2826                 "    DELETE FROM SYS_FIELDS WHERE INDEX_ID=ixid;\n" 
 2827                 "    DELETE FROM SYS_INDEXES WHERE CURRENT OF index_cur;\n" 
 2830                 "CLOSE index_cur;\n" 
 2839         trx->
op_info = 
"dropping partially created indexes";
 
 2840         row_mysql_lock_data_dictionary(trx);
 
 2846         trx->
op_info = 
"dropping indexes";
 
 2849         if (error != DB_SUCCESS) {
 
 2856                 fprintf(stderr, 
" InnoDB: Error: row_merge_drop_temp_indexes " 
 2857                         "failed with error code: %u.\n", (
unsigned) error);
 
 2879         struct PSI_file_locker* locker = NULL;
 
 2880         PSI_file_locker_state   state;
 
 2881         register_pfs_file_open_begin(&state, locker, innodb_file_temp_key,
 
 2883                                      "Innodb Merge Temp File",
 
 2884                                      __FILE__, __LINE__);
 
 2888         register_pfs_file_open_end(locker, fd);
 
 2893                         "Cannot create temporary merge file");
 
 2910         merge_file->
n_rec = 0;
 
 2912         if (merge_file->
fd >= 0) {
 
 2913                 if (srv_disable_sort_file_cache) {
 
 2915                                 "row0merge.cc", 
"sort");
 
 2918         return(merge_file->
fd);
 
 2931         struct PSI_file_locker* locker = NULL;
 
 2932         PSI_file_locker_state   state;
 
 2933         register_pfs_file_io_begin(&state, locker,
 
 2934                                    fd, 0, PSI_FILE_CLOSE,
 
 2935                                    __FILE__, __LINE__);
 
 2941         register_pfs_file_io_end(locker, 0);
 
 2954         if (merge_file->
fd != -1) {
 
 2956                 merge_file->
fd = -1;
 
 2970         table_id_t      table_id,       
 
 2971         index_id_t      index_id)       
 
 2979         static const char rename_index[] =
 
 2980                 "PROCEDURE RENAME_INDEX_PROC () IS\n" 
 2982                 "UPDATE SYS_INDEXES SET NAME=SUBSTR(NAME,1,LENGTH(NAME)-1)\n" 
 2983                 "WHERE TABLE_ID = :tableid AND ID = :indexid;\n" 
 2990         trx->
op_info = 
"renaming index to add";
 
 2997         if (err != DB_SUCCESS) {
 
 3005                         " InnoDB: Error: row_merge_rename_index_to_add " 
 3006                          "failed with error code: %u.\n", (
unsigned) err);
 
 3024         table_id_t      table_id,       
 
 3025         index_id_t      index_id)       
 
 3035         static const char rename_index[] =
 
 3036                 "PROCEDURE RENAME_INDEX_PROC () IS\n" 
 3038                 "UPDATE SYS_INDEXES SET NAME=CONCAT('" 
 3040                 "WHERE TABLE_ID = :tableid AND ID = :indexid;\n" 
 3047         trx->
op_info = 
"renaming index to drop";
 
 3054         if (err != DB_SUCCESS) {
 
 3062                         " InnoDB: Error: row_merge_rename_index_to_drop " 
 3063                          "failed with error code: %u.\n", (
unsigned) err);
 
 3081         const char*     new_name)       
 
 3111         const char*     tmp_name,       
 
 3118         ut_ad(old_table != new_table);
 
 3124         trx->
op_info = 
"renaming tables";
 
 3136                            "PROCEDURE RENAME_TABLES () IS\n" 
 3138                            "UPDATE SYS_TABLES SET NAME = :tmp_name\n" 
 3139                            " WHERE NAME = :old_name;\n" 
 3140                            "UPDATE SYS_TABLES SET NAME = :old_name\n" 
 3141                            " WHERE NAME = :new_name;\n" 
 3142                            "END;\n", FALSE, trx);
 
 3146         if (err == DB_SUCCESS
 
 3147             && old_table->
space != TRX_SYS_SPACE
 
 3157                                            (lint) old_table->
space);
 
 3160                                    "PROCEDURE RENAME_OLD_SPACE () IS\n" 
 3162                                    "UPDATE SYS_TABLESPACES" 
 3163                                    " SET NAME = :tmp_name\n" 
 3164                                    " WHERE SPACE = :old_space;\n" 
 3165                                    "UPDATE SYS_DATAFILES" 
 3166                                    " SET PATH = :tmp_path\n" 
 3167                                    " WHERE SPACE = :old_space;\n" 
 3168                                    "END;\n", FALSE, trx);
 
 3175         if (err == DB_SUCCESS && new_table->
space != TRX_SYS_SPACE) {
 
 3178                         new_table, old_table->
name);
 
 3185                                            (lint) new_table->
space);
 
 3188                                    "PROCEDURE RENAME_NEW_SPACE () IS\n" 
 3190                                    "UPDATE SYS_TABLESPACES" 
 3191                                    " SET NAME = :old_name\n" 
 3192                                    " WHERE SPACE = :new_space;\n" 
 3193                                    "UPDATE SYS_DATAFILES" 
 3194                                    " SET PATH = :old_path\n" 
 3195                                    " WHERE SPACE = :new_space;\n" 
 3196                                    "END;\n", FALSE, trx);
 
 3203                         trx, new_table->
id, 
true, 
true);
 
 3214 static __attribute__((nonnull, warn_unused_result))
 
 3216 row_merge_create_index_graph(
 
 3233         index->table = 
table;
 
 3242         err = trx->error_state;
 
 3263         ulint           n_fields = index_def->
n_fields;
 
 3277         for (i = 0; i < n_fields; i++) {
 
 3286         err = row_merge_create_index_graph(trx, table, index);
 
 3288         if (err == DB_SUCCESS) {
 
 3365         const ulint*    key_numbers,    
 
 3367         struct TABLE*   table,          
 
 3372         const ulint*    col_map,        
 
 3391         ib_int64_t              sig_count = 0;
 
 3392         DBUG_ENTER(
"row_merge_build_indexes");
 
 3395         ut_ad((old_table == new_table) == !col_map);
 
 3396         ut_ad(!add_cols || col_map);
 
 3405         if (block == NULL) {
 
 3406                 DBUG_RETURN(DB_OUT_OF_MEMORY);
 
 3409         trx_start_if_not_started_xa(trx);
 
 3412                 mem_alloc(n_indexes * 
sizeof *merge_files));
 
 3418         for (i = 0; i < n_indexes; i++) {
 
 3419                 merge_files[
i].
fd = -1;
 
 3422         for (i = 0; i < n_indexes; i++) {
 
 3424                         error = DB_OUT_OF_MEMORY;
 
 3428                 if (indexes[i]->
type & DICT_FTS) {
 
 3429                         ibool   opt_doc_id_size = FALSE;
 
 3436                                 indexes[i], old_table, &opt_doc_id_size);
 
 3440                         dup->
index = fts_sort_idx;
 
 3446                                 trx, dup, new_table, opt_doc_id_size,
 
 3447                                 &psort_info, &merge_info);
 
 3454                 error = DB_OUT_OF_MEMORY;
 
 3465         error = row_merge_read_clustered_index(
 
 3466                 trx, table, old_table, new_table, online, indexes,
 
 3467                 fts_sort_idx, psort_info, merge_files, key_numbers,
 
 3468                 n_indexes, add_cols, col_map,
 
 3469                 add_autoinc, sequence, block);
 
 3471         if (error != DB_SUCCESS) {
 
 3476         DEBUG_SYNC_C(
"row_merge_after_scan");
 
 3481         for (i = 0; i < n_indexes; i++) {
 
 3484                 if (indexes[i]->
type & DICT_FTS) {
 
 3487                         sort_idx = fts_sort_idx;
 
 3489                         fts_parallel_merge_event
 
 3492                         if (FTS_PLL_MERGE) {
 
 3493                                 ulint   trial_count = 0;
 
 3494                                 bool    all_exit = 
false;
 
 3500                                         fts_parallel_merge_event, 1000000,
 
 3503                                 for (j = 0; j < FTS_NUM_AUX_INDEX; j++) {
 
 3504                                         if (merge_info[j].child_status
 
 3505                                             != FTS_CHILD_COMPLETE
 
 3506                                             && merge_info[j].child_status
 
 3507                                             != FTS_CHILD_EXITING) {
 
 3509                                                 fts_parallel_merge_event);
 
 3517                                 while (!all_exit && trial_count < 10000) {
 
 3520                                         for (j = 0; j < FTS_NUM_AUX_INDEX;
 
 3522                                                 if (merge_info[j].child_status
 
 3523                                                     != FTS_CHILD_EXITING) {
 
 3534                                                 "Not all child merge threads" 
 3535                                                 " exited when creating FTS" 
 3543                                         sort_idx, new_table,
 
 3547 #ifdef FTS_INTERNAL_DIAG_PRINT 
 3548                         DEBUG_FTS_SORT_PRINT(
"FTS_SORT: Complete Insert\n");
 
 3552                                 sort_idx, 
table, col_map, 0};
 
 3555                                 trx, &dup, &merge_files[i],
 
 3558                         if (error == DB_SUCCESS) {
 
 3559                                 error = row_merge_insert_index_tuples(
 
 3560                                         trx->
id, sort_idx, old_table,
 
 3561                                         merge_files[i].
fd, block);
 
 3568                 if (indexes[i]->
type & DICT_FTS) {
 
 3570                 } 
else if (error != DB_SUCCESS || !online) {
 
 3572                 } 
else if (old_table != new_table) {
 
 3577                         DEBUG_SYNC_C(
"row_log_apply_before");
 
 3579                         DEBUG_SYNC_C(
"row_log_apply_after");
 
 3582                 if (error != DB_SUCCESS) {
 
 3588                         char*   
name = (
char*) indexes[i]->name;
 
 3595                         fprintf(stderr, 
" InnoDB: Finished building " 
 3596                                 "full-text index %s\n", name);
 
 3602                 "ib_build_indexes_too_many_concurrent_trxs",
 
 3608         for (i = 0; i < n_indexes; i++) {
 
 3621         if (online && old_table == new_table && error != DB_SUCCESS) {
 
 3624                 for (i = 0; i < n_indexes; i++) {
 
 3654                                         MONITOR_BACKGROUND_DROP_INDEX);