ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

innodb的缓冲池(buffer pool)

2022-06-27 17:06:39  阅读:180  来源: 互联网

标签:8k 16k buffer innodb 内存 mysql pool


参数:innodb_buffer_pool_size。我们线上基本上设置50-75%。设过80,发现OOM有点严重。

不过这个值肯定是越大,性能越好。

如何在缓冲池中标记一个页?

(space,page_num)

space指的是你ibd文件的编号。在information_shcema中 innodb_sys_tablespaces中,就有标注表的space id。

同样innodb_buffer_page中。就有当前缓冲池中有哪些页。

另外,线上不要看这个表,你用来学习没问题。

 

那么问题来了。大家都知道,在disk中,mysql是用b+树来管理数据的。

那么如果我要查询的数据,就在内存中,但是此时内存中有1w个页同时存在。怎么快速定位。或者说,内存中,mysql是怎么管理page的。

答案是hash表。用(space,page_num)做的索引列。

 

而缓冲池中,不仅仅只有数据页,还有其他东西要存放。

比如:

数据页,change buffer(这么写肯定不专业,因为change buffer包括很多,比如insert buffer,delete buffer,不过我懒。),自适应hash,锁(没错,mysql的锁信息是保存在内存中的,和oracle不一样)。

另外关于锁的部分有一点要补充。5.5版本前,你要向内存中存放锁信息,其实是向bf申请16k的页,不够继续要,也就是说,你可能加锁失败。5.5之后就好很多了,直接找操作系统要,底层代码是直接malloc。

 

上次我们有聊过compressed压缩表。比如说你disk中,页大小是8k。

那么加载到内存中后,会先解压,并且同时在内存中持有一个8k页和一个16k页。并且在二次读取的时候,直接读16k页,不用重复解压。

那么如果要对这个页上的row做dml怎么办?

实际上是会对16k的页直接改数据,然后在8k的数据页上写redo log。如果8k的页写redo log写满了,mysql会对16k的页进行压缩,如果压缩不到8k,那么会再申请一个8k页和16k的解压页。至于落盘,则是直接落8k。

记录日志的原因就是不用每次写入都进行解压和压缩。节约cpu。所以压缩表是用cpu换IO,这是优点。缺点就是占bf。如果你线上表要做报表,也就是olap,那么就不要开压缩表了。join很占内存的。

 

未完待续。

标签:8k,16k,buffer,innodb,内存,mysql,pool
来源: https://www.cnblogs.com/white-zhan/p/16416725.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有