关于数据库:面试问到数据库-最后我这样回答-让面试官怀疑人生

5次阅读

共计 2169 个字符,预计需要花费 6 分钟才能阅读完成。

前言

  很多小伙伴面试都有被问到 MySql 数据库的 Buffer Pool,次要波及到 Buffer Pool 的性能及其对于 LRU 的优化,接下来就好好聊聊这个 Buffer Pool。

1、什么是 Buffer Pool

  缓冲池是主内存中的一块区域,用于在 InnoDB 拜访时来缓存表和索引数据。Buffer Pool 容许间接从内存拜访常常应用的数据,防止每次都去拜访数据库,从而放慢处理速度,因为内存容量较小且低廉,因而 Buffer Pool 的容量不会很大,MySql 通过优化 LRU 算法来扩充 Buffer Pool 带来的收益。

2、Buffer Pool 底层构造

  LRU 全称 Least Recently Used, 也就是最近起码应用的意思,晚期用于 linux 的操作系统中,其中页面 置换算法 就是 LRU 的经典利用,将最近最久未应用的页面进行淘汰。罕用的 LRU 算法如下

一般的 LRU

  一般的 LRU 在新增元素时,将元素退出到汇合头部,如果退出之前汇合曾经满了,那么汇合尾部的元素将会被移除,如果在汇合中的元素有被应用,那么就将这个元素退出到汇合头部,上图因为汇合满了,1 号元素被淘汰了,当汇合中的元素再次被应用时,改元素会挪动到头部,如下图所示。

  介绍了一般的 LRU 再来看看 Buffer Pool 应用的 LRU,它是基于一般的 LRU 根底上进行过优化的,其构造如下图所示。

优化过的 LRU

  区别于一般的 LRU 构造, 它将外部按比例分成 2 段,前 5 / 8 区域被定义为“年老代”,后 3 / 8 区域被定义为“老年代”,每当有新的元素要退出到 Buffer Pool 中时,不会间接退出到“新生代”的头部,而是会先加到“老年代”的头部,当“老年代”区域的数据被读取时,该数据就会被退出到“年老代”区域。

  咱们能够看到,当“老年代”区域的 7 号元素被读取时,该元素被退出到“年老代”区域,而“年老代”区域尾部的数据则被挪动到“老年代”区域的头部地位。

  这么做的益处是什么?首先咱们得晓得,mysql 读取数据时,会对其左近的数据进行 预读,当一部分数据被读取时,其左近的数据大概率也会被读取,由此来进步读取数据的效率。

思考问题 1:mysql 预读的数据并没有被应用怎么办?</Center>

  若采纳传统的 LRU 算法,如果 MySql 预读了大量的数据,而后续没有被应用到,这些数据将间接会被放入到汇合的头部,这样就白白浪费了空间,而通过优化的 buffer pool 在面对这种预读了然而并未应用的数据采纳了比拟好的策略,首先只有 MySql 读取数据,这部分数据就会退出到“老年代”区域的头部,一旦“老年代”区域里的数据被应用,这部分数据就会退出到“年老代”区域的头部,当“年老代”区域的数据满了,“年老代”区域尾部的数据就会进入到“老年代”区域头部。每当有数据新退出时,会退出到“老年代”区域的头部,如果“老年代”区域的数据满了,那么就淘汰“老年代”区域尾部的数据,因而优化后的 LRU 在面对 预读生效 (数据被读进 Buffer Pool 然而并没有用上) 的状况下依然有很好的成果。

思考问题 2:因为 SQL 没写好把整张表的数据都读出来了,LRU 内数据岂不是全换了?

  当某一个 SQL 语句扫描出大量的数据时,这些数据先会被退出到”老年代“区域,而后再被增加到”年老代“区域,这可能导致缓冲池的所有页都替换进来 导致大量的热数据被换出 MYSQL 性能急剧下降这种状况叫缓冲池净化。

MySQL 缓冲池退出了一个“老生代停留时间窗口”的机制:

1. 假如 T = 老生代停留时间窗口
2. 插入老生代头部的页,即便立即被拜访,并不会立即放入新生代头部
3. 只有满足“被拜访”并且“在老生代停留时间”大于 T,才会被放入新生代头部

3、相干的配置

  MySql 反对对 Buffer Pool 的大小的配置、对“老年代”区域和“年老代”区域的比例的配置以及“老生代停留时间窗口”的配置。

show variables like '%innodb_buffer_pool_size%'; -- 查看 buffer pool 的大小
show variables like '%innodb_old_blocks_pct%'; -- 查看老年代与新生代的比例(设置成 100 就是一般的 LRU)show variables like '%innodb_old_blocks_time%'; -- 查看工夫阈值



4、Buffer Pool 与 Query Cache 的区别

  Query Cache 缓存相似哈希表存储,是将 Sql 脚本通过 Hash 作为 Key,后果集当做 Value 如果每次执行的 Sql 语句不一样 (大小写不一样也算作不一样) 那么就不可能能读到缓存。

  Buffer Pool 是将实在的数据进行缓存,任何 SQL 都有可能间接命中 Buffer Pool 中的数据 因此缩小磁盘 IO 优化了性能。

5、总结

  通过 Buffer Pool 的机制能够适当的调节配置来优化以后的一个业务环境, 批改 SQL 语句来尽量让更多的内存来存储缓存热点数据。

参考资料
https://dev.mysql.com/doc/ref…

❤️ 谢谢反对

以上便是本次分享的全部内容,心愿对你有所帮忙 ^_^

喜爱的话别忘了 分享、点赞、珍藏 三连哦~。

欢送关注公众号 程序员巴士,一辆乏味、有范儿、有温度的程序员巴士,涉猎大厂面经、程序员生存、实战教程、技术前沿等内容,关注我,交个敌人。

正文完
 0