📄 dict0load.c
字号:
/******************************************************Loads to the memory cache database object definitionsfrom dictionary tables(c) 1996 Innobase OyCreated 4/24/1996 Heikki Tuuri*******************************************************/#include "dict0load.h"#ifndef UNIV_HOTBACKUP#include "mysql_version.h"#endif /* !UNIV_HOTBACKUP */#ifdef UNIV_NONINL#include "dict0load.ic"#endif#include "btr0pcur.h"#include "btr0btr.h"#include "page0page.h"#include "mach0data.h"#include "dict0dict.h"#include "dict0boot.h"#include "rem0cmp.h"#include "srv0start.h"#include "srv0srv.h"/************************************************************************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! */ const char* name) /* in: database name which ends in '/' */{ dict_table_t* sys_tables; btr_pcur_t pcur; dict_index_t* sys_index; dtuple_t* tuple; mem_heap_t* heap; dfield_t* dfield; rec_t* rec; byte* field; ulint len; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ heap = mem_heap_create(1000); mtr_start(&mtr); sys_tables = dict_table_get_low("SYS_TABLES"); sys_index = UT_LIST_GET_FIRST(sys_tables->indexes); ut_a(!sys_tables->comp); tuple = dtuple_create(heap, 1); dfield = dtuple_get_nth_field(tuple, 0); dfield_set_data(dfield, name, ut_strlen(name)); 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);loop: rec = btr_pcur_get_rec(&pcur); if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) { /* Not found */ btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); return(NULL); } field = rec_get_nth_field_old(rec, 0, &len); if (len < strlen(name) || ut_memcmp(name, field, strlen(name)) != 0) { /* Not found */ btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); return(NULL); } if (!rec_get_deleted_flag(rec, sys_tables->comp)) { /* We found one */ char* table_name = mem_strdupl((char*) field, len); btr_pcur_close(&pcur); mtr_commit(&mtr); mem_heap_free(heap); return(table_name); } btr_pcur_move_to_next_user_rec(&pcur, &mtr); goto loop;}/************************************************************************Prints to the standard output information on all tables found in the datadictionary system table. */voiddict_print(void)/*============*/{ dict_table_t* sys_tables; dict_index_t* sys_index; dict_table_t* table; btr_pcur_t pcur; rec_t* rec; byte* field; ulint len; mtr_t mtr; /* Enlarge the fatal semaphore wait timeout during the InnoDB table monitor printout */ mutex_enter(&kernel_mutex); srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */ mutex_exit(&kernel_mutex); 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); mutex_exit(&(dict_sys->mutex)); /* Restore the fatal semaphore wait timeout */ mutex_enter(&kernel_mutex); srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */ mutex_exit(&kernel_mutex); return; } field = rec_get_nth_field_old(rec, 0, &len); if (!rec_get_deleted_flag(rec, sys_tables->comp)) { /* We found one */ char* table_name = mem_strdupl((char*) field, len); btr_pcur_store_position(&pcur, &mtr); mtr_commit(&mtr); table = dict_table_get_low(table_name); mem_free(table_name); if (table == NULL) { fputs("InnoDB: Failed to load table ", stderr); ut_print_namel(stderr, NULL, (char*) field, len); putc('\n', stderr); } else { /* 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); } mtr_start(&mtr); btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr); } goto loop;}/************************************************************************In a crash recovery we already have all the tablespace objects created.This function compares the space id information in the InnoDB data dictionaryto what we already read with fil_load_single_table_tablespaces().In a normal startup, we create the tablespace objects for every table inInnoDB's data dictionary, if the corresponding .ibd file exists.We also scan the biggest space id, and store it to fil_system. */voiddict_check_tablespaces_and_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); ut_a(!sys_tables->comp); 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_old(rec, 0, &len); if (!rec_get_deleted_flag(rec, sys_tables->comp)) { /* We found one */ char* name = mem_strdupl((char*) field, len); field = rec_get_nth_field_old(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, FALSE, TRUE, TRUE); } if (space_id != 0 && !in_crash_recovery) { /* It is a normal database startup: create the space object and check that the .ibd file exists. */ fil_open_single_table_tablespace(FALSE, space_id, name); } 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. */staticvoiddict_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; ulint mtype; ulint prtype; ulint col_len; ulint prec; ulint i; mtr_t mtr; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&(dict_sys->mutex)));#endif /* UNIV_SYNC_DEBUG */ mtr_start(&mtr); sys_columns = dict_table_get_low("SYS_COLUMNS"); sys_index = UT_LIST_GET_FIRST(sys_columns->indexes); ut_a(!sys_columns->comp); 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, sys_columns->comp)); field = rec_get_nth_field_old(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_old(rec, 1, &len); ut_ad(len == 4); ut_a(i == mach_read_from_4(field)); ut_a(0 == ut_strcmp("NAME", dict_field_get_col( dict_index_get_nth_field(sys_index, 4))->name)); field = rec_get_nth_field_old(rec, 4, &len); name = mem_heap_strdupl(heap, (char*) field, len); field = rec_get_nth_field_old(rec, 5, &len); mtype = mach_read_from_4(field); field = rec_get_nth_field_old(rec, 6, &len); prtype = mach_read_from_4(field); if (dtype_get_charset_coll(prtype) == 0 && dtype_is_string_type(mtype)) { /* The table was created with < 4.1.2. */ if (dtype_is_binary_string_type(mtype, prtype)) { /* Use the binary collation for string columns of binary type. */ prtype = dtype_form_prtype(prtype, DATA_MYSQL_BINARY_CHARSET_COLL); } else { /* Use the default charset for other than binary columns. */ prtype = dtype_form_prtype(prtype, data_mysql_default_charset_coll); } } field = rec_get_nth_field_old(rec, 7, &len); col_len = mach_read_from_4(field); ut_a(0 == ut_strcmp("PREC", dict_field_get_col( dict_index_get_nth_field(sys_index, 8))->name)); field = rec_get_nth_field_old(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);}/************************************************************************Report that an index field or index for a table has been delete marked. */staticvoiddict_load_report_deleted_index(/*===========================*/ const char* name, /* in: table name */ ulint field) /* in: index field, or ULINT_UNDEFINED */{ 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 { fputs("InnoDB: An index is delete marked.\n", stderr); }}/************************************************************************Loads definitions for index fields. */staticvoiddict_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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -