summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/heap/hp_scan.c4
-rw-r--r--storage/innobase/btr/btr0scrub.cc7
-rw-r--r--storage/innobase/dict/dict0dict.cc110
-rw-r--r--storage/innobase/dict/dict0load.cc21
-rw-r--r--storage/innobase/fil/fil0crypt.cc27
-rw-r--r--storage/innobase/fil/fil0fil.cc20
-rw-r--r--storage/innobase/handler/ha_innodb.cc36
-rw-r--r--storage/innobase/include/dict0dict.h30
-rw-r--r--storage/innobase/include/dict0types.h8
-rw-r--r--storage/innobase/include/fil0crypt.h6
-rw-r--r--storage/innobase/row/row0ins.cc79
-rw-r--r--storage/innobase/row/row0mysql.cc8
-rw-r--r--storage/mroonga/ha_mroonga.cpp3
13 files changed, 177 insertions, 182 deletions
diff --git a/storage/heap/hp_scan.c b/storage/heap/hp_scan.c
index 3315cb05b3f..f07efe6cf67 100644
--- a/storage/heap/hp_scan.c
+++ b/storage/heap/hp_scan.c
@@ -50,7 +50,9 @@ int heap_scan(register HP_INFO *info, uchar *record)
}
else
{
- info->next_block+=share->block.records_in_block;
+ /* increase next_block to the next records_in_block boundary */
+ ulong rem= info->next_block % share->block.records_in_block;
+ info->next_block+=share->block.records_in_block - rem;
if (info->next_block >= share->records+share->deleted)
{
info->next_block= share->records+share->deleted;
diff --git a/storage/innobase/btr/btr0scrub.cc b/storage/innobase/btr/btr0scrub.cc
index 7d8966d4109..2839f4f872f 100644
--- a/storage/innobase/btr/btr0scrub.cc
+++ b/storage/innobase/btr/btr0scrub.cc
@@ -626,13 +626,8 @@ btr_scrub_get_table_and_index(
scrub_data->current_table = NULL;
}
- /* argument to dict_table_open_on_index_id */
- bool dict_locked = true;
-
/* open table based on index_id */
- dict_table_t* table = dict_table_open_on_index_id(
- index_id,
- dict_locked);
+ dict_table_t* table = dict_table_open_on_index_id(index_id);
if (table != NULL) {
/* mark table as being scrubbed */
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index cb0e8b6b488..47803ed19a1 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -427,7 +427,7 @@ dict_table_try_drop_aborted(
if (table == NULL) {
table = dict_table_open_on_id_low(
- table_id, DICT_ERR_IGNORE_NONE, FALSE);
+ table_id, DICT_ERR_IGNORE_FK_NOKEY, FALSE);
} else {
ut_ad(table->id == table_id);
}
@@ -1002,7 +1002,7 @@ dict_table_open_on_id(
table_id,
table_op == DICT_TABLE_OP_LOAD_TABLESPACE
? DICT_ERR_IGNORE_RECOVER_LOCK
- : DICT_ERR_IGNORE_NONE,
+ : DICT_ERR_IGNORE_FK_NOKEY,
table_op == DICT_TABLE_OP_OPEN_ONLY_IF_CACHED);
if (table != NULL) {
@@ -1164,7 +1164,7 @@ dict_table_open_on_name(
if (table != NULL) {
/* If table is encrypted or corrupted */
- if (ignore_err == DICT_ERR_IGNORE_NONE
+ if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY)
&& !table->is_readable()) {
/* Make life easy for drop table. */
dict_table_prevent_eviction(table);
@@ -3128,11 +3128,6 @@ dict_index_build_internal_fts(
}
/*====================== FOREIGN KEY PROCESSING ========================*/
-#define DB_FOREIGN_KEY_IS_PREFIX_INDEX 200
-#define DB_FOREIGN_KEY_COL_NOT_NULL 201
-#define DB_FOREIGN_KEY_COLS_NOT_EQUAL 202
-#define DB_FOREIGN_KEY_INDEX_NOT_FOUND 203
-
/** Check whether the dict_table_t is a partition.
A partitioned table on the SQL level is composed of InnoDB tables,
where each InnoDB table is a [sub]partition including its secondary indexes
@@ -3239,7 +3234,7 @@ dict_foreign_find_index(
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
- ulint* error, /*!< out: error code */
+ fkerr_t* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
@@ -3247,17 +3242,15 @@ dict_foreign_find_index(
/*!< out: index where error
happened */
{
- dict_index_t* index;
-
ut_ad(mutex_own(&dict_sys->mutex));
if (error) {
- *error = DB_FOREIGN_KEY_INDEX_NOT_FOUND;
+ *error = FK_INDEX_NOT_FOUND;
}
- index = dict_table_get_first_index(table);
-
- while (index != NULL) {
+ for (dict_index_t* index = dict_table_get_first_index(table);
+ index;
+ index = dict_table_get_next_index(index)) {
if (types_idx != index
&& !index->to_be_dropped
&& !dict_index_is_online_ddl(index)
@@ -3265,42 +3258,17 @@ dict_foreign_find_index(
table, col_names, columns, n_cols,
index, types_idx,
check_charsets, check_null,
- error, err_col_no,err_index)) {
+ error, err_col_no, err_index)) {
if (error) {
- *error = DB_SUCCESS;
+ *error = FK_SUCCESS;
}
return(index);
}
-
- index = dict_table_get_next_index(index);
}
return(NULL);
}
-#ifdef WITH_WSREP
-dict_index_t*
-wsrep_dict_foreign_find_index(
-/*====================*/
- dict_table_t* table, /*!< in: table */
- const char** col_names, /*!< in: column names, or NULL
- to use table->col_names */
- const char** columns,/*!< in: array of column names */
- ulint n_cols, /*!< in: number of columns */
- dict_index_t* types_idx, /*!< in: NULL or an index to whose types the
- column types must match */
- ibool check_charsets,
- /*!< in: whether to check charsets.
- only has an effect if types_idx != NULL */
- ulint check_null)
- /*!< in: nonzero if none of the columns must
- be declared NOT NULL */
-{
- return dict_foreign_find_index(
- table, col_names, columns, n_cols, types_idx, check_charsets,
- check_null, NULL, NULL, NULL);
-}
-#endif /* WITH_WSREP */
/**********************************************************************//**
Report an error in a foreign key definition. */
static
@@ -3397,15 +3365,11 @@ dict_foreign_add_to_cache(
}
if (ref_table && !for_in_cache->referenced_table) {
- ulint index_error;
- ulint err_col;
- dict_index_t *err_index=NULL;
-
index = dict_foreign_find_index(
ref_table, NULL,
for_in_cache->referenced_col_names,
for_in_cache->n_fields, for_in_cache->foreign_index,
- check_charsets, false, &index_error, &err_col, &err_index);
+ check_charsets, false);
if (index == NULL
&& !(ignore_err & DICT_ERR_IGNORE_FK_NOKEY)) {
@@ -3437,10 +3401,6 @@ dict_foreign_add_to_cache(
}
if (for_table && !for_in_cache->foreign_table) {
- ulint index_error;
- ulint err_col;
- dict_index_t *err_index=NULL;
-
index = dict_foreign_find_index(
for_table, col_names,
for_in_cache->foreign_col_names,
@@ -3448,8 +3408,7 @@ dict_foreign_add_to_cache(
for_in_cache->referenced_index, check_charsets,
for_in_cache->type
& (DICT_FOREIGN_ON_DELETE_SET_NULL
- | DICT_FOREIGN_ON_UPDATE_SET_NULL),
- &index_error, &err_col, &err_index);
+ | DICT_FOREIGN_ON_UPDATE_SET_NULL));
if (index == NULL
&& !(ignore_err & DICT_ERR_IGNORE_FK_NOKEY)) {
@@ -4161,7 +4120,7 @@ dict_foreign_push_index_error(
const char* latest_foreign, /*!< in: start of latest foreign key
constraint name */
const char** columns, /*!< in: foreign key columns */
- ulint index_error, /*!< in: error code */
+ fkerr_t index_error, /*!< in: error code */
ulint err_col, /*!< in: column where error happened
*/
dict_index_t* err_index, /*!< in: index where error happened
@@ -4170,37 +4129,37 @@ dict_foreign_push_index_error(
FILE* ef) /*!< in: output stream */
{
switch (index_error) {
- case DB_FOREIGN_KEY_INDEX_NOT_FOUND: {
+ case FK_SUCCESS:
+ break;
+ case FK_INDEX_NOT_FOUND:
fprintf(ef,
- "%s table '%s' with foreign key constraint"
+ "%s table %s with foreign key constraint"
" failed. There is no index in the referenced"
" table where the referenced columns appear"
" as the first columns near '%s'.\n",
operation, create_name, latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
- "%s table '%s' with foreign key constraint"
+ "%s table %s with foreign key constraint"
" failed. There is no index in the referenced"
" table where the referenced columns appear"
" as the first columns near '%s'.",
operation, create_name, latest_foreign);
- break;
- }
- case DB_FOREIGN_KEY_IS_PREFIX_INDEX: {
+ return;
+ case FK_IS_PREFIX_INDEX:
fprintf(ef,
- "%s table '%s' with foreign key constraint"
+ "%s table %s with foreign key constraint"
" failed. There is only prefix index in the referenced"
" table where the referenced columns appear"
" as the first columns near '%s'.\n",
operation, create_name, latest_foreign);
ib_push_warning(trx, DB_CANNOT_ADD_CONSTRAINT,
- "%s table '%s' with foreign key constraint"
+ "%s table %s with foreign key constraint"
" failed. There is only prefix index in the referenced"
" table where the referenced columns appear"
" as the first columns near '%s'.",
operation, create_name, latest_foreign);
- break;
- }
- case DB_FOREIGN_KEY_COL_NOT_NULL: {
+ return;
+ case FK_COL_NOT_NULL:
fprintf(ef,
"%s table %s with foreign key constraint"
" failed. You have defined a SET NULL condition but "
@@ -4211,9 +4170,8 @@ dict_foreign_push_index_error(
" failed. You have defined a SET NULL condition but "
"column '%s' on index is defined as NOT NULL near '%s'.",
operation, create_name, columns[err_col], latest_foreign);
- break;
- }
- case DB_FOREIGN_KEY_COLS_NOT_EQUAL: {
+ return;
+ case FK_COLS_NOT_EQUAL:
dict_field_t* field;
const char* col_name;
field = dict_index_get_nth_field(err_index, err_col);
@@ -4232,11 +4190,9 @@ dict_foreign_push_index_error(
" failed. Field type or character set for column '%s' "
"does not mach referenced column '%s' near '%s'.",
operation, create_name, columns[err_col], col_name, latest_foreign);
- break;
- }
- default:
- ut_error;
+ return;
}
+ DBUG_ASSERT(!"unknown error");
}
/*********************************************************************//**
@@ -4268,7 +4224,7 @@ dict_create_foreign_constraints_low(
const char* start_of_latest_foreign = sql_string;
const char* start_of_latest_set = NULL;
FILE* ef = dict_foreign_err_file;
- ulint index_error = DB_SUCCESS;
+ fkerr_t index_error = FK_SUCCESS;
dict_index_t* err_index = NULL;
ulint err_col;
const char* constraint_name;
@@ -6720,7 +6676,7 @@ dict_foreign_qualify_index(
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
- ulint* error, /*!< out: error code */
+ fkerr_t* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
@@ -6748,7 +6704,7 @@ dict_foreign_qualify_index(
/* We do not accept column prefix
indexes here */
if (error && err_col_no && err_index) {
- *error = DB_FOREIGN_KEY_IS_PREFIX_INDEX;
+ *error = FK_IS_PREFIX_INDEX;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
@@ -6758,7 +6714,7 @@ dict_foreign_qualify_index(
if (check_null
&& (field->col->prtype & DATA_NOT_NULL)) {
if (error && err_col_no && err_index) {
- *error = DB_FOREIGN_KEY_COL_NOT_NULL;
+ *error = FK_COL_NOT_NULL;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
@@ -6788,7 +6744,7 @@ dict_foreign_qualify_index(
dict_index_get_nth_col(types_idx, i),
check_charsets)) {
if (error && err_col_no && err_index) {
- *error = DB_FOREIGN_KEY_COLS_NOT_EQUAL;
+ *error = FK_COLS_NOT_EQUAL;
*err_col_no = i;
*err_index = (dict_index_t*)index;
}
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc
index 6700bca5ba4..817a4059e8a 100644
--- a/storage/innobase/dict/dict0load.cc
+++ b/storage/innobase/dict/dict0load.cc
@@ -3086,7 +3086,7 @@ func_exit:
mem_heap_free(heap);
ut_ad(!table
- || ignore_err != DICT_ERR_IGNORE_NONE
+ || (ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY)
|| !table->is_readable()
|| !table->corrupted);
@@ -3775,29 +3775,14 @@ dict_load_table_id_on_index_id(
return(found);
}
-UNIV_INTERN
-dict_table_t*
-dict_table_open_on_index_id(
-/*========================*/
- index_id_t index_id, /*!< in: index id */
- bool dict_locked) /*!< in: dict locked */
+dict_table_t* dict_table_open_on_index_id(index_id_t index_id)
{
- if (!dict_locked) {
- mutex_enter(&dict_sys->mutex);
- }
-
- ut_ad(mutex_own(&dict_sys->mutex));
table_id_t table_id;
dict_table_t * table = NULL;
if (dict_load_table_id_on_index_id(index_id, &table_id)) {
- bool local_dict_locked = true;
- table = dict_table_open_on_id(table_id,
- local_dict_locked,
+ table = dict_table_open_on_id(table_id, true,
DICT_TABLE_OP_LOAD_TABLESPACE);
}
- if (!dict_locked) {
- mutex_exit(&dict_sys->mutex);
- }
return table;
}
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 35b70501002..9d64f81e406 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -356,6 +356,33 @@ fil_space_destroy_crypt_data(
}
}
+/** Fill crypt data information to the give page.
+It should be called during ibd file creation.
+@param[in] flags tablespace flags
+@param[in,out] page first page of the tablespace */
+void
+fil_space_crypt_t::fill_page0(
+ ulint flags,
+ byte* page)
+{
+ const uint len = sizeof(iv);
+ const ulint offset = FSP_HEADER_OFFSET
+ + fsp_header_get_encryption_offset(page_size_t(flags));
+ page0_offset = offset;
+
+ memcpy(page + offset, CRYPT_MAGIC, MAGIC_SZ);
+ mach_write_to_1(page + offset + MAGIC_SZ, type);
+ mach_write_to_1(page + offset + MAGIC_SZ + 1, len);
+ memcpy(page + offset + MAGIC_SZ + 2, &iv, len);
+
+ mach_write_to_4(page + offset + MAGIC_SZ + 2 + len,
+ min_key_version);
+ mach_write_to_4(page + offset + MAGIC_SZ + 2 + len + 4,
+ key_id);
+ mach_write_to_1(page + offset + MAGIC_SZ + 2 + len + 8,
+ encryption);
+}
+
/******************************************************************
Write crypt data to a page (0)
@param[in] space tablespace
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index d796d2a7f2a..5bf7fb9df58 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -3076,6 +3076,19 @@ err_exit:
fsp_header_init_fields(page, space_id, flags);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id);
+ /* Create crypt data if the tablespace is either encrypted or user has
+ requested it to remain unencrypted. */
+ if (mode == FIL_ENCRYPTION_ON || mode == FIL_ENCRYPTION_OFF ||
+ srv_encrypt_tables) {
+ crypt_data = fil_space_create_crypt_data(mode, key_id);
+ }
+
+ if (crypt_data) {
+ /* Write crypt data information in page0 while creating
+ ibd file. */
+ crypt_data->fill_page0(flags, page);
+ }
+
const page_size_t page_size(flags);
IORequest request(IORequest::WRITE);
@@ -3127,13 +3140,6 @@ err_exit:
}
}
- /* Create crypt data if the tablespace is either encrypted or user has
- requested it to remain unencrypted. */
- if (mode == FIL_ENCRYPTION_ON || mode == FIL_ENCRYPTION_OFF ||
- srv_encrypt_tables) {
- crypt_data = fil_space_create_crypt_data(mode, key_id);
- }
-
space = fil_space_create(name, space_id, flags, FIL_TYPE_TABLESPACE,
crypt_data, mode);
if (!space) {
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 29cc4dc3c40..59a7c8641f8 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3110,7 +3110,7 @@ static bool innobase_query_caching_table_check(
const char* norm_name)
{
dict_table_t* table = dict_table_open_on_name(
- norm_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ norm_name, FALSE, FALSE, DICT_ERR_IGNORE_FK_NOKEY);
if (table == NULL) {
return false;
@@ -6084,9 +6084,7 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
int
ha_innobase::open(const char* name, int, uint)
{
- dict_table_t* ib_table;
char norm_name[FN_REFLEN];
- dict_err_ignore_t ignore_err = DICT_ERR_IGNORE_NONE;
DBUG_ENTER("ha_innobase::open");
@@ -6100,15 +6098,8 @@ ha_innobase::open(const char* name, int, uint)
char* is_part = is_partition(norm_name);
THD* thd = ha_thd();
-
- /* Check whether FOREIGN_KEY_CHECKS is set to 0. If so, the table
- can be opened even if some FK indexes are missing. If not, the table
- can't be opened in the same situation */
- if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
- ignore_err = DICT_ERR_IGNORE_FK_NOKEY;
- }
-
- ib_table = open_dict_table(name, norm_name, is_part, ignore_err);
+ dict_table_t* ib_table = open_dict_table(name, norm_name, is_part,
+ DICT_ERR_IGNORE_FK_NOKEY);
DEBUG_SYNC(thd, "ib_open_after_dict_open");
@@ -10172,17 +10163,6 @@ next_record:
}
#ifdef WITH_WSREP
-extern dict_index_t*
-wsrep_dict_foreign_find_index(
-/*==========================*/
- dict_table_t* table,
- const char** col_names,
- const char** columns,
- ulint n_cols,
- dict_index_t* types_idx,
- ibool check_charsets,
- ulint check_null);
-
inline
const char*
wsrep_key_type_to_str(wsrep_key_type type)
@@ -10245,7 +10225,7 @@ wsrep_append_foreign_key(
foreign->referenced_table_name_lookup);
if (foreign->referenced_table) {
foreign->referenced_index =
- wsrep_dict_foreign_find_index(
+ dict_foreign_find_index(
foreign->referenced_table, NULL,
foreign->referenced_col_names,
foreign->n_fields,
@@ -10259,7 +10239,7 @@ wsrep_append_foreign_key(
if (foreign->foreign_table) {
foreign->foreign_index =
- wsrep_dict_foreign_find_index(
+ dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields,
@@ -13178,8 +13158,8 @@ innobase_rename_table(
row_mysql_lock_data_dictionary(trx);
}
- dict_table_t* table = dict_table_open_on_name(norm_from, TRUE, FALSE,
- DICT_ERR_IGNORE_NONE);
+ dict_table_t* table = dict_table_open_on_name(
+ norm_from, TRUE, FALSE, DICT_ERR_IGNORE_FK_NOKEY);
/* Since DICT_BG_YIELD has sleep for 250 milliseconds,
Convert lock_wait_timeout unit from second to 250 milliseconds */
@@ -14300,7 +14280,7 @@ ha_innobase::defragment_table(
normalize_table_name(norm_name, name);
table = dict_table_open_on_name(norm_name, FALSE,
- FALSE, DICT_ERR_IGNORE_NONE);
+ FALSE, DICT_ERR_IGNORE_FK_NOKEY);
for (index = dict_table_get_first_index(table); index;
index = dict_table_get_next_index(index)) {
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 6f84f2eadf7..12a566a27c6 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -115,12 +115,7 @@ dict_table_open_on_id(
/**********************************************************************//**
Returns a table object based on table id.
@return table, NULL if does not exist */
-UNIV_INTERN
-dict_table_t*
-dict_table_open_on_index_id(
-/*==================*/
- table_id_t table_id, /*!< in: table id */
- bool dict_locked) /*!< in: TRUE=data dictionary locked */
+dict_table_t* dict_table_open_on_index_id(index_id_t index_id)
__attribute__((warn_unused_result));
/********************************************************************//**
Decrements the count of open handles to a table. */
@@ -523,6 +518,21 @@ dict_table_open_on_name(
dict_err_ignore_t ignore_err)
MY_ATTRIBUTE((warn_unused_result));
+/** Outcome of dict_foreign_find_index() or dict_foreign_qualify_index() */
+enum fkerr_t
+{
+ /** A backing index was found for a FOREIGN KEY constraint */
+ FK_SUCCESS = 0,
+ /** There is no index that covers the columns in the constraint. */
+ FK_INDEX_NOT_FOUND,
+ /** The index is for a prefix index, not a full column. */
+ FK_IS_PREFIX_INDEX,
+ /** A condition of SET NULL conflicts with a NOT NULL column. */
+ FK_COL_NOT_NULL,
+ /** The column types do not match */
+ FK_COLS_NOT_EQUAL
+};
+
/*********************************************************************//**
Tries to find an index whose first fields are the columns in the array,
in the same order and is not marked for deletion and is not the same
@@ -549,11 +559,11 @@ dict_foreign_find_index(
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
- ulint* error, /*!< out: error code */
- ulint* err_col_no,
+ fkerr_t* error = NULL, /*!< out: error code */
+ ulint* err_col_no = NULL,
/*!< out: column number where
error happened */
- dict_index_t** err_index)
+ dict_index_t** err_index = NULL)
/*!< out: index where error
happened */
@@ -629,7 +639,7 @@ dict_foreign_qualify_index(
/*!< in: nonzero if none of
the columns must be declared
NOT NULL */
- ulint* error, /*!< out: error code */
+ fkerr_t* error, /*!< out: error code */
ulint* err_col_no,
/*!< out: column number where
error happened */
diff --git a/storage/innobase/include/dict0types.h b/storage/innobase/include/dict0types.h
index cab88104b87..fec101529f9 100644
--- a/storage/innobase/include/dict0types.h
+++ b/storage/innobase/include/dict0types.h
@@ -67,11 +67,11 @@ Note: please define the IGNORE_ERR_* as bits, so their value can
be or-ed together */
enum dict_err_ignore_t {
DICT_ERR_IGNORE_NONE = 0, /*!< no error to ignore */
- DICT_ERR_IGNORE_INDEX_ROOT = 1, /*!< ignore error if index root
- page is FIL_NULL or incorrect value */
- DICT_ERR_IGNORE_CORRUPT = 2, /*!< skip corrupted indexes */
- DICT_ERR_IGNORE_FK_NOKEY = 4, /*!< ignore error if any foreign
+ DICT_ERR_IGNORE_FK_NOKEY = 1, /*!< ignore error if any foreign
key is missing */
+ DICT_ERR_IGNORE_INDEX_ROOT = 2, /*!< ignore error if index root
+ page is FIL_NULL or incorrect value */
+ DICT_ERR_IGNORE_CORRUPT = 4, /*!< skip corrupted indexes */
DICT_ERR_IGNORE_RECOVER_LOCK = 8,
/*!< Used when recovering table locks
for resurrected transactions.
diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h
index 47ac35d6bce..2296945bbf9 100644
--- a/storage/innobase/include/fil0crypt.h
+++ b/storage/innobase/include/fil0crypt.h
@@ -180,6 +180,12 @@ struct fil_space_crypt_t : st_encryption_scheme
return (encryption == FIL_ENCRYPTION_OFF);
}
+ /** Fill crypt data information to the give page.
+ It should be called during ibd file creation.
+ @param[in] flags tablespace flags
+ @param[in,out] page first page of the tablespace */
+ void fill_page0(ulint flags, byte* page);
+
/** Write crypt data to a page (0)
@param[in] space tablespace
@param[in,out] page0 first page of the tablespace
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 12bd2001495..bb7daf6399a 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -874,8 +874,12 @@ row_ins_foreign_report_add_err(
fk_str = dict_print_info_on_foreign_key_in_create_format(trx, foreign,
TRUE);
fputs(fk_str.c_str(), ef);
- fprintf(ef, " in parent table, in index %s",
- foreign->foreign_index->name());
+ if (foreign->foreign_index) {
+ fprintf(ef, " in parent table, in index %s",
+ foreign->foreign_index->name());
+ } else {
+ fputs(" in parent table", ef);
+ }
if (entry) {
fputs(" tuple:\n", ef);
/* TODO: DB_TRX_ID and DB_ROLL_PTR may be uninitialized.
@@ -1656,34 +1660,51 @@ row_ins_check_foreign_constraint(
|| !check_table->is_readable()
|| check_index == NULL) {
- if (!srv_read_only_mode && check_ref) {
- FILE* ef = dict_foreign_err_file;
- std::string fk_str;
-
- row_ins_set_detailed(trx, foreign);
-
- row_ins_foreign_trx_print(trx);
-
- fputs("Foreign key constraint fails for table ", ef);
- ut_print_name(ef, trx,
- foreign->foreign_table_name);
- fputs(":\n", ef);
- fk_str = dict_print_info_on_foreign_key_in_create_format(
- trx, foreign, TRUE);
- fputs(fk_str.c_str(), ef);
- fprintf(ef, "\nTrying to add to index %s tuple:\n",
- foreign->foreign_index->name());
+ FILE* ef = dict_foreign_err_file;
+ std::string fk_str;
+
+ row_ins_set_detailed(trx, foreign);
+ row_ins_foreign_trx_print(trx);
+
+ fputs("Foreign key constraint fails for table ", ef);
+ ut_print_name(ef, trx, check_ref
+ ? foreign->foreign_table_name
+ : foreign->referenced_table_name);
+ fputs(":\n", ef);
+ fk_str = dict_print_info_on_foreign_key_in_create_format(
+ trx, foreign, TRUE);
+ fputs(fk_str.c_str(), ef);
+ if (check_ref) {
+ if (foreign->foreign_index) {
+ fprintf(ef, "\nTrying to add to index %s"
+ " tuple:\n",
+ foreign->foreign_index->name());
+ } else {
+ fputs("\nTrying to add tuple:\n", ef);
+ }
dtuple_print(ef, entry);
fputs("\nBut the parent table ", ef);
- ut_print_name(ef, trx,
- foreign->referenced_table_name);
- fputs("\nor its .ibd file does"
+ ut_print_name(ef, trx, foreign->referenced_table_name);
+ fputs("\nor its .ibd file or the required index does"
" not currently exist!\n", ef);
- mutex_exit(&dict_foreign_err_mutex);
-
err = DB_NO_REFERENCED_ROW;
+ } else {
+ if (foreign->referenced_index) {
+ fprintf(ef, "\nTrying to modify index %s"
+ " tuple:\n",
+ foreign->referenced_index->name());
+ } else {
+ fputs("\nTrying to modify tuple:\n", ef);
+ }
+ dtuple_print(ef, entry);
+ fputs("\nBut the referencing table ", ef);
+ ut_print_name(ef, trx, foreign->foreign_table_name);
+ fputs("\nor its .ibd file or the required index does"
+ " not currently exist!\n", ef);
+ err = DB_ROW_IS_REFERENCED;
}
+ mutex_exit(&dict_foreign_err_mutex);
goto exit_func;
}
@@ -1965,6 +1986,7 @@ row_ins_check_foreign_constraints(
/*==============================*/
dict_table_t* table, /*!< in: table */
dict_index_t* index, /*!< in: index */
+ bool pk, /*!< in: index->is_primary() */
dtuple_t* entry, /*!< in: index entry for index */
que_thr_t* thr) /*!< in: query thread */
{
@@ -1973,6 +1995,8 @@ row_ins_check_foreign_constraints(
trx_t* trx;
ibool got_s_lock = FALSE;
+ DBUG_ASSERT(index->is_primary() == pk);
+
trx = thr_get_trx(thr);
DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
@@ -1984,7 +2008,8 @@ row_ins_check_foreign_constraints(
foreign = *it;
- if (foreign->foreign_index == index) {
+ if (foreign->foreign_index == index
+ || (pk && !foreign->foreign_index)) {
dict_table_t* ref_table = NULL;
dict_table_t* referenced_table
= foreign->referenced_table;
@@ -3196,7 +3221,7 @@ row_ins_clust_index_entry(
if (!index->table->foreign_set.empty()) {
err = row_ins_check_foreign_constraints(
- index->table, index, entry, thr);
+ index->table, index, true, entry, thr);
if (err != DB_SUCCESS) {
DBUG_RETURN(err);
@@ -3277,7 +3302,7 @@ row_ins_sec_index_entry(
if (!index->table->foreign_set.empty()) {
err = row_ins_check_foreign_constraints(index->table, index,
- entry, thr);
+ false, entry, thr);
if (err != DB_SUCCESS) {
return(err);
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 43808f157d5..836785b935b 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2901,7 +2901,7 @@ row_discard_tablespace_begin(
dict_table_t* table;
table = dict_table_open_on_name(
- name, TRUE, FALSE, DICT_ERR_IGNORE_NONE);
+ name, TRUE, FALSE, DICT_ERR_IGNORE_FK_NOKEY);
if (table) {
dict_stats_wait_bg_to_stop_using_table(table, trx);
@@ -3279,7 +3279,7 @@ row_drop_table_from_cache(
dict_table_remove_from_cache(table);
- if (dict_load_table(tablename, true, DICT_ERR_IGNORE_NONE)) {
+ if (dict_load_table(tablename, true, DICT_ERR_IGNORE_FK_NOKEY)) {
ib::error() << "Not able to remove table "
<< ut_get_name(trx, tablename)
<< " from the dictionary cache!";
@@ -4193,7 +4193,7 @@ row_rename_table_for_mysql(
dict_locked = trx->dict_operation_lock_mode == RW_X_LATCH;
table = dict_table_open_on_name(old_name, dict_locked, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_FK_NOKEY);
/* We look for pattern #P# to see if the table is partitioned
MySQL table. */
@@ -4241,7 +4241,7 @@ row_rename_table_for_mysql(
par_case_name, old_name, FALSE);
#endif
table = dict_table_open_on_name(par_case_name, dict_locked, FALSE,
- DICT_ERR_IGNORE_NONE);
+ DICT_ERR_IGNORE_FK_NOKEY);
}
if (!table) {
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index c194a4dc330..4e084400ed6 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -9005,10 +9005,12 @@ bool ha_mroonga::is_foreign_key_field(const char *table_name,
grn_obj *range = grn_ctx_at(ctx, grn_obj_get_range(ctx, column));
if (!range) {
+ grn_obj_unlink(ctx, column);
DBUG_RETURN(false);
}
if (!mrn::grn::is_table(range)) {
+ grn_obj_unlink(ctx, column);
DBUG_RETURN(false);
}
@@ -9022,6 +9024,7 @@ bool ha_mroonga::is_foreign_key_field(const char *table_name,
DBUG_RETURN(true);
}
+ grn_obj_unlink(ctx, column);
DBUG_RETURN(false);
}