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);