内存结构
Mysql内存组成可以分为SGA(系统全局)和PGA(程序缓存区)
SGA内存主要构成
innodb_buffer_pool | 用来缓存innodb表的数据,索引,插入缓存,数据字典等信息 |
innodb_log_buffer | 即redo log buffer 事务在内存中的缓冲 |
query cache | 只能缓存静态数据信息,建议生产环境关闭,5.6之后默认是关闭的,query_cache_type设置为off,query_cache_size设置为0,才会生效 |
PGA内存主要构成
sort_buffer_size | 用户sql语句在内存中的临时排序 |
join_buffer_size | 表连接使用,适用于BKA ,该缓存中会保存join字段的数据方便与另外一张表进行连接 |
read_buffer_size | 表顺序扫描的缓存,只适用于MyISAM存储引擎 |
read_rnd_buffer_size | mysql随机读取缓存区大小,用户做MRR,MRR优化的目的就是为了减少磁盘的随机访问,对于MySQL的二级索引(非聚集索引)而言,过于随机的回表会造成随机读取过于严重,范围扫描(range access)中MySQL将扫描到的数据存入read_rnd_buffer_size,然后对其按照Primary Key(RowID)排序,然后使用排序好的数据进行顺序回表,因为我们知道InnoDB中叶子节点数据是按照PRIMARY KEY(ROWID)进行排列的,那么这样就转换随机读取为顺序读取了 |
tmp_table_size | sql语句在排序/分组时没有使用到索引,会使用临时表空间 |
Buffer状态及其链表结构
page在InnoDB磁盘I/O最小单位,数据都存放在page中,对应到内存中就是一个个buffer.
-
buffer状态
1.freeBuffer:该buufer未被使用
2.cleanBuffer:内存中的buffer与磁盘中的page的数据一致
3.dirtyBuffer:内存中的数据还未被刷到磁盘,和磁盘中的数据不一致
buffer由chain来管理,也就是链,三种不同的buffer生出三条链表
-
chain链表
1.free list :把free buffer串联起来,使用时不够用,从lru list和flush list中释放出free buffer
2.lru list :把最近少访问到的clean buffer串联起来释放出free buffer
3.flush list : 把dirty buffer串联起来方便线程将数据刷新到磁盘,释放更过的free buffer
各大刷线线程及其作用
-
后台线程中主线程-master thread,其内部有4大循环
1.主循环 loop
每1s操作 | 1.日志刷新到磁盘,即使事务还没提交,2.刷新脏页到磁盘,3.执行合并插入缓冲操作,4.产生checkpoint,5.清楚无用的table cache,6.当前没有操作切换到background loop |
每10s操作 | 1.日志刷新到磁盘,即使事务还没提交,2.刷新脏页到磁盘,3.执行合并插入缓冲操作,4.产生checkpoint,5.删除无用的undo |
2.后台循环 background loop
3.刷新循环 flush loop
4.暂停循环 supsend loop
-
4大I/O线程
1.read thread:读请求线程(默认值都是4个,可以适当调大)
2.write thread:写请求线程(默认值都是4个,可以适当调大)
3.redo log thread:负责把日志缓冲区的内容刷新到redo log(默认值都是4个,可以适当调大)
4.changge buffer threD:把插入缓冲区内容刷新到磁盘(默认值都是4个,可以适当调大)
-
其他线程 1.page clean tread:将脏页刷到缓存中,可以调为多个
2.purge thread:删除无用的undo页,通过innodb_purge_thread参数调整线程数默认是1个,最大调整为32个
3.error monitor thread:负责数据库报错的线程
4.lock monitor thread:负责监控锁的线程