summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0mysql.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row/row0mysql.cc')
-rw-r--r--storage/innobase/row/row0mysql.cc139
1 files changed, 74 insertions, 65 deletions
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 7e3a7d580c5..57ba35a57f6 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,"
@@ -1399,6 +1400,55 @@ run_again:
return(err);
}
+/** 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
+@retval DB_DECRYPTION_FAILED table is encrypted but decryption failed
+@retval DB_CORRUPTION table is corrupted
+@retval 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;
+ 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() << ".ibd file is missing for table "
+ << table->name;
+ err = DB_TABLESPACE_NOT_FOUND;
+ }
+
+ return(err);
+}
+
/** Does an insert for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle
@@ -1432,19 +1482,8 @@ 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;
@@ -1594,9 +1633,9 @@ error_exit:
que_thr_stop_for_mysql_no_error(thr, trx);
if (table->is_system_db) {
- srv_stats.n_system_rows_inserted.inc();
+ srv_stats.n_system_rows_inserted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_inserted.inc();
+ srv_stats.n_rows_inserted.inc(size_t(trx->id));
}
/* Not protected by dict_table_stats_lock() for performance
@@ -1858,21 +1897,8 @@ row_update_for_mysql_using_upd_graph(
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 (!table->is_readable()) {
+ return(row_mysql_get_table_status(table, trx, true));
}
if(srv_force_recovery) {
@@ -2090,9 +2116,9 @@ run_again:
than protecting the following code with a latch. */
dict_table_n_rows_dec(node->table);
- srv_stats.n_rows_deleted.add((size_t)trx->id, 1);
+ srv_stats.n_rows_deleted.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));
}
row_update_statistics_if_needed(node->table);
@@ -2106,17 +2132,16 @@ run_again:
with a latch. */
dict_table_n_rows_dec(prebuilt->table);
- if (table->is_system_db) {
- srv_stats.n_system_rows_deleted.inc();
+ if (table->is_system_db) {
+ srv_stats.n_system_rows_deleted.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_deleted.inc();
+ srv_stats.n_rows_deleted.inc(size_t(trx->id));
}
-
} else {
if (table->is_system_db) {
- srv_stats.n_system_rows_updated.inc();
+ srv_stats.n_system_rows_updated.inc(size_t(trx->id));
} else {
- srv_stats.n_rows_updated.inc();
+ srv_stats.n_rows_updated.inc(size_t(trx->id));
}
}
@@ -2424,7 +2449,7 @@ row_create_table_for_mysql(
trx_t* trx, /*!< in/out: transaction */
bool commit, /*!< in: if true, commit the transaction */
fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ uint32_t key_id) /*!< in: encryption key_id */
{
tab_node_t* node;
mem_heap_t* heap;
@@ -3261,7 +3286,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;
@@ -3300,7 +3325,7 @@ row_discard_tablespace(
/*********************************************************************//**
Discards the tablespace of a table which stored in an .ibd file. Discarding
means that this function renames the .ibd file and assigns a new table id for
-the table. Also the flag table->ibd_file_missing is set to TRUE.
+the table. Also the file_unreadable flag is set.
@return error code or DB_SUCCESS */
dberr_t
row_discard_tablespace_for_mysql(
@@ -3317,8 +3342,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,
@@ -3326,7 +3349,7 @@ row_discard_tablespace_for_mysql(
err = DB_ERROR;
- } else if (table->space == srv_sys_space.space_id()) {
+ } else if (table->space == TRX_SYS_SPACE) {
char table_name[MAX_FULL_NAME_LEN + 1];
innobase_format_name(
@@ -3657,18 +3680,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)) {
@@ -4067,13 +4078,11 @@ row_drop_table_for_mysql(
switch (err) {
ulint space_id;
- bool ibd_file_missing;
bool is_discarded;
ulint table_flags;
case DB_SUCCESS:
space_id = table->space;
- ibd_file_missing = table->ibd_file_missing;
is_discarded = dict_table_is_discarded(table);
table_flags = table->flags;
ut_ad(!dict_table_is_temporary(table));
@@ -4104,8 +4113,7 @@ row_drop_table_for_mysql(
/* Do not attempt to drop known-to-be-missing tablespaces,
nor the system tablespace. */
- if (is_discarded || ibd_file_missing
- || is_system_tablespace(space_id)) {
+ if (is_discarded || is_system_tablespace(space_id)) {
break;
}
@@ -4338,7 +4346,8 @@ loop:
<< table->name << ".frm' was lost.";
}
- if (table->ibd_file_missing) {
+ if (!table->is_readable()
+ && !fil_space_get(table->space)) {
ib::warn() << "Missing .ibd file for table "
<< table->name << ".";
}
@@ -4594,7 +4603,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;
@@ -4660,8 +4670,7 @@ row_rename_table_for_mysql(
/* SYS_TABLESPACES and SYS_DATAFILES need to be updated if
the table is in a single-table tablespace. */
if (err == DB_SUCCESS
- && dict_table_is_file_per_table(table)
- && !table->ibd_file_missing) {
+ && dict_table_is_file_per_table(table)) {
/* Make a new pathname to update SYS_DATAFILES. */
char* new_path = row_make_new_pathname(table, new_name);