第16章 + 第17章
optimizer trace
what
- 可以让用户查看优化器为指定语句生成执行计划的过程
步骤
- 打开optimizer trace功能
- 输入查询语句
- 从OPTIMIZER_TRACE表中查看上一个查询的优化过程
- 关闭optimizer trace功能
缓冲池(Buffer Pool)
前导知识
- InnoDB处理客户端的请求时,如果需要访问某个页的数据,会将完整的页中的数据全部加载到内存中将整个页加载到内存中就可以进行读写访问了,而且读写访问之后不着急释放该页对应的内存,而是将其缓存起来,在之后再有请求访问该页面,就可以省去磁盘I/O的开销
what
- 缓冲池是MySQL服务器向OS申请的一片连续的内存,默认大小128MB
缓冲页与控制块
- 缓冲池中的页就是缓冲页
- 每个页对应的控制信息占用的内存称为控制块,控制块与缓冲页一一对应
- 控制块放在缓冲池的前面,缓冲页放在缓冲池的后面
free链表
- 将所有空闲的缓冲页的控制块组织成一个链表,就是free链表
- 真正从链表中获取的是控制块,通过控制块来访问空闲的缓冲页
缓冲页的哈希处理
- 怎样知道一个页是否在缓冲池中?
用表空间+页号作为key,用缓冲页控制块的地址作为value创建一个字典
flush链表
- 如果修改了缓冲池中某个页的数据,该页与磁盘上的数据不一致,这样的缓冲页为脏页
- 每次修改缓冲页后,不着急将数据立即刷新到磁盘上,而是在未来的某个时间点进行刷新
- 将脏页的控制块组织成一个链表,就是flush链表
- 某个缓冲页对应的控制块不可能既在free链表中,又在flush链表中
LRU链表管理
-
当缓冲池中不再有空闲的缓冲页时,需要淘汰掉最近最少使用的部分缓冲页
- 如果一个页不在缓冲池中,将该页从磁盘加载到内存,将该页的控制块加入LRU链表的头部
- 如果该页已经在缓冲池中,直接将该页对应的控制块移动到LRU链表的头部
- 当缓冲池中的空闲缓冲页用完时,从LRU链表的尾部淘汰部分页面
-
根据数据冷热,将LRU链表分为old和young区域
刷脏
- 后台有专门的线程负责每隔一段时间进行刷脏,不影响用户线程处理正常的请求
多个缓冲池实例
-
why
- 多线程环境下,访问缓冲池中的各个链表都要加锁。在缓冲池特别大并且多线程并发访问量特别高时,单一的缓冲池可能会影响请求的处理速度。因此可以将缓冲池进行拆分。