用户访问表时,表对象在缓存时: 通过HASH算法找到TABLE_SHARE,然后每个线程构造各自的实例化TABLE即可。
用户访问表时,当表没有被缓存的情况下: 第一需要打开表,首先需要从系统表中将这个表的所有信息都读入内存中,这些信息包括表名、库名、所有列信息、列的默认值、表的字符集、对应的frm文件路径、所属存储引擎、主键等,将这些信息构造一个TABLE_SHARE结构体,这个结构体是表对象缓存的第一层,所有用户共享访问且为静态不允许修改,它是缓存在table_def_cache(由参数table_definition_cache控制)中的。
而真正与用户打交道的是TABLE_SHARE的衍生品,它对应结构体为TABLE,在被使用前需要将TABLE_SHARE结构体实例化TABLE才能被使用,由每个线程构造各自的实例化TABLE即可。(实例化的TABLE由table_open_cache及table_open_cache_instance控制)
注意1: DDL *** 作时会将所有instance锁住,而DML *** 作时instance之间互不干扰。
(DDL statements still require a lock on the entire cache, but such statements are much less frequent than DML statements.)
注意2: 一个线程中如果打开表过多,超过一个instance限制的大小时,是不能跨instance缓存的
(instance大小:table_open_cache / table_open_cache_instances)
表缓存涉及其他参数: 通过下面参数判断table_open_cache参数设置是否合理
table_open_cache_hit:能够从table open cache的free list中找到table则为命中,+1
table_open_cache_misses:与table_open_cache_hit相反,如果找不到则需要重新实例化则+1,通常发生在初始化第一次加载表或超过table_open_cache的设置被淘汰后需要重新实例化。
table_open_cache_overflow:table cache淘汰的数量,每次淘汰+1
opened_tables:已经打开的表数。如果Opened_tables很大,那么table_open_cache的值可能太小了。
open_tables:总的instance (table cache)的总数
my.ini文件中
[wampmysqld]port = 3306
socket = /tmp/mysql.sock
key_buffer_size = 16M // 改这里
max_allowed_packet = 1M
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
PS 如果是安装版的mysql 你需要改的MY.ini 可能是在
C:\ProgramData\MySQL\MySQL Server 5.7
这个目录有可能是隐藏的目录,你可以设置文件夹属性,显示所有文件
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)