得到一个table_share
1)先从table_def_cache中查找, 如果有, 直接返回
2)如果没有找到,
为table_share分配内存,初始化,打开.frm文件,并将share放置hashTable中
如果hashTable的容量超过限制,根据lru策略,在oldest_unused_tables中循环删除table share
注意:
oldest_unused_tables中的元素是close_table时放入进去的
/* Get TABLE_SHARE for a table. get_table_share() thd Thread handle table_list Table that should be opened key Table cache key key_length Length of key db_flags Flags to open_table_def(): OPEN_VIEW error out: Error code from open_table_def() IMPLEMENTATION Get a table definition from the table definition cache. If it doesn't exist, create a new from the table definition file. NOTES We must have wrlock on LOCK_open when we come here (To be changed later) RETURN 0 Error # Share for table */ TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, uint key_length, uint db_flags, int *error, my_hash_value_type hash_value) { TABLE_SHARE *share; DBUG_ENTER("get_table_share"); *error= ; /* To be able perform any operation on table we should own some kind of metadata lock on it. */ DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table_list->db, table_list->table_name, MDL_SHARED)); /* Read table definition from cache */ if ((share= (TABLE_SHARE*) my_hash_search_using_hash_value(&table_def_cache, hash_value, (uchar*) key, key_length))) goto found; if (!(share= alloc_table_share(table_list, key, key_length))) { DBUG_RETURN(); } /* We assign a new table id under the protection of LOCK_open. We do this instead of creating a new mutex and using it for the sole purpose of serializing accesses to a static variable, we assign the table id here. We assign it to the share before inserting it into the table_def_cache to be really sure that it cannot be read from the cache without having a table id assigned. CAVEAT. This means that the table cannot be used for binlogging/replication purposes, unless get_table_share() has been called directly or indirectly. */ assign_new_table_id(share); if (my_hash_insert(&table_def_cache, (uchar*) share)) { free_table_share(share); DBUG_RETURN(); // return error } if (open_table_def(thd, share, db_flags)) { *error= share->error; (void) my_hash_delete(&table_def_cache, (uchar*) share); DBUG_RETURN(); } share->ref_count++; // Mark in use DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", (ulong) share, share->ref_count)); DBUG_RETURN(share); found: /* We found an existing table definition. Return it if we didn't get an error when reading the table definition from file. */ if (share->error) { /* Table definition contained an error */ open_table_error(share, share->error, share->open_errno, share->errarg); DBUG_RETURN(); } if (share->is_view && !(db_flags & OPEN_VIEW)) { open_table_error(share, , ENOENT, ); DBUG_RETURN(); } ++share->ref_count; && share->prev) { /* Share was not used before and it was in the old_unused_share list Unlink share from this list */ DBUG_PRINT("info", ("Unlinking from not used list")); *share->prev= share->next; share->next->prev= share->prev; share->next= ; share->prev= ; } /* Free cache if too big */ while (table_def_cache.records > table_def_size && oldest_unused_share->next) my_hash_delete(&table_def_cache, (uchar*) oldest_unused_share); DBUG_PRINT("exit", ("share: 0x%lx ref_count: %u", (ulong) share, share->ref_count)); DBUG_RETURN(share); }