📄 fil0fil.c
字号:
mutex_enter(&(system->mutex)); HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(name), space, 0 == strcmp(name, space->name)); if (space != NULL) { ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Warning: trying to init to the tablespace memory cache\n""InnoDB: a tablespace %lu of name ", (ulong) id); ut_print_filename(stderr, name); fprintf(stderr, ",\n""InnoDB: but a tablespace %lu of the same name\n""InnoDB: already exists in the tablespace memory cache!\n", (ulong) space->id); if (id == 0 || purpose != FIL_TABLESPACE) { mutex_exit(&(system->mutex)); return(FALSE); } fprintf(stderr,"InnoDB: We assume that InnoDB did a crash recovery, and you had\n""InnoDB: an .ibd file for which the table did not exist in the\n""InnoDB: InnoDB internal data dictionary in the ibdata files.\n""InnoDB: We assume that you later removed the .ibd and .frm files,\n""InnoDB: and are now trying to recreate the table. We now remove the\n""InnoDB: conflicting tablespace object from the memory cache and try\n""InnoDB: the init again.\n"); namesake_id = space->id; mutex_exit(&(system->mutex)); fil_space_free(namesake_id); goto try_again; } HASH_SEARCH(hash, system->spaces, id, space, space->id == id); if (space != NULL) { fprintf(stderr,"InnoDB: Error: trying to add tablespace %lu of name ", (ulong) id); ut_print_filename(stderr, name); fprintf(stderr, "\n""InnoDB: to the tablespace memory cache, but tablespace\n""InnoDB: %lu of name ", (ulong) space->id); ut_print_filename(stderr, space->name); fputs(" already exists in the tablespace\n""InnoDB: memory cache!\n", stderr); mutex_exit(&(system->mutex)); return(FALSE); } space = mem_alloc(sizeof(fil_space_t)); space->name = mem_strdup(name); space->id = id; system->tablespace_version++; space->tablespace_version = system->tablespace_version; space->mark = FALSE; if (purpose == FIL_TABLESPACE && id > system->max_assigned_id) { system->max_assigned_id = id; } space->stop_ios = FALSE; space->stop_ibuf_merges = FALSE; space->is_being_deleted = FALSE; space->purpose = purpose; space->size = 0; space->n_reserved_extents = 0; space->n_pending_flushes = 0; space->n_pending_ibuf_merges = 0; UT_LIST_INIT(space->chain); space->magic_n = FIL_SPACE_MAGIC_N; space->ibuf_data = NULL; rw_lock_create(&(space->latch)); rw_lock_set_level(&(space->latch), SYNC_FSP); HASH_INSERT(fil_space_t, hash, system->spaces, id, space); HASH_INSERT(fil_space_t, name_hash, system->name_hash, ut_fold_string(name), space); space->is_in_unflushed_spaces = FALSE; UT_LIST_ADD_LAST(space_list, system->space_list, space); mutex_exit(&(system->mutex)); return(TRUE);}/***********************************************************************Assigns a new space id for a new single-table tablespace. This works simply byincrementing the global counter. If 4 billion id's is not enough, we may needto recycle id's. */staticulintfil_assign_new_space_id(void)/*=========================*/ /* out: new tablespace id; ULINT_UNDEFINED if could not assign an id */{ fil_system_t* system = fil_system; ulint id; mutex_enter(&(system->mutex)); system->max_assigned_id++; id = system->max_assigned_id; if (id > (SRV_LOG_SPACE_FIRST_ID / 2) && (id % 1000000UL == 0)) { ut_print_timestamp(stderr); fprintf(stderr,"InnoDB: Warning: you are running out of new single-table tablespace id's.\n""InnoDB: Current counter is %lu and it must not exceed %lu!\n""InnoDB: To reset the counter to zero you have to dump all your tables and\n""InnoDB: recreate the whole InnoDB installation.\n", (ulong) id, (ulong) SRV_LOG_SPACE_FIRST_ID); } if (id >= SRV_LOG_SPACE_FIRST_ID) { ut_print_timestamp(stderr); fprintf(stderr,"InnoDB: You have run out of single-table tablespace id's!\n""InnoDB: Current counter is %lu.\n""InnoDB: To reset the counter to zero you have to dump all your tables and\n""InnoDB: recreate the whole InnoDB installation.\n", (ulong) id); system->max_assigned_id--; id = ULINT_UNDEFINED; } mutex_exit(&(system->mutex)); return(id);}/***********************************************************************Frees a space object from the tablespace memory cache. Closes the files inthe chain but does not delete them. There must not be any pending i/o's orflushes on the files. */iboolfil_space_free(/*===========*/ /* out: TRUE if success */ ulint id) /* in: space id */{ fil_system_t* system = fil_system; fil_space_t* space; fil_space_t* namespace; fil_node_t* fil_node; mutex_enter(&(system->mutex)); HASH_SEARCH(hash, system->spaces, id, space, space->id == id); if (!space) { ut_print_timestamp(stderr); fprintf(stderr," InnoDB: Error: trying to remove tablespace %lu from the cache but\n""InnoDB: it is not there.\n", (ulong) id); mutex_exit(&(system->mutex)); return(FALSE); } HASH_DELETE(fil_space_t, hash, system->spaces, id, space); HASH_SEARCH(name_hash, system->name_hash, ut_fold_string(space->name), namespace, 0 == strcmp(space->name, namespace->name)); ut_a(namespace); ut_a(space == namespace); HASH_DELETE(fil_space_t, name_hash, system->name_hash, ut_fold_string(space->name), space); if (space->is_in_unflushed_spaces) { space->is_in_unflushed_spaces = FALSE; UT_LIST_REMOVE(unflushed_spaces, system->unflushed_spaces, space); } UT_LIST_REMOVE(space_list, system->space_list, space); ut_a(space->magic_n == FIL_SPACE_MAGIC_N); ut_a(0 == space->n_pending_flushes); fil_node = UT_LIST_GET_FIRST(space->chain); while (fil_node != NULL) { fil_node_free(fil_node, system, space); fil_node = UT_LIST_GET_FIRST(space->chain); } ut_a(0 == UT_LIST_GET_LEN(space->chain)); mutex_exit(&(system->mutex)); rw_lock_free(&(space->latch)); mem_free(space->name); mem_free(space); return(TRUE);}#ifdef UNIV_HOTBACKUP/***********************************************************************Returns the tablespace object for a given id, or NULL if not found from thetablespace memory cache. */staticfil_space_t*fil_get_space_for_id_low(/*=====================*/ /* out: tablespace object or NULL; NOTE that you must own &(fil_system->mutex) to call this function! */ ulint id) /* in: space id */{ fil_system_t* system = fil_system; fil_space_t* space; ut_ad(system); HASH_SEARCH(hash, system->spaces, id, space, space->id == id); return(space);}#endif/***********************************************************************Returns the size of the space in pages. The tablespace must be cached in thememory cache. */ulintfil_space_get_size(/*===============*/ /* out: space size, 0 if space not found */ ulint id) /* in: space id */{ fil_system_t* system = fil_system; fil_node_t* node; fil_space_t* space; ulint size; ut_ad(system); fil_mutex_enter_and_prepare_for_io(id); HASH_SEARCH(hash, system->spaces, id, space, space->id == id); if (space == NULL) { mutex_exit(&(system->mutex)); return(0); } if (space->size == 0 && space->purpose == FIL_TABLESPACE) { ut_a(id != 0); ut_a(1 == UT_LIST_GET_LEN(space->chain)); node = UT_LIST_GET_FIRST(space->chain); /* It must be a single-table tablespace and we have not opened the file yet; the following calls will open it and update the size fields */ fil_node_prepare_for_io(node, system, space); fil_node_complete_io(node, system, OS_FILE_READ); } size = space->size; mutex_exit(&(system->mutex)); return(size);}/***********************************************************************Checks if the pair space, page_no refers to an existing page in a tablespacefile space. The tablespace must be cached in the memory cache. */iboolfil_check_adress_in_tablespace(/*===========================*/ /* out: TRUE if the address is meaningful */ ulint id, /* in: space id */ ulint page_no)/* in: page number */{ if (fil_space_get_size(id) > page_no) { return(TRUE); } return(FALSE);} /********************************************************************Creates a the tablespace memory cache. */staticfil_system_t*fil_system_create(/*==============*/ /* out, own: tablespace memory cache */ ulint hash_size, /* in: hash table size */ ulint max_n_open) /* in: maximum number of open files; must be > 10 */{ fil_system_t* system; ut_a(hash_size > 0); ut_a(max_n_open > 0); system = mem_alloc(sizeof(fil_system_t)); mutex_create(&(system->mutex)); mutex_set_level(&(system->mutex), SYNC_ANY_LATCH); system->spaces = hash_create(hash_size); system->name_hash = hash_create(hash_size); UT_LIST_INIT(system->LRU); system->n_open = 0; system->max_n_open = max_n_open; system->modification_counter = 0; system->max_assigned_id = 0; system->tablespace_version = 0; UT_LIST_INIT(system->unflushed_spaces); UT_LIST_INIT(system->space_list); return(system);}/********************************************************************Initializes the tablespace memory cache. */voidfil_init(/*=====*/ ulint max_n_open) /* in: max number of open files */{ ut_a(fil_system == NULL); /*printf("Initializing the tablespace cache with max %lu open files\n", max_n_open); */ fil_system = fil_system_create(FIL_SYSTEM_HASH_SIZE, max_n_open);}/***********************************************************************Opens all log files and system tablespace data files. They stay open until thedatabase server shutdown. This should be called at a server startup after thespace objects for the log and the system tablespace have been created. Thepurpose of this operation is to make sure we never run out of file descriptorsif we need to read from the insert buffer or to write to the log. */voidfil_open_log_and_system_tablespace_files(void)/*==========================================*/{ fil_system_t* system = fil_system; fil_space_t* space; fil_node_t* node; mutex_enter(&(system->mutex)); space = UT_LIST_GET_FIRST(system->space_list); while (space != NULL) { if (space->purpose != FIL_TABLESPACE || space->id == 0) { node = UT_LIST_GET_FIRST(space->chain); while (node != NULL) { if (!node->open) { fil_node_open_file(node, system, space); } if (system->max_n_open < 10 + system->n_open) { fprintf(stderr,"InnoDB: Warning: you must raise the value of innodb_max_open_files in\n""InnoDB: my.cnf! Remember that InnoDB keeps all log files and all system\n""InnoDB: tablespace files open for the whole time mysqld is running, and\n""InnoDB: needs to open also some .ibd files if the file-per-table storage\n""InnoDB: model is used. Current open files %lu, max allowed open files %lu.\n", (ulong) system->n_open, (ulong) system->max_n_open); } node = UT_LIST_GET_NEXT(chain, node); } } space = UT_LIST_GET_NEXT(space_list, space); } mutex_exit(&(system->mutex));}/***********************************************************************Closes all open files. There must not be any pending i/o's or not flushedmodifications in the files. */voidfil_close_all_files(void)/*=====================*/{ fil_system_t* system = fil_system; fil_space_t* space; fil_node_t* node; mutex_enter(&(system->mutex)); space = UT_LIST_GET_FIRST(system->space_list); while (space != NULL) { node = UT_LIST_GET_FIRST(space->chain); while (node != NULL) { if (node->open) { fil_node_close_file(node, system); } node = UT_LIST_GET_NEXT(chain, node); } space = UT_LIST_GET_NEXT(space_list, space); } mutex_exit(&(system->mutex));}/***********************************************************************Sets the max tablespace id counter if the given number is bigger than theprevious value. */voidfil_set_max_space_id_if_bigger(/*===========================*/ ulint max_id) /* in: maximum known id */{ fil_system_t* system = fil_system; if (max_id >= SRV_LOG_SPACE_FIRST_ID) { fprintf(stderr,"InnoDB: Fatal error: max tablespace id is too high, %lu\n", (ulong) max_id); ut_a(0); } mutex_enter(&(system->mutex)); if (system->max_assigned_id < max_id) { system->max_assigned_id = max_id; } mutex_exit(&(system->mutex));}/********************************************************************Initializes the ibuf data structure for space 0 == the system tablespace.This can be called after the file space headers have been created and thedictionary system has been initialized. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -