63 # define posix_fadvise(fd, offset, len, advice)
70 static ibool row_merge_print_cmp;
72 static ibool row_merge_print_read;
74 static ibool row_merge_print_write;
77 static ibool row_merge_print_block;
79 static ibool row_merge_print_block_read;
81 static ibool row_merge_print_block_write;
93 typedef byte row_merge_block_t[1048576];
101 typedef byte mrec_buf_t[UNIV_PAGE_SIZE_MAX];
141 row_merge_tuple_print(
149 for (j = 0; j < n_fields; j++) {
153 fputs(
"\n NULL;", f);
156 ulint len =
ut_min(field_len, 20);
163 if (len != field_len) {
164 fprintf(f,
" (total %lu bytes)", field_len);
177 row_merge_buf_create_low(
186 ut_ad(max_tuples > 0);
187 ut_ad(max_tuples <=
sizeof(row_merge_block_t));
188 ut_ad(max_tuples < buf_size);
195 2 * max_tuples *
sizeof *buf->
tuples));
206 row_merge_buf_create(
215 max_tuples =
sizeof(row_merge_block_t)
218 buf_size = (
sizeof *buf) + (max_tuples - 1) *
sizeof *buf->
tuples;
222 buf = row_merge_buf_create_low(heap, index, max_tuples, buf_size);
241 buf_size = (
sizeof *buf) + (max_tuples - 1) *
sizeof *buf->
tuples;
245 return(row_merge_buf_create_low(heap, index, max_tuples, buf_size));
284 UNIV_PREFETCH_R(row->
fields);
297 ifield = dict_index_get_nth_field(index, 0);
299 for (i = 0; i < n_fields; i++, field++, ifield++) {
307 row_field = dtuple_get_nth_field(row, col_no);
314 }
else if (UNIV_LIKELY(!ext)) {
319 if (UNIV_LIKELY_NULL(row_buf)) {
331 if (UNIV_LIKELY_NULL(row_buf)) {
344 len, static_cast<const char *>(dfield_get_data(field)));
348 ut_ad(len <= col->len || col->
mtype == DATA_BLOB);
356 || (col->
len < 256 && col->
mtype != DATA_BLOB)) {
375 entry, n_fields, &extra);
377 ut_ad(data_size + extra_size + REC_N_NEW_EXTRA_BYTES == size);
378 ut_ad(extra_size + REC_N_NEW_EXTRA_BYTES == extra);
386 data_size += (extra_size + 1) + ((extra_size + 1) >= 0x80);
394 ut_ad(data_size <
sizeof(row_merge_block_t));
397 if (buf->
total_size + data_size >=
sizeof(row_merge_block_t) - 1) {
410 }
while (--n_fields);
429 row_merge_dup_report(
455 buf =
static_cast<mrec_buf_t *
>(
mem_heap_alloc(heap,
sizeof *buf));
461 offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
488 }
while (!cmp && --n_field);
490 if (UNIV_UNLIKELY(!cmp) && UNIV_LIKELY_NULL(dup)) {
495 for (b = field; b != a; b++) {
502 row_merge_dup_report(dup, field);
515 #define row_merge_tuple_sort_ctx(a,b,c,d) \
516 row_merge_tuple_sort(n_field, dup, a, b, c, d)
522 #define row_merge_tuple_cmp_ctx(a,b) row_merge_tuple_cmp(n_field, a, b, dup)
528 row_merge_tuple_sort(
540 tuples, aux, low, high, row_merge_tuple_cmp_ctx);
566 row_merge_block_t* block)
568 # define row_merge_buf_write(buf, of, block) row_merge_buf_write(buf, block)
573 byte* b = &(*block)[0];
577 for (i = 0; i < buf->
n_tuples; i++) {
586 ut_ad(size > extra_size);
587 ut_ad(extra_size >= REC_N_NEW_EXTRA_BYTES);
588 extra_size -= REC_N_NEW_EXTRA_BYTES;
589 size -= REC_N_NEW_EXTRA_BYTES;
592 if (extra_size + 1 < 0x80) {
593 *b++ = (byte) (extra_size + 1);
595 ut_ad((extra_size + 1) < 0x8000);
596 *b++ = (byte) (0x80 | ((extra_size + 1) >> 8));
597 *b++ = (byte) (extra_size + 1);
600 ut_ad(b + size < block[1]);
609 if (row_merge_print_write) {
610 fprintf(stderr,
"row_merge_buf_write %p,%d,%lu %lu",
611 (
void*) b, of->fd, (ulong) of->offset,
613 row_merge_tuple_print(stderr, entry, n_fields);
622 #ifdef UNIV_DEBUG_VALGRIND
625 memset(b, 0xff, block[1] - b);
628 if (row_merge_print_write) {
629 fprintf(stderr,
"row_merge_buf_write %p,%d,%lu EOF\n",
630 (
void*) b, of->fd, (ulong) of->offset);
641 row_merge_heap_create(
648 ulint i = 1 + REC_OFFS_HEADER_SIZE
653 *buf =
static_cast<mrec_buf_t*
>(
mem_heap_alloc(heap, 3 *
sizeof **buf));
654 *offsets1 =
static_cast<ulint*
>(
mem_heap_alloc(heap, i *
sizeof **offsets1));
655 *offsets2 =
static_cast<ulint*
>(
mem_heap_alloc(heap, i *
sizeof **offsets2));
657 (*offsets1)[0] = (*offsets2)[0] = i;
669 row_merge_dict_table_get_index(
676 const char** column_names;
678 column_names =
static_cast<const char **
>(mem_alloc(index_def->
n_fields *
sizeof *column_names));
680 for (i = 0; i < index_def->
n_fields; ++i) {
685 table, index_def->
name, column_names, index_def->
n_fields);
703 row_merge_block_t* buf)
705 ib_uint64_t ofs = ((ib_uint64_t) offset) *
sizeof *buf;
709 if (row_merge_print_block_read) {
710 fprintf(stderr,
"row_merge_read fd=%d ofs=%lu\n",
716 (ulint) (ofs & 0xFFFFFFFF),
719 #ifdef POSIX_FADV_DONTNEED
721 posix_fadvise(fd, ofs,
sizeof *buf, POSIX_FADV_DONTNEED);
724 if (UNIV_UNLIKELY(!success)) {
727 " InnoDB: failed to read merge block at %"PRIu64
"\n", ofs);
730 return(UNIV_LIKELY(success));
745 size_t buf_len =
sizeof(row_merge_block_t);
746 ib_uint64_t ofs = buf_len * (ib_uint64_t) offset;
750 (ulint) (ofs & 0xFFFFFFFF),
755 if (row_merge_print_block_write) {
756 fprintf(stderr,
"row_merge_write fd=%d ofs=%lu\n",
761 #ifdef POSIX_FADV_DONTNEED
764 posix_fadvise(fd, ofs, buf_len, POSIX_FADV_DONTNEED);
767 return(UNIV_LIKELY(ret));
773 static __attribute__((nonnull))
777 row_merge_block_t* block,
794 ut_ad(b >= block[0]);
801 ut_ad(*offsets == 1 + REC_OFFS_HEADER_SIZE
806 if (UNIV_UNLIKELY(!extra_size)) {
810 if (row_merge_print_read) {
811 fprintf(stderr,
"row_merge_read %p,%p,%d,%lu EOF\n",
812 (
const void*) b, (
const void*) block,
819 if (extra_size >= 0x80) {
822 if (UNIV_UNLIKELY(b >= block[1])) {
823 if (!row_merge_read(fd, ++(*foffs), block)) {
834 extra_size = (extra_size & 0x7f) << 8;
843 if (UNIV_UNLIKELY(b + extra_size >= block[1])) {
848 avail_size = block[1] - b;
850 memcpy(*buf, b, avail_size);
852 if (!row_merge_read(fd, ++(*foffs), block)) {
861 memcpy(*buf + avail_size, b, extra_size - avail_size);
862 b += extra_size - avail_size;
864 *mrec = *buf + extra_size;
873 ut_a(extra_size + data_size <
sizeof *buf);
874 ut_a(b + data_size < block[1]);
877 memcpy(*buf + extra_size, b, data_size);
883 *mrec = b + extra_size;
888 ut_ad(extra_size + data_size <
sizeof *buf);
890 b += extra_size + data_size;
892 if (UNIV_LIKELY(b < block[1])) {
900 b -= extra_size + data_size;
901 avail_size = block[1] - b;
902 memcpy(*buf, b, avail_size);
903 *mrec = *buf + extra_size;
909 offsets[2] = (ulint) *mrec;
910 offsets[3] = (ulint) index;
913 if (!row_merge_read(fd, ++(*foffs), block)) {
922 memcpy(*buf + avail_size, b, extra_size + data_size - avail_size);
923 b += extra_size + data_size - avail_size;
927 if (row_merge_print_read) {
928 fprintf(stderr,
"row_merge_read %p,%p,%d,%lu ",
929 (
const void*) b, (
const void*) block,
943 row_merge_write_rec_low(
953 const ulint* offsets)
955 # define row_merge_write_rec_low(b, e, size, fd, foffs, mrec, offsets) \
956 row_merge_write_rec_low(b, e, mrec, offsets)
960 const byte*
const end = b + size;
963 if (row_merge_print_write) {
964 fprintf(stderr,
"row_merge_write %p,%d,%lu ",
965 (
void*) b, fd, (ulong) foffs);
974 *b++ = (byte) (0x80 | (e >> 8));
989 row_merge_block_t* block,
995 const ulint* offsets)
1003 ut_ad(b >= block[0]);
1004 ut_ad(b < block[1]);
1007 ut_ad(mrec < block[0] || mrec > block[1]);
1008 ut_ad(mrec < buf[0] || mrec > buf[1]);
1013 size = extra_size + (extra_size >= 0x80)
1016 if (UNIV_UNLIKELY(b + size >= block[1])) {
1019 avail_size = block[1] - b;
1021 row_merge_write_rec_low(buf[0],
1022 extra_size, size, fd, *foffs,
1028 memcpy(b, buf[0], avail_size);
1030 if (!row_merge_write(fd, (*foffs)++, block)) {
1034 UNIV_MEM_INVALID(block[0],
sizeof block[0]);
1038 memcpy(b, buf[0] + avail_size, size - avail_size);
1039 b += size - avail_size;
1041 row_merge_write_rec_low(b, extra_size, size, fd, *foffs,
1054 row_merge_write_eof(
1056 row_merge_block_t* block,
1062 ut_ad(b >= block[0]);
1063 ut_ad(b < block[1]);
1066 if (row_merge_print_write) {
1067 fprintf(stderr,
"row_merge_write %p,%p,%d,%lu EOF\n",
1068 (
void*) b, (
void*) block, fd, (ulong) *foffs);
1073 UNIV_MEM_ASSERT_RW(block[0], b - block[0]);
1074 UNIV_MEM_ASSERT_W(block[0],
sizeof block[0]);
1075 #ifdef UNIV_DEBUG_VALGRIND
1078 memset(b, 0xff, block[1] - b);
1081 if (!row_merge_write(fd, (*foffs)++, block)) {
1085 UNIV_MEM_INVALID(block[0],
sizeof block[0]);
1096 const mrec_t* mrec1,
1098 const mrec_t* mrec2,
1100 const ulint* offsets1,
1101 const ulint* offsets2,
1112 if (row_merge_print_cmp) {
1113 fputs(
"row_merge_cmp1 ", stderr);
1115 fputs(
"\nrow_merge_cmp2 ", stderr);
1117 fprintf(stderr,
"\nrow_merge_cmp=%d\n", cmp);
1128 static __attribute__((nonnull))
1130 row_merge_read_clustered_index(
1143 row_merge_block_t* block)
1152 ulint err = DB_SUCCESS;
1154 ulint n_nonnull = 0;
1156 ulint* nonnull = NULL;
1158 trx->op_info =
"reading clustered index";
1168 merge_buf =
static_cast<row_merge_buf_t **
>(mem_alloc(n_index *
sizeof *merge_buf));
1170 for (i = 0; i < n_index; i++) {
1171 merge_buf[i] = row_merge_buf_create(index[i]);
1179 clust_index = dict_table_get_first_index(old_table);
1184 if (UNIV_UNLIKELY(old_table != new_table)) {
1195 nonnull =
static_cast<ulint*
>(mem_alloc(n_cols *
sizeof *nonnull));
1197 for (i = 0; i < n_cols; i++) {
1198 if (dict_table_get_nth_col(old_table, i)->prtype
1204 if (dict_table_get_nth_col(new_table, i)->prtype
1207 nonnull[n_nonnull++] = i;
1225 ibool has_next = TRUE;
1234 err = DB_INTERRUPTED;
1235 trx->error_key_num = 0;
1247 if (UNIV_LIKELY(has_next)) {
1248 rec = btr_pcur_get_rec(&pcur);
1249 offsets = rec_get_offsets(rec, clust_index, NULL,
1250 ULINT_UNDEFINED, &row_heap);
1258 srv_n_rows_inserted++;
1262 row =
row_build(ROW_COPY_POINTERS, clust_index,
1264 new_table, &ext, row_heap);
1266 if (UNIV_LIKELY_NULL(nonnull)) {
1267 for (i = 0; i < n_nonnull; i++) {
1269 = &row->
fields[nonnull[i]];
1271 = dfield_get_type(field);
1277 err = DB_PRIMARY_KEY_IS_NULL;
1278 trx->error_key_num = 0;
1282 field_type->
prtype |= DATA_NOT_NULL;
1290 for (i = 0; i < n_index; i++) {
1296 (row && row_merge_buf_add(buf, row, ext))) {
1315 row_merge_buf_sort(buf, &dup);
1318 err = DB_DUPLICATE_KEY;
1319 trx->error_key_num = i;
1323 row_merge_buf_sort(buf, NULL);
1327 row_merge_buf_write(buf, file, block);
1329 if (!row_merge_write(file->
fd, file->
offset++,
1331 err = DB_OUT_OF_FILE_SPACE;
1332 trx->error_key_num = i;
1336 UNIV_MEM_INVALID(block[0],
sizeof block[0]);
1337 merge_buf[i] = row_merge_buf_empty(buf);
1339 if (UNIV_LIKELY(row != NULL)) {
1345 (!row_merge_buf_add(buf, row, ext))) {
1357 if (UNIV_UNLIKELY(!has_next)) {
1367 if (UNIV_LIKELY_NULL(nonnull)) {
1371 for (i = 0; i < n_index; i++) {
1372 row_merge_buf_free(merge_buf[i]);
1385 #define ROW_MERGE_WRITE_GET_NEXT(N, AT_END) \
1387 b2 = row_merge_write_rec(&block[2], &buf[2], b2, \
1388 of->fd, &of->offset, \
1389 mrec##N, offsets##N); \
1390 if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
1393 b##N = row_merge_read_rec(&block[N], &buf[N], \
1395 file->fd, foffs##N, \
1396 &mrec##N, offsets##N); \
1397 if (UNIV_UNLIKELY(!b##N)) { \
1415 row_merge_block_t* block,
1432 const mrec_t* mrec0;
1433 const mrec_t* mrec1;
1438 if (row_merge_print_block) {
1440 "row_merge_blocks fd=%d ofs=%lu + fd=%d ofs=%lu"
1441 " = fd=%d ofs=%lu\n",
1442 file->
fd, (ulong) *foffs0,
1443 file->
fd, (ulong) *foffs1,
1448 heap = row_merge_heap_create(index, &buf, &offsets0, &offsets1);
1450 buf =
static_cast<mrec_buf_t *
>(
mem_heap_alloc(heap,
sizeof(mrec_buf_t) * 3));
1455 if (!row_merge_read(file->
fd, *foffs0, &block[0])
1456 || !row_merge_read(file->
fd, *foffs1, &block[1])) {
1459 return(DB_CORRUPTION);
1466 b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->
fd,
1467 foffs0, &mrec0, offsets0);
1468 b1 = row_merge_read_rec(&block[1], &buf[1], b1, index, file->
fd,
1469 foffs1, &mrec1, offsets1);
1470 if (UNIV_UNLIKELY(!b0 && mrec0)
1471 || UNIV_UNLIKELY(!b1 && mrec1)) {
1476 while (mrec0 && mrec1) {
1477 ibool null_eq = FALSE;
1478 switch (row_merge_cmp(mrec0, mrec1,
1479 offsets0, offsets1, index,
1487 return(DB_DUPLICATE_KEY);
1491 ROW_MERGE_WRITE_GET_NEXT(0,
goto merged);
1494 ROW_MERGE_WRITE_GET_NEXT(1,
goto merged);
1506 ROW_MERGE_WRITE_GET_NEXT(0,
goto done0);
1513 ROW_MERGE_WRITE_GET_NEXT(1,
goto done1);
1519 b2 = row_merge_write_eof(&block[2], b2, of->
fd, &of->
offset);
1520 return(b2 ? DB_SUCCESS : DB_CORRUPTION);
1526 static __attribute__((nonnull))
1528 row_merge_blocks_copy(
1532 row_merge_block_t* block,
1542 const mrec_t* mrec0;
1547 if (row_merge_print_block) {
1549 "row_merge_blocks_copy fd=%d ofs=%lu"
1550 " = fd=%d ofs=%lu\n",
1551 file->fd, (ulong) foffs0,
1552 of->fd, (ulong) of->offset);
1556 heap = row_merge_heap_create(index, &buf, &offsets0, &offsets1);
1557 buf =
static_cast<mrec_buf_t *
>(
mem_heap_alloc(heap,
sizeof(mrec_buf_t) * 3));
1562 if (!row_merge_read(file->fd, *foffs0, &block[0])) {
1571 b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
1572 foffs0, &mrec0, offsets0);
1573 if (UNIV_UNLIKELY(!b0 && mrec0)) {
1581 ROW_MERGE_WRITE_GET_NEXT(0,
goto done0);
1591 return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset)
1598 static __attribute__((nonnull))
1606 row_merge_block_t* block,
1621 const ulint ihalf = run_offset[*num_run / 2];
1627 UNIV_MEM_ASSERT_W(block[0], 3 *
sizeof block[0]);
1628 ut_ad(ihalf < file->offset);
1634 #ifdef POSIX_FADV_SEQUENTIAL
1638 posix_fadvise(file->fd, 0, 0,
1639 POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE);
1646 UNIV_MEM_INVALID(run_offset, *num_run *
sizeof *run_offset);
1648 for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
1651 return(DB_INTERRUPTED);
1655 run_offset[n_run++] = of.
offset;
1657 error = row_merge_blocks(index, file, block,
1658 &foffs0, &foffs1, &of, table);
1660 if (error != DB_SUCCESS) {
1668 while (foffs0 < ihalf) {
1670 return(DB_INTERRUPTED);
1674 run_offset[n_run++] = of.
offset;
1676 if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
1677 return(DB_CORRUPTION);
1681 ut_ad(foffs0 == ihalf);
1683 while (foffs1 < file->offset) {
1685 return(DB_INTERRUPTED);
1689 run_offset[n_run++] = of.
offset;
1691 if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
1692 return(DB_CORRUPTION);
1696 ut_ad(foffs1 == file->offset);
1698 if (UNIV_UNLIKELY(of.
n_rec != file->n_rec)) {
1699 return(DB_CORRUPTION);
1702 ut_ad(n_run <= *num_run);
1710 ut_ad((*num_run) <= file->offset);
1720 UNIV_MEM_INVALID(block[0], 3 *
sizeof block[0]);
1736 row_merge_block_t* block,
1742 ulint half = file->
offset / 2;
1745 ulint error = DB_SUCCESS;
1751 if (num_runs <= 1) {
1756 run_offset = (ulint*) mem_alloc(file->
offset *
sizeof(ulint));
1760 run_offset[half] = half;
1768 error = row_merge(trx, index, file, block, tmpfd,
1769 table, &num_runs, run_offset);
1771 UNIV_MEM_ASSERT_RW(run_offset, num_runs *
sizeof *run_offset);
1773 if (error != DB_SUCCESS) {
1776 }
while (num_runs > 1);
1787 row_merge_copy_blobs(
1790 const ulint* offsets,
1798 for (i = 0; i < n_fields; i++) {
1801 dfield_t* field = dtuple_get_nth_field(tuple, i);
1815 mrec, offsets, zip_size, i, &len, heap);
1832 row_merge_insert_index_tuples(
1840 row_merge_block_t* block)
1847 ulint error = DB_SUCCESS;
1858 trx->
op_info =
"inserting index entries";
1870 ulint i = 1 + REC_OFFS_HEADER_SIZE
1872 offsets =
static_cast<ulint *
>(
mem_heap_alloc(graph_heap, i *
sizeof *offsets));
1879 if (!row_merge_read(fd, foffs, block)) {
1880 error = DB_CORRUPTION;
1882 mrec_buf_t* buf =
static_cast<mrec_buf_t *
>(
mem_heap_alloc(graph_heap,
sizeof *buf));
1889 b = row_merge_read_rec(block, buf, b, index,
1890 fd, &foffs, &mrec, offsets);
1891 if (UNIV_UNLIKELY(!b)) {
1894 error = DB_CORRUPTION;
1900 mrec, index, offsets, &n_ext, tuple_heap);
1902 if (UNIV_UNLIKELY(n_ext)) {
1903 row_merge_copy_blobs(mrec, offsets, zip_size,
1904 dtuple, tuple_heap);
1911 ut_ad(dtuple_validate(dtuple));
1920 if (UNIV_LIKELY(error == DB_SUCCESS)) {
1958 enum lock_mode mode)
1967 ut_ad(mode == LOCK_X || mode == LOCK_S);
1971 trx->
op_info =
"setting table lock for creating or dropping index";
1991 if (UNIV_LIKELY(err == DB_SUCCESS)) {
1996 if (err != DB_QUE_THR_SUSPENDED) {
1997 ibool was_lock_wait;
2000 &err, trx, thr, NULL);
2002 if (was_lock_wait) {
2012 ut_a(run_thr == thr);
2048 static const char str1[] =
2049 "PROCEDURE DROP_INDEX_PROC () IS\n"
2054 "UPDATE SYS_INDEXES SET NAME=CONCAT('"
2058 "DELETE FROM SYS_FIELDS WHERE INDEX_ID = :indexid;\n"
2060 "DELETE FROM SYS_INDEXES WHERE ID = :indexid;\n"
2063 ut_ad(index && table && trx);
2068 trx->
op_info =
"dropping index";
2074 ut_a(err == DB_SUCCESS);
2101 for (key_num = 0; key_num < num_created; key_num++) {
2122 trx->
op_info =
"dropping partially created indexes";
2123 row_mysql_lock_data_dictionary(trx);
2136 table_id_t table_id;
2145 rec = btr_pcur_get_rec(&pcur);
2146 field = rec_get_nth_field_old(rec, DICT_SYS_INDEXES_NAME_FIELD,
2148 if (len == UNIV_SQL_NULL || len == 0
2155 field = rec_get_nth_field_old(rec, 0, &len);
2172 for (index = dict_table_get_first_index(table);
2173 index; index = next_index) {
2175 next_index = dict_table_get_next_index(index);
2201 row_merge_file_create_low(
void)
2209 struct PSI_file_locker* locker = NULL;
2210 PSI_file_locker_state state;
2211 register_pfs_file_open_begin(&state, locker, innodb_file_temp_key,
2213 "Innodb Merge Temp File",
2214 __FILE__, __LINE__);
2218 register_pfs_file_open_end(locker, fd);
2226 row_merge_file_create(
2230 merge_file->
fd = row_merge_file_create_low();
2232 merge_file->
n_rec = 0;
2240 row_merge_file_destroy_low(
2245 struct PSI_file_locker* locker = NULL;
2246 PSI_file_locker_state state;
2247 register_pfs_file_io_begin(&state, locker,
2248 fd, 0, PSI_FILE_CLOSE,
2249 __FILE__, __LINE__);
2253 register_pfs_file_io_end(locker, 0);
2260 row_merge_file_destroy(
2264 if (merge_file->
fd != -1) {
2265 row_merge_file_destroy_low(merge_file->
fd);
2266 merge_file->
fd = -1;
2276 row_merge_col_prtype(
2279 const char* col_name,
2283 ulint prtype = col->
prtype;
2288 if (prtype & DATA_NOT_NULL) {
2296 for (i = 0; i < index_def->
n_fields; i++) {
2298 return(prtype | DATA_NOT_NULL);
2313 const char* table_name,
2333 for (i = 0; i < n_cols; i++) {
2335 const char* col_name;
2337 col = dict_table_get_nth_col(table, i);
2341 row_merge_col_prtype(col, col_name,
2349 if (error != DB_SUCCESS) {
2369 ulint err = DB_SUCCESS;
2375 static const char rename_indexes[] =
2376 "PROCEDURE RENAME_INDEXES_PROC () IS\n"
2378 "UPDATE SYS_INDEXES SET NAME=SUBSTR(NAME,1,LENGTH(NAME)-1)\n"
2379 "WHERE TABLE_ID = :tableid AND SUBSTR(NAME,0,1)='"
2387 trx->
op_info =
"renaming indexes";
2393 if (err == DB_SUCCESS) {
2394 dict_index_t* index = dict_table_get_first_index(table);
2399 index = dict_table_get_next_index(index);
2421 const char* tmp_name,
2424 ulint err = DB_ERROR;
2426 char old_name[MAX_FULL_NAME_LEN + 1];
2429 ut_ad(old_table != new_table);
2435 if (strlen(old_table->
name) + 1 <=
sizeof(old_name)) {
2436 memcpy(old_name, old_table->
name, strlen(old_table->
name) + 1);
2439 fprintf(stderr,
"InnoDB: too long table name: '%s', "
2440 "max length is %d\n", old_table->
name,
2446 if (strlen(old_table->
name) + 1 <=
sizeof(old_name)) {
2447 memcpy(old_name, old_table->
name, strlen(old_table->
name) + 1);
2450 fprintf(stderr,
"InnoDB: too long table name: '%s', "
2451 "max length is %d\n", old_table->
name,
2452 MAX_TABLE_NAME_LEN);
2456 trx->
op_info =
"renaming tables";
2468 "PROCEDURE RENAME_TABLES () IS\n"
2470 "UPDATE SYS_TABLES SET NAME = :tmp_name\n"
2471 " WHERE NAME = :old_name;\n"
2472 "UPDATE SYS_TABLES SET NAME = :old_name\n"
2473 " WHERE NAME = :new_name;\n"
2474 "END;\n", FALSE, trx);
2476 if (err != DB_SUCCESS) {
2493 if (err != DB_SUCCESS) {
2510 row_merge_create_index_graph(
2527 index->
table = table;
2556 ulint n_fields = index_def->
n_fields;
2568 for (i = 0; i < n_fields; i++) {
2576 err = row_merge_create_index_graph(trx, table, index);
2578 if (err == DB_SUCCESS) {
2580 index = row_merge_dict_table_get_index(
2647 row_merge_block_t* block;
2664 merge_files =
static_cast<merge_file_t *
>(mem_alloc(n_indexes *
sizeof *merge_files));
2665 block_size = 3 *
sizeof *block;
2668 for (i = 0; i < n_indexes; i++) {
2670 row_merge_file_create(&merge_files[i]);
2673 tmpfd = row_merge_file_create_low();
2682 error = row_merge_read_clustered_index(
2683 trx, table, old_table, new_table, indexes,
2684 merge_files, n_indexes, block);
2686 if (error != DB_SUCCESS) {
2694 for (i = 0; i < n_indexes; i++) {
2695 error = row_merge_sort(trx, indexes[i], &merge_files[i],
2696 block, &tmpfd, table);
2698 if (error == DB_SUCCESS) {
2699 error = row_merge_insert_index_tuples(
2700 trx, indexes[i], new_table,
2702 merge_files[i].fd, block);
2706 row_merge_file_destroy(&merge_files[i]);
2708 if (error != DB_SUCCESS) {
2715 row_merge_file_destroy_low(tmpfd);
2717 for (i = 0; i < n_indexes; i++) {
2718 row_merge_file_destroy(&merge_files[i]);
#define UT_SORT_FUNCTION_BODY(SORT_FUN, ARR, AUX_ARR, LOW, HIGH, CMP_FUN)
UNIV_INTERN ins_node_t * ins_node_create(ulint ins_type, dict_table_t *table, mem_heap_t *heap)
UNIV_INTERN void que_thr_stop_for_mysql_no_error(que_thr_t *thr, trx_t *trx)
UNIV_INLINE ibool read_view_sees_trx_id(const read_view_t *view, trx_id_t trx_id)
UNIV_INTERN int cmp_rec_rec_simple(const rec_t *rec1, const rec_t *rec2, const ulint *offsets1, const ulint *offsets2, const dict_index_t *index, ibool *null_eq)
UNIV_INTERN void dict_mem_index_add_field(dict_index_t *index, const char *name, ulint prefix_len)
UNIV_INTERN byte * btr_rec_copy_externally_stored_field(const rec_t *rec, const ulint *offsets, ulint zip_size, ulint no, ulint *len, mem_heap_t *heap)
UNIV_INLINE void trx_start_if_not_started(trx_t *trx)
UNIV_INLINE void btr_pcur_move_to_next_on_page(btr_pcur_t *cursor)
UNIV_INTERN void rec_print_comp(FILE *file, const rec_t *rec, const ulint *offsets)
UNIV_INTERN ind_node_t * ind_create_graph_create(dict_index_t *index, mem_heap_t *heap)
UNIV_INLINE ibool btr_pcur_is_on_user_rec(const btr_pcur_t *cursor)
UNIV_INTERN const char * dict_table_get_col_name(const dict_table_t *table, ulint col_nr)
UNIV_INTERN void innobase_rec_to_mysql(Table *table, const rec_t *rec, const dict_index_t *index, const ulint *offsets)
UNIV_INTERN int row_create_table_for_mysql(dict_table_t *table, trx_t *trx)
UNIV_INTERN que_thr_t * pars_complete_graph_for_exec(que_node_t *node, trx_t *trx, mem_heap_t *heap)
UNIV_INLINE ulint dict_index_get_n_fields(const dict_index_t *index)
UNIV_INLINE void dfield_set_len(dfield_t *field, ulint len)
UNIV_INTERN void dict_table_replace_index_in_foreign_list(dict_table_t *table, dict_index_t *index, const trx_t *trx)
UNIV_INLINE dict_table_t * dict_table_get_on_id_low(table_id_t table_id)
UNIV_INTERN ulint lock_table(ulint flags, dict_table_t *table, enum lock_mode mode, que_thr_t *thr)
UNIV_INLINE ulint dfield_is_ext(const dfield_t *field)
UNIV_INTERN dtuple_t * row_build(ulint type, const dict_index_t *index, const rec_t *rec, const ulint *offsets, const dict_table_t *col_table, row_ext_t **ext, mem_heap_t *heap)
UNIV_INLINE ulint rec_offs_data_size(const ulint *offsets)
UNIV_INLINE ulint dtuple_get_n_ext(const dtuple_t *tuple)
UNIV_INTERN void ut_print_buf(FILE *file, const void *buf, ulint len)
UNIV_INTERN ulint dtype_get_at_most_n_mbchars(ulint prtype, ulint mbminmaxlen, ulint prefix_len, ulint data_len, const char *str)
UNIV_INTERN void que_run_threads(que_thr_t *thr)
UNIV_INTERN void rec_init_offsets_comp_ordinary(const rec_t *rec, ulint extra, const dict_index_t *index, ulint *offsets)
UNIV_INLINE ibool dict_table_is_comp(const dict_table_t *table)
UNIV_INTERN void row_merge_drop_temp_indexes(void)
UNIV_INTERN ibool row_mysql_handle_errors(ulint *new_err, trx_t *trx, que_thr_t *thr, trx_savept_t *savept)
UNIV_INLINE ulint rec_offs_extra_size(const ulint *offsets)
UNIV_INTERN void innobase_rec_reset(Table *table)
UNIV_INTERN void os_mem_free_large(void *ptr, ulint size)
UNIV_INTERN dict_index_t * dict_mem_index_create(const char *table_name, const char *index_name, ulint space, ulint type, ulint n_fields)
UNIV_INTERN int trx_general_rollback_for_mysql(trx_t *trx, trx_savept_t *savept)
UNIV_INTERN void * os_mem_alloc_large(ulint *n)
#define mem_heap_free(heap)
UNIV_INTERN rec_t * rec_convert_dtuple_to_rec(byte *buf, const dict_index_t *index, const dtuple_t *dtuple, ulint n_ext)
UNIV_INTERN ibool row_merge_is_index_usable(const trx_t *trx, const dict_index_t *index)
UNIV_INLINE void dfield_copy(dfield_t *field1, const dfield_t *field2)
UNIV_INTERN ulint trx_commit_for_mysql(trx_t *trx)
UNIV_INTERN void trx_free_for_background(trx_t *trx)
UNIV_INTERN ulint row_merge_lock_table(trx_t *trx, dict_table_t *table, enum lock_mode mode)
UNIV_INTERN ulint row_merge_drop_table(trx_t *trx, dict_table_t *table)
UNIV_INLINE ulint dtuple_get_n_fields(const dtuple_t *tuple)
UNIV_INTERN ulint row_merge_rename_indexes(trx_t *trx, dict_table_t *table)
UNIV_INLINE void btr_pcur_close(btr_pcur_t *cursor)
const dict_index_t * index
UNIV_INTERN ibool trx_is_interrupted(trx_t *trx)
UNIV_INTERN trx_t * trx_allocate_for_background(void)
UNIV_INLINE ulint ut_min(ulint n1, ulint n2)
UNIV_INTERN sel_node_t * sel_node_create(mem_heap_t *heap)
UNIV_INLINE ulint rec_get_deleted_flag(const rec_t *rec, ulint comp)
UNIV_INTERN void pars_info_add_str_literal(pars_info_t *info, const char *name, const char *str)
UNIV_INTERN void mtr_commit(mtr_t *mtr) __attribute__((nonnull))
#define TEMP_INDEX_PREFIX_STR
UNIV_INLINE void dfield_set_data(dfield_t *field, const void *data, ulint len)
dict_table_t * sys_indexes
UNIV_INLINE ulint dict_table_zip_size(const dict_table_t *table)
UNIV_INLINE ulint dfield_get_len(const dfield_t *field)
UNIV_INTERN dict_table_t * row_merge_create_temporary_table(const char *table_name, const merge_index_def_t *index_def, const dict_table_t *table, trx_t *trx)
UNIV_INTERN ibool dict_table_rename_in_cache(dict_table_t *table, const char *new_name, ibool rename_also_foreigns)
UNIV_INTERN void que_graph_free(que_t *graph)
UNIV_INTERN dtuple_t * row_rec_to_index_entry_low(const rec_t *rec, const dict_index_t *index, const ulint *offsets, ulint *n_ext, mem_heap_t *heap)
UNIV_INTERN ulint row_merge_build_indexes(trx_t *trx, dict_table_t *old_table, dict_table_t *new_table, dict_index_t **indexes, ulint n_indexes, TABLE *table)
UNIV_INTERN dict_table_t * dict_mem_table_create(const char *name, ulint space, ulint n_cols, ulint flags)
UNIV_INLINE ulint dict_col_get_no(const dict_col_t *col)
UNIV_INLINE ulint dict_index_is_clust(const dict_index_t *index) __attribute__((pure))
UNIV_INTERN ulint rec_get_converted_size_comp(const dict_index_t *index, ulint status, const dfield_t *fields, ulint n_fields, ulint *extra)
UNIV_INTERN void btr_pcur_store_position(btr_pcur_t *cursor, mtr_t *mtr)
UNIV_INTERN ulint row_merge_rename_tables(dict_table_t *old_table, dict_table_t *new_table, const char *tmp_name, trx_t *trx)
UNIV_INLINE ulint ut_max(ulint n1, ulint n2)
ulint dict_operation_lock_mode
UNIV_INTERN pars_info_t * pars_info_create(void)
UNIV_INLINE void * mem_heap_alloc(mem_heap_t *heap, ulint n)
UNIV_INLINE ulint dict_index_get_min_size(const dict_index_t *index)
#define mem_heap_create(N)
UNIV_INTERN ulint que_eval_sql(pars_info_t *info, const char *sql, ibool reserve_dict_mutex, trx_t *trx)
UNIV_INLINE void * mem_heap_zalloc(mem_heap_t *heap, ulint n)
UNIV_INLINE que_thr_t * que_fork_get_first_thr(que_fork_t *fork)
UNIV_INTERN void dict_mem_table_add_col(dict_table_t *table, mem_heap_t *heap, const char *name, ulint mtype, ulint prtype, ulint len)
UNIV_INTERN void pars_info_add_ull_literal(pars_info_t *info, const char *name, ib_uint64_t val)
merge_index_field_t * fields
ulint n_mysql_handles_opened
UNIV_INTERN int innobase_mysql_tmpfile(void)
UNIV_INTERN dict_index_t * dict_table_get_index_by_max_id(dict_table_t *table, const char *name, const char **columns, ulint n_cols)
UNIV_INLINE const byte * row_ext_lookup(const row_ext_t *ext, ulint col, ulint *len)
UNIV_INTERN void que_thr_stop_for_mysql(que_thr_t *thr)
UNIV_INLINE void mem_heap_empty(mem_heap_t *heap)
UNIV_INLINE ulint dfield_is_null(const dfield_t *field)
UNIV_INLINE int cmp_dfield_dfield(const dfield_t *dfield1, const dfield_t *dfield2)
UNIV_INTERN dict_index_t * row_merge_create_index(trx_t *trx, dict_table_t *table, const merge_index_def_t *index_def)
UNIV_INTERN void que_thr_move_to_run_state_for_mysql(que_thr_t *thr, trx_t *trx)
UNIV_INLINE ulint dict_table_get_n_cols(const dict_table_t *table)
UNIV_INLINE que_node_t * que_node_get_parent(que_node_t *node)
UNIV_INLINE ulint dict_table_get_n_user_cols(const dict_table_t *table)
UNIV_INLINE ulint dict_index_get_n_unique(const dict_index_t *index)
UNIV_INTERN void row_merge_drop_index(dict_index_t *index, dict_table_t *table, trx_t *trx)
UNIV_INTERN void rec_convert_dtuple_to_rec_comp(rec_t *rec, ulint extra, const dict_index_t *index, ulint status, const dfield_t *fields, ulint n_fields)
UNIV_INTERN void ut_print_timestamp(FILE *file)
UNIV_INLINE void dfield_dup(dfield_t *field, mem_heap_t *heap)
UNIV_INLINE ulint dict_index_is_unique(const dict_index_t *index) __attribute__((pure))
UNIV_INTERN ulint row_ins_index_entry(dict_index_t *index, dtuple_t *entry, ulint n_ext, ibool foreign, que_thr_t *thr)
UNIV_INTERN os_thread_id_t os_thread_get_curr_id(void)
UNIV_INLINE void mtr_start(mtr_t *mtr) __attribute__((nonnull))
UNIV_INLINE ibool btr_pcur_move_to_next_user_rec(btr_pcur_t *cursor, mtr_t *mtr)
#define OS_FILE_FROM_FD(fd)
UNIV_INLINE ibool btr_pcur_is_after_last_on_page(const btr_pcur_t *cursor)
UNIV_INLINE ulint rec_offs_size(const ulint *offsets)
UNIV_INLINE void dfield_set_ext(dfield_t *field)
const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE]
UNIV_INLINE void btr_pcur_open_at_index_side(ibool from_left, dict_index_t *index, ulint latch_mode, btr_pcur_t *pcur, ibool do_init, mtr_t *mtr)
UNIV_INLINE ib_uint64_t mach_read_from_8(const byte *b) __attribute__((nonnull
UNIV_INTERN que_thr_t * que_fork_start_command(que_fork_t *fork)
UNIV_INTERN void row_mysql_unlock_data_dictionary(trx_t *trx)
UNIV_INTERN void row_merge_drop_indexes(trx_t *trx, dict_table_t *table, dict_index_t **index, ulint num_created)
UNIV_INTERN int row_drop_table_for_mysql(const char *name, trx_t *trx, ibool drop_db)
#define TEMP_INDEX_PREFIX
#define UT_BITS_IN_BYTES(b)
UNIV_INLINE const dtuple_t * dtuple_from_fields(dtuple_t *tuple, const dfield_t *fields, ulint n_fields)
UNIV_INLINE void btr_pcur_commit_specify_mtr(btr_pcur_t *pcur, mtr_t *mtr)
const dfield_t ** tmp_tuples
UNIV_INTERN ulint dict_load_foreigns(const char *table_name, ibool check_recursive, ibool check_charsets)
UNIV_INTERN void dict_index_remove_from_cache(dict_table_t *table, dict_index_t *index)