mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-34823 Invalid arguments in ib_push_warning()
In the bug report MDEV-32817 it occurred that the function row_mysql_get_table_status() is outputting a fil_space_t* as if it were a numeric tablespace identifier. ib_push_warning(): Remove. Let us invoke push_warning_printf() directly. innodb_decryption_failed(): Report a decryption failure and set the dict_table_t::file_unreadable flag. This code was being duplicated in very many places. We return the constant value DB_DECRYPTION_FAILED in order to avoid code duplication in the callers and to allow tail calls. innodb_fk_error(): Report a FOREIGN KEY error. dict_foreign_def_get(), dict_foreign_def_get_fields(): Remove. This code was being used in dict_create_add_foreign_to_dictionary() in an apparently uncovered code path. That ib_push_warning() call would pass the integer i+1 instead of a pointer to NUL terminated string ("%s"), and therefore the call should have resulted in a crash. dict_print_info_on_foreign_key_in_create_format(), innobase_quote_identifier(): Add const qualifiers. row_mysql_get_table_error(): Replaces row_mysql_get_table_status(). Display no message on DB_CORRUPTION; it should be properly reported at the SQL layer anyway.
This commit is contained in:
@@ -16,7 +16,7 @@ CONSTRAINT test FOREIGN KEY (b) REFERENCES t2 (id)
|
||||
ERROR HY000: Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update")
|
||||
show warnings;
|
||||
Level Code Message
|
||||
Warning 121 Create or Alter table `test`.`t2` with foreign key constraint failed. Foreign key constraint `test`.`test` already exists on data dictionary. Foreign key constraint names need to be unique in database. Error in foreign key definition: CONSTRAINT `test` FOREIGN KEY (`b`) REFERENCES `test`.`t2` (`id`).
|
||||
Warning 121 CREATE or ALTER TABLE `test`.`t2` failed: duplicate name, CONSTRAINT `test` FOREIGN KEY (`b`) REFERENCES `t2` (`id`)
|
||||
Error 1005 Can't create table `test`.`t2` (errno: 121 "Duplicate key on write or update")
|
||||
Warning 1022 Can't write; duplicate key in table 't2'
|
||||
drop table t1;
|
||||
|
@@ -228,16 +228,7 @@ btr_root_block_get(
|
||||
mtr);
|
||||
|
||||
if (!block) {
|
||||
index->table->file_unreadable = true;
|
||||
|
||||
ib_push_warning(
|
||||
static_cast<THD*>(NULL), DB_DECRYPTION_FAILED,
|
||||
"Table %s in file %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name.m_name,
|
||||
UT_LIST_GET_FIRST(index->table->space->chain)->name);
|
||||
|
||||
innodb_decryption_failed(nullptr, index->table);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@@ -1617,13 +1617,7 @@ retry_page_get:
|
||||
if (err != DB_SUCCESS) {
|
||||
ut_ad(block == NULL);
|
||||
if (err == DB_DECRYPTION_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_DECRYPTION_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name.m_name);
|
||||
index->table->file_unreadable = true;
|
||||
innodb_decryption_failed(nullptr, index->table);
|
||||
}
|
||||
|
||||
goto func_exit;
|
||||
@@ -1729,13 +1723,8 @@ retry_page_get:
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_DECRYPTION_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_DECRYPTION_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name.m_name);
|
||||
index->table->file_unreadable = true;
|
||||
innodb_decryption_failed(nullptr,
|
||||
index->table);
|
||||
}
|
||||
|
||||
goto func_exit;
|
||||
@@ -1759,13 +1748,8 @@ retry_page_get:
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_DECRYPTION_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_DECRYPTION_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name.m_name);
|
||||
index->table->file_unreadable = true;
|
||||
innodb_decryption_failed(nullptr,
|
||||
index->table);
|
||||
}
|
||||
|
||||
goto func_exit;
|
||||
@@ -2634,13 +2618,8 @@ btr_cur_open_at_index_side_func(
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_DECRYPTION_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_DECRYPTION_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name.m_name);
|
||||
index->table->file_unreadable = true;
|
||||
innodb_decryption_failed(nullptr,
|
||||
index->table);
|
||||
}
|
||||
|
||||
goto exit_loop;
|
||||
@@ -2976,13 +2955,8 @@ btr_cur_open_at_rnd_pos_func(
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_DECRYPTION_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_DECRYPTION_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name.m_name);
|
||||
index->table->file_unreadable = true;
|
||||
innodb_decryption_failed(nullptr,
|
||||
index->table);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -6136,13 +6110,8 @@ btr_estimate_n_rows_in_range_on_level(
|
||||
|
||||
if (!block) {
|
||||
if (err == DB_DECRYPTION_FAILED) {
|
||||
ib_push_warning((void *)NULL,
|
||||
DB_DECRYPTION_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name.m_name);
|
||||
index->table->file_unreadable = true;
|
||||
innodb_decryption_failed(nullptr,
|
||||
index->table);
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
@@ -1726,104 +1726,6 @@ dict_create_add_foreign_field_to_dictionary(
|
||||
table_name, foreign->id, trx));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Construct foreign key constraint defintion from data dictionary information.
|
||||
*/
|
||||
UNIV_INTERN
|
||||
char*
|
||||
dict_foreign_def_get(
|
||||
/*=================*/
|
||||
dict_foreign_t* foreign,/*!< in: foreign */
|
||||
trx_t* trx) /*!< in: trx */
|
||||
{
|
||||
char* fk_def = (char *)mem_heap_alloc(foreign->heap, 4*1024);
|
||||
const char* tbname;
|
||||
char tablebuf[MAX_TABLE_NAME_LEN + 1] = "";
|
||||
unsigned i;
|
||||
char* bufend;
|
||||
|
||||
tbname = dict_remove_db_name(foreign->id);
|
||||
bufend = innobase_convert_name(tablebuf, MAX_TABLE_NAME_LEN,
|
||||
tbname, strlen(tbname), trx->mysql_thd);
|
||||
tablebuf[bufend - tablebuf] = '\0';
|
||||
|
||||
sprintf(fk_def,
|
||||
(char *)"CONSTRAINT %s FOREIGN KEY (", (char *)tablebuf);
|
||||
|
||||
for(i = 0; i < foreign->n_fields; i++) {
|
||||
char buf[MAX_TABLE_NAME_LEN + 1] = "";
|
||||
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
|
||||
foreign->foreign_col_names[i],
|
||||
strlen(foreign->foreign_col_names[i]),
|
||||
trx->mysql_thd);
|
||||
strcat(fk_def, buf);
|
||||
if (i < static_cast<unsigned>(foreign->n_fields-1)) {
|
||||
strcat(fk_def, (char *)",");
|
||||
}
|
||||
}
|
||||
|
||||
strcat(fk_def,(char *)") REFERENCES ");
|
||||
|
||||
bufend = innobase_convert_name(tablebuf, MAX_TABLE_NAME_LEN,
|
||||
foreign->referenced_table_name,
|
||||
strlen(foreign->referenced_table_name),
|
||||
trx->mysql_thd);
|
||||
tablebuf[bufend - tablebuf] = '\0';
|
||||
|
||||
strcat(fk_def, tablebuf);
|
||||
strcat(fk_def, " (");
|
||||
|
||||
for(i = 0; i < foreign->n_fields; i++) {
|
||||
char buf[MAX_TABLE_NAME_LEN + 1] = "";
|
||||
bufend = innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
|
||||
foreign->referenced_col_names[i],
|
||||
strlen(foreign->referenced_col_names[i]),
|
||||
trx->mysql_thd);
|
||||
buf[bufend - buf] = '\0';
|
||||
strcat(fk_def, buf);
|
||||
if (i < (uint)foreign->n_fields-1) {
|
||||
strcat(fk_def, (char *)",");
|
||||
}
|
||||
}
|
||||
strcat(fk_def, (char *)")");
|
||||
|
||||
return fk_def;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Convert foreign key column names from data dictionary to SQL-layer.
|
||||
*/
|
||||
static
|
||||
void
|
||||
dict_foreign_def_get_fields(
|
||||
/*========================*/
|
||||
dict_foreign_t* foreign,/*!< in: foreign */
|
||||
trx_t* trx, /*!< in: trx */
|
||||
char** field, /*!< out: foreign column */
|
||||
char** field2, /*!< out: referenced column */
|
||||
ulint col_no) /*!< in: column number */
|
||||
{
|
||||
char* bufend;
|
||||
char* fieldbuf = (char *)mem_heap_alloc(foreign->heap, MAX_TABLE_NAME_LEN+1);
|
||||
char* fieldbuf2 = (char *)mem_heap_alloc(foreign->heap, MAX_TABLE_NAME_LEN+1);
|
||||
|
||||
bufend = innobase_convert_name(fieldbuf, MAX_TABLE_NAME_LEN,
|
||||
foreign->foreign_col_names[col_no],
|
||||
strlen(foreign->foreign_col_names[col_no]),
|
||||
trx->mysql_thd);
|
||||
|
||||
fieldbuf[bufend - fieldbuf] = '\0';
|
||||
|
||||
bufend = innobase_convert_name(fieldbuf2, MAX_TABLE_NAME_LEN,
|
||||
foreign->referenced_col_names[col_no],
|
||||
strlen(foreign->referenced_col_names[col_no]),
|
||||
trx->mysql_thd);
|
||||
|
||||
fieldbuf2[bufend - fieldbuf2] = '\0';
|
||||
*field = fieldbuf;
|
||||
*field2 = fieldbuf2;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Add a foreign key definition to the data dictionary tables.
|
||||
@return error code or DB_SUCCESS */
|
||||
@@ -1865,29 +1767,8 @@ dict_create_add_foreign_to_dictionary(
|
||||
, name, foreign->id, trx);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
|
||||
if (error == DB_DUPLICATE_KEY) {
|
||||
char buf[MAX_TABLE_NAME_LEN + 1] = "";
|
||||
char tablename[MAX_TABLE_NAME_LEN + 1] = "";
|
||||
char* fk_def;
|
||||
|
||||
innobase_convert_name(tablename, MAX_TABLE_NAME_LEN,
|
||||
name, strlen(name), trx->mysql_thd);
|
||||
|
||||
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
|
||||
foreign->id, strlen(foreign->id), trx->mysql_thd);
|
||||
|
||||
fk_def = dict_foreign_def_get((dict_foreign_t*)foreign, trx);
|
||||
|
||||
ib_push_warning(trx, error,
|
||||
"Create or Alter table %s with foreign key constraint"
|
||||
" failed. Foreign key constraint %s"
|
||||
" already exists on data dictionary."
|
||||
" Foreign key constraint names need to be unique in database."
|
||||
" Error in foreign key definition: %s.",
|
||||
tablename, buf, fk_def);
|
||||
}
|
||||
|
||||
err_exit:
|
||||
innodb_fk_error(trx, error, name, *foreign);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@@ -1896,27 +1777,7 @@ dict_create_add_foreign_to_dictionary(
|
||||
i, name, foreign, trx);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
char buf[MAX_TABLE_NAME_LEN + 1] = "";
|
||||
char tablename[MAX_TABLE_NAME_LEN + 1] = "";
|
||||
char* field=NULL;
|
||||
char* field2=NULL;
|
||||
char* fk_def;
|
||||
|
||||
innobase_convert_name(tablename, MAX_TABLE_NAME_LEN,
|
||||
name, strlen(name), trx->mysql_thd);
|
||||
innobase_convert_name(buf, MAX_TABLE_NAME_LEN,
|
||||
foreign->id, strlen(foreign->id), trx->mysql_thd);
|
||||
fk_def = dict_foreign_def_get((dict_foreign_t*)foreign, trx);
|
||||
dict_foreign_def_get_fields((dict_foreign_t*)foreign, trx, &field, &field2, i);
|
||||
|
||||
ib_push_warning(trx, error,
|
||||
"Create or Alter table %s with foreign key constraint"
|
||||
" failed. Error adding foreign key constraint name %s"
|
||||
" fields %s or %s to the dictionary."
|
||||
" Error in foreign key definition: %s.",
|
||||
tablename, buf, i+1, fk_def);
|
||||
|
||||
DBUG_RETURN(error);
|
||||
goto err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3949,15 +3949,10 @@ dict_index_calc_min_rec_len(
|
||||
return(sum);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Outputs info on a foreign key of a table in a format suitable for
|
||||
CREATE TABLE. */
|
||||
std::string
|
||||
dict_print_info_on_foreign_key_in_create_format(
|
||||
/*============================================*/
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
dict_foreign_t* foreign, /*!< in: foreign key constraint */
|
||||
ibool add_newline) /*!< in: whether to add a newline */
|
||||
dict_print_info_on_foreign_key_in_create_format(const trx_t *trx,
|
||||
const dict_foreign_t *foreign,
|
||||
bool add_newline)
|
||||
{
|
||||
const char* stripped_id;
|
||||
ulint i;
|
||||
|
@@ -2921,7 +2921,7 @@ innobase_invalidate_query_cache(
|
||||
void
|
||||
innobase_quote_identifier(
|
||||
FILE* file,
|
||||
trx_t* trx,
|
||||
const trx_t* trx,
|
||||
const char* id)
|
||||
{
|
||||
const int q = trx != NULL && trx->mysql_thd != NULL
|
||||
@@ -2951,7 +2951,7 @@ innobase_quote_identifier(
|
||||
std::string
|
||||
innobase_quote_identifier(
|
||||
/*======================*/
|
||||
trx_t* trx,
|
||||
const trx_t* trx,
|
||||
const char* id)
|
||||
{
|
||||
std::string quoted_identifier;
|
||||
@@ -21447,66 +21447,46 @@ static void innodb_remember_check_sysvar_funcs()
|
||||
check_sysvar_int = MYSQL_SYSVAR_NAME(flush_log_at_timeout).check;
|
||||
}
|
||||
|
||||
static const size_t MAX_BUF_SIZE = 4 * 1024;
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
trx_t* trx, /*!< in: trx */
|
||||
dberr_t error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...)
|
||||
/** Report that a table cannot be decrypted.
|
||||
@param thd connection context
|
||||
@param table table that cannot be decrypted
|
||||
@retval DB_DECRYPTION_FAILED (always) */
|
||||
ATTRIBUTE_COLD
|
||||
dberr_t innodb_decryption_failed(THD *thd, dict_table_t *table)
|
||||
{
|
||||
if (trx && trx->mysql_thd) {
|
||||
THD *thd = (THD *)trx->mysql_thd;
|
||||
va_list args;
|
||||
char *buf;
|
||||
|
||||
va_start(args, format);
|
||||
buf = (char *)my_malloc(PSI_INSTRUMENT_ME, MAX_BUF_SIZE, MYF(MY_WME));
|
||||
buf[MAX_BUF_SIZE - 1] = 0;
|
||||
vsnprintf(buf, MAX_BUF_SIZE - 1, format, args);
|
||||
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
uint(convert_error_code_to_mysql(error, 0, thd)), buf);
|
||||
my_free(buf);
|
||||
va_end(args);
|
||||
}
|
||||
table->file_unreadable= true;
|
||||
if (!thd)
|
||||
thd= current_thd;
|
||||
const int dblen= int(table->name.dblen());
|
||||
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
HA_ERR_DECRYPTION_FAILED,
|
||||
"Table %`.*s.%`s in tablespace " UINT32PF
|
||||
" (file %s) cannot be decrypted.",
|
||||
dblen, table->name.m_name,
|
||||
table->name.m_name + dblen + 1,
|
||||
uint32_t(table->space_id),
|
||||
UT_LIST_GET_FIRST(table->space->chain)->name);
|
||||
return DB_DECRYPTION_FAILED;
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
void* ithd, /*!< in: thd */
|
||||
dberr_t error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...)
|
||||
/** Report a foreign key error.
|
||||
@param error error to report
|
||||
@param name table name
|
||||
@param foreign constraint */
|
||||
ATTRIBUTE_COLD
|
||||
void innodb_fk_error(const trx_t *trx, dberr_t err, const char *name,
|
||||
const dict_foreign_t& foreign)
|
||||
{
|
||||
va_list args;
|
||||
THD *thd = (THD *)ithd;
|
||||
char *buf;
|
||||
|
||||
if (ithd == NULL) {
|
||||
thd = current_thd;
|
||||
}
|
||||
|
||||
if (thd) {
|
||||
va_start(args, format);
|
||||
buf = (char *)my_malloc(PSI_INSTRUMENT_ME, MAX_BUF_SIZE, MYF(MY_WME));
|
||||
buf[MAX_BUF_SIZE - 1] = 0;
|
||||
vsnprintf(buf, MAX_BUF_SIZE - 1, format, args);
|
||||
|
||||
push_warning_printf(
|
||||
thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
uint(convert_error_code_to_mysql(error, 0, thd)), buf);
|
||||
my_free(buf);
|
||||
va_end(args);
|
||||
}
|
||||
const int dblen= int(table_name_t(const_cast<char*>(name)).dblen());
|
||||
std::string fk= dict_print_info_on_foreign_key_in_create_format
|
||||
(trx, &foreign, false);
|
||||
push_warning_printf(trx->mysql_thd, Sql_condition::WARN_LEVEL_WARN,
|
||||
convert_error_code_to_mysql(err, 0, nullptr),
|
||||
"CREATE or ALTER TABLE %`.*s.%`s failed%s%.*s",
|
||||
dblen, name, name + dblen + 1,
|
||||
err == DB_DUPLICATE_KEY
|
||||
? ": duplicate name" : "",
|
||||
int(fk.length()), fk.data());
|
||||
}
|
||||
|
||||
/** Helper function to push warnings from InnoDB internals to SQL-layer.
|
||||
|
@@ -209,16 +209,6 @@ dict_create_add_foreign_to_dictionary(
|
||||
trx_t* trx) /*!< in/out: dictionary transaction */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/********************************************************************//**
|
||||
Construct foreign key constraint defintion from data dictionary information.
|
||||
*/
|
||||
UNIV_INTERN
|
||||
char*
|
||||
dict_foreign_def_get(
|
||||
/*=================*/
|
||||
dict_foreign_t* foreign,/*!< in: foreign */
|
||||
trx_t* trx); /*!< in: trx */
|
||||
|
||||
/* Table create node structure */
|
||||
struct tab_node_t{
|
||||
que_common_t common; /*!< node type: QUE_NODE_TABLE_CREATE */
|
||||
|
@@ -577,15 +577,15 @@ dict_print_info_on_foreign_keys(
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
dict_table_t* table); /*!< in: table */
|
||||
|
||||
/**********************************************************************//**
|
||||
Outputs info on a foreign key of a table in a format suitable for
|
||||
CREATE TABLE. */
|
||||
/** Output info on a foreign key of a table in a format suitable for
|
||||
CREATE TABLE.
|
||||
@param trx transaction
|
||||
@param foreign constraint
|
||||
@param add_newline whether to add a newline */
|
||||
std::string
|
||||
dict_print_info_on_foreign_key_in_create_format(
|
||||
/*============================================*/
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
dict_foreign_t* foreign, /*!< in: foreign key constraint */
|
||||
ibool add_newline); /*!< in: whether to add a newline */
|
||||
dict_print_info_on_foreign_key_in_create_format(const trx_t *trx,
|
||||
const dict_foreign_t *foreign,
|
||||
bool add_newline);
|
||||
|
||||
/*********************************************************************//**
|
||||
Tries to find an index whose first fields are the columns in the array,
|
||||
|
@@ -37,6 +37,9 @@ simple headers.
|
||||
/* Forward declarations */
|
||||
class THD;
|
||||
class Field;
|
||||
struct dict_table_t;
|
||||
struct dict_foreign_t;
|
||||
struct table_name_t;
|
||||
|
||||
// JAN: TODO missing features:
|
||||
#undef MYSQL_FT_INIT_EXT
|
||||
@@ -83,7 +86,7 @@ innobase_invalidate_query_cache(
|
||||
void
|
||||
innobase_quote_identifier(
|
||||
FILE* file,
|
||||
trx_t* trx,
|
||||
const trx_t* trx,
|
||||
const char* id);
|
||||
|
||||
/** Quote an standard SQL identifier like tablespace, index or column name.
|
||||
@@ -93,7 +96,7 @@ Return the string as an std:string object.
|
||||
@return a std::string with id properly quoted. */
|
||||
std::string
|
||||
innobase_quote_identifier(
|
||||
trx_t* trx,
|
||||
const trx_t* trx,
|
||||
const char* id);
|
||||
|
||||
/*****************************************************************//**
|
||||
@@ -456,25 +459,20 @@ innobase_convert_to_filename_charset(
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes */
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
trx_t* trx, /*!< in: trx */
|
||||
dberr_t error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...);
|
||||
/** Report that a table cannot be decrypted.
|
||||
@param thd connection context
|
||||
@param table table that cannot be decrypted
|
||||
@retval DB_DECRYPTION_FAILED (always) */
|
||||
ATTRIBUTE_COLD
|
||||
dberr_t innodb_decryption_failed(THD *thd, dict_table_t *table);
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ib_push_warning(
|
||||
void* ithd, /*!< in: thd */
|
||||
dberr_t error, /*!< in: error code to push as warning */
|
||||
const char *format,/*!< in: warning message */
|
||||
...);
|
||||
/** Report a foreign key error.
|
||||
@param error error to report
|
||||
@param name table name
|
||||
@param foreign constraint */
|
||||
ATTRIBUTE_COLD
|
||||
void innodb_fk_error(const trx_t *trx, dberr_t err, const char *name,
|
||||
const dict_foreign_t& foreign);
|
||||
|
||||
/********************************************************************//**
|
||||
Helper function to push warnings from InnoDB internals to SQL-layer. */
|
||||
|
@@ -3043,13 +3043,8 @@ row_ins_sec_index_entry_low(
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == DB_DECRYPTION_FAILED) {
|
||||
ib_push_warning(thr_get_trx(thr)->mysql_thd,
|
||||
DB_DECRYPTION_FAILED,
|
||||
"Table %s is encrypted but encryption service or"
|
||||
" used key_id is not available. "
|
||||
" Can't continue reading table.",
|
||||
index->table->name.m_name);
|
||||
index->table->file_unreadable = true;
|
||||
innodb_decryption_failed(thr_get_trx(thr)->mysql_thd,
|
||||
index->table);
|
||||
}
|
||||
goto func_exit;
|
||||
}
|
||||
|
@@ -4473,13 +4473,9 @@ row_merge_build_indexes(
|
||||
/* Do not continue if we can't encrypt table pages */
|
||||
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_readable() ? old_table->name.m_name :
|
||||
new_table->name.m_name);
|
||||
error = innodb_decryption_failed(trx->mysql_thd,
|
||||
!old_table->is_readable()
|
||||
? old_table : new_table);
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
@@ -68,7 +68,7 @@ Created 9/17/2000 Heikki Tuuri
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <vector>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
/** Provide optional 4.x backwards compatibility for 5.0 and above */
|
||||
ibool row_rollback_on_timeout = FALSE;
|
||||
@@ -1257,51 +1257,26 @@ 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
|
||||
/** Report an error for a failure to access a table.
|
||||
@param table unreadable table
|
||||
@param trx transaction
|
||||
@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)
|
||||
ATTRIBUTE_COLD
|
||||
static dberr_t row_mysql_get_table_error(trx_t *trx, dict_table_t *table)
|
||||
{
|
||||
dberr_t err;
|
||||
if (const fil_space_t* space = 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.m_name, table->space);
|
||||
if (const fil_space_t *space= table->space)
|
||||
{
|
||||
if (space->crypt_data && space->crypt_data->is_encrypted())
|
||||
return innodb_decryption_failed(trx->mysql_thd, table);
|
||||
return DB_CORRUPTION;
|
||||
}
|
||||
|
||||
err = DB_DECRYPTION_FAILED;
|
||||
} else {
|
||||
if (push_warning) {
|
||||
ib_push_warning(trx, DB_CORRUPTION,
|
||||
"Table %s in tablespace %lu corrupted.",
|
||||
table->name.m_name, table->space);
|
||||
}
|
||||
|
||||
err = DB_CORRUPTION;
|
||||
}
|
||||
} else {
|
||||
ib::error() << ".ibd file is missing for table "
|
||||
<< table->name;
|
||||
err = DB_TABLESPACE_NOT_FOUND;
|
||||
}
|
||||
|
||||
return(err);
|
||||
const int dblen= int(table->name.dblen());
|
||||
sql_print_error("InnoDB .ibd file is missing for table %`.*s.%`s",
|
||||
dblen, table->name.m_name, table->name.m_name + dblen + 1);
|
||||
return DB_TABLESPACE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/** Does an insert for MySQL.
|
||||
@@ -1339,7 +1314,7 @@ row_insert_for_mysql(
|
||||
return(DB_TABLESPACE_DELETED);
|
||||
|
||||
} else if (!prebuilt->table->is_readable()) {
|
||||
return(row_mysql_get_table_status(prebuilt->table, trx, true));
|
||||
return row_mysql_get_table_error(trx, prebuilt->table);
|
||||
} else if (high_level_read_only) {
|
||||
return(DB_READ_ONLY);
|
||||
}
|
||||
@@ -1726,7 +1701,7 @@ row_update_for_mysql(row_prebuilt_t* prebuilt)
|
||||
ut_ad(table->stat_initialized);
|
||||
|
||||
if (!table->is_readable()) {
|
||||
return(row_mysql_get_table_status(table, trx, true));
|
||||
return row_mysql_get_table_error(trx, table);
|
||||
}
|
||||
|
||||
if (high_level_read_only) {
|
||||
|
@@ -4753,13 +4753,8 @@ wait_table_again:
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err == 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.",
|
||||
prebuilt->table->name.m_name);
|
||||
index->table->file_unreadable = true;
|
||||
innodb_decryption_failed(trx->mysql_thd,
|
||||
index->table);
|
||||
}
|
||||
rec = NULL;
|
||||
goto page_read_error;
|
||||
|
Reference in New Issue
Block a user