29 #include "row0import.ic"
50 #define IO_BUFFER_SIZE(n) ((1024 * 1024) / n)
133 ulint
get_n_rows(
const char* name)
const UNIV_NOTHROW;
139 ulint
find_col(
const char* name)
const UNIV_NOTHROW;
147 const char* name)
const UNIV_NOTHROW;
188 THD* thd) UNIV_NOTHROW;
196 THD* thd) UNIV_NOTHROW;
237 RecIterator() UNIV_NOTHROW
239 memset(&m_cur, 0x0,
sizeof(m_cur));
255 void next() UNIV_NOTHROW
262 rec_t* current() UNIV_NOTHROW
265 return(page_cur_get_rec(&m_cur));
270 bool end() UNIV_NOTHROW
312 "Phase II - Purge records from index %s",
321 dberr_t garbage_collect() UNIV_NOTHROW;
333 void open() UNIV_NOTHROW;
337 void close() UNIV_NOTHROW;
348 void purge_pessimistic_delete() UNIV_NOTHROW;
353 void purge() UNIV_NOTHROW;
358 IndexPurge(const IndexPurge&);
359 IndexPurge &operator=(const IndexPurge&);
378 m_space(ULINT_UNDEFINED),
380 m_xdes_page_no(ULINT_UNDEFINED),
381 m_space_flags(ULINT_UNDEFINED),
382 m_table_flags(ULINT_UNDEFINED) UNIV_NOTHROW { }
400 bool is_compressed_table() const UNIV_NOTHROW
402 return(get_zip_size() > 0);
412 if (is_compressed_table()) {
416 return(buf_block_get_frame(
block));
425 return(DB_INTERRUPTED);
460 m_xdes_page_no = page_no;
471 if (state != XDES_FREE) {
476 DBUG_EXECUTE_IF(
"ib_import_OOM_13",
477 delete [] m_xdes; m_xdes = 0;);
480 return(DB_OUT_OF_MEMORY);
503 bool is_free(ulint page_no)
const UNIV_NOTHROW
509 const xdes_t* xdesc = xdes(page_no, m_xdes);
510 ulint pos = page_no % FSP_EXTENT_SIZE;
569 if (err != DB_SUCCESS) {
579 ib_logf(IB_LOG_LEVEL_ERROR,
"Page size is 0");
581 }
else if (!is_compressed_table() &&
m_page_size != UNIV_PAGE_SIZE) {
584 "Page size %lu of ibd file is not the same "
585 "as the server page size %lu",
593 "File size " UINT64PF
" is not a multiple "
594 "of the page size %lu",
595 (ib_uint64_t) file_size, (ulong) m_page_size);
600 ut_a(m_space == ULINT_UNDEFINED);
606 if ((err = set_current_xdes(0, page)) != DB_SUCCESS) {
621 Index(index_id_t
id, ulint page_no)
624 m_page_no(page_no) { }
630 typedef std::vector<Index> Indexes;
638 m_table(table) UNIV_NOTHROW { }
645 virtual ulint get_space_id() const UNIV_NOTHROW
654 dberr_t check_row_format(ulint ibd_table_flags) UNIV_NOTHROW
657 rec_format_t ibd_rec_format;
658 rec_format_t table_rec_format;
662 ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
663 ER_TABLE_SCHEMA_MISMATCH,
664 ".ibd file has invlad table flags: %lx",
670 ibd_rec_format = dict_tf_get_rec_format(ibd_table_flags);
671 table_rec_format = dict_tf_get_rec_format(
m_table->
flags);
673 if (table_rec_format != ibd_rec_format) {
675 ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
676 ER_TABLE_SCHEMA_MISMATCH,
677 "Table has %s row format, .ibd "
678 "file has %s row format.",
725 if ((err = periodic_check()) != DB_SUCCESS) {
735 "Page offset doesn't match file offset: "
736 "page offset: %lu, file offset: %lu",
745 && is_root_page(page)) {
754 m_table_flags = dict_sys_tables_type_to_tf(
758 err = check_row_format(m_table_flags);
771 Indexes::const_iterator end =
m_indexes.end();
777 if (cfg->m_n_indexes == 0) {
779 ib_logf(IB_LOG_LEVEL_ERROR,
"No B+Tree found in tablespace");
784 cfg->m_indexes =
new(std::nothrow)
row_index_t[cfg->m_n_indexes];
787 DBUG_EXECUTE_IF(
"ib_import_OOM_11",
788 delete [] cfg->m_indexes; cfg->m_indexes = 0;);
790 if (cfg->m_indexes == 0) {
791 return(DB_OUT_OF_MEMORY);
794 memset(cfg->m_indexes, 0x0,
sizeof(*cfg->m_indexes) * cfg->m_n_indexes);
798 for (Indexes::const_iterator it =
m_indexes.begin();
804 ut_snprintf(name,
sizeof(name),
"index" IB_ID_FMT, it->m_id);
806 ulint len = strlen(name) + 1;
808 cfg_index->
m_name =
new(std::nothrow) byte[len];
811 DBUG_EXECUTE_IF(
"ib_import_OOM_12",
812 delete [] cfg_index->
m_name;
815 if (cfg_index->
m_name == 0) {
816 return(DB_OUT_OF_MEMORY);
819 memcpy(cfg_index->
m_name, name, len);
821 cfg_index->
m_id = it->m_id;
872 virtual ulint get_space_id() const UNIV_NOTHROW
874 return(m_cfg->m_table->space);
888 enum import_page_status_t {
889 IMPORT_PAGE_STATUS_OK,
890 IMPORT_PAGE_STATUS_ALL_ZERO,
891 IMPORT_PAGE_STATUS_CORRUPTED
901 ulint& page_type) UNIV_NOTHROW;
903 #if defined UNIV_DEBUG
906 bool trigger_corruption() UNIV_NOTHROW
911 #define trigger_corruption() (false)
931 import_page_status_t validate(
947 dberr_t adjust_cluster_index_blob_column(
950 ulint
i) UNIV_NOTHROW;
958 dberr_t adjust_cluster_index_blob_columns(
960 const ulint*
offsets) UNIV_NOTHROW;
968 dberr_t adjust_cluster_index_blob_ref(
970 const ulint*
offsets) UNIV_NOTHROW;
977 bool purge(
const ulint*
offsets) UNIV_NOTHROW;
990 bool deleted) UNIV_NOTHROW;
995 row_index_t* find_index(index_id_t
id) UNIV_NOTHROW
999 for (ulint
i = 0;
i < m_cfg->m_n_indexes; ++
i, ++
index) {
1000 if (
id == index->
m_id) {
1016 lsn_t m_current_lsn;
1025 ulint m_offsets_[REC_OFFS_NORMAL_SIZE];
1051 for (ulint j = 0; j < n_fields; ++j) {
1052 delete [] fields[j].
name;
1075 const char* name)
const UNIV_NOTHROW
1078 const char* index_name;
1081 index_name =
reinterpret_cast<const char*
>(index->
m_name);
1083 if (strcmp(index_name, name) == 0) {
1098 const char* name)
const UNIV_NOTHROW
1113 const char* name)
const UNIV_NOTHROW
1128 const char* name)
const UNIV_NOTHROW
1131 const char* col_name;
1133 col_name =
reinterpret_cast<const char*
>(
m_col_names[
i]);
1135 if (strcmp(col_name, name) == 0) {
1140 return(ULINT_UNDEFINED);
1148 row_import::find_field(
1150 const char* name)
const UNIV_NOTHROW
1154 for (ulint
i = 0;
i < cfg_index->
m_n_fields; ++
i, ++field) {
1155 const char* field_name;
1157 field_name =
reinterpret_cast<const char*
>(field->
name);
1159 if (strcmp(field_name, name) == 0) {
1181 if (cfg_index == 0) {
1182 ib_errf(thd, IB_LOG_LEVEL_ERROR,
1183 ER_TABLE_SCHEMA_MISMATCH,
1184 "Index %s not found in tablespace meta-data file.",
1194 for (ulint
i = 0;
i < index->n_fields; ++
i, ++field) {
1198 cfg_field = find_field(cfg_index, field->
name);
1200 if (cfg_field == 0) {
1201 ib_errf(thd, IB_LOG_LEVEL_ERROR,
1202 ER_TABLE_SCHEMA_MISMATCH,
1203 "Index %s field %s not found in tablespace "
1205 index->name, field->
name);
1211 ib_errf(thd, IB_LOG_LEVEL_ERROR,
1212 ER_TABLE_SCHEMA_MISMATCH,
1213 "Index %s field %s prefix len %lu "
1214 "doesn't match meta-data file value "
1216 index->name, field->
name,
1224 ib_errf(thd, IB_LOG_LEVEL_ERROR,
1225 ER_TABLE_SCHEMA_MISMATCH,
1226 "Index %s field %s fixed len %lu "
1227 "doesn't match meta-data file value "
1229 index->name, field->
name,
1248 THD* thd) UNIV_NOTHROW
1255 const char* col_name;
1256 ulint cfg_col_index;
1261 cfg_col_index =
find_col(col_name);
1263 if (cfg_col_index == ULINT_UNDEFINED) {
1265 ib_errf(thd, IB_LOG_LEVEL_ERROR,
1266 ER_TABLE_SCHEMA_MISMATCH,
1267 "Column %s not found in tablespace.",
1271 }
else if (cfg_col_index != col->
ind) {
1273 ib_errf(thd, IB_LOG_LEVEL_ERROR,
1274 ER_TABLE_SCHEMA_MISMATCH,
1275 "Column %s ordinal value mismatch, it's at "
1276 "%lu in the table and %lu in the tablespace "
1279 (ulong) col->
ind, (ulong) cfg_col_index);
1285 cfg_col = &
m_cols[cfg_col_index];
1286 ut_a(cfg_col->
ind == cfg_col_index);
1291 ER_TABLE_SCHEMA_MISMATCH,
1292 "Column %s precise type mismatch.",
1300 ER_TABLE_SCHEMA_MISMATCH,
1301 "Column %s main type mismatch.",
1306 if (cfg_col->
len != col->
len) {
1309 ER_TABLE_SCHEMA_MISMATCH,
1310 "Column %s length mismatch.",
1318 ER_TABLE_SCHEMA_MISMATCH,
1319 "Column %s multi-byte len mismatch.",
1324 if (cfg_col->
ind != col->
ind) {
1331 ER_TABLE_SCHEMA_MISMATCH,
1332 "Column %s ordering mismatch.",
1340 ER_TABLE_SCHEMA_MISMATCH,
1341 "Column %s max prefix mismatch.",
1358 THD* thd) UNIV_NOTHROW
1363 ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
1364 "Table flags don't match, server table has 0x%lx "
1365 "and the meta-data file has 0x%lx",
1370 ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
1371 "Number of columns don't match, table has %lu "
1372 "columns but the tablespace meta-data file has "
1383 ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
1384 "Number of indexes don't match, table has %lu "
1385 "indexes but the tablespace meta-data file has "
1395 if (err != DB_SUCCESS) {
1411 if (index_err != DB_SUCCESS) {
1429 const char* index_name;
1431 index_name =
reinterpret_cast<const char*
>(cfg_index->
m_name);
1461 table_name,
sizeof(table_name),
m_table->
name, FALSE);
1464 "Table %s should have %lu indexes but the tablespace "
1480 if (index->type & DICT_FTS) {
1483 "Skipping FTS index: %s", index->name);
1486 delete [] cfg_index[
i].
m_name;
1488 ulint len = strlen(index->name) + 1;
1490 cfg_index[
i].
m_name =
new(std::nothrow) byte[len];
1493 DBUG_EXECUTE_IF(
"ib_import_OOM_14",
1494 delete[] cfg_index[i].m_name;
1497 if (cfg_index[i].m_name == 0) {
1498 err = DB_OUT_OF_MEMORY;
1502 memcpy(cfg_index[i].m_name, index->name, len);
1531 while ((err = next()) == DB_SUCCESS) {
1533 rec_t*
rec = btr_pcur_get_rec(&m_pcur);
1547 return(err == DB_END_OF_INDEX ? DB_SUCCESS : err);
1553 IndexPurge::open() UNIV_NOTHROW
1566 IndexPurge::close() UNIV_NOTHROW
1576 IndexPurge::next() UNIV_NOTHROW
1588 return(DB_INTERRUPTED);
1603 return(DB_END_OF_INDEX);
1614 IndexPurge::purge_pessimistic_delete() UNIV_NOTHROW
1621 btr_pcur_get_rec(&m_pcur),
1625 &err, FALSE, btr_pcur_get_btr_cur(&m_pcur), 0,
RB_NONE, &m_mtr);
1627 ut_a(err == DB_SUCCESS);
1636 IndexPurge::purge() UNIV_NOTHROW
1640 purge_pessimistic_delete();
1660 m_heap(0) UNIV_NOTHROW
1665 ut_a(m_current_lsn > 0);
1667 m_offsets = m_offsets_;
1668 rec_offs_init(m_offsets_);
1670 m_cluster_index = dict_table_get_first_index(m_cfg->
m_table);
1680 PageConverter::adjust_cluster_index_blob_column(
1683 ulint
i) UNIV_NOTHROW
1690 DBUG_EXECUTE_IF(
"ib_import_trigger_corruption_2",
1695 char index_name[MAX_FULL_NAME_LEN + 1];
1698 index_name,
sizeof(index_name),
1699 m_cluster_index->name, TRUE);
1701 ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR,
1702 ER_INNODB_INDEX_CORRUPT,
1703 "Externally stored column(%lu) has a reference "
1704 "length of %lu in the cluster index %s",
1705 (ulong)
i, (ulong) len, index_name);
1712 if (is_compressed_table()) {
1716 m_page_zip_ptr,
rec, m_cluster_index,
offsets,
i, 0);
1731 PageConverter::adjust_cluster_index_blob_columns(
1733 const ulint*
offsets) UNIV_NOTHROW
1746 err = adjust_cluster_index_blob_column(
rec,
offsets,
i);
1748 if (err != DB_SUCCESS) {
1764 PageConverter::adjust_cluster_index_blob_ref(
1766 const ulint*
offsets) UNIV_NOTHROW
1771 err = adjust_cluster_index_blob_columns(
rec,
offsets);
1773 if (err != DB_SUCCESS) {
1787 PageConverter::purge(
const ulint*
offsets) UNIV_NOTHROW
1792 if (m_rec_iter.remove(index, m_page_zip_ptr, m_offsets)) {
1794 ++m_index->m_stats.m_n_purged;
1798 ++m_index->m_stats.m_n_purge_failed;
1811 PageConverter::adjust_cluster_record(
1815 bool deleted) UNIV_NOTHROW
1819 if ((err = adjust_cluster_index_blob_ref(
rec,
offsets)) == DB_SUCCESS) {
1826 rec, m_page_zip_ptr, m_cluster_index, m_offsets,
1839 PageConverter::update_records(
1843 bool clust_index = m_index->m_srv_index == m_cluster_index;
1847 m_rec_iter.open(
block);
1849 while (!m_rec_iter.end()) {
1851 rec_t*
rec = m_rec_iter.current();
1866 if (deleted || clust_index) {
1867 m_offsets = rec_get_offsets(
1868 rec, m_index->m_srv_index, m_offsets,
1869 ULINT_UNDEFINED, &m_heap);
1874 dberr_t err = adjust_cluster_record(
1875 m_index->m_srv_index, rec, m_offsets,
1878 if (err != DB_SUCCESS) {
1890 if (!purge(m_offsets)) {
1894 ++m_index->m_stats.m_n_deleted;
1896 ++m_index->m_stats.m_n_rows;
1908 PageConverter::update_index_page(
1931 if (m_cfg->m_missing && (m_index == 0 || m_index->m_srv_index == 0)) {
1935 #ifdef UNIV_ZIP_DEBUG
1936 ut_a(!is_compressed_table()
1937 || page_zip_validate(m_page_zip_ptr, page, m_index->m_srv_index));
1942 btr_page_set_index_id(
1943 page, m_page_zip_ptr, m_index->m_srv_index->id, 0);
1960 return(update_records(
block));
1968 PageConverter::update_header(
1975 case ULINT_UNDEFINED:
1977 "Space id check in the header failed "
1986 "Unsupported tablespace format %lu",
1987 (ulong) space_flags);
2013 PageConverter::update_page(
2015 ulint& page_type) UNIV_NOTHROW
2023 return(update_header(
block));
2039 return(update_index_page(
block));
2046 err = set_current_xdes(
2066 ib_logf(IB_LOG_LEVEL_WARN,
"Unknown page type (%lu)", page_type);
2076 PageConverter::import_page_status_t
2077 PageConverter::validate(
2091 return(IMPORT_PAGE_STATUS_CORRUPTED);
2094 const byte* b =
page;
2095 const byte* e = b + m_page_size;
2103 if (*b++ && !trigger_corruption()) {
2104 return(IMPORT_PAGE_STATUS_CORRUPTED);
2109 return(IMPORT_PAGE_STATUS_ALL_ZERO);
2112 return(IMPORT_PAGE_STATUS_OK);
2129 if ((err = periodic_check()) != DB_SUCCESS) {
2133 if (is_compressed_table()) {
2136 ut_ad(m_page_zip_ptr == 0);
2140 case IMPORT_PAGE_STATUS_OK:
2145 if ((err = update_page(
block, page_type)) != DB_SUCCESS) {
2158 !is_compressed_table()
2160 !is_compressed_table() ? 0 : m_page_zip_ptr,
2167 get_frame(
block), get_zip_size(),
2173 case IMPORT_PAGE_STATUS_ALL_ZERO:
2177 case IMPORT_PAGE_STATUS_CORRUPTED:
2180 "%s: Page %lu at offset " UINT64PF
" looks corrupted.",
2193 static __attribute__((nonnull))
2195 row_import_discard_changes(
2203 ut_a(err != DB_SUCCESS);
2205 prebuilt->trx->error_info = NULL;
2210 table_name,
sizeof(table_name),
2211 prebuilt->table->name, FALSE);
2214 "Discarding tablespace of table %s: %s",
2219 row_mysql_lock_data_dictionary(trx);
2244 static __attribute__((nonnull, warn_unused_result))
2252 ut_a(prebuilt->trx != trx);
2254 if (err != DB_SUCCESS) {
2255 row_import_discard_changes(prebuilt, trx, err);
2258 ut_a(trx->dict_operation_lock_mode == RW_X_LATCH);
2260 DBUG_EXECUTE_IF(
"ib_import_before_commit_crash", DBUG_SUICIDE(););
2268 prebuilt->trx->op_info =
"";
2270 DBUG_EXECUTE_IF(
"ib_import_before_checkpoint_crash", DBUG_SUICIDE(););
2279 static __attribute__((nonnull, warn_unused_result))
2291 table_name,
sizeof(table_name),
2292 prebuilt->table->name, FALSE);
2295 trx->mysql_thd, IB_LOG_LEVEL_WARN,
2296 ER_INNODB_IMPORT_ERROR,
2297 table_name, (ulong) err,
ut_strerr(err));
2300 return(row_import_cleanup(prebuilt, trx, err));
2307 static __attribute__((nonnull, warn_unused_result))
2309 row_import_adjust_root_pages_of_secondary_indexes(
2320 ulint n_rows_in_table;
2324 index = dict_table_get_first_index(table);
2326 n_rows_in_table = cfg.get_n_rows(index->
name);
2328 DBUG_EXECUTE_IF(
"ib_import_sec_rec_count_mismatch_failure",
2329 n_rows_in_table++;);
2332 while ((index = dict_table_get_next_index(index)) != NULL) {
2333 char index_name[MAX_FULL_NAME_LEN + 1];
2336 index_name,
sizeof(index_name), index->
name, TRUE);
2350 "Skip adjustment of root pages for "
2351 "index %s.", index->
name);
2356 if (err != DB_SUCCESS) {
2364 ER_INNODB_INDEX_CORRUPT,
2365 "Index '%s' not found or corrupt, "
2366 "you should recreate this index.",
2383 if (!cfg.requires_purge(index->
name)) {
2389 trx->op_info =
"secondary: purge delete marked records";
2391 err = purge.garbage_collect();
2395 if (err != DB_SUCCESS) {
2397 }
else if (purge.get_n_rows() != n_rows_in_table) {
2401 ER_INNODB_INDEX_CORRUPT,
2402 "Index '%s' contains %lu entries, "
2403 "should be %lu, you should recreate "
2404 "this index.", index_name,
2405 (ulong) purge.get_n_rows(),
2406 (ulong) n_rows_in_table);
2423 static __attribute__((nonnull, warn_unused_result))
2425 row_import_set_sys_max_row_id(
2438 index = dict_table_get_first_index(table);
2455 rec = btr_pcur_get_rec(&pcur);
2462 ulint offsets_[1 + REC_OFFS_HEADER_SIZE];
2465 rec_offs_init(offsets_);
2467 offsets = rec_get_offsets(
2468 rec, index, offsets_, ULINT_UNDEFINED, &heap);
2470 field = rec_get_nth_field(
2475 if (len == DATA_ROW_ID_LEN) {
2493 DBUG_EXECUTE_IF(
"ib_import_set_max_rowid_failure",
2496 if (err != DB_SUCCESS) {
2497 char index_name[MAX_FULL_NAME_LEN + 1];
2500 index_name,
sizeof(index_name), index->
name, TRUE);
2502 ib_errf(prebuilt->trx->mysql_thd,
2504 ER_INNODB_INDEX_CORRUPT,
2505 "Index '%s' corruption detected, invalid DB_ROW_ID "
2506 "in index.", index_name);
2510 }
else if (row_id > 0) {
2533 row_import_cfg_read_string(
2540 DBUG_EXECUTE_IF(
"ib_import_string_read_error",
2545 while (!feof(file)) {
2546 int ch = fgetc(file);
2550 }
else if (ch != 0) {
2551 if (len < max_len) {
2557 }
else if (len != max_len - 1) {
2573 static __attribute__((nonnull, warn_unused_result))
2575 row_import_cfg_read_index_fields(
2582 byte row[
sizeof(ib_uint32_t) * 3];
2583 ulint n_fields = index->m_n_fields;
2585 index->m_fields =
new(std::nothrow)
dict_field_t[n_fields];
2588 DBUG_EXECUTE_IF(
"ib_import_OOM_4",
2589 delete [] index->m_fields; index->m_fields = 0;);
2591 if (index->m_fields == 0) {
2592 return(DB_OUT_OF_MEMORY);
2597 memset(field, 0x0,
sizeof(*field) * n_fields);
2599 for (ulint
i = 0;
i < n_fields; ++
i, ++field) {
2603 DBUG_EXECUTE_IF(
"ib_import_io_read_error_1",
2604 (
void) fseek(file, 0L, SEEK_END););
2606 if (fread(row, 1,
sizeof(row), file) !=
sizeof(row)) {
2609 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2610 errno, strerror(errno),
2611 "while reading index fields.");
2617 ptr +=
sizeof(ib_uint32_t);
2620 ptr +=
sizeof(ib_uint32_t);
2625 byte* name =
new(std::nothrow) byte[len];
2628 DBUG_EXECUTE_IF(
"ib_import_OOM_5",
delete [] name; name = 0;);
2631 return(DB_OUT_OF_MEMORY);
2634 field->
name =
reinterpret_cast<const char*
>(
name);
2636 dberr_t err = row_import_cfg_read_string(file, name, len);
2638 if (err != DB_SUCCESS) {
2641 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2642 errno, strerror(errno),
2643 "while parsing table name.");
2656 static __attribute__((nonnull, warn_unused_result))
2658 row_import_read_index_data(
2666 byte row[
sizeof(index_id_t) +
sizeof(ib_uint32_t) * 9];
2669 ut_a(cfg->m_n_indexes > 0);
2670 ut_a(cfg->m_n_indexes < 1024);
2672 cfg->m_indexes =
new(std::nothrow)
row_index_t[cfg->m_n_indexes];
2675 DBUG_EXECUTE_IF(
"ib_import_OOM_6",
2676 delete [] cfg->m_indexes; cfg->m_indexes = 0;);
2678 if (cfg->m_indexes == 0) {
2679 return(DB_OUT_OF_MEMORY);
2682 memset(cfg->m_indexes, 0x0,
sizeof(*cfg->m_indexes) * cfg->m_n_indexes);
2684 cfg_index = cfg->m_indexes;
2686 for (ulint
i = 0;
i < cfg->m_n_indexes; ++
i, ++cfg_index) {
2688 DBUG_EXECUTE_IF(
"ib_import_io_read_error_2",
2689 (
void) fseek(file, 0L, SEEK_END););
2692 size_t n_bytes = fread(row, 1,
sizeof(row), file);
2695 DBUG_EXECUTE_IF(
"ib_import_io_read_error",
2696 (
void) fseek(file, 0L, SEEK_END););
2698 if (n_bytes !=
sizeof(row)) {
2702 "while reading index meta-data, expected "
2703 "to read %lu bytes but read only %lu "
2705 (ulong)
sizeof(row), (ulong) n_bytes);
2708 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2709 errno, strerror(errno), msg);
2711 ib_logf(IB_LOG_LEVEL_ERROR,
"IO Error: %s", msg);
2719 ptr +=
sizeof(index_id_t);
2722 ptr +=
sizeof(ib_uint32_t);
2725 ptr +=
sizeof(ib_uint32_t);
2728 ptr +=
sizeof(ib_uint32_t);
2737 ptr +=
sizeof(ib_uint32_t);
2740 ptr +=
sizeof(ib_uint32_t);
2743 ptr +=
sizeof(ib_uint32_t);
2746 ptr +=
sizeof(ib_uint32_t);
2749 ptr +=
sizeof(ib_uint32_t);
2754 if (len > OS_FILE_MAX_PATH) {
2755 ib_errf(thd, IB_LOG_LEVEL_ERROR,
2756 ER_INNODB_INDEX_CORRUPT,
2757 "Index name length (%lu) is too long, "
2758 "the meta-data is corrupt", len);
2763 cfg_index->
m_name =
new(std::nothrow) byte[len];
2766 DBUG_EXECUTE_IF(
"ib_import_OOM_7",
2767 delete [] cfg_index->
m_name;
2770 if (cfg_index->
m_name == 0) {
2771 return(DB_OUT_OF_MEMORY);
2776 err = row_import_cfg_read_string(file, cfg_index->
m_name, len);
2778 if (err != DB_SUCCESS) {
2781 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2782 errno, strerror(errno),
2783 "while parsing index name.");
2788 err = row_import_cfg_read_index_fields(
2789 file, thd, cfg_index, cfg);
2791 if (err != DB_SUCCESS) {
2805 row_import_read_indexes(
2811 byte row[
sizeof(ib_uint32_t)];
2814 DBUG_EXECUTE_IF(
"ib_import_io_read_error_3",
2815 (
void) fseek(file, 0L, SEEK_END););
2818 if (fread(row, 1,
sizeof(row), file) !=
sizeof(row)) {
2820 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2821 errno, strerror(errno),
2822 "while reading number of indexes.");
2830 ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2831 "Number of indexes in meta-data file is 0");
2837 ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2838 "Number of indexes in meta-data file is too high: %lu",
2845 return(row_import_read_index_data(file, thd, cfg));
2851 static __attribute__((nonnull, warn_unused_result))
2853 row_import_read_columns(
2860 byte row[
sizeof(ib_uint32_t) * 8];
2863 ut_a(cfg->m_n_cols > 0);
2864 ut_a(cfg->m_n_cols < 1024);
2866 cfg->m_cols =
new(std::nothrow)
dict_col_t[cfg->m_n_cols];
2869 DBUG_EXECUTE_IF(
"ib_import_OOM_8",
2870 delete [] cfg->m_cols; cfg->m_cols = 0;);
2872 if (cfg->m_cols == 0) {
2873 return(DB_OUT_OF_MEMORY);
2876 cfg->m_col_names =
new(std::nothrow) byte* [cfg->m_n_cols];
2879 DBUG_EXECUTE_IF(
"ib_import_OOM_9",
2880 delete [] cfg->m_col_names; cfg->m_col_names = 0;);
2882 if (cfg->m_col_names == 0) {
2883 return(DB_OUT_OF_MEMORY);
2886 memset(cfg->m_cols, 0x0,
sizeof(cfg->m_cols) * cfg->m_n_cols);
2887 memset(cfg->m_col_names, 0x0,
sizeof(cfg->m_col_names) * cfg->m_n_cols);
2891 for (ulint
i = 0;
i < cfg->m_n_cols; ++
i, ++col) {
2895 DBUG_EXECUTE_IF(
"ib_import_io_read_error_4",
2896 (
void) fseek(file, 0L, SEEK_END););
2898 if (fread(row, 1,
sizeof(row), file) !=
sizeof(row)) {
2900 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2901 errno, strerror(errno),
2902 "while reading table column meta-data.");
2908 ptr +=
sizeof(ib_uint32_t);
2911 ptr +=
sizeof(ib_uint32_t);
2914 ptr +=
sizeof(ib_uint32_t);
2917 ptr +=
sizeof(ib_uint32_t);
2920 ptr +=
sizeof(ib_uint32_t);
2923 ptr +=
sizeof(ib_uint32_t);
2926 ptr +=
sizeof(ib_uint32_t);
2934 if (len == 0 || len > 128) {
2935 ib_errf(thd, IB_LOG_LEVEL_ERROR,
2937 "Column name length %lu, is invalid",
2943 cfg->m_col_names[
i] =
new(std::nothrow) byte[len];
2946 DBUG_EXECUTE_IF(
"ib_import_OOM_10",
2947 delete [] cfg->m_col_names[
i];
2948 cfg->m_col_names[
i] = 0;);
2950 if (cfg->m_col_names[
i] == 0) {
2951 return(DB_OUT_OF_MEMORY);
2956 err = row_import_cfg_read_string(
2957 file, cfg->m_col_names[
i], len);
2959 if (err != DB_SUCCESS) {
2962 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2963 errno, strerror(errno),
2964 "while parsing table column name.");
2976 static __attribute__((nonnull, warn_unused_result))
2984 byte value[
sizeof(ib_uint32_t)];
2987 DBUG_EXECUTE_IF(
"ib_import_io_read_error_5",
2988 (
void) fseek(file, 0L, SEEK_END););
2991 if (fread(value, 1,
sizeof(value), file) !=
sizeof(value)) {
2993 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
2994 errno, strerror(errno),
2995 "while reading meta-data export hostname length.");
3003 cfg->m_hostname =
new(std::nothrow) byte[len];
3006 DBUG_EXECUTE_IF(
"ib_import_OOM_1",
3007 delete [] cfg->m_hostname; cfg->m_hostname = 0;);
3009 if (cfg->m_hostname == 0) {
3010 return(DB_OUT_OF_MEMORY);
3013 dberr_t err = row_import_cfg_read_string(file, cfg->m_hostname, len);
3015 if (err != DB_SUCCESS) {
3018 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
3019 errno, strerror(errno),
3020 "while parsing export hostname.");
3026 DBUG_EXECUTE_IF(
"ib_import_io_read_error_6",
3027 (
void) fseek(file, 0L, SEEK_END););
3030 if (fread(value, 1,
sizeof(value), file) !=
sizeof(value)) {
3032 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
3033 errno, strerror(errno),
3034 "while reading meta-data table name length.");
3042 cfg->m_table_name =
new(std::nothrow) byte[len];
3045 DBUG_EXECUTE_IF(
"ib_import_OOM_2",
3046 delete [] cfg->m_table_name; cfg->m_table_name = 0;);
3048 if (cfg->m_table_name == 0) {
3049 return(DB_OUT_OF_MEMORY);
3052 err = row_import_cfg_read_string(file, cfg->m_table_name, len);
3054 if (err != DB_SUCCESS) {
3056 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
3057 errno, strerror(errno),
3058 "while parsing table name.");
3064 "Importing tablespace for table '%s' that was exported "
3065 "from host '%s'", cfg->m_table_name, cfg->m_hostname);
3067 byte row[
sizeof(ib_uint32_t) * 3];
3070 DBUG_EXECUTE_IF(
"ib_import_io_read_error_7",
3071 (
void) fseek(file, 0L, SEEK_END););
3074 if (fread(row, 1,
sizeof(ib_uint64_t), file) !=
sizeof(ib_uint64_t)) {
3076 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
3077 errno, strerror(errno),
3078 "while reading autoinc value.");
3086 DBUG_EXECUTE_IF(
"ib_import_io_read_error_8",
3087 (
void) fseek(file, 0L, SEEK_END););
3090 if (fread(row, 1,
sizeof(row), file) !=
sizeof(row)) {
3092 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
3093 errno, strerror(errno),
3094 "while reading meta-data header.");
3102 ptr +=
sizeof(ib_uint32_t);
3104 if (cfg->m_page_size != UNIV_PAGE_SIZE) {
3106 ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
3107 "Tablespace to be imported has a different "
3108 "page size than this server. Server page size "
3109 "is %lu, whereas tablespace page size is %lu",
3110 UNIV_PAGE_SIZE, (ulong) cfg->m_page_size);
3116 ptr +=
sizeof(ib_uint32_t);
3124 }
else if ((err = row_import_read_columns(file, thd, cfg))
3129 }
else if ((err = row_import_read_indexes(file, thd, cfg))
3135 ut_a(err == DB_SUCCESS);
3142 static __attribute__((nonnull, warn_unused_result))
3144 row_import_read_meta_data(
3151 byte row[
sizeof(ib_uint32_t)];
3154 DBUG_EXECUTE_IF(
"ib_import_io_read_error_9",
3155 (
void) fseek(file, 0L, SEEK_END););
3157 if (fread(&row, 1,
sizeof(row), file) !=
sizeof(row)) {
3159 thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
3160 errno, strerror(errno),
3161 "while reading meta-data version.");
3169 switch (cfg.m_version) {
3172 return(row_import_read_v1(file, thd, &cfg));
3174 ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_IO_READ_ERROR,
3175 "Unsupported meta-data version number (%lu), "
3176 "file ignored", (ulong) cfg.m_version);
3185 static __attribute__((nonnull, warn_unused_result))
3187 row_import_read_cfg(
3194 char name[OS_FILE_MAX_PATH];
3196 cfg.m_table =
table;
3200 FILE* file = fopen(name,
"rb");
3206 "Error opening '%s', will attempt to import "
3207 "without schema verification", name);
3210 thd, IB_LOG_LEVEL_WARN, ER_IO_READ_ERROR,
3211 errno, strerror(errno), msg);
3213 cfg.m_missing =
true;
3218 cfg.m_missing =
false;
3220 err = row_import_read_meta_data(table, file, thd, cfg);
3250 static const char sql[] = {
3251 "PROCEDURE UPDATE_INDEX_ROOT() IS\n"
3253 "UPDATE SYS_INDEXES\n"
3254 "SET SPACE = :space,\n"
3255 " PAGE_NO = :page,\n"
3257 "WHERE TABLE_ID = :table_id AND ID = :index_id;\n"
3264 for (index = dict_table_get_first_index(table);
3266 index = dict_table_get_next_index(index)) {
3272 index_id_t index_id;
3273 table_id_t table_id;
3278 reinterpret_cast<byte*>(&type),
3282 reinterpret_cast<byte*>(&page),
3286 reinterpret_cast<byte*>(&space),
3290 reinterpret_cast<byte*>(&index_id),
3294 reinterpret_cast<byte*>(&table_id),
3313 graph->
fork_type = QUE_FORK_MYSQL_INTERFACE;
3319 DBUG_EXECUTE_IF(
"ib_import_internal_error",
3324 if (err != DB_SUCCESS) {
3325 char index_name[MAX_FULL_NAME_LEN + 1];
3328 index_name,
sizeof(index_name),
3333 "While updating the <space, root page "
3334 "number> of index %s - %s",
3363 row_import_set_discarded(
3369 discard_t* discard =
static_cast<discard_t*
>(user_arg);
3371 dtype_t* type = dfield_get_type(dfield);
3375 ut_a(len ==
sizeof(ib_uint32_t));
3378 static_cast<byte*>(dfield_get_data(dfield)));
3380 if (discard->state) {
3391 ut_a(discard->n_recs == 1);
3405 table_id_t table_id,
3417 static const char sql[] =
3418 "PROCEDURE UPDATE_DISCARDED_FLAG() IS\n"
3419 "DECLARE FUNCTION my_func;\n"
3420 "DECLARE CURSOR c IS\n"
3423 " WHERE ID = :table_id FOR UPDATE;"
3427 "WHILE 1 = 1 LOOP\n"
3428 " FETCH c INTO my_func();\n"
3429 " IF c % NOTFOUND THEN\n"
3434 " SET MIX_LEN = :flags2"
3435 " WHERE ID = :table_id;\n"
3440 discard.state = discarded;
3441 discard.flags2 = ULINT32_UNDEFINED;
3449 info,
"my_func", row_import_set_discarded, &discard);
3453 ut_a(discard.n_recs == 1);
3454 ut_a(discard.flags2 != ULINT32_UNDEFINED);
3472 ib_uint64_t autoinc = 0;
3473 char table_name[MAX_FULL_NAME_LEN + 1];
3474 char* filepath = NULL;
3479 table_name,
sizeof(table_name), table->
name, FALSE);
3485 trx_start_if_not_started(prebuilt->
trx);
3492 trx_start_if_not_started(trx);
3511 DBUG_EXECUTE_IF(
"ib_import_undo_assign_failure",
3514 if (err != DB_SUCCESS) {
3516 return(row_import_cleanup(prebuilt, trx, err));
3521 return(row_import_cleanup(prebuilt, trx, err));
3524 prebuilt->
trx->
op_info =
"read meta-data file";
3532 memset(&cfg, 0x0,
sizeof(cfg));
3534 err = row_import_read_cfg(table, trx->
mysql_thd, cfg);
3539 if (err == DB_SUCCESS) {
3550 if (err == DB_SUCCESS) {
3557 DBUG_EXECUTE_IF(
"ib_import_set_index_root_failure",
3568 ut_a(err == DB_FAIL);
3576 fetchIndexRootPages);
3578 if (err == DB_SUCCESS) {
3586 if (err == DB_SUCCESS) {
3595 if (err != DB_SUCCESS) {
3596 return(row_import_error(prebuilt, trx, err));
3599 prebuilt->
trx->
op_info =
"importing tablespace";
3601 ib_logf(IB_LOG_LEVEL_INFO,
"Phase I - Update all pages");
3613 DBUG_EXECUTE_IF(
"ib_import_reset_space_and_lsn_failure",
3616 if (err != DB_SUCCESS) {
3617 char table_name[MAX_FULL_NAME_LEN + 1];
3620 table_name,
sizeof(table_name), table->
name, FALSE);
3624 "Cannot reset LSNs in table '%s' : %s",
3627 return(row_import_cleanup(prebuilt, trx, err));
3630 row_mysql_lock_data_dictionary(trx);
3651 true,
true, table->
space,
3653 table->
name, filepath);
3655 DBUG_EXECUTE_IF(
"ib_import_open_tablespace_failure",
3656 err = DB_TABLESPACE_NOT_FOUND;);
3658 if (err != DB_SUCCESS) {
3667 return(row_import_cleanup(prebuilt, trx, err));
3676 DBUG_EXECUTE_IF(
"ib_import_check_bitmap_failure", err =
DB_CORRUPTION;);
3678 if (err != DB_SUCCESS) {
3679 return(row_import_cleanup(prebuilt, trx, err));
3684 dict_index_t* index = dict_table_get_first_index(table);
3695 DBUG_EXECUTE_IF(
"ib_import_cluster_root_adjust_failure",
3698 if (err != DB_SUCCESS) {
3699 return(row_import_error(prebuilt, trx, err));
3702 if (err != DB_SUCCESS) {
3703 return(row_import_error(prebuilt, trx, err));
3712 trx->
op_info =
"cluster: purging delete marked records";
3719 DBUG_EXECUTE_IF(
"ib_import_cluster_failure", err =
DB_CORRUPTION;);
3721 if (err != DB_SUCCESS) {
3722 return(row_import_error(prebuilt, trx, err));
3728 err = row_import_adjust_root_pages_of_secondary_indexes(
3729 prebuilt, trx, table, cfg);
3731 DBUG_EXECUTE_IF(
"ib_import_sec_root_adjust_failure",
3734 if (err != DB_SUCCESS) {
3735 return(row_import_error(prebuilt, trx, err));
3743 err = row_import_set_sys_max_row_id(prebuilt, table);
3745 if (err != DB_SUCCESS) {
3746 return(row_import_error(prebuilt, trx, err));
3750 ib_logf(IB_LOG_LEVEL_INFO,
"Phase III - Flush changes to disk");
3760 ib_logf(IB_LOG_LEVEL_INFO,
"Phase III - Flush interrupted");
3761 return(row_import_error(prebuilt, trx, DB_INTERRUPTED));
3763 ib_logf(IB_LOG_LEVEL_INFO,
"Phase IV - Flush complete");
3769 row_mysql_lock_data_dictionary(trx);
3774 if (err != DB_SUCCESS) {
3775 return(row_import_error(prebuilt, trx, err));
3781 if (err != DB_SUCCESS) {
3782 return(row_import_error(prebuilt, trx, err));
3789 char table_name[MAX_FULL_NAME_LEN + 1];
3792 table_name,
sizeof(table_name), table->
name, FALSE);
3794 ib_logf(IB_LOG_LEVEL_INFO,
"%s autoinc value set to " IB_ID_FMT,
3795 table_name, autoinc);
3802 ut_a(err == DB_SUCCESS);
3804 return(row_import_cleanup(prebuilt, trx, err));