summaryrefslogtreecommitdiff
path: root/innobase/dict
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/dict')
-rw-r--r--innobase/dict/dict0boot.c115
-rw-r--r--innobase/dict/dict0crea.c96
-rw-r--r--innobase/dict/dict0dict.c338
-rw-r--r--innobase/dict/dict0load.c251
-rw-r--r--innobase/dict/dict0mem.c44
5 files changed, 556 insertions, 288 deletions
diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c
index 1cae2750fbe..f156cf67a18 100644
--- a/innobase/dict/dict0boot.c
+++ b/innobase/dict/dict0boot.c
@@ -254,29 +254,26 @@ dict_boot(void)
/* Insert into the dictionary cache the descriptions of the basic
system tables */
/*-------------------------*/
- table = dict_mem_table_create((char *) "SYS_TABLES", DICT_HDR_SPACE,8);
-
- dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, (char *) "ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, (char *) "N_COLS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "TYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "MIX_ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, (char *) "MIX_LEN", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "CLUSTER_NAME", DATA_BINARY,
- 0, 0, 0);
- dict_mem_table_add_col(table, (char *) "SPACE", DATA_INT, 0, 4, 0);
+ table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE,8);
+
+ dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "N_COLS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "MIX_ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "MIX_LEN", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "CLUSTER_NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
table->id = DICT_TABLES_ID;
dict_table_add_to_cache(table);
dict_sys->sys_tables = table;
- index = dict_mem_index_create((char *) "SYS_TABLES", (char *)
- "CLUST_IND",
- DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 1);
+ index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
+ DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 1);
- dict_mem_index_add_field(index, (char *) "NAME", 0, 0);
+ dict_mem_index_add_field(index, "NAME", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLES,
MLOG_4BYTES, &mtr);
@@ -284,89 +281,89 @@ dict_boot(void)
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- index = dict_mem_index_create((char *) "SYS_TABLES",
- (char *) "ID_IND", DICT_HDR_SPACE,
- DICT_UNIQUE, 1);
- dict_mem_index_add_field(index, (char *) "ID", 0, 0);
+ index = dict_mem_index_create("SYS_TABLES", "ID_IND",
+ DICT_HDR_SPACE, DICT_UNIQUE, 1);
+ dict_mem_index_add_field(index, "ID", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS,
MLOG_4BYTES, &mtr);
index->id = DICT_TABLE_IDS_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create((char *) "SYS_COLUMNS",DICT_HDR_SPACE,7);
-
- dict_mem_table_add_col(table, (char *) "TABLE_ID", DATA_BINARY,0,0,0);
- dict_mem_table_add_col(table, (char *) "POS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, (char *) "MTYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "PRTYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "LEN", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "PREC", DATA_INT, 0, 4, 0);
+ table = dict_mem_table_create("SYS_COLUMNS",DICT_HDR_SPACE,7);
+
+ dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY,0,0,0);
+ dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "MTYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4, 0);
table->id = DICT_COLUMNS_ID;
dict_table_add_to_cache(table);
dict_sys->sys_columns = table;
- index = dict_mem_index_create((char *) "SYS_COLUMNS",
- (char *) "CLUST_IND", DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
+ DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, (char *) "TABLE_ID", 0, 0);
- dict_mem_index_add_field(index, (char *) "POS", 0, 0);
+ dict_mem_index_add_field(index, "TABLE_ID", 0, 0);
+ dict_mem_index_add_field(index, "POS", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS,
MLOG_4BYTES, &mtr);
index->id = DICT_COLUMNS_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create((char *) "SYS_INDEXES",DICT_HDR_SPACE,7);
+ table = dict_mem_table_create("SYS_INDEXES",DICT_HDR_SPACE,7);
- dict_mem_table_add_col(table, (char *) "TABLE_ID", DATA_BINARY, 0,0,0);
- dict_mem_table_add_col(table, (char *) "ID", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, (char *) "NAME", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, (char *) "N_FIELDS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "TYPE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "SPACE", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "PAGE_NO", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0,0,0);
+ dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "N_FIELDS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "PAGE_NO", DATA_INT, 0, 4, 0);
/* The '+ 2' below comes from the 2 system fields */
- ut_ad(DICT_SYS_INDEXES_PAGE_NO_FIELD == 6 + 2);
- ut_ad(DICT_SYS_INDEXES_SPACE_NO_FIELD == 5 + 2);
+#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
+#error "DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2"
+#endif
+#if DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2
+#error "DICT_SYS_INDEXES_SPACE_NO_FIELD != 5 + 2"
+#endif
table->id = DICT_INDEXES_ID;
dict_table_add_to_cache(table);
dict_sys->sys_indexes = table;
- index = dict_mem_index_create((char *) "SYS_INDEXES",
- (char *) "CLUST_IND", DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
+ DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, (char *) "TABLE_ID", 0, 0);
- dict_mem_index_add_field(index, (char *) "ID", 0, 0);
+ dict_mem_index_add_field(index, "TABLE_ID", 0, 0);
+ dict_mem_index_add_field(index, "ID", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES,
MLOG_4BYTES, &mtr);
index->id = DICT_INDEXES_ID;
ut_a(dict_index_add_to_cache(table, index));
/*-------------------------*/
- table = dict_mem_table_create((char *) "SYS_FIELDS", DICT_HDR_SPACE,3);
+ table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE,3);
- dict_mem_table_add_col(table, (char *) "INDEX_ID", DATA_BINARY, 0,0,0);
- dict_mem_table_add_col(table, (char *) "POS", DATA_INT, 0, 4, 0);
- dict_mem_table_add_col(table, (char *) "COL_NAME", DATA_BINARY, 0,0,0);
+ dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0,0,0);
+ dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4, 0);
+ dict_mem_table_add_col(table, "COL_NAME", DATA_BINARY, 0,0,0);
table->id = DICT_FIELDS_ID;
dict_table_add_to_cache(table);
dict_sys->sys_fields = table;
- index = dict_mem_index_create((char *) "SYS_FIELDS",
- (char *) "CLUST_IND", DICT_HDR_SPACE,
- DICT_UNIQUE | DICT_CLUSTERED, 2);
+ index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
+ DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2);
- dict_mem_index_add_field(index, (char *) "INDEX_ID", 0, 0);
- dict_mem_index_add_field(index, (char *) "POS", 0, 0);
+ dict_mem_index_add_field(index, "INDEX_ID", 0, 0);
+ dict_mem_index_add_field(index, "POS", 0, 0);
index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS,
MLOG_4BYTES, &mtr);
@@ -419,6 +416,4 @@ dict_create(void)
dict_boot();
dict_insert_initial_data();
-
- sync_order_checks_on = TRUE;
}
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index 31a601e68b0..c887d821a3f 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -204,6 +204,8 @@ dict_build_table_def_step(
dict_table_t* table;
dict_table_t* cluster_table;
dtuple_t* row;
+ ulint error;
+ mtr_t mtr;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
@@ -232,6 +234,32 @@ dict_build_table_def_step(
table->mix_id = dict_hdr_get_new_id(DICT_HDR_MIX_ID);
}
+ if (srv_file_per_table) {
+ /* We create a new single-table tablespace for the table.
+ We initially let it be 4 pages:
+ - page 0 is the fsp header and an extent descriptor page,
+ - page 1 is an ibuf bitmap page,
+ - page 2 is the first inode page,
+ - page 3 will contain the root of the clustered index of the
+ table we create here. */
+
+ table->space = 0; /* reset to zero for the call below */
+
+ error = fil_create_new_single_table_tablespace(
+ &(table->space), table->name,
+ FIL_IBD_FILE_INITIAL_SIZE);
+ if (error != DB_SUCCESS) {
+
+ return(error);
+ }
+
+ mtr_start(&mtr);
+
+ fsp_header_init(table->space, FIL_IBD_FILE_INITIAL_SIZE, &mtr);
+
+ mtr_commit(&mtr);
+ }
+
row = dict_create_sys_tables_tuple(table, node->heap);
ins_node_set_new_row(node->tab_def, row);
@@ -425,8 +453,8 @@ dict_create_sys_fields_tuple(
}
/*********************************************************************
-Creates the tuple with which the index entry is searched for
-writing the index tree root page number, if such a tree is created. */
+Creates the tuple with which the index entry is searched for writing the index
+tree root page number, if such a tree is created. */
static
dtuple_t*
dict_create_search_tuple(
@@ -473,11 +501,14 @@ dict_build_index_def_step(
dict_table_t* table;
dict_index_t* index;
dtuple_t* row;
+ trx_t* trx;
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
+ trx = thr_get_trx(thr);
+
index = node->index;
table = dict_table_get_low(index->table_name);
@@ -486,7 +517,7 @@ dict_build_index_def_step(
return(DB_TABLE_NOT_FOUND);
}
- thr_get_trx(thr)->table_id = table->id;
+ trx->table_id = table->id;
node->table = table;
@@ -495,10 +526,10 @@ dict_build_index_def_step(
index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
- if (index->type & DICT_CLUSTERED) {
- /* Inherit the space from the table */
- index->space = table->space;
- }
+ /* Inherit the space id from the table; we store all indexes of a
+ table in the same tablespace */
+
+ index->space = table->space;
index->page_no = FIL_NULL;
@@ -581,6 +612,9 @@ dict_create_index_tree_step(
index->page_no = btr_create(index->type, index->space, index->id,
&mtr);
+ /* printf("Created a new index tree in space %lu root page %lu\n",
+ index->space, index->page_no); */
+
page_rec_write_index_page_no(btr_pcur_get_rec(&pcur),
DICT_SYS_INDEXES_PAGE_NO_FIELD,
index->page_no, &mtr);
@@ -631,7 +665,14 @@ dict_drop_index_tree(
ut_ad(len == 4);
space = mtr_read_ulint(ptr, MLOG_4BYTES, mtr);
-
+
+ if (!fil_tablespace_exists_in_mem(space)) {
+ /* It is a single table tablespace and the .ibd file is
+ missing: do nothing */
+
+ return;
+ }
+
/* We free all the pages but the root page first; this operation
may span several mini-transactions */
@@ -641,6 +682,8 @@ dict_drop_index_tree(
we write FIL_NULL to the appropriate field in the SYS_INDEXES
record: this mini-transaction marks the B-tree totally freed */
+ /* printf("Dropping index tree in space %lu root page %lu\n", space,
+ root_page_no); */
btr_free_root(space, root_page_no, mtr);
page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
@@ -965,12 +1008,12 @@ dict_create_or_check_foreign_constraint_tables(void)
que_t* graph;
ulint error;
trx_t* trx;
- char* str;
+ const char* str;
mutex_enter(&(dict_sys->mutex));
- table1 = dict_table_get_low((char *) "SYS_FOREIGN");
- table2 = dict_table_get_low((char *) "SYS_FOREIGN_COLS");
+ table1 = dict_table_get_low("SYS_FOREIGN");
+ table2 = dict_table_get_low("SYS_FOREIGN_COLS");
if (table1 && table2
&& UT_LIST_GET_LEN(table1->indexes) == 3
@@ -988,20 +1031,20 @@ dict_create_or_check_foreign_constraint_tables(void)
trx = trx_allocate_for_mysql();
- trx->op_info = (char *) "creating foreign key sys tables";
+ trx->op_info = "creating foreign key sys tables";
row_mysql_lock_data_dictionary(trx);
if (table1) {
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN table\n");
- row_drop_table_for_mysql((char*)"SYS_FOREIGN", trx, TRUE);
+ row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
}
if (table2) {
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN_COLS table\n");
- row_drop_table_for_mysql((char*)"SYS_FOREIGN_COLS", trx, TRUE);
+ row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
}
fprintf(stderr,
@@ -1011,7 +1054,7 @@ dict_create_or_check_foreign_constraint_tables(void)
there are 2 secondary indexes on SYS_FOREIGN, and they
are defined just like below */
- str = (char *)
+ str =
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
"BEGIN\n"
"CREATE TABLE\n"
@@ -1041,7 +1084,8 @@ dict_create_or_check_foreign_constraint_tables(void)
error = trx->error_state;
if (error != DB_SUCCESS) {
- fprintf(stderr, "InnoDB: error %lu in creation\n", error);
+ fprintf(stderr, "InnoDB: error %lu in creation\n",
+ (ulong) error);
ut_a(error == DB_OUT_OF_FILE_SPACE);
@@ -1050,15 +1094,15 @@ dict_create_or_check_foreign_constraint_tables(void)
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN tables\n");
- row_drop_table_for_mysql((char*)"SYS_FOREIGN", trx, TRUE);
- row_drop_table_for_mysql((char*)"SYS_FOREIGN_COLS", trx, TRUE);
+ row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
+ row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
error = DB_MUST_GET_MORE_FILE_SPACE;
}
que_graph_free(graph);
- trx->op_info = (char *) "";
+ trx->op_info = "";
row_mysql_unlock_data_dictionary(trx);
@@ -1121,7 +1165,7 @@ dict_create_add_foreigns_to_dictionary(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- if (NULL == dict_table_get_low((char *) "SYS_FOREIGN")) {
+ if (NULL == dict_table_get_low("SYS_FOREIGN")) {
fprintf(stderr,
"InnoDB: table SYS_FOREIGN not found from internal data dictionary\n");
@@ -1140,7 +1184,7 @@ loop:
ulint namelen = strlen(table->name);
char* id = mem_heap_alloc(foreign->heap, namelen + 20);
/* no overflow if number < 1e13 */
- sprintf(id, "%s_ibfk_%lu", table->name, number++);
+ sprintf(id, "%s_ibfk_%lu", table->name, (ulong) number++);
foreign->id = id;
}
@@ -1181,7 +1225,7 @@ loop:
*sqlend++ = '\'';
sqlend = ut_strcpyq(sqlend, '\'', foreign->id);
*sqlend++ = '\''; *sqlend++ = ',';
- sqlend += sprintf(sqlend, "%010lu", i);
+ sqlend += sprintf(sqlend, "%010lu", (ulong) i);
*sqlend++ = ','; *sqlend++ = '\'';
sqlend = ut_strcpyq(sqlend, '\'',
foreign->foreign_col_names[i]);
@@ -1223,9 +1267,9 @@ loop:
ut_print_timestamp(ef);
fputs(" Error in foreign key constraint creation for table ",
ef);
- ut_print_name(ef, table->name);
+ ut_print_name(ef, trx, table->name);
fputs(".\nA foreign key constraint of name ", ef);
- ut_print_name(ef, foreign->id);
+ ut_print_name(ef, trx, foreign->id);
fputs("\nalready exists."
" (Note that internally InnoDB adds 'databasename/'\n"
"in front of the user-defined constraint name).\n",
@@ -1239,13 +1283,13 @@ loop:
if (error != DB_SUCCESS) {
fprintf(stderr,
"InnoDB: Foreign key constraint creation failed:\n"
- "InnoDB: internal error number %lu\n", error);
+ "InnoDB: internal error number %lu\n", (ulong) error);
mutex_enter(&dict_foreign_err_mutex);
ut_print_timestamp(ef);
fputs(" Internal error in foreign key constraint creation"
" for table ", ef);
- ut_print_name(ef, table->name);
+ ut_print_name(ef, trx, table->name);
fputs(".\n"
"See the MySQL .err log in the datadir for more information.\n", ef);
mutex_exit(&dict_foreign_err_mutex);
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 4340934ab3d..aa7e90700f8 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -70,7 +70,7 @@ dict_col_reposition_in_cache(
/*=========================*/
dict_table_t* table, /* in: table */
dict_col_t* col, /* in: column */
- char* new_name); /* in: new table name */
+ const char* new_name); /* in: new table name */
/**************************************************************************
Removes a column from the data dictionary hash table. */
static
@@ -198,13 +198,14 @@ dict_tables_have_same_db(
/************************************************************************
Return the end of table name where we have removed dbname and '/'. */
static
-char*
+const char*
dict_remove_db_name(
/*================*/
- /* out: table name */
- char* name) /* in: table name in the form dbname '/' tablename */
+ /* out: table name */
+ const char* name) /* in: table name in the form
+ dbname '/' tablename */
{
- char* s;
+ const char* s;
s = strchr(name, '/');
ut_a(s);
if (s) s++;
@@ -309,7 +310,7 @@ dict_table_get_index_noninline(
/*===========================*/
/* out: index, NULL if does not exist */
dict_table_t* table, /* in: table */
- char* name) /* in: index name */
+ const char* name) /* in: index name */
{
return(dict_table_get_index(table, name));
}
@@ -604,7 +605,7 @@ dict_table_get_on_id(
}
/************************************************************************
-Looks for column n postion in the clustered index. */
+Looks for column n position in the clustered index. */
ulint
dict_table_get_nth_col_pos(
@@ -618,6 +619,44 @@ dict_table_get_nth_col_pos(
n));
}
+/************************************************************************
+Checks if a column is in the ordering columns of the clustered index of a
+table. Column prefixes are treated like whole columns. */
+
+ibool
+dict_table_col_in_clustered_key(
+/*============================*/
+ /* out: TRUE if the column, or its prefix, is
+ in the clustered key */
+ dict_table_t* table, /* in: table */
+ ulint n) /* in: column number */
+{
+ dict_index_t* index;
+ dict_field_t* field;
+ dict_col_t* col;
+ ulint pos;
+ ulint n_fields;
+
+ ut_ad(table);
+
+ col = dict_table_get_nth_col(table, n);
+
+ index = dict_table_get_first_index(table);
+
+ n_fields = dict_index_get_n_unique(index);
+
+ for (pos = 0; pos < n_fields; pos++) {
+ field = dict_index_get_nth_field(index, pos);
+
+ if (col == field->col) {
+
+ return(TRUE);
+ }
+ }
+
+ return(FALSE);
+}
+
/**************************************************************************
Inits the data dictionary module. */
@@ -660,9 +699,10 @@ directory dict_table_get_low is usually the appropriate function. */
dict_table_t*
dict_table_get(
/*===========*/
- /* out: table, NULL if does not exist */
- char* table_name, /* in: table name */
- trx_t* trx) /* in: transaction handle or NULL */
+ /* out: table, NULL if
+ does not exist */
+ const char* table_name, /* in: table name */
+ trx_t* trx) /* in: transaction handle or NULL */
{
dict_table_t* table;
@@ -689,9 +729,10 @@ Returns a table object and increments MySQL open handle count on the table. */
dict_table_t*
dict_table_get_and_increment_handle_count(
/*======================================*/
- /* out: table, NULL if does not exist */
- char* table_name, /* in: table name */
- trx_t* trx) /* in: transaction handle or NULL */
+ /* out: table, NULL if
+ does not exist */
+ const char* table_name, /* in: table name */
+ trx_t* trx) /* in: transaction handle or NULL */
{
dict_table_t* table;
@@ -709,7 +750,7 @@ dict_table_get_and_increment_handle_count(
mutex_exit(&(dict_sys->mutex));
if (table != NULL) {
- if (!table->stat_initialized) {
+ if (!table->stat_initialized && !table->ibd_file_missing) {
dict_update_statistics(table);
}
}
@@ -748,23 +789,33 @@ dict_table_add_to_cache(
The clustered index will not always physically contain all
system columns. */
- dict_mem_table_add_col(table, (char *) "DB_ROW_ID", DATA_SYS,
+ dict_mem_table_add_col(table, "DB_ROW_ID", DATA_SYS,
DATA_ROW_ID, 0, 0);
- ut_ad(DATA_ROW_ID == 0);
- dict_mem_table_add_col(table, (char *) "DB_TRX_ID", DATA_SYS,
+#if DATA_ROW_ID != 0
+#error "DATA_ROW_ID != 0"
+#endif
+ dict_mem_table_add_col(table, "DB_TRX_ID", DATA_SYS,
DATA_TRX_ID, 0, 0);
- ut_ad(DATA_TRX_ID == 1);
- dict_mem_table_add_col(table, (char *) "DB_ROLL_PTR", DATA_SYS,
- DATA_ROLL_PTR,
- 0, 0);
- ut_ad(DATA_ROLL_PTR == 2);
+#if DATA_TRX_ID != 1
+#error "DATA_TRX_ID != 1"
+#endif
+ dict_mem_table_add_col(table, "DB_ROLL_PTR", DATA_SYS,
+ DATA_ROLL_PTR, 0, 0);
+#if DATA_ROLL_PTR != 2
+#error "DATA_ROLL_PTR != 2"
+#endif
- dict_mem_table_add_col(table, (char *) "DB_MIX_ID", DATA_SYS,
+ dict_mem_table_add_col(table, "DB_MIX_ID", DATA_SYS,
DATA_MIX_ID, 0, 0);
- ut_ad(DATA_MIX_ID == 3);
- ut_ad(DATA_N_SYS_COLS == 4); /* This assert reminds that if a new
- system column is added to the program,
- it should be dealt with here */
+#if DATA_MIX_ID != 3
+#error "DATA_MIX_ID != 3"
+#endif
+
+ /* This check reminds that if a new system column is added to
+ the program, it should be dealt with here */
+#if DATA_N_SYS_COLS != 4
+#error "DATA_N_SYS_COLS != 4"
+#endif
/* Look for a table with the same name: error if such exists */
{
@@ -853,7 +904,7 @@ dict_table_rename_in_cache(
/*=======================*/
/* out: TRUE if success */
dict_table_t* table, /* in: table */
- char* new_name, /* in: new name */
+ const char* new_name, /* in: new name */
ibool rename_also_foreigns)/* in: in ALTER TABLE we want
to preserve the original table name
in constraints which reference it */
@@ -863,6 +914,7 @@ dict_table_rename_in_cache(
ulint fold;
ulint old_size;
char* old_name;
+ ibool success;
ulint i;
ut_ad(table);
@@ -880,6 +932,21 @@ dict_table_rename_in_cache(
HASH_SEARCH(name_hash, dict_sys->table_hash, fold, table2,
(ut_strcmp(table2->name, new_name) == 0));
if (table2) {
+ fprintf(stderr,
+"InnoDB: Error: dictionary cache already contains a table of name %s\n",
+ new_name);
+ return(FALSE);
+ }
+ }
+
+ /* If the table is stored in a single-table tablespace, rename the
+ .ibd file */
+
+ if (table->space != 0) {
+ success = fil_rename_tablespace(table->name, table->space,
+ new_name);
+ if (!success) {
+
return(FALSE);
}
}
@@ -901,7 +968,6 @@ dict_table_rename_in_cache(
/* Add table to hash table of tables */
HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold,
table);
-
dict_sys->size += (mem_heap_get_size(table->heap) - old_size);
/* Update the table_name field in indexes */
@@ -1047,6 +1113,33 @@ dict_table_rename_in_cache(
}
/**************************************************************************
+Change the id of a table object in the dictionary cache. This is used in
+DISCARD TABLESPACE. */
+
+void
+dict_table_change_id_in_cache(
+/*==========================*/
+ dict_table_t* table, /* in: table object already in cache */
+ dulint new_id) /* in: new id to set */
+{
+ ut_ad(table);
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+#endif /* UNIV_SYNC_DEBUG */
+ ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
+
+ /* Remove the table from the hash table of id's */
+
+ HASH_DELETE(dict_table_t, id_hash, dict_sys->table_id_hash,
+ ut_fold_dulint(table->id), table);
+ table->id = new_id;
+
+ /* Add the table back to the hash table */
+ HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash,
+ ut_fold_dulint(table->id), table);
+}
+
+/**************************************************************************
Removes a table object from the dictionary cache. */
void
@@ -1221,7 +1314,7 @@ dict_col_reposition_in_cache(
/*=========================*/
dict_table_t* table, /* in: table */
dict_col_t* col, /* in: column */
- char* new_name) /* in: new table name */
+ const char* new_name) /* in: new table name */
{
ulint fold;
@@ -1898,7 +1991,7 @@ dict_foreign_find(
/*==============*/
/* out: foreign constraint */
dict_table_t* table, /* in: table object */
- char* id) /* in: foreign constraint id */
+ const char* id) /* in: foreign constraint id */
{
dict_foreign_t* foreign;
@@ -1946,7 +2039,7 @@ dict_foreign_find_index(
column types must match */
{
dict_index_t* index;
- char* col_name;
+ const char* col_name;
ulint i;
index = dict_table_get_first_index(table);
@@ -1996,14 +2089,14 @@ Report an error in a foreign key definition. */
static
void
dict_foreign_error_report_low(
+/*==========================*/
FILE* file, /* in: output stream */
const char* name) /* in: table name */
{
rewind(file);
ut_print_timestamp(file);
- fputs(" Error in foreign key constraint of table ", file);
- ut_print_name(file, name);
- fputs(":\n", file);
+ fprintf(file, " Error in foreign key constraint of table %s:\n",
+ name);
}
/**************************************************************************
@@ -2011,6 +2104,7 @@ Report an error in a foreign key definition. */
static
void
dict_foreign_error_report(
+/*======================*/
FILE* file, /* in: output stream */
dict_foreign_t* fk, /* in: foreign key constraint */
const char* msg) /* in: the error message */
@@ -2019,10 +2113,10 @@ dict_foreign_error_report(
dict_foreign_error_report_low(file, fk->foreign_table_name);
fputs(msg, file);
fputs(" Constraint:\n", file);
- dict_print_info_on_foreign_key_in_create_format(file, fk);
+ dict_print_info_on_foreign_key_in_create_format(file, NULL, fk);
if (fk->foreign_index) {
fputs("\nThe index in the foreign key in table is ", file);
- ut_print_name(file, fk->foreign_index->name);
+ ut_print_name(file, NULL, fk->foreign_index->name);
fputs(
"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
"for correct foreign key definition.\n",
@@ -2293,7 +2387,7 @@ dict_scan_id(
*id = mem_heap_strdupl(heap, s, len);
} else {
/* no heap given: id will point to source string */
- *id = (char*) s;
+ *id = s;
}
return(ptr);
@@ -2492,14 +2586,14 @@ static
char*
dict_strip_comments(
/*================*/
- /* out, own: SQL string stripped from
- comments; the caller must free this
- with mem_free()! */
- char* sql_string) /* in: SQL string */
+ /* out, own: SQL string stripped from
+ comments; the caller must free this
+ with mem_free()! */
+ const char* sql_string) /* in: SQL string */
{
- char* str;
- char* sptr;
- char* ptr;
+ char* str;
+ const char* sptr;
+ char* ptr;
/* unclosed quote character (0 if none) */
char quote = 0;
@@ -2686,7 +2780,7 @@ dict_create_foreign_constraints_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- table = dict_table_get_low((char*) name);
+ table = dict_table_get_low(name);
if (table == NULL) {
mutex_enter(&dict_foreign_err_mutex);
@@ -2868,7 +2962,7 @@ col_loop1:
mutex_enter(&dict_foreign_err_mutex);
dict_foreign_error_report_low(ef, name);
fputs("There is no index in table ", ef);
- ut_print_name(ef, name);
+ ut_print_name(ef, NULL, name);
fprintf(ef, " where the columns appear\n"
"as the first columns. Constraint:\n%s\n"
"See http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
@@ -3185,16 +3279,19 @@ allowed to contain more fields than mentioned in the constraint. */
ulint
dict_create_foreign_constraints(
/*============================*/
- /* out: error code or DB_SUCCESS */
- trx_t* trx, /* in: transaction */
- char* sql_string, /* in: table create or ALTER TABLE
- statement where foreign keys are declared like:
- FOREIGN KEY (a, b) REFERENCES table2(c, d),
- table2 can be written also with the database
- name before it: test.table2; the default
- database is the database of parameter name */
- char* name) /* in: table full name in the normalized form
- database_name/table_name */
+ /* out: error code or DB_SUCCESS */
+ trx_t* trx, /* in: transaction */
+ const char* sql_string, /* in: table create statement where
+ foreign keys are declared like:
+ FOREIGN KEY (a, b) REFERENCES
+ table2(c, d), table2 can be written
+ also with the database
+ name before it: test.table2; the
+ default database id the database of
+ parameter name */
+ const char* name) /* in: table full name in the
+ normalized form
+ database_name/table_name */
{
char* str;
ulint err;
@@ -3310,12 +3407,12 @@ loop:
ut_print_timestamp(ef);
fputs(
" Error in dropping of a foreign key constraint of table ", ef);
- ut_print_name(ef, table->name);
+ ut_print_name(ef, NULL, table->name);
fputs(",\n"
"in SQL command\n", ef);
fputs(str, ef);
fputs("\nCannot find a constraint with the given id ", ef);
- ut_print_name(ef, id);
+ ut_print_name(ef, NULL, id);
fputs(".\n", ef);
mutex_exit(&dict_foreign_err_mutex);
@@ -3332,7 +3429,7 @@ syntax_error:
ut_print_timestamp(ef);
fputs(
" Syntax error in dropping of a foreign key constraint of table ", ef);
- ut_print_name(ef, table->name);
+ ut_print_name(ef, NULL, table->name);
fprintf(ef, ",\n"
"close to:\n%s\n in SQL command\n%s\n", ptr, str);
mutex_exit(&dict_foreign_err_mutex);
@@ -3428,7 +3525,7 @@ dict_tree_free(
/*===========*/
dict_tree_t* tree) /* in, own: index tree */
{
- ut_ad(tree);
+ ut_a(tree);
ut_ad(tree->magic_n == DICT_TREE_MAGIC_N);
rw_lock_free(&(tree->lock));
@@ -3443,7 +3540,8 @@ dict_tree_find_index_low(
/*=====================*/
/* out: index */
dict_tree_t* tree, /* in: index tree */
- rec_t* rec) /* in: record for which to find correct index */
+ rec_t* rec) /* in: record for which to find correct
+ index */
{
dict_index_t* index;
dict_table_t* table;
@@ -3481,7 +3579,8 @@ dict_tree_find_index(
/*=================*/
/* out: index */
dict_tree_t* tree, /* in: index tree */
- rec_t* rec) /* in: record for which to find correct index */
+ rec_t* rec) /* in: record for which to find correct
+ index */
{
dict_index_t* index;
@@ -3571,7 +3670,8 @@ dict_tree_build_node_ptr(
/*=====================*/
/* out, own: node pointer */
dict_tree_t* tree, /* in: index tree */
- rec_t* rec, /* in: record for which to build node pointer */
+ rec_t* rec, /* in: record for which to build node
+ pointer */
ulint page_no,/* in: page number to put in node pointer */
mem_heap_t* heap, /* in: memory heap where pointer created */
ulint level) /* in: level of rec in tree: 0 means leaf
@@ -3733,6 +3833,18 @@ dict_update_statistics_low(
ulint size;
ulint sum_of_index_sizes = 0;
+ if (table->ibd_file_missing) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: cannot calculate statistics for table %s\n"
+"InnoDB: because the .ibd file is missing. For help, please refer to\n"
+"InnoDB: "
+"http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n",
+ table->name);
+
+ return;
+ }
+
/* If we have set a high innodb_force_recovery level, do not calculate
statistics, as a badly corrupted index can cause a crash in it. */
@@ -3814,25 +3926,19 @@ dict_foreign_print_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- fputs(" FOREIGN KEY CONSTRAINT ", stderr);
- ut_print_name(stderr, foreign->id);
- fputs(": ", stderr);
- ut_print_name(stderr, foreign->foreign_table_name);
- fputs(" (", stderr);
+ fprintf(stderr, " FOREIGN KEY CONSTRAINT %s: %s (",
+ foreign->id, foreign->foreign_table_name);
for (i = 0; i < foreign->n_fields; i++) {
- putc(' ', stderr);
- ut_print_name(stderr, foreign->foreign_col_names[i]);
+ fprintf(stderr, " %s", foreign->foreign_col_names[i]);
}
- fputs(" )\n"
- " REFERENCES ", stderr);
- ut_print_name(stderr, foreign->referenced_table_name);
- fputs(" (", stderr);
+ fprintf(stderr, " )\n"
+ " REFERENCES %s (",
+ foreign->referenced_table_name);
for (i = 0; i < foreign->n_fields; i++) {
- putc(' ', stderr);
- ut_print_name(stderr, foreign->referenced_col_names[i]);
+ fprintf(stderr, " %s", foreign->referenced_col_names[i]);
}
fputs(" )\n", stderr);
@@ -3857,7 +3963,7 @@ Prints a table data when we know the table name. */
void
dict_table_print_by_name(
/*=====================*/
- char* name)
+ const char* name)
{
dict_table_t* table;
@@ -3889,16 +3995,16 @@ dict_table_print_low(
dict_update_statistics_low(table, TRUE);
- fputs("--------------------------------------\n"
- "TABLE: name ", stderr);
- ut_print_name(stderr, table->name);
fprintf(stderr,
- ", id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n"
- " COLUMNS: ",
- ut_dulint_get_high(table->id),
- ut_dulint_get_low(table->id),
- table->n_cols, UT_LIST_GET_LEN(table->indexes),
- (ulint)table->stat_n_rows);
+"--------------------------------------\n"
+"TABLE: name %s, id %lu %lu, columns %lu, indexes %lu, appr.rows %lu\n"
+" COLUMNS: ",
+ table->name,
+ (ulong) ut_dulint_get_high(table->id),
+ (ulong) ut_dulint_get_low(table->id),
+ (ulong) table->n_cols,
+ (ulong) UT_LIST_GET_LEN(table->indexes),
+ (ulong) table->stat_n_rows);
for (i = 0; i < table->n_cols - 1; i++) {
dict_col_print_low(dict_table_get_nth_col(table, i));
@@ -3944,8 +4050,7 @@ dict_col_print_low(
#endif /* UNIV_SYNC_DEBUG */
type = dict_col_get_type(col);
- ut_print_name(stderr, col->name);
- fputs(": ", stderr);
+ fprintf(stderr, "%s: ", col->name);
dtype_print(type);
}
@@ -3975,21 +4080,20 @@ dict_index_print_low(
n_vals = index->stat_n_diff_key_vals[1];
}
- fputs(" INDEX: ", stderr);
- dict_index_name_print(stderr, index);
fprintf(stderr,
- ", id %lu %lu, fields %lu/%lu, type %lu\n"
+ " INDEX: name %s, id %lu %lu, fields %lu/%lu, type %lu\n"
" root page %lu, appr.key vals %lu,"
" leaf pages %lu, size pages %lu\n"
" FIELDS: ",
- ut_dulint_get_high(tree->id),
- ut_dulint_get_low(tree->id),
- index->n_user_defined_cols,
- index->n_fields, index->type,
- tree->page,
- (ulint)n_vals,
- index->stat_n_leaf_pages,
- index->stat_index_size);
+ index->name,
+ (ulong) ut_dulint_get_high(tree->id),
+ (ulong) ut_dulint_get_low(tree->id),
+ (ulong) index->n_user_defined_cols,
+ (ulong) index->n_fields, (ulong) index->type,
+ (ulong) tree->page,
+ (ulong) n_vals,
+ (ulong) index->stat_n_leaf_pages,
+ (ulong) index->stat_index_size);
for (i = 0; i < index->n_fields; i++) {
dict_field_print_low(dict_index_get_nth_field(index, i));
@@ -4013,11 +4117,10 @@ dict_field_print_low(
#ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- putc(' ', stderr);
- ut_print_name(stderr, field->name);
+ fprintf(stderr, " %s", field->name);
if (field->prefix_len != 0) {
- fprintf(stderr, "(%lu)", field->prefix_len);
+ fprintf(stderr, "(%lu)", (ulong) field->prefix_len);
}
}
@@ -4029,6 +4132,7 @@ void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
FILE* file, /* in: file where to print */
+ trx_t* trx, /* in: transaction */
dict_foreign_t* foreign)/* in: foreign key constraint */
{
const char* stripped_id;
@@ -4043,11 +4147,11 @@ dict_print_info_on_foreign_key_in_create_format(
}
fputs(",\n CONSTRAINT ", file);
- ut_print_name(file, stripped_id);
+ ut_print_name(file, trx, stripped_id);
fputs(" FOREIGN KEY (", file);
for (i = 0;;) {
- ut_print_name(file, foreign->foreign_col_names[i]);
+ ut_print_name(file, trx, foreign->foreign_col_names[i]);
if (++i < foreign->n_fields) {
fputs(", ", file);
} else {
@@ -4060,7 +4164,7 @@ dict_print_info_on_foreign_key_in_create_format(
if (dict_tables_have_same_db(foreign->foreign_table_name,
foreign->referenced_table_name)) {
/* Do not print the database name of the referenced table */
- ut_print_name(file, dict_remove_db_name(
+ ut_print_name(file, trx, dict_remove_db_name(
foreign->referenced_table_name));
} else {
/* Look for the '/' in the table name */
@@ -4070,16 +4174,17 @@ dict_print_info_on_foreign_key_in_create_format(
i++;
}
- ut_print_namel(file, foreign->referenced_table_name, i);
+ ut_print_namel(file, trx, foreign->referenced_table_name, i);
putc('.', file);
- ut_print_name(file, foreign->referenced_table_name + i + 1);
+ ut_print_name(file, trx,
+ foreign->referenced_table_name + i + 1);
}
putc(' ', file);
putc('(', file);
for (i = 0;;) {
- ut_print_name(file, foreign->referenced_col_names[i]);
+ ut_print_name(file, trx, foreign->referenced_col_names[i]);
if (++i < foreign->n_fields) {
fputs(", ", file);
} else {
@@ -4125,6 +4230,7 @@ dict_print_info_on_foreign_keys(
a CREATE TABLE, otherwise in the format
of SHOW TABLE STATUS */
FILE* file, /* in: file where to print */
+ trx_t* trx, /* in: transaction */
dict_table_t* table) /* in: table */
{
dict_foreign_t* foreign;
@@ -4142,7 +4248,7 @@ dict_print_info_on_foreign_keys(
while (foreign != NULL) {
if (create_table_format) {
dict_print_info_on_foreign_key_in_create_format(
- file, foreign);
+ file, trx, foreign);
} else {
ulint i;
fputs("; (", file);
@@ -4152,19 +4258,20 @@ dict_print_info_on_foreign_keys(
putc(' ', file);
}
- ut_print_name(file,
+ ut_print_name(file, trx,
foreign->foreign_col_names[i]);
}
fputs(") REFER ", file);
- ut_print_name(file, foreign->referenced_table_name);
+ ut_print_name(file, trx,
+ foreign->referenced_table_name);
putc('(', file);
for (i = 0; i < foreign->n_fields; i++) {
if (i) {
putc(' ', file);
}
- ut_print_name(file,
+ ut_print_name(file, trx,
foreign->referenced_col_names[i]);
}
@@ -4207,10 +4314,11 @@ void
dict_index_name_print(
/*==================*/
FILE* file, /* in: output stream */
+ trx_t* trx, /* in: transaction */
const dict_index_t* index) /* in: index to print */
{
fputs("index ", file);
- ut_print_name(file, index->name);
+ ut_print_name(file, trx, index->name);
fputs(" of table ", file);
- ut_print_name(file, index->table_name);
+ ut_print_name(file, trx, index->table_name);
}
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index 6a4d4c86824..9293b117899 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -19,6 +19,7 @@ Created 4/24/1996 Heikki Tuuri
#include "mach0data.h"
#include "dict0dict.h"
#include "dict0boot.h"
+#include "srv0start.h"
/************************************************************************
Finds the first table name in the given database. */
@@ -26,9 +27,10 @@ Finds the first table name in the given database. */
char*
dict_get_first_table_name_in_db(
/*============================*/
- /* out, own: table name, NULL if does not exist;
- the caller must free the memory in the string! */
- char* name) /* in: database name which ends to '/' */
+ /* out, own: table name, NULL if
+ does not exist; the caller must
+ free the memory in the string! */
+ const char* name) /* in: database name which ends in '/' */
{
dict_table_t* sys_tables;
btr_pcur_t pcur;
@@ -49,7 +51,7 @@ dict_get_first_table_name_in_db(
mtr_start(&mtr);
- sys_tables = dict_table_get_low((char *) "SYS_TABLES");
+ sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
tuple = dtuple_create(heap, 1);
@@ -125,7 +127,7 @@ dict_print(void)
mtr_start(&mtr);
- sys_tables = dict_table_get_low((char *) "SYS_TABLES");
+ sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
@@ -163,7 +165,7 @@ loop:
if (table == NULL) {
fputs("InnoDB: Failed to load table ", stderr);
- ut_print_namel(stderr, field, len);
+ ut_print_namel(stderr, NULL, field, len);
putc('\n', stderr);
} else {
/* The table definition was corrupt if there
@@ -185,6 +187,99 @@ loop:
}
/************************************************************************
+In a crash recovery we already have all the tablespace objects created.
+This function compares the space id information in the InnoDB data dictionary
+to what we already read with fil_load_single_table_tablespaces().
+In a normal startup we just scan the biggest space id, and store it to
+fil_system. */
+
+void
+dict_check_tablespaces_or_store_max_id(
+/*===================================*/
+ ibool in_crash_recovery) /* in: are we doing a crash recovery */
+{
+ dict_table_t* sys_tables;
+ dict_index_t* sys_index;
+ btr_pcur_t pcur;
+ rec_t* rec;
+ byte* field;
+ ulint len;
+ ulint space_id;
+ ulint max_space_id = 0;
+ mtr_t mtr;
+
+ mutex_enter(&(dict_sys->mutex));
+
+ mtr_start(&mtr);
+
+ sys_tables = dict_table_get_low("SYS_TABLES");
+ sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
+
+ btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
+ TRUE, &mtr);
+loop:
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+
+ rec = btr_pcur_get_rec(&pcur);
+
+ if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
+ /* end of index */
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+
+ /* We must make the tablespace cache aware of the biggest
+ known space id */
+
+ /* printf("Biggest space id in data dictionary %lu\n",
+ max_space_id); */
+ fil_set_max_space_id_if_bigger(max_space_id);
+
+ mutex_exit(&(dict_sys->mutex));
+
+ return;
+ }
+
+ field = rec_get_nth_field(rec, 0, &len);
+
+ if (!rec_get_deleted_flag(rec)) {
+
+ /* We found one */
+
+ char* name = mem_strdupl(field, len);
+
+ field = rec_get_nth_field(rec, 9, &len);
+ ut_a(len == 4);
+
+ space_id = mach_read_from_4(field);
+
+ btr_pcur_store_position(&pcur, &mtr);
+
+ mtr_commit(&mtr);
+
+ if (space_id != 0 && in_crash_recovery) {
+ /* Check that the tablespace (the .ibd file) really
+ exists; print a warning to the .err log if not */
+
+ fil_space_for_table_exists_in_mem(space_id, name,
+ TRUE, TRUE);
+ }
+
+ mem_free(name);
+
+ if (space_id > max_space_id) {
+ max_space_id = space_id;
+ }
+
+ mtr_start(&mtr);
+
+ btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr);
+ }
+
+ goto loop;
+}
+
+/************************************************************************
Loads definitions for table columns. */
static
void
@@ -216,7 +311,7 @@ dict_load_columns(
mtr_start(&mtr);
- sys_columns = dict_table_get_low((char*) "SYS_COLUMNS");
+ sys_columns = dict_table_get_low("SYS_COLUMNS");
sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
tuple = dtuple_create(heap, 1);
@@ -246,7 +341,7 @@ dict_load_columns(
ut_ad(len == 4);
ut_a(i == mach_read_from_4(field));
- ut_a(0 == ut_strcmp((char*) "NAME",
+ ut_a(0 == ut_strcmp("NAME",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_columns), 4))->name));
@@ -260,10 +355,19 @@ dict_load_columns(
field = rec_get_nth_field(rec, 6, &len);
prtype = mach_read_from_4(field);
+ if (dtype_is_non_binary_string_type(mtype, prtype)
+ && dtype_get_charset_coll(prtype) == 0) {
+ /* This is a non-binary string type, and the table
+ was created with < 4.1.2. Use the default charset. */
+
+ prtype = dtype_form_prtype(prtype,
+ data_mysql_default_charset_coll);
+ }
+
field = rec_get_nth_field(rec, 7, &len);
col_len = mach_read_from_4(field);
- ut_a(0 == ut_strcmp((char*) "PREC",
+ ut_a(0 == ut_strcmp("PREC",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_columns), 8))->name));
@@ -285,18 +389,16 @@ Report that an index field or index for a table has been delete marked. */
static
void
dict_load_report_deleted_index(
- char* name, /* in: table name */
- ulint field) /* in: index field, or ULINT_UNDEFINED */
+/*===========================*/
+ const char* name, /* in: table name */
+ ulint field) /* in: index field, or ULINT_UNDEFINED */
{
- fputs("InnoDB: Error: data dictionary entry"
- " for table ", stderr);
- ut_print_name(stderr, name);
- fputs(" is corrupt!\n", stderr);
+ fprintf(stderr, "InnoDB: Error: data dictionary entry"
+ " for table %s is corrupt!\n", name);
if (field != ULINT_UNDEFINED) {
fprintf(stderr,
"InnoDB: Index field %lu is delete marked.\n", field);
- }
- else {
+ } else {
fputs("InnoDB: An index is delete marked.\n", stderr);
}
}
@@ -333,7 +435,7 @@ dict_load_fields(
mtr_start(&mtr);
- sys_fields = dict_table_get_low((char*) "SYS_FIELDS");
+ sys_fields = dict_table_get_low("SYS_FIELDS");
sys_index = UT_LIST_GET_FIRST(sys_fields->indexes);
tuple = dtuple_create(heap, 1);
@@ -373,18 +475,18 @@ dict_load_fields(
pos_and_prefix_len = mach_read_from_4(field);
- ut_a((pos_and_prefix_len & 0xFFFF) == i
- || (pos_and_prefix_len & 0xFFFF0000) == (i << 16));
+ ut_a((pos_and_prefix_len & 0xFFFFUL) == i
+ || (pos_and_prefix_len & 0xFFFF0000UL) == (i << 16));
if ((i == 0 && pos_and_prefix_len > 0)
- || (pos_and_prefix_len & 0xFFFF0000) > 0) {
+ || (pos_and_prefix_len & 0xFFFF0000UL) > 0) {
- prefix_len = pos_and_prefix_len & 0xFFFF;
+ prefix_len = pos_and_prefix_len & 0xFFFFUL;
} else {
prefix_len = 0;
}
- ut_a(0 == ut_strcmp((char*) "COL_NAME",
+ ut_a(0 == ut_strcmp("COL_NAME",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_fields), 4))->name));
@@ -446,7 +548,7 @@ dict_load_indexes(
mtr_start(&mtr);
- sys_indexes = dict_table_get_low((char*) "SYS_INDEXES");
+ sys_indexes = dict_table_get_low("SYS_INDEXES");
sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes);
tuple = dtuple_create(heap, 1);
@@ -489,7 +591,7 @@ dict_load_indexes(
ut_ad(len == 8);
id = mach_read_from_8(field);
- ut_a(0 == ut_strcmp((char*)"NAME",
+ ut_a(0 == ut_strcmp("NAME",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_indexes), 4))->name));
@@ -506,7 +608,7 @@ dict_load_indexes(
field = rec_get_nth_field(rec, 7, &len);
space = mach_read_from_4(field);
- ut_a(0 == ut_strcmp((char*) "PAGE_NO",
+ ut_a(0 == ut_strcmp("PAGE_NO",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_indexes), 8))->name));
@@ -516,12 +618,10 @@ dict_load_indexes(
if (page_no == FIL_NULL) {
- fputs("InnoDB: Error: trying to load index ", stderr);
- ut_print_name(stderr, name_buf);
- fputs(" for table ", stderr);
- ut_print_name(stderr, table->name);
- fputs("\n"
- "InnoDB: but the index tree has been freed!\n", stderr);
+ fprintf(stderr,
+ "InnoDB: Error: trying to load index %s for table %s\n"
+ "InnoDB: but the index tree has been freed!\n",
+ name_buf, table->name);
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -532,12 +632,10 @@ dict_load_indexes(
if ((type & DICT_CLUSTERED) == 0
&& NULL == dict_table_get_first_index(table)) {
- fputs("InnoDB: Error: trying to load index ", stderr);
- ut_print_namel(stderr, name_buf, name_len);
- fputs(" for table ", stderr);
- ut_print_name(stderr, table->name);
- fputs("\n"
- "InnoDB: but the first index is not clustered!\n", stderr);
+ fprintf(stderr,
+ "InnoDB: Error: trying to load index %s for table %s\n"
+ "InnoDB: but the first index is not clustered!\n",
+ name_buf, table->name);
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -549,11 +647,11 @@ dict_load_indexes(
&& ((type & DICT_CLUSTERED)
|| ((table == dict_sys->sys_tables)
&& (name_len == (sizeof "ID_IND") - 1)
- && (0 == ut_memcmp(name_buf, (char*)"ID_IND",
+ && (0 == ut_memcmp(name_buf, "ID_IND",
name_len))))) {
- /* The index was created in memory already in
- booting */
+ /* The index was created in memory already at booting
+ of the database server */
} else {
index = dict_mem_index_create(table->name, name_buf,
space, type, n_fields);
@@ -584,9 +682,15 @@ dictionary cache. */
dict_table_t*
dict_load_table(
/*============*/
- /* out: table, NULL if does not exist */
- char* name) /* in: table name */
+ /* out: table, NULL if does not exist;
+ if the table is stored in an .ibd file,
+ but the file does not exist,
+ then we set the ibd_file_missing flag TRUE
+ in the table object we return */
+ const char* name) /* in: table name in the
+ databasename/tablename format */
{
+ ibool ibd_file_missing = FALSE;
dict_table_t* table;
dict_table_t* sys_tables;
btr_pcur_t pcur;
@@ -610,7 +714,7 @@ dict_load_table(
mtr_start(&mtr);
- sys_tables = dict_table_get_low((char *) "SYS_TABLES");
+ sys_tables = dict_table_get_low("SYS_TABLES");
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
tuple = dtuple_create(heap, 1);
@@ -646,7 +750,7 @@ dict_load_table(
return(NULL);
}
- ut_a(0 == ut_strcmp((char *) "SPACE",
+ ut_a(0 == ut_strcmp("SPACE",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 9))->name));
@@ -654,7 +758,24 @@ dict_load_table(
field = rec_get_nth_field(rec, 9, &len);
space = mach_read_from_4(field);
- ut_a(0 == ut_strcmp((char *) "N_COLS",
+ /* Check if the tablespace exists and has the right name */
+ if (space != 0) {
+ if (fil_space_for_table_exists_in_mem(space, name, FALSE,
+ FALSE)) {
+ /* Ok; (if we did a crash recovery then the tablespace
+ can already be in the memory cache) */
+ } else {
+ /* Try to open the tablespace */
+ if (!fil_open_single_table_tablespace(space, name)) {
+ /* We failed to find a sensible tablespace
+ file */
+
+ ibd_file_missing = TRUE;
+ }
+ }
+ }
+
+ ut_a(0 == ut_strcmp("N_COLS",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 4))->name));
@@ -664,7 +785,9 @@ dict_load_table(
table = dict_mem_table_create(name, space, n_cols);
- ut_a(0 == ut_strcmp((char *) "ID",
+ table->ibd_file_missing = ibd_file_missing;
+
+ ut_a(0 == ut_strcmp("ID",
dict_field_get_col(
dict_index_get_nth_field(
dict_table_get_first_index(sys_tables), 3))->name));
@@ -853,7 +976,7 @@ static
void
dict_load_foreign_cols(
/*===================*/
- char* id, /* in: foreign constraint id as a null-
+ const char* id, /* in: foreign constraint id as a null-
terminated string */
dict_foreign_t* foreign)/* in: foreign constraint object */
{
@@ -879,7 +1002,7 @@ dict_load_foreign_cols(
foreign->n_fields * sizeof(void*));
mtr_start(&mtr);
- sys_foreign_cols = dict_table_get_low((char *) "SYS_FOREIGN_COLS");
+ sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS");
sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes);
tuple = dtuple_create(foreign->heap, 1);
@@ -926,9 +1049,9 @@ static
ulint
dict_load_foreign(
/*==============*/
- /* out: DB_SUCCESS or error code */
- char* id) /* in: foreign constraint id as a null-terminated
- string */
+ /* out: DB_SUCCESS or error code */
+ const char* id) /* in: foreign constraint id as a
+ null-terminated string */
{
dict_foreign_t* foreign;
dict_table_t* sys_foreign;
@@ -951,7 +1074,7 @@ dict_load_foreign(
mtr_start(&mtr);
- sys_foreign = dict_table_get_low((char *) "SYS_FOREIGN");
+ sys_foreign = dict_table_get_low("SYS_FOREIGN");
sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes);
tuple = dtuple_create(heap2, 1);
@@ -968,10 +1091,9 @@ dict_load_foreign(
|| rec_get_deleted_flag(rec)) {
/* Not found */
- fputs("InnoDB: Error A: cannot load foreign constraint ",
- stderr);
- ut_print_name(stderr, id);
- putc('\n', stderr);
+ fprintf(stderr,
+ "InnoDB: Error A: cannot load foreign constraint %s\n",
+ id);
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -985,10 +1107,9 @@ dict_load_foreign(
/* Check if the id in record is the searched one */
if (len != ut_strlen(id) || ut_memcmp(id, field, len) != 0) {
- fputs("InnoDB: Error B: cannot load foreign constraint ",
- stderr);
- ut_print_name(stderr, id);
- putc('\n', stderr);
+ fprintf(stderr,
+ "InnoDB: Error B: cannot load foreign constraint %s\n",
+ id);
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -1011,7 +1132,7 @@ dict_load_foreign(
/* We store the type to the bits 24-31 of n_fields */
foreign->type = foreign->n_fields >> 24;
- foreign->n_fields = foreign->n_fields & 0xFFFFFF;
+ foreign->n_fields = foreign->n_fields & 0xFFFFFFUL;
foreign->id = mem_heap_strdup(foreign->heap, id);
@@ -1057,8 +1178,8 @@ already in the dictionary cache. */
ulint
dict_load_foreigns(
/*===============*/
- /* out: DB_SUCCESS or error code */
- char* table_name) /* in: table name */
+ /* out: DB_SUCCESS or error code */
+ const char* table_name) /* in: table name */
{
btr_pcur_t pcur;
mem_heap_t* heap;
@@ -1077,7 +1198,7 @@ dict_load_foreigns(
ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */
- sys_foreign = dict_table_get_low((char *) "SYS_FOREIGN");
+ sys_foreign = dict_table_get_low("SYS_FOREIGN");
if (sys_foreign == NULL) {
/* No foreign keys defined yet in this database */
diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c
index 85bd79a72f5..8f05475df47 100644
--- a/innobase/dict/dict0mem.c
+++ b/innobase/dict/dict0mem.c
@@ -30,15 +30,14 @@ dict_table_t*
dict_mem_table_create(
/*==================*/
/* out, own: table object */
- char* name, /* in: table name */
- ulint space, /* in: space where the clustered index of
+ const char* name, /* in: table name */
+ ulint space, /* in: space where the clustered index of
the table is placed; this parameter is
ignored if the table is made a member of
a cluster */
- ulint n_cols) /* in: number of columns */
+ ulint n_cols) /* in: number of columns */
{
dict_table_t* table;
- char* str;
mem_heap_t* heap;
ut_ad(name);
@@ -48,12 +47,12 @@ dict_mem_table_create(
table = mem_heap_alloc(heap, sizeof(dict_table_t));
table->heap = heap;
-
- str = mem_heap_strdup(heap, name);
table->type = DICT_TABLE_ORDINARY;
- table->name = str;
+ table->name = mem_heap_strdup(heap, name);
table->space = space;
+ table->ibd_file_missing = FALSE;
+ table->tablespace_discarded = FALSE;
table->n_def = 0;
table->n_cols = n_cols + DATA_N_SYS_COLS;
table->mem_fix = 0;
@@ -101,11 +100,11 @@ dict_table_t*
dict_mem_cluster_create(
/*====================*/
/* out, own: cluster object */
- char* name, /* in: cluster name */
- ulint space, /* in: space where the clustered indexes
+ const char* name, /* in: cluster name */
+ ulint space, /* in: space where the clustered indexes
of the member tables are placed */
- ulint n_cols, /* in: number of columns */
- ulint mix_len) /* in: length of the common key prefix in the
+ ulint n_cols, /* in: number of columns */
+ ulint mix_len)/* in: length of the common key prefix in the
cluster */
{
dict_table_t* cluster;
@@ -125,7 +124,7 @@ void
dict_mem_table_make_cluster_member(
/*===============================*/
dict_table_t* table, /* in: non-published table */
- char* cluster_name) /* in: cluster name */
+ const char* cluster_name) /* in: cluster name */
{
table->type = DICT_TABLE_CLUSTER_MEMBER;
table->cluster_name = cluster_name;
@@ -138,7 +137,7 @@ void
dict_mem_table_add_col(
/*===================*/
dict_table_t* table, /* in: table */
- char* name, /* in: column name */
+ const char* name, /* in: column name */
ulint mtype, /* in: main datatype */
ulint prtype, /* in: precise type */
ulint len, /* in: length */
@@ -172,14 +171,15 @@ Creates an index memory object. */
dict_index_t*
dict_mem_index_create(
/*==================*/
- /* out, own: index object */
- char* table_name, /* in: table name */
- char* index_name, /* in: index name */
- ulint space, /* in: space where the index tree is placed,
- ignored if the index is of the clustered
- type */
- ulint type, /* in: DICT_UNIQUE, DICT_CLUSTERED, ... ORed */
- ulint n_fields) /* in: number of fields */
+ /* out, own: index object */
+ const char* table_name, /* in: table name */
+ const char* index_name, /* in: index name */
+ ulint space, /* in: space where the index tree is
+ placed, ignored if the index is of
+ the clustered type */
+ ulint type, /* in: DICT_UNIQUE,
+ DICT_CLUSTERED, ... ORed */
+ ulint n_fields) /* in: number of fields */
{
dict_index_t* index;
mem_heap_t* heap;
@@ -255,7 +255,7 @@ void
dict_mem_index_add_field(
/*=====================*/
dict_index_t* index, /* in: index */
- char* name, /* in: column name */
+ const char* name, /* in: column name */
ulint order, /* in: order criterion; 0 means an
ascending order */
ulint prefix_len) /* in: 0 or the column prefix length