Commit 3e3edcfa authored by sunny's avatar sunny

Prevent loading of tables that have unsupported features most notably

FTS indexes.
parent b48d3b66
...@@ -551,11 +551,13 @@ dict_load_fields( ...@@ -551,11 +551,13 @@ dict_load_fields(
Loads definitions for table indexes. Adds them to the data dictionary Loads definitions for table indexes. Adds them to the data dictionary
cache. */ cache. */
static static
ibool ulint
dict_load_indexes( dict_load_indexes(
/*==============*/ /*==============*/
/* out: TRUE if ok, FALSE if corruption /* out: DB_SUCCESS if ok, DB_CORRUPTION
of dictionary table */ if corruption of dictionary table or
DB_UNSUPPORTED if table has unknown index
type */
dict_table_t* table, /* in: table */ dict_table_t* table, /* in: table */
mem_heap_t* heap) /* in: memory heap for temporary storage */ mem_heap_t* heap) /* in: memory heap for temporary storage */
{ {
...@@ -578,6 +580,7 @@ dict_load_indexes( ...@@ -578,6 +580,7 @@ dict_load_indexes(
ibool is_sys_table; ibool is_sys_table;
dulint id; dulint id;
mtr_t mtr; mtr_t mtr;
ulint error = DB_SUCCESS;
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
...@@ -624,10 +627,8 @@ dict_load_indexes( ...@@ -624,10 +627,8 @@ dict_load_indexes(
dict_load_report_deleted_index(table->name, dict_load_report_deleted_index(table->name,
ULINT_UNDEFINED); ULINT_UNDEFINED);
btr_pcur_close(&pcur); error = DB_CORRUPTION;
mtr_commit(&mtr); goto func_exit;
return(FALSE);
} }
field = rec_get_nth_field_old(rec, 1, &len); field = rec_get_nth_field_old(rec, 1, &len);
...@@ -653,7 +654,18 @@ dict_load_indexes( ...@@ -653,7 +654,18 @@ dict_load_indexes(
field = rec_get_nth_field_old(rec, 8, &len); field = rec_get_nth_field_old(rec, 8, &len);
page_no = mach_read_from_4(field); page_no = mach_read_from_4(field);
if (page_no == FIL_NULL) { /* We check for unsupported types first, so that the
subsequent checks are relevant for the supported types. */
if (type & ~(DICT_CLUSTERED | DICT_UNIQUE)) {
fprintf(stderr,
"InnoDB: Error: unknown type %lu"
" of index %s of table %s\n",
(ulong) type, name_buf, table->name);
error = DB_UNSUPPORTED;
goto func_exit;
} else if (page_no == FIL_NULL) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: trying to load index %s" "InnoDB: Error: trying to load index %s"
...@@ -661,14 +673,10 @@ dict_load_indexes( ...@@ -661,14 +673,10 @@ dict_load_indexes(
"InnoDB: but the index tree has been freed!\n", "InnoDB: but the index tree has been freed!\n",
name_buf, table->name); name_buf, table->name);
btr_pcur_close(&pcur); error = DB_CORRUPTION;
mtr_commit(&mtr); goto func_exit;
} else if ((type & DICT_CLUSTERED) == 0
return(FALSE); && NULL == dict_table_get_first_index(table)) {
}
if ((type & DICT_CLUSTERED) == 0
&& NULL == dict_table_get_first_index(table)) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: trying to load index %s" "InnoDB: Error: trying to load index %s"
...@@ -677,18 +685,14 @@ dict_load_indexes( ...@@ -677,18 +685,14 @@ dict_load_indexes(
" is not clustered!\n", " is not clustered!\n",
name_buf, table->name); name_buf, table->name);
btr_pcur_close(&pcur); error = DB_CORRUPTION;
mtr_commit(&mtr); goto func_exit;
} else if (is_sys_table
return(FALSE); && ((type & DICT_CLUSTERED)
} || ((table == dict_sys->sys_tables)
&& (name_len == (sizeof "ID_IND") - 1)
if (is_sys_table && (0 == ut_memcmp(name_buf,
&& ((type & DICT_CLUSTERED) "ID_IND", name_len))))) {
|| ((table == dict_sys->sys_tables)
&& (name_len == (sizeof "ID_IND") - 1)
&& (0 == ut_memcmp(name_buf, "ID_IND",
name_len))))) {
/* The index was created in memory already at booting /* The index was created in memory already at booting
of the database server */ of the database server */
...@@ -704,10 +708,11 @@ dict_load_indexes( ...@@ -704,10 +708,11 @@ dict_load_indexes(
btr_pcur_move_to_next_user_rec(&pcur, &mtr); btr_pcur_move_to_next_user_rec(&pcur, &mtr);
} }
func_exit:
btr_pcur_close(&pcur); btr_pcur_close(&pcur);
mtr_commit(&mtr); mtr_commit(&mtr);
return(TRUE); return(error);
} }
/************************************************************************ /************************************************************************
...@@ -857,11 +862,20 @@ dict_load_table( ...@@ -857,11 +862,20 @@ dict_load_table(
mem_heap_empty(heap); mem_heap_empty(heap);
dict_load_indexes(table, heap); err = dict_load_indexes(table, heap);
err = dict_load_foreigns(table->name, TRUE); /* If the force recovery flag is set, we open the table irrespective
of the error condition, since the user may want to dump data from the
clustered index. However we load the foreign key information only if
all indexes were loaded. */
if (err != DB_SUCCESS && !srv_force_recovery) {
dict_mem_table_free(table);
table = NULL;
} else if (err == DB_SUCCESS) {
err = dict_load_foreigns(table->name, TRUE);
}
#if 0 #if 0
if (err != DB_SUCCESS) { if (err != DB_SUCCESS && table != NULL) {
mutex_enter(&dict_foreign_err_mutex); mutex_enter(&dict_foreign_err_mutex);
......
...@@ -2334,13 +2334,18 @@ ha_innobase::open( ...@@ -2334,13 +2334,18 @@ ha_innobase::open(
if (NULL == ib_table) { if (NULL == ib_table) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
sql_print_error("Cannot find table %s from the internal data " sql_print_error("Cannot find or open table %s from\n"
"dictionary\nof InnoDB though the .frm file " "the internal data dictionary of InnoDB "
"for the table exists. Maybe you\nhave " "though the .frm file for the\n"
"deleted and recreated InnoDB data files but " "table exists. Maybe you have deleted and "
"have forgotten\nto delete the corresponding " "recreated InnoDB data\n"
".frm files of InnoDB tables, or you\n" "files but have forgotten to delete the "
"have moved .frm files to another database?\n" "corresponding .frm files\n"
"of InnoDB tables, or you have moved .frm "
"files to another database?\n"
"or, the table contains indexes that this "
"version of the engine\n"
"doesn't support.\n"
"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n" "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
"how you can resolve the problem.\n", "how you can resolve the problem.\n",
norm_name); norm_name);
......
...@@ -61,12 +61,14 @@ Created 5/24/1996 Heikki Tuuri ...@@ -61,12 +61,14 @@ Created 5/24/1996 Heikki Tuuri
activated by the operation would activated by the operation would
lead to a duplicate key in some lead to a duplicate key in some
table */ table */
#define DB_TOO_MANY_CONCURRENT_TRXS 47 /* when InnoDB runs out of the #define DB_TOO_MANY_CONCURRENT_TRXS 47 /* when InnoDB runs out of the
preconfigured undo slots, this can preconfigured undo slots, this can
only happen when there are too many only happen when there are too many
concurrent transactions */ concurrent transactions */
#define DB_UNSUPPORTED 48 /* when InnoDB sees any artefact or
a feature that it can't recoginize or
work with e.g., FT indexes created by
a later version of the engine. */
/* The following are partial failure codes */ /* The following are partial failure codes */
#define DB_FAIL 1000 #define DB_FAIL 1000
#define DB_OVERFLOW 1001 #define DB_OVERFLOW 1001
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment