innodb的缓冲池(buffer 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