summaryrefslogtreecommitdiff
path: root/storage/xtradb/row/row0mysql.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/row/row0mysql.cc')
-rw-r--r--storage/xtradb/row/row0mysql.cc174
1 files changed, 95 insertions, 79 deletions
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 7c8636d354f..463981f51dd 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2016, 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
@@ -663,6 +663,7 @@ handle_new_error:
abort();
case DB_CORRUPTION:
+ case DB_PAGE_CORRUPTED:
fputs("InnoDB: We detected index corruption"
" in an InnoDB type table.\n"
"InnoDB: You have to dump + drop + reimport"
@@ -1280,6 +1281,71 @@ run_again:
}
/*********************************************************************//**
+Determine is tablespace encrypted but decryption failed, is table corrupted
+or is tablespace .ibd file missing.
+@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;
+ FilSpace space(table->space, true);
+ char buf[MAX_FULL_NAME_LEN];
+ ut_format_name(table->name, TRUE, buf, sizeof(buf));
+
+ if (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,HA_ERR_DECRYPTION_FAILED,
+ "Table %s in file %s is encrypted but encryption service or"
+ " used key_id %u is not available. "
+ " Can't continue reading table.",
+ buf, space()->chain.start->name,
+ space()->crypt_data->key_id);
+ }
+
+ err = DB_DECRYPTION_FAILED;
+ } else {
+ if (push_warning) {
+ ib_push_warning(trx, DB_CORRUPTION,
+ "Table %s in file %s corrupted.",
+ buf, space()->chain.start->name);
+ }
+
+ err = DB_CORRUPTION;
+ }
+
+ } else {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "InnoDB: MySQL is trying to use a table handle"
+ " but the .ibd file for"
+ " table %s 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.",
+ buf);
+
+ err = DB_TABLESPACE_NOT_FOUND;
+ }
+
+ return (err);
+}
+
+/*********************************************************************//**
Does an insert for MySQL.
@return error code or DB_SUCCESS */
UNIV_INTERN
@@ -1308,20 +1374,8 @@ row_insert_for_mysql(
return(DB_TABLESPACE_DELETED);
- } else if (prebuilt->table->ibd_file_missing) {
-
- ib_logf(IB_LOG_LEVEL_ERROR,
- ".ibd file is missing for table %s",
- 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 %lu 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 (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
fprintf(stderr,
"InnoDB: Error: trying to free a corrupt\n"
@@ -1460,11 +1514,10 @@ error_exit:
que_thr_stop_for_mysql_no_error(thr, trx);
if (UNIV_LIKELY(!(trx->fake_changes))) {
-
if (table->is_system_db) {
- srv_stats.n_system_rows_inserted.add((size_t)trx->id, 1);
+ srv_stats.n_system_rows_inserted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_inserted.add((size_t)trx->id, 1);
+ srv_stats.n_rows_inserted.inc(size_t(trx->id));
}
if (prebuilt->clust_index_was_generated) {
@@ -1712,28 +1765,8 @@ row_update_for_mysql(
ut_ad(trx != NULL);
UT_NOT_USED(mysql_rec);
- if (prebuilt->table->ibd_file_missing) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: Error:\n"
- "InnoDB: MySQL is trying to use a table handle"
- " but the .ibd file for\n"
- "InnoDB: table %s does not exist.\n"
- "InnoDB: Have you deleted the .ibd file"
- " from the database directory under\n"
- "InnoDB: the MySQL datadir, or have you"
- " used DISCARD TABLESPACE?\n"
- "InnoDB: Look from\n"
- "InnoDB: " REFMAN "innodb-troubleshooting.html\n"
- "InnoDB: how you can resolve the problem.\n",
- prebuilt->table->name);
- return(DB_ERROR);
- } else if (prebuilt->table->is_encrypted) {
- 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.",
- prebuilt->table->name, prebuilt->table->space);
- return (DB_TABLE_NOT_FOUND);
+ if (!table->is_readable()) {
+ return (row_mysql_get_table_status(table, trx, true));
}
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
@@ -1873,17 +1906,15 @@ run_again:
dict_table_n_rows_dec(prebuilt->table);
if (table->is_system_db) {
- srv_stats.n_system_rows_deleted.add(
- (size_t)trx->id, 1);
+ srv_stats.n_system_rows_deleted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ srv_stats.n_rows_deleted.inc(size_t(trx->id));
}
} else {
if (table->is_system_db) {
- srv_stats.n_system_rows_updated.add(
- (size_t)trx->id, 1);
+ srv_stats.n_system_rows_updated.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ srv_stats.n_rows_updated.inc(size_t(trx->id));
}
}
@@ -2121,17 +2152,15 @@ run_again:
dict_table_n_rows_dec(table);
if (table->is_system_db) {
- srv_stats.n_system_rows_deleted.add(
- (size_t)trx->id, 1);
+ srv_stats.n_system_rows_deleted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ srv_stats.n_rows_deleted.inc(size_t(trx->id));
}
} else {
if (table->is_system_db) {
- srv_stats.n_system_rows_updated.add(
- (size_t)trx->id, 1);
+ srv_stats.n_system_rows_updated.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_updated.add((size_t)trx->id, 1);
+ srv_stats.n_rows_updated.inc(size_t(trx->id));
}
}
@@ -3128,7 +3157,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;
@@ -3185,8 +3214,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 (table->space == TRX_SYS_SPACE) {
char table_name[MAX_FULL_NAME_LEN + 1];
@@ -3401,10 +3428,8 @@ row_truncate_table_for_mysql(
if (dict_table_is_discarded(table)) {
return(DB_TABLESPACE_DELETED);
- } else if (table->is_encrypted) {
- return(DB_DECRYPTION_FAILED);
- } else if (table->ibd_file_missing) {
- return(DB_TABLESPACE_NOT_FOUND);
+ } else if (!table->is_readable()) {
+ return (row_mysql_get_table_status(table, trx, true));
}
trx_start_for_ddl(trx, TRX_DICT_OP_TABLE);
@@ -3570,7 +3595,7 @@ row_truncate_table_for_mysql(
"create a new tablespace",
table->name);
- table->ibd_file_missing = 1;
+ table->file_unreadable = true;
err = DB_ERROR;
goto funct_exit;
}
@@ -3994,19 +4019,6 @@ row_drop_table_for_mysql(
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;
- }
-
/* Turn on this drop bit before we could release the dictionary
latch */
table->to_be_dropped = true;
@@ -4378,7 +4390,7 @@ row_drop_table_for_mysql(
from table->heap, which will be freed by
dict_table_remove_from_cache(table) below. */
space_id = table->space;
- ibd_file_missing = table->ibd_file_missing;
+ ibd_file_missing = table->file_unreadable;
table_flags = table->flags;
is_temp = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY);
@@ -4389,7 +4401,8 @@ row_drop_table_for_mysql(
have a temp flag but not know the temp path */
ut_a(table->dir_path_of_temp_table == NULL || is_temp);
if (dict_table_is_discarded(table)
- || table->ibd_file_missing) {
+ || (!table->is_readable()
+ && fil_space_get(table->space) == NULL)) {
/* Do not attempt to drop known-to-be-missing
tablespaces. */
space_id = 0;
@@ -4465,8 +4478,9 @@ row_drop_table_for_mysql(
if (!is_temp
&& !fil_space_for_table_exists_in_mem(
space_id, tablename,
- print_msg, false, NULL, 0,
+ print_msg, IS_XTRABACKUP() && print_msg, false, NULL, 0,
table_flags)) {
+
/* This might happen if we are dropping a
discarded tablespace */
err = DB_SUCCESS;
@@ -4801,7 +4815,8 @@ loop:
"'%s.frm' was lost.", table->name);
}
- if (table->ibd_file_missing) {
+ if (!table->is_readable()
+ && fil_space_get(table->space) == NULL) {
ib_logf(IB_LOG_LEVEL_WARN,
"Missing %s.ibd file for table %s.",
table->name, table->name);
@@ -5075,7 +5090,8 @@ row_rename_table_for_mysql(
stderr);
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;
@@ -5145,7 +5161,7 @@ row_rename_table_for_mysql(
which have space IDs > 0. */
if (err == DB_SUCCESS
&& table->space != TRX_SYS_SPACE
- && !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);