summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2015-08-16 09:53:27 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2015-09-04 20:19:33 +0300
commite1978234ebe6606c3ad5a0d1be6ce0f86fcf7642 (patch)
treea44bb09038c82aa69fa727582faebf1ec9f32abe /storage/innobase
parente9b6f95013b0db125c616269d747a0c365f5f5c8 (diff)
downloadmariadb-git-e1978234ebe6606c3ad5a0d1be6ce0f86fcf7642.tar.gz
MDEV-8588: Assertion failure in file ha_innodb.cc line 21140 if at least one encrypted table exists and encryption service is not available
Analysis: Problem was that in fil_read_first_page we do find that table has encryption information and that encryption service or used key_id is not available. But, then we just printed fatal error message that causes above assertion. Fix: When we open single table tablespace if it has encryption information (crypt_data) store this crypt data to the table structure. When we open a table and we find out that tablespace is not available, check has table a encryption information and from there is encryption service or used key_id is not available. If it is, add additional warning for SQL-layer.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/dict/dict0load.cc4
-rw-r--r--storage/innobase/fil/fil0fil.cc44
-rw-r--r--storage/innobase/handler/ha_innodb.cc20
-rw-r--r--storage/innobase/include/dict0mem.h4
-rw-r--r--storage/innobase/include/fil0fil.h6
-rw-r--r--storage/innobase/row/row0import.cc2
6 files changed, 63 insertions, 17 deletions
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 149811dab60..d8bd0a66ade 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -1168,7 +1168,7 @@ loop:
dberr_t err = fil_open_single_table_tablespace(
read_page_0, srv_read_only_mode ? false : true,
space_id, dict_tf_to_fsp_flags(flags),
- name, filepath);
+ name, filepath, NULL);
if (err != DB_SUCCESS) {
ib_logf(IB_LOG_LEVEL_ERROR,
@@ -2412,7 +2412,7 @@ err_exit:
err = fil_open_single_table_tablespace(
true, false, table->space,
dict_tf_to_fsp_flags(table->flags),
- name, filepath);
+ name, filepath, table);
if (err != DB_SUCCESS) {
/* We failed to find a sensible
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 0768496a6bb..831a3319eff 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1986,6 +1986,7 @@ fil_read_first_page(
const char* check_msg = NULL;
fil_space_crypt_t* cdata;
+
buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
/* Align the memory for a possible read from a raw device */
@@ -2015,6 +2016,10 @@ fil_read_first_page(
fsp_flags_get_zip_size(*flags), NULL);
cdata = fil_space_read_crypt_data(space, page, offset);
+ if (crypt_data) {
+ *crypt_data = cdata;
+ }
+
/* If file space is encrypted we need to have at least some
encryption service available where to get keys */
if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) ||
@@ -2022,16 +2027,14 @@ fil_read_first_page(
cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
if (!encryption_key_id_exists(cdata->key_id)) {
- ib_logf(IB_LOG_LEVEL_FATAL,
- "Tablespace id %ld encrypted but encryption service"
- " not available. Can't continue opening tablespace.\n",
- space);
- ut_error;
- }
- }
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Tablespace id %ld is encrypted but encryption service"
+ " or used key_id %u is not available. Can't continue opening tablespace.",
+ space, cdata->key_id);
- if (crypt_data) {
- *crypt_data = cdata;
+ return ("table encrypted but encryption service not available.");
+
+ }
}
ut_free(buf);
@@ -3621,7 +3624,8 @@ fil_open_single_table_tablespace(
ulint flags, /*!< in: tablespace flags */
const char* tablename, /*!< in: table name in the
databasename/tablename format */
- const char* path_in) /*!< in: tablespace filepath */
+ const char* path_in, /*!< in: tablespace filepath */
+ dict_table_t* table) /*!< in: table */
{
dberr_t err = DB_SUCCESS;
bool dict_filepath_same_as_default = false;
@@ -3738,6 +3742,10 @@ fil_open_single_table_tablespace(
&def.lsn, &def.lsn, &def.crypt_data);
def.valid = !def.check_msg;
+ if (table) {
+ table->crypt_data = def.crypt_data;
+ }
+
/* Validate this single-table-tablespace with SYS_TABLES,
but do not compare the DATA_DIR flag, in case the
tablespace was relocated. */
@@ -3763,6 +3771,10 @@ fil_open_single_table_tablespace(
&remote.lsn, &remote.lsn, &remote.crypt_data);
remote.valid = !remote.check_msg;
+ if (table) {
+ table->crypt_data = remote.crypt_data;
+ }
+
/* Validate this single-table-tablespace with SYS_TABLES,
but do not compare the DATA_DIR flag, in case the
tablespace was relocated. */
@@ -3789,6 +3801,10 @@ fil_open_single_table_tablespace(
&dict.lsn, &dict.lsn, &dict.crypt_data);
dict.valid = !dict.check_msg;
+ if (table) {
+ table->crypt_data = dict.crypt_data;
+ }
+
/* Validate this single-table-tablespace with SYS_TABLES,
but do not compare the DATA_DIR flag, in case the
tablespace was relocated. */
@@ -3970,7 +3986,9 @@ cleanup_and_exit:
mem_free(remote.filepath);
}
if (remote.crypt_data && remote.crypt_data != crypt_data) {
- fil_space_destroy_crypt_data(&remote.crypt_data);
+ if (err == DB_SUCCESS) {
+ fil_space_destroy_crypt_data(&remote.crypt_data);
+ }
}
if (dict.success) {
os_file_close(dict.file);
@@ -3985,7 +4003,9 @@ cleanup_and_exit:
os_file_close(def.file);
}
if (def.crypt_data && def.crypt_data != crypt_data) {
- fil_space_destroy_crypt_data(&def.crypt_data);
+ if (err == DB_SUCCESS) {
+ fil_space_destroy_crypt_data(&def.crypt_data);
+ }
}
mem_free(def.filepath);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index b07c756e81f..6722ee85428 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -5629,6 +5629,26 @@ table_opened:
free_share(share);
my_errno = ENOENT;
+ /* If table has no talespace but it has crypt data, check
+ is tablespace made unaccessible because encryption service
+ or used key_id is not available. */
+ if (ib_table && ib_table->crypt_data) {
+ fil_space_crypt_t* crypt_data = ib_table->crypt_data;
+ if ((crypt_data->encryption == FIL_SPACE_ENCRYPTION_ON) ||
+ (srv_encrypt_tables &&
+ crypt_data && crypt_data->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) {
+
+ if (!encryption_key_id_exists(crypt_data->key_id)) {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_ERR_NO_SUCH_TABLE,
+ "Table %s is encrypted but encryption service or"
+ " used key_id %u is not available. "
+ " Can't continue reading table.",
+ ib_table->name, crypt_data->key_id);
+ }
+ }
+ }
+
dict_table_close(ib_table, FALSE, FALSE);
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 24db728ae08..059ba2208e3 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -48,6 +48,9 @@ Created 1/8/1996 Heikki Tuuri
#include "trx0types.h"
#include "fts0fts.h"
#include "os0once.h"
+#include "fil0fil.h"
+#include <my_crypt.h>
+#include "fil0crypt.h"
#include <set>
#include <algorithm>
#include <iterator>
@@ -1014,6 +1017,7 @@ struct dict_table_t{
table_id_t id; /*!< id of the table */
mem_heap_t* heap; /*!< memory heap */
char* name; /*!< table name */
+ fil_space_crypt_t *crypt_data; /*!< crypt data if present */
const char* dir_path_of_temp_table;/*!< NULL or the directory path
where a TEMPORARY table that was explicitly
created by a user should be placed if
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 93ff999bcfe..e842049e734 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -213,7 +213,8 @@ struct fsp_open_info {
#ifdef UNIV_LOG_ARCHIVE
ulint arch_log_no; /*!< latest archived log file number */
#endif /* UNIV_LOG_ARCHIVE */
- fil_space_crypt_t* crypt_data; /*!< crypt data */
+ fil_space_crypt_t* crypt_data; /*!< crypt data */
+ dict_table_t* table; /*!< table */
};
struct fil_space_t;
@@ -833,7 +834,8 @@ fil_open_single_table_tablespace(
ulint flags, /*!< in: tablespace flags */
const char* tablename, /*!< in: table name in the
databasename/tablename format */
- const char* filepath) /*!< in: tablespace filepath */
+ const char* filepath, /*!< in: tablespace filepath */
+ dict_table_t* table) /*!< in: table */
__attribute__((nonnull(5), warn_unused_result));
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 93804e4da39..4034a228153 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -3628,7 +3628,7 @@ row_import_for_mysql(
err = fil_open_single_table_tablespace(
true, true, table->space,
dict_tf_to_fsp_flags(table->flags),
- table->name, filepath);
+ table->name, filepath, table);
DBUG_EXECUTE_IF("ib_import_open_tablespace_failure",
err = DB_TABLESPACE_NOT_FOUND;);