summaryrefslogtreecommitdiff
path: root/storage/innobase/row
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row')
-rw-r--r--storage/innobase/row/row0import.cc11
-rw-r--r--storage/innobase/row/row0ins.cc9
-rw-r--r--storage/innobase/row/row0merge.cc96
-rw-r--r--storage/innobase/row/row0mysql.cc133
-rw-r--r--storage/innobase/row/row0purge.cc10
-rw-r--r--storage/innobase/row/row0sel.cc18
-rw-r--r--storage/innobase/row/row0trunc.cc9
7 files changed, 172 insertions, 114 deletions
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 01a55d0dc61..a2773baa34e 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1959,16 +1959,13 @@ PageConverter::validate(
buf_block_t* block) UNIV_NOTHROW
{
buf_frame_t* page = get_frame(block);
- ulint space_id = mach_read_from_4(
- page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
- fil_space_t* space = fil_space_found_by_id(space_id);
/* Check that the page number corresponds to the offset in
the file. Flag as corrupt if it doesn't. Disable the check
for LSN in buf_page_is_corrupted() */
if (buf_page_is_corrupted(
- false, page, get_page_size(), space)
+ false, page, get_page_size(), NULL)
|| (page_get_page_no(page) != offset / m_page_size.physical()
&& page_get_page_no(page) != 0)) {
@@ -2101,7 +2098,7 @@ row_import_discard_changes(
index->space = FIL_NULL;
}
- table->ibd_file_missing = TRUE;
+ table->file_unreadable = true;
fil_close_tablespace(trx, table->space);
}
@@ -3357,7 +3354,7 @@ row_import_for_mysql(
ut_a(table->space);
ut_ad(prebuilt->trx);
- ut_a(table->ibd_file_missing);
+ ut_a(!table->is_readable());
ibuf_delete_for_discarded_space(table->space);
@@ -3691,7 +3688,7 @@ row_import_for_mysql(
return(row_import_error(prebuilt, trx, err));
}
- table->ibd_file_missing = false;
+ table->file_unreadable = false;
table->flags2 &= ~DICT_TF2_DISCARDED;
/* Set autoinc value read from .cfg file, if one was specified.
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 5803bc226cd..fb162592f75 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1656,7 +1656,7 @@ row_ins_check_foreign_constraint(
}
if (check_table == NULL
- || check_table->ibd_file_missing
+ || !check_table->is_readable()
|| check_index == NULL) {
if (!srv_read_only_mode && check_ref) {
@@ -2617,6 +2617,11 @@ row_ins_clust_index_entry_low(
__FILE__, __LINE__, auto_inc, &mtr);
cursor = btr_pcur_get_btr_cur(&pcur);
cursor->thr = thr;
+ if (err != DB_SUCCESS) {
+ index->table->file_unreadable = true;
+ mtr_commit(&mtr);
+ goto func_exit;
+ }
#ifdef UNIV_DEBUG
{
@@ -2950,7 +2955,7 @@ row_ins_sec_index_entry_low(
" used key_id is not available. "
" Can't continue reading table.",
index->table->name);
- index->table->is_encrypted = true;
+ index->table->file_unreadable = true;
}
goto func_exit;
}
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 82da61dc03b..4c30d0bfa49 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2014, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -26,6 +26,7 @@ Completed by Sunny Bains and Marko Makela
*******************************************************/
#include <my_config.h>
#include <log.h>
+#include <sql_class.h>
#include <math.h>
@@ -1995,7 +1996,8 @@ row_merge_read_clustered_index(
page_cur_t* cur = btr_pcur_get_page_cur(&pcur);
/* Do not continue if table pages are still encrypted */
- if (old_table->is_encrypted || new_table->is_encrypted) {
+ if (!old_table->is_readable() ||
+ !new_table->is_readable()) {
err = DB_DECRYPTION_FAILED;
trx->error_key_num = 0;
goto func_exit;
@@ -3300,7 +3302,11 @@ row_merge_sort(
}
#endif /* UNIV_SOLARIS */
- sql_print_information("InnoDB: Online DDL : merge-sorting has estimated %lu runs", num_runs);
+ if (global_system_variables.log_warnings > 2) {
+ sql_print_information("InnoDB: Online DDL : merge-sorting"
+ " has estimated " ULINTPF " runs",
+ num_runs);
+ }
/* Merge the runs until we have one big run */
do {
@@ -4295,7 +4301,7 @@ row_merge_rename_tables_dict(
renamed along with the table. */
if (err == DB_SUCCESS
&& dict_table_is_file_per_table(old_table)
- && !old_table->ibd_file_missing) {
+ && fil_space_get(old_table->space) != NULL) {
/* Make pathname to update SYS_DATAFILES. */
char* tmp_path = row_make_new_pathname(old_table, tmp_name);
@@ -4765,20 +4771,24 @@ row_merge_build_indexes(
duplicate keys. */
innobase_rec_reset(table);
- sql_print_information("InnoDB: Online DDL : Start");
- sql_print_information("InnoDB: Online DDL : Start reading clustered "
- "index of the table and create temporary files");
+ if (global_system_variables.log_warnings > 2) {
+ sql_print_information("InnoDB: Online DDL : Start reading"
+ " clustered index of the table"
+ " and create temporary files");
+ }
pct_cost = COST_READ_CLUSTERED_INDEX * 100 / (total_static_cost + total_dynamic_cost);
/* Do not continue if we can't encrypt table pages */
- if (old_table->is_encrypted || new_table->is_encrypted) {
+ if (!old_table->is_readable() ||
+ !new_table->is_readable()) {
error = DB_DECRYPTION_FAILED;
ib_push_warning(trx->mysql_thd, DB_DECRYPTION_FAILED,
"Table %s is encrypted but encryption service or"
" used key_id is not available. "
" Can't continue reading table.",
- old_table->is_encrypted ? old_table->name : new_table->name);
+ !old_table->is_readable() ? old_table->name :
+ new_table->name);
goto func_exit;
}
@@ -4795,8 +4805,11 @@ row_merge_build_indexes(
pct_progress += pct_cost;
- sql_print_information("InnoDB: Online DDL : End of reading "
- "clustered index of the table and create temporary files");
+ if (global_system_variables.log_warnings > 2) {
+ sql_print_information("InnoDB: Online DDL : End of reading "
+ "clustered index of the table"
+ " and create temporary files");
+ }
for (i = 0; i < n_indexes; i++) {
total_index_blocks += merge_files[i].offset;
@@ -4895,8 +4908,7 @@ wait_again:
DEBUG_FTS_SORT_PRINT("FTS_SORT: Complete Insert\n");
#endif
} else if (merge_files[i].fd >= 0) {
- char buf[3 * NAME_LEN];
- char *bufend;
+ char buf[NAME_LEN + 1];
row_merge_dup_t dup = {
sort_idx, table, col_map, 0};
@@ -4905,17 +4917,24 @@ wait_again:
total_index_blocks)) /
(total_static_cost + total_dynamic_cost)
* PCT_COST_MERGESORT_INDEX * 100;
-
- bufend = innobase_convert_name(
+ char* bufend = innobase_convert_name(
buf, sizeof buf,
- indexes[i]->name, strlen(indexes[i]->name),
+ indexes[i]->name,
+ strlen(indexes[i]->name),
trx->mysql_thd);
-
buf[bufend - buf]='\0';
- sql_print_information("InnoDB: Online DDL : Start merge-sorting"
- " index %s (%lu / %lu), estimated cost : %2.4f",
- buf, (i+1), n_indexes, pct_cost);
+ if (global_system_variables.log_warnings > 2) {
+ sql_print_information("InnoDB: Online DDL :"
+ " Start merge-sorting"
+ " index %s"
+ " (" ULINTPF
+ " / " ULINTPF "),"
+ " estimated cost :"
+ " %2.4f",
+ buf, i + 1, n_indexes,
+ pct_cost);
+ }
error = row_merge_sort(
trx, &dup, &merge_files[i],
@@ -4925,9 +4944,14 @@ wait_again:
pct_progress += pct_cost;
- sql_print_information("InnoDB: Online DDL : End of "
- " merge-sorting index %s (%lu / %lu)",
- buf, (i+1), n_indexes);
+ if (global_system_variables.log_warnings > 2) {
+ sql_print_information("InnoDB: Online DDL :"
+ " End of "
+ " merge-sorting index %s"
+ " (" ULINTPF
+ " / " ULINTPF ")",
+ buf, i + 1, n_indexes);
+ }
DBUG_EXECUTE_IF(
"ib_merge_wait_after_sort",
@@ -4944,10 +4968,15 @@ wait_again:
(total_static_cost + total_dynamic_cost) *
PCT_COST_INSERT_INDEX * 100;
- sql_print_information("InnoDB: Online DDL : Start "
- "building index %s (%lu / %lu), estimated "
- "cost : %2.4f", buf, (i+1),
- n_indexes, pct_cost);
+ if (global_system_variables.log_warnings > 2) {
+ sql_print_information(
+ "InnoDB: Online DDL : Start "
+ "building index %s"
+ " (" ULINTPF
+ " / " ULINTPF "), estimated "
+ "cost : %2.4f", buf, i + 1,
+ n_indexes, pct_cost);
+ }
error = row_merge_insert_index_tuples(
trx->id, sort_idx, old_table,
@@ -4960,9 +4989,13 @@ wait_again:
pct_progress += pct_cost;
- sql_print_information("InnoDB: Online DDL : "
- "End of building index %s (%lu / %lu)",
- buf, (i+1), n_indexes);
+ if (global_system_variables.log_warnings > 2) {
+ sql_print_information(
+ "InnoDB: Online DDL : "
+ "End of building index %s"
+ " (" ULINTPF " / " ULINTPF ")",
+ buf, i + 1, n_indexes);
+ }
}
}
@@ -4988,11 +5021,8 @@ wait_again:
DEBUG_SYNC_C("row_log_apply_before");
error = row_log_apply(trx, sort_idx, table, stage);
DEBUG_SYNC_C("row_log_apply_after");
- sql_print_information("InnoDB: Online DDL : End of applying row log");
}
- sql_print_information("InnoDB: Online DDL : Completed");
-
if (error != DB_SUCCESS) {
trx->error_key_num = key_numbers[i];
goto func_exit;
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 20a8777b71e..6160450d510 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2015, 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -819,6 +819,7 @@ handle_new_error:
break;
case DB_CORRUPTION:
+ case DB_PAGE_CORRUPTED:
ib::error() << "We detected index corruption in an InnoDB type"
" table. You have to dump + drop + reimport the"
" table or, in a case of widespread corruption,"
@@ -1402,6 +1403,63 @@ run_again:
/** Does an insert for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle
+@param[in] table Table
+@param[in] trx Transaction
+@param[in] push_warning true if we should push warning to user
+@return DB_DECRYPTION_FAILED table is encrypted but decryption failed
+DB_CORRUPTION table is corrupted
+DB_TABLESPACE_NOT_FOUND tablespace .ibd file not found */
+static
+dberr_t
+row_mysql_get_table_status(
+ const dict_table_t* table,
+ trx_t* trx,
+ bool push_warning = true)
+{
+ dberr_t err = DB_SUCCESS;
+ if (fil_space_t* space = fil_space_acquire_silent(table->space)) {
+ if (space->crypt_data && space->crypt_data->is_encrypted()) {
+ // maybe we cannot access the table due to failing
+ // to decrypt
+ if (push_warning) {
+ ib_push_warning(trx, DB_DECRYPTION_FAILED,
+ "Table %s in tablespace %lu encrypted."
+ "However key management plugin or used key_id is not found or"
+ " used encryption algorithm or method does not match.",
+ table->name, table->space);
+ }
+
+ err = DB_DECRYPTION_FAILED;
+ } else {
+ if (push_warning) {
+ ib_push_warning(trx, DB_CORRUPTION,
+ "Table %s in tablespace %lu corrupted.",
+ table->name, table->space);
+ }
+
+ err = DB_CORRUPTION;
+ }
+
+ fil_space_release(space);
+ } else {
+ ib::error()
+ << "InnoDB: MySQL is trying to use a table handle"
+ " but the .ibd file for"
+ " table " << table->name << " does not exist."
+ " Have you deleted the .ibd file"
+ " from the database directory under"
+ " the MySQL datadir, or have you"
+ " used DISCARD TABLESPACE?"
+ " Look from " REFMAN "innodb-troubleshooting.html"
+ " how you can resolve the problem.";
+
+ err = DB_TABLESPACE_NOT_FOUND;
+ }
+
+ return (err);
+}
+
+/*********************************************************************//**
@return error code or DB_SUCCESS */
dberr_t
row_insert_for_mysql(
@@ -1432,32 +1490,10 @@ row_insert_for_mysql(
return(DB_TABLESPACE_DELETED);
- } else if (prebuilt->table->ibd_file_missing) {
-
- ib::error() << ".ibd file is missing for table "
- << prebuilt->table->name;
-
- return(DB_TABLESPACE_NOT_FOUND);
- } else if (prebuilt->table->is_encrypted) {
- ib_push_warning(trx, DB_DECRYPTION_FAILED,
- "Table %s in tablespace " ULINTPF " encrypted."
- "However key management plugin or used key_id is not found or"
- " used encryption algorithm or method does not match.",
- prebuilt->table->name, prebuilt->table->space);
- return(DB_DECRYPTION_FAILED);
+ } else if (!prebuilt->table->is_readable()) {
+ return (row_mysql_get_table_status(prebuilt->table, trx, true));
} else if (srv_force_recovery) {
- ib::error() << MODIFICATIONS_NOT_ALLOWED_MSG_FORCE_RECOVERY;
- return(DB_READ_ONLY);
- }
- DBUG_EXECUTE_IF("mark_table_corrupted", {
- /* Mark the table corrupted for the clustered index */
- dict_index_t* index = dict_table_get_first_index(table);
- ut_ad(dict_index_is_clust(index));
- dict_set_corrupted(index, trx, "INSERT TABLE"); });
-
- if (dict_table_is_corrupted(table)) {
-
ib::error() << "Table " << table->name << " is corrupt.";
return(DB_TABLE_CORRUPT);
}
@@ -1852,27 +1888,17 @@ row_update_for_mysql_using_upd_graph(
bool got_s_lock = false;
DBUG_ENTER("row_update_for_mysql_using_upd_graph");
+ if (!table->is_readable()) {
+ return (row_mysql_get_table_status(table, trx, true));
+ }
ut_ad(trx);
ut_a(prebuilt->magic_n == ROW_PREBUILT_ALLOCATED);
ut_a(prebuilt->magic_n2 == ROW_PREBUILT_ALLOCATED);
UT_NOT_USED(mysql_rec);
- if (prebuilt->table->ibd_file_missing) {
- ib::error() << "MySQL is trying to use a table handle but the"
- " .ibd file for table " << prebuilt->table->name
- << " does not exist. Have you deleted"
- " the .ibd file from the database directory under"
- " the MySQL datadir, or have you used DISCARD"
- " TABLESPACE? " << TROUBLESHOOTING_MSG;
- DBUG_RETURN(DB_ERROR);
- } else if (prebuilt->table->is_encrypted) {
- ib_push_warning(trx, DB_DECRYPTION_FAILED,
- "Table %s in tablespace " ULINTPF " encrypted."
- "However key management plugin or used key_id is not found or"
- " used encryption algorithm or method does not match.",
- prebuilt->table->name, prebuilt->table->space);
- return (DB_TABLE_NOT_FOUND);
+ if (UNIV_UNLIKELY(prebuilt->table->file_unreadable)) {
+ return (row_mysql_get_table_status(table, trx, true));
}
if(srv_force_recovery) {
@@ -3259,7 +3285,7 @@ row_discard_tablespace(
/* All persistent operations successful, update the
data dictionary memory cache. */
- table->ibd_file_missing = TRUE;
+ table->file_unreadable = true;
table->flags2 |= DICT_TF2_DISCARDED;
@@ -3315,8 +3341,6 @@ row_discard_tablespace_for_mysql(
if (table == 0) {
err = DB_TABLE_NOT_FOUND;
- } else if (table->is_encrypted) {
- err = DB_DECRYPTION_FAILED;
} else if (dict_table_is_temporary(table)) {
ib_senderrf(trx->mysql_thd, IB_LOG_LEVEL_ERROR,
@@ -3487,7 +3511,6 @@ row_drop_ancillary_fts_tables(
/* Drop ancillary FTS tables */
if (dict_table_has_fts_index(table)
|| DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)) {
-
ut_ad(table->get_ref_count() == 0);
ut_ad(trx_is_started(trx));
@@ -3655,18 +3678,6 @@ row_drop_table_for_mysql(
err = DB_TABLE_NOT_FOUND;
goto funct_exit;
}
- /* If table is encrypted and table page encryption failed
- return error. */
- if (table->is_encrypted) {
-
- if (table->can_be_evicted) {
- dict_table_move_from_lru_to_non_lru(table);
- }
-
- dict_table_close(table, TRUE, FALSE);
- err = DB_DECRYPTION_FAILED;
- goto funct_exit;
- }
/* This function is called recursively via fts_drop_tables(). */
if (!trx_is_started(trx)) {
@@ -4071,7 +4082,7 @@ row_drop_table_for_mysql(
case DB_SUCCESS:
space_id = table->space;
- ibd_file_missing = table->ibd_file_missing;
+ ibd_file_missing = table->file_unreadable;
is_discarded = dict_table_is_discarded(table);
table_flags = table->flags;
ut_ad(!dict_table_is_temporary(table));
@@ -4336,7 +4347,8 @@ loop:
<< table->name << ".frm' was lost.";
}
- if (table->ibd_file_missing) {
+ if (!table->is_readable()
+ && fil_space_get(table->space) == NULL) {
ib::warn() << "Missing .ibd file for table "
<< table->name << ".";
}
@@ -4592,7 +4604,8 @@ row_rename_table_for_mysql(
err = DB_TABLE_NOT_FOUND;
goto funct_exit;
- } else if (table->ibd_file_missing
+ } else if (!table->is_readable()
+ && fil_space_get(table->space) == NULL
&& !dict_table_is_discarded(table)) {
err = DB_TABLE_NOT_FOUND;
@@ -4659,7 +4672,7 @@ row_rename_table_for_mysql(
the table is in a single-table tablespace. */
if (err == DB_SUCCESS
&& dict_table_is_file_per_table(table)
- && !table->ibd_file_missing) {
+ && table->is_readable()) {
/* Make a new pathname to update SYS_DATAFILES. */
char* new_path = row_make_new_pathname(table, new_name);
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 492d864ec96..37d3fd3ad89 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -880,6 +880,16 @@ try_again:
innobase_init_vc_templ(node->table);
}
+ if (!node->table->is_readable()) {
+ /* We skip purge of missing .ibd files */
+
+ dict_table_close(node->table, FALSE, FALSE);
+
+ node->table = NULL;
+
+ goto err_exit;
+ }
+
clust_index = dict_table_get_first_index(node->table);
if (clust_index == NULL
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 229bd567c48..f7ba78c9f0b 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -4191,13 +4191,12 @@ row_search_mvcc(
DBUG_RETURN(DB_TABLESPACE_DELETED);
- } else if (prebuilt->table->ibd_file_missing) {
-
- DBUG_RETURN(DB_TABLESPACE_NOT_FOUND);
-
- } else if (prebuilt->table->is_encrypted) {
-
- return(DB_DECRYPTION_FAILED);
+ } else if (!prebuilt->table->is_readable()) {
+ if (fil_space_get(prebuilt->table->space) == NULL) {
+ return(DB_TABLESPACE_NOT_FOUND);
+ } else {
+ return(DB_DECRYPTION_FAILED);
+ }
} else if (!prebuilt->index_usable) {
DBUG_RETURN(DB_MISSING_HISTORY);
@@ -4673,7 +4672,7 @@ wait_table_again:
" used key_id is not available. "
" Can't continue reading table.",
prebuilt->table->name);
- index->table->is_encrypted = true;
+ index->table->file_unreadable = true;
}
rec = NULL;
goto lock_wait_or_error;
@@ -4695,7 +4694,7 @@ rec_loop:
rec = btr_pcur_get_rec(pcur);
- if (!rec) {
+ if (!index->table->is_readable()) {
err = DB_DECRYPTION_FAILED;
goto lock_wait_or_error;
}
@@ -4787,6 +4786,7 @@ wrong_offs:
<< ". Run CHECK TABLE. You may need to"
" restore from a backup, or dump + drop +"
" reimport the table.";
+
ut_ad(0);
err = DB_CORRUPTION;
diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc
index 1fc30e714f4..5724fad801f 100644
--- a/storage/innobase/row/row0trunc.cc
+++ b/storage/innobase/row/row0trunc.cc
@@ -1681,10 +1681,13 @@ row_truncate_sanity_checks(
return(DB_TABLESPACE_DELETED);
- } else if (table->ibd_file_missing) {
-
- return(DB_TABLESPACE_NOT_FOUND);
+ } else if (!table->is_readable()) {
+ if (fil_space_get(table->space) == NULL) {
+ return(DB_TABLESPACE_NOT_FOUND);
+ } else {
+ return(DB_DECRYPTION_FAILED);
+ }
} else if (dict_table_is_corrupted(table)) {
return(DB_TABLE_CORRUPT);