summaryrefslogtreecommitdiff
path: root/innobase/dict/dict0load.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/dict/dict0load.c')
-rw-r--r--innobase/dict/dict0load.c711
1 files changed, 362 insertions, 349 deletions
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index 221a6c7dabb..e9caa37fecc 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -21,33 +21,6 @@ Created 4/24/1996 Heikki Tuuri
#include "dict0boot.h"
/************************************************************************
-Loads definitions for table columns. */
-static
-void
-dict_load_columns(
-/*==============*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap); /* in: memory heap for temporary storage */
-/************************************************************************
-Loads definitions for table indexes. */
-static
-void
-dict_load_indexes(
-/*==============*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap); /* in: memory heap for temporary storage */
-/************************************************************************
-Loads definitions for index fields. */
-static
-void
-dict_load_fields(
-/*=============*/
- dict_table_t* table, /* in: table */
- dict_index_t* index, /* in: index whose fields to load */
- mem_heap_t* heap); /* in: memory heap for temporary storage */
-
-
-/************************************************************************
Finds the first table name in the given database. */
char*
@@ -194,7 +167,12 @@ loop:
fprintf(stderr, "InnoDB: Failed to load table %s\n",
table_name);
} else {
- dict_update_statistics_low(table, TRUE);
+ /* The table definition was corrupt if there
+ is no index */
+
+ if (dict_table_get_first_index(table)) {
+ dict_update_statistics_low(table, TRUE);
+ }
dict_table_print_low(table);
}
@@ -208,6 +186,361 @@ loop:
}
/************************************************************************
+Loads definitions for table columns. */
+static
+void
+dict_load_columns(
+/*==============*/
+ dict_table_t* table, /* in: table */
+ mem_heap_t* heap) /* in: memory heap for temporary storage */
+{
+ dict_table_t* sys_columns;
+ dict_index_t* sys_index;
+ btr_pcur_t pcur;
+ dtuple_t* tuple;
+ dfield_t* dfield;
+ rec_t* rec;
+ byte* field;
+ ulint len;
+ byte* buf;
+ char* name_buf;
+ char* name;
+ ulint mtype;
+ ulint prtype;
+ ulint col_len;
+ ulint prec;
+ ulint i;
+ mtr_t mtr;
+
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+
+ mtr_start(&mtr);
+
+ sys_columns = dict_table_get_low((char*) "SYS_COLUMNS");
+ sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
+
+ tuple = dtuple_create(heap, 1);
+ dfield = dtuple_get_nth_field(tuple, 0);
+
+ buf = mem_heap_alloc(heap, 8);
+ mach_write_to_8(buf, table->id);
+
+ dfield_set_data(dfield, buf, 8);
+ dict_index_copy_types(tuple, sys_index, 1);
+
+ btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
+ BTR_SEARCH_LEAF, &pcur, &mtr);
+ for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) {
+
+ rec = btr_pcur_get_rec(&pcur);
+
+ ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
+
+ ut_a(!rec_get_deleted_flag(rec));
+
+ field = rec_get_nth_field(rec, 0, &len);
+ ut_ad(len == 8);
+ ut_a(ut_dulint_cmp(table->id, mach_read_from_8(field)) == 0);
+
+ field = rec_get_nth_field(rec, 1, &len);
+ ut_ad(len == 4);
+ ut_a(i == mach_read_from_4(field));
+
+ ut_a(0 == ut_strcmp((char*) "NAME",
+ dict_field_get_col(
+ dict_index_get_nth_field(
+ dict_table_get_first_index(sys_columns), 4))->name));
+
+ field = rec_get_nth_field(rec, 4, &len);
+
+ name_buf = mem_heap_alloc(heap, len + 1);
+ ut_memcpy(name_buf, field, len);
+ name_buf[len] = '\0';
+
+ name = name_buf;
+
+ field = rec_get_nth_field(rec, 5, &len);
+ mtype = mach_read_from_4(field);
+
+ field = rec_get_nth_field(rec, 6, &len);
+ prtype = mach_read_from_4(field);
+
+ field = rec_get_nth_field(rec, 7, &len);
+ col_len = mach_read_from_4(field);
+
+ ut_a(0 == ut_strcmp((char*) "PREC",
+ dict_field_get_col(
+ dict_index_get_nth_field(
+ dict_table_get_first_index(sys_columns), 8))->name));
+
+ field = rec_get_nth_field(rec, 8, &len);
+ prec = mach_read_from_4(field);
+
+ dict_mem_table_add_col(table, name, mtype, prtype, col_len,
+ prec);
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+ }
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+}
+
+/************************************************************************
+Loads definitions for index fields. */
+static
+void
+dict_load_fields(
+/*=============*/
+ dict_table_t* table, /* in: table */
+ dict_index_t* index, /* in: index whose fields to load */
+ mem_heap_t* heap) /* in: memory heap for temporary storage */
+{
+ dict_table_t* sys_fields;
+ dict_index_t* sys_index;
+ btr_pcur_t pcur;
+ dtuple_t* tuple;
+ dfield_t* dfield;
+ char* col_name;
+ rec_t* rec;
+ byte* field;
+ ulint len;
+ byte* buf;
+ ulint i;
+ mtr_t mtr;
+
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+
+ UT_NOT_USED(table);
+
+ mtr_start(&mtr);
+
+ sys_fields = dict_table_get_low((char*) "SYS_FIELDS");
+ sys_index = UT_LIST_GET_FIRST(sys_fields->indexes);
+
+ tuple = dtuple_create(heap, 1);
+ dfield = dtuple_get_nth_field(tuple, 0);
+
+ buf = mem_heap_alloc(heap, 8);
+ mach_write_to_8(buf, index->id);
+
+ dfield_set_data(dfield, buf, 8);
+ dict_index_copy_types(tuple, sys_index, 1);
+
+ btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
+ BTR_SEARCH_LEAF, &pcur, &mtr);
+ for (i = 0; i < index->n_fields; i++) {
+
+ rec = btr_pcur_get_rec(&pcur);
+
+ ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
+ if (rec_get_deleted_flag(rec)) {
+ fprintf(stderr,
+"InnoDB: Error: data dictionary entry for table %s is corrupt!\n",
+"InnoDB: An index field is delete marked.\n",
+ table->name);
+ }
+
+ field = rec_get_nth_field(rec, 0, &len);
+ ut_ad(len == 8);
+ ut_a(ut_memcmp(buf, field, len) == 0);
+
+ field = rec_get_nth_field(rec, 1, &len);
+ ut_ad(len == 4);
+ ut_a(i == mach_read_from_4(field));
+
+ ut_a(0 == ut_strcmp((char*) "COL_NAME",
+ dict_field_get_col(
+ dict_index_get_nth_field(
+ dict_table_get_first_index(sys_fields), 4))->name));
+
+ field = rec_get_nth_field(rec, 4, &len);
+
+ col_name = mem_heap_alloc(heap, len + 1);
+ ut_memcpy(col_name, field, len);
+ col_name[len] = '\0';
+
+ dict_mem_index_add_field(index, col_name, 0);
+
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+ }
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+}
+
+/************************************************************************
+Loads definitions for table indexes. Adds them to the data dictionary
+cache. */
+static
+ibool
+dict_load_indexes(
+/*==============*/
+ /* out: TRUE if ok, FALSE if corruption
+ of dictionary table */
+ dict_table_t* table, /* in: table */
+ mem_heap_t* heap) /* in: memory heap for temporary storage */
+{
+ dict_table_t* sys_indexes;
+ dict_index_t* sys_index;
+ dict_index_t* index;
+ btr_pcur_t pcur;
+ dtuple_t* tuple;
+ dfield_t* dfield;
+ rec_t* rec;
+ byte* field;
+ ulint len;
+ ulint name_len;
+ char* name_buf;
+ ulint type;
+ ulint space;
+ ulint page_no;
+ ulint n_fields;
+ byte* buf;
+ ibool is_sys_table;
+ dulint id;
+ mtr_t mtr;
+
+ ut_ad(mutex_own(&(dict_sys->mutex)));
+
+ if ((ut_dulint_get_high(table->id) == 0)
+ && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) {
+ is_sys_table = TRUE;
+ } else {
+ is_sys_table = FALSE;
+ }
+
+ mtr_start(&mtr);
+
+ sys_indexes = dict_table_get_low((char*) "SYS_INDEXES");
+ sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes);
+
+ tuple = dtuple_create(heap, 1);
+ dfield = dtuple_get_nth_field(tuple, 0);
+
+ buf = mem_heap_alloc(heap, 8);
+ mach_write_to_8(buf, table->id);
+
+ dfield_set_data(dfield, buf, 8);
+ dict_index_copy_types(tuple, sys_index, 1);
+
+ btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
+ BTR_SEARCH_LEAF, &pcur, &mtr);
+ for (;;) {
+ if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
+
+ break;
+ }
+
+ rec = btr_pcur_get_rec(&pcur);
+
+ field = rec_get_nth_field(rec, 0, &len);
+ ut_ad(len == 8);
+
+ if (ut_memcmp(buf, field, len) != 0) {
+ break;
+ }
+
+ if (rec_get_deleted_flag(rec)) {
+ fprintf(stderr,
+"InnoDB: Error: data dictionary entry for table %s is corrupt!\n"
+"InnoDB: An index is delete marked.\n",
+ table->name);
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+
+ return(FALSE);
+ }
+
+ field = rec_get_nth_field(rec, 1, &len);
+ ut_ad(len == 8);
+ id = mach_read_from_8(field);
+
+ ut_a(0 == ut_strcmp("NAME",
+ dict_field_get_col(
+ dict_index_get_nth_field(
+ dict_table_get_first_index(sys_indexes), 4))->name));
+
+ field = rec_get_nth_field(rec, 4, &name_len);
+
+ name_buf = mem_heap_alloc(heap, name_len + 1);
+ ut_memcpy(name_buf, field, name_len);
+ name_buf[name_len] = '\0';
+
+ field = rec_get_nth_field(rec, 5, &len);
+ n_fields = mach_read_from_4(field);
+
+ field = rec_get_nth_field(rec, 6, &len);
+ type = mach_read_from_4(field);
+
+ field = rec_get_nth_field(rec, 7, &len);
+ space = mach_read_from_4(field);
+
+ ut_a(0 == ut_strcmp((char*) "PAGE_NO",
+ dict_field_get_col(
+ dict_index_get_nth_field(
+ dict_table_get_first_index(sys_indexes), 8))->name));
+
+ field = rec_get_nth_field(rec, 8, &len);
+ page_no = mach_read_from_4(field);
+
+ if (page_no == FIL_NULL) {
+
+ 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);
+
+ return(FALSE);
+ }
+
+ if ((type & DICT_CLUSTERED) == 0
+ && NULL == dict_table_get_first_index(table)) {
+
+ fprintf(stderr,
+ "InnoDB: Error: trying to load index %s for table %s\n"
+ "InnoDB: but the first index was not clustered!\n",
+ name_buf, table->name);
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+
+ return(FALSE);
+ }
+
+ if (is_sys_table
+ && ((type & DICT_CLUSTERED)
+ || ((table == dict_sys->sys_tables)
+ && (name_len == ut_strlen("ID_IND"))
+ && (0 == ut_memcmp(name_buf, "ID_IND",
+ name_len))))) {
+
+ /* The index was created in memory already in
+ booting */
+ } else {
+ index = dict_mem_index_create(table->name, name_buf,
+ space, type, n_fields);
+ index->page_no = page_no;
+ index->id = id;
+
+ dict_load_fields(table, index, heap);
+
+ dict_index_add_to_cache(table, index);
+ }
+
+ btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+ }
+
+ btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+
+ return(TRUE);
+}
+
+/************************************************************************
Loads a table definition and also all its index definitions, and also
the cluster definition if the table is a member in a cluster. Also loads
all foreign key constraints where the foreign key is in the table or where
@@ -338,7 +671,7 @@ dict_load_table(
dict_load_columns(table, heap);
dict_table_add_to_cache(table);
-
+
dict_load_indexes(table, heap);
ut_a(DB_SUCCESS == dict_load_foreigns(table->name));
@@ -436,8 +769,6 @@ dict_load_table_on_id(
/* Load the table definition to memory */
table = dict_load_table(name);
-
- ut_a(table);
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -468,324 +799,6 @@ dict_load_sys_table(
}
/************************************************************************
-Loads definitions for table columns. */
-static
-void
-dict_load_columns(
-/*==============*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
-{
- dict_table_t* sys_columns;
- dict_index_t* sys_index;
- btr_pcur_t pcur;
- dtuple_t* tuple;
- dfield_t* dfield;
- rec_t* rec;
- byte* field;
- ulint len;
- byte* buf;
- char* name_buf;
- char* name;
- ulint mtype;
- ulint prtype;
- ulint col_len;
- ulint prec;
- ulint i;
- mtr_t mtr;
-
- ut_ad(mutex_own(&(dict_sys->mutex)));
-
- mtr_start(&mtr);
-
- sys_columns = dict_table_get_low((char *) "SYS_COLUMNS");
- sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
-
- tuple = dtuple_create(heap, 1);
- dfield = dtuple_get_nth_field(tuple, 0);
-
- buf = mem_heap_alloc(heap, 8);
- mach_write_to_8(buf, table->id);
-
- dfield_set_data(dfield, buf, 8);
- dict_index_copy_types(tuple, sys_index, 1);
-
- btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
- BTR_SEARCH_LEAF, &pcur, &mtr);
- for (i = 0; i < table->n_cols - DATA_N_SYS_COLS; i++) {
-
- rec = btr_pcur_get_rec(&pcur);
-
- ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
-
- ut_a(!rec_get_deleted_flag(rec));
-
- field = rec_get_nth_field(rec, 0, &len);
- ut_ad(len == 8);
- ut_a(ut_dulint_cmp(table->id, mach_read_from_8(field)) == 0);
-
- field = rec_get_nth_field(rec, 1, &len);
- ut_ad(len == 4);
- ut_a(i == mach_read_from_4(field));
-
- ut_a(0 == ut_strcmp((char *) "NAME",
- dict_field_get_col(
- dict_index_get_nth_field(
- dict_table_get_first_index(sys_columns), 4))->name));
-
- field = rec_get_nth_field(rec, 4, &len);
-
- name_buf = mem_heap_alloc(heap, len + 1);
- ut_memcpy(name_buf, field, len);
- name_buf[len] = '\0';
-
- name = name_buf;
-
- field = rec_get_nth_field(rec, 5, &len);
- mtype = mach_read_from_4(field);
-
- field = rec_get_nth_field(rec, 6, &len);
- prtype = mach_read_from_4(field);
-
- field = rec_get_nth_field(rec, 7, &len);
- col_len = mach_read_from_4(field);
-
- ut_a(0 == ut_strcmp((char *) "PREC",
- dict_field_get_col(
- dict_index_get_nth_field(
- dict_table_get_first_index(sys_columns), 8))->name));
-
- field = rec_get_nth_field(rec, 8, &len);
- prec = mach_read_from_4(field);
-
- dict_mem_table_add_col(table, name, mtype, prtype, col_len,
- prec);
- btr_pcur_move_to_next_user_rec(&pcur, &mtr);
- }
-
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
-}
-
-/************************************************************************
-Loads definitions for table indexes. Adds them to the data dictionary cache.
-*/
-static
-void
-dict_load_indexes(
-/*==============*/
- dict_table_t* table, /* in: table */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
-{
- dict_table_t* sys_indexes;
- dict_index_t* sys_index;
- dict_index_t* index;
- btr_pcur_t pcur;
- dtuple_t* tuple;
- dfield_t* dfield;
- rec_t* rec;
- byte* field;
- ulint len;
- ulint name_len;
- char* name_buf;
- ulint type;
- ulint space;
- ulint page_no;
- ulint n_fields;
- byte* buf;
- ibool is_sys_table;
- dulint id;
- mtr_t mtr;
-
- ut_ad(mutex_own(&(dict_sys->mutex)));
-
- if ((ut_dulint_get_high(table->id) == 0)
- && (ut_dulint_get_low(table->id) < DICT_HDR_FIRST_ID)) {
- is_sys_table = TRUE;
- } else {
- is_sys_table = FALSE;
- }
-
- mtr_start(&mtr);
-
- sys_indexes = dict_table_get_low((char *) "SYS_INDEXES");
- sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes);
-
- tuple = dtuple_create(heap, 1);
- dfield = dtuple_get_nth_field(tuple, 0);
-
- buf = mem_heap_alloc(heap, 8);
- mach_write_to_8(buf, table->id);
-
- dfield_set_data(dfield, buf, 8);
- dict_index_copy_types(tuple, sys_index, 1);
-
- btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
- BTR_SEARCH_LEAF, &pcur, &mtr);
- for (;;) {
- if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
-
- break;
- }
-
- rec = btr_pcur_get_rec(&pcur);
-
- field = rec_get_nth_field(rec, 0, &len);
- ut_ad(len == 8);
-
- if (ut_memcmp(buf, field, len) != 0) {
- break;
- }
-
- ut_a(!rec_get_deleted_flag(rec));
-
- field = rec_get_nth_field(rec, 1, &len);
- ut_ad(len == 8);
- id = mach_read_from_8(field);
-
- ut_a(0 == ut_strcmp((char *) "NAME",
- dict_field_get_col(
- dict_index_get_nth_field(
- dict_table_get_first_index(sys_indexes), 4))->name));
-
- field = rec_get_nth_field(rec, 4, &name_len);
-
- name_buf = mem_heap_alloc(heap, name_len + 1);
- ut_memcpy(name_buf, field, name_len);
- name_buf[name_len] = '\0';
-
- field = rec_get_nth_field(rec, 5, &len);
- n_fields = mach_read_from_4(field);
-
- field = rec_get_nth_field(rec, 6, &len);
- type = mach_read_from_4(field);
-
- field = rec_get_nth_field(rec, 7, &len);
- space = mach_read_from_4(field);
-
- ut_a(0 == ut_strcmp((char *) "PAGE_NO",
- dict_field_get_col(
- dict_index_get_nth_field(
- dict_table_get_first_index(sys_indexes), 8))->name));
-
- field = rec_get_nth_field(rec, 8, &len);
- page_no = mach_read_from_4(field);
-
- if (is_sys_table
- && ((type & DICT_CLUSTERED)
- || ((table == dict_sys->sys_tables)
- && (name_len == ut_strlen((char *) "ID_IND"))
- && (0 == ut_memcmp(name_buf, (char *) "ID_IND",
- name_len))))) {
-
- /* The index was created in memory already in
- booting */
- } else {
- index = dict_mem_index_create(table->name, name_buf,
- space, type, n_fields);
- index->page_no = page_no;
- index->id = id;
-
- dict_load_fields(table, index, heap);
-
- if (index->type & DICT_CLUSTERED == 0
- && NULL == dict_table_get_first_index(table)) {
-
- fprintf(stderr,
- "InnoDB: Error: trying to load index %s for table %s\n"
- "InnoDB: but the first index was not clustered\n",
- index->name, table->name);
- } else {
- dict_index_add_to_cache(table, index);
- }
- }
-
- btr_pcur_move_to_next_user_rec(&pcur, &mtr);
- }
-
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
-}
-
-/************************************************************************
-Loads definitions for index fields. */
-static
-void
-dict_load_fields(
-/*=============*/
- dict_table_t* table, /* in: table */
- dict_index_t* index, /* in: index whose fields to load */
- mem_heap_t* heap) /* in: memory heap for temporary storage */
-{
- dict_table_t* sys_fields;
- dict_index_t* sys_index;
- btr_pcur_t pcur;
- dtuple_t* tuple;
- dfield_t* dfield;
- char* col_name;
- rec_t* rec;
- byte* field;
- ulint len;
- byte* buf;
- ulint i;
- mtr_t mtr;
-
- ut_ad(mutex_own(&(dict_sys->mutex)));
-
- UT_NOT_USED(table);
-
- mtr_start(&mtr);
-
- sys_fields = dict_table_get_low((char *) "SYS_FIELDS");
- sys_index = UT_LIST_GET_FIRST(sys_fields->indexes);
-
- tuple = dtuple_create(heap, 1);
- dfield = dtuple_get_nth_field(tuple, 0);
-
- buf = mem_heap_alloc(heap, 8);
- mach_write_to_8(buf, index->id);
-
- dfield_set_data(dfield, buf, 8);
- dict_index_copy_types(tuple, sys_index, 1);
-
- btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
- BTR_SEARCH_LEAF, &pcur, &mtr);
- for (i = 0; i < index->n_fields; i++) {
-
- rec = btr_pcur_get_rec(&pcur);
-
- ut_a(btr_pcur_is_on_user_rec(&pcur, &mtr));
- ut_a(!rec_get_deleted_flag(rec));
-
- field = rec_get_nth_field(rec, 0, &len);
- ut_ad(len == 8);
- ut_a(ut_memcmp(buf, field, len) == 0);
-
- field = rec_get_nth_field(rec, 1, &len);
- ut_ad(len == 4);
- ut_a(i == mach_read_from_4(field));
-
- ut_a(0 == ut_strcmp((char *) "COL_NAME",
- dict_field_get_col(
- dict_index_get_nth_field(
- dict_table_get_first_index(sys_fields), 4))->name));
-
- field = rec_get_nth_field(rec, 4, &len);
-
- col_name = mem_heap_alloc(heap, len + 1);
- ut_memcpy(col_name, field, len);
- col_name[len] = '\0';
-
- dict_mem_index_add_field(index, col_name, 0);
-
- btr_pcur_move_to_next_user_rec(&pcur, &mtr);
- }
-
- btr_pcur_close(&pcur);
- mtr_commit(&mtr);
-}
-
-/************************************************************************
Loads foreign key constraint col names (also for the referenced table). */
static
void