diff options
Diffstat (limited to 'innobase/dict')
-rw-r--r-- | innobase/dict/dict0boot.c | 115 | ||||
-rw-r--r-- | innobase/dict/dict0crea.c | 96 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 338 | ||||
-rw-r--r-- | innobase/dict/dict0load.c | 251 | ||||
-rw-r--r-- | innobase/dict/dict0mem.c | 44 |
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 |