枣阳网站开发,做全世界的生意的网站,腾讯静态网站托管,建一个公司网站要多少钱目录Buffer Pool回顾Buffer Pool内部组成freelistflushlistLRU链表管理以及改进Buffer Pool回顾
我们知道针对数据库的增删改删操作都是在Buffer Pool中完成的#xff0c;一条sql的执行步骤可以认为是这样的#xff1a; 1、innodb存储引擎首先在缓冲池中查询有没有对应的数据… 目录Buffer Pool回顾Buffer Pool内部组成freelistflushlistLRU链表管理以及改进 Buffer Pool回顾
我们知道针对数据库的增删改删操作都是在Buffer Pool中完成的一条sql的执行步骤可以认为是这样的 1、innodb存储引擎首先在缓冲池中查询有没有对应的数据有就直接返回 2、如果不存在则去磁盘进行加载并加入缓冲池 3、同时该记录会被加上独占锁防止多人修改出现数据不一致 而且我们知道可以通过设置my.cnf配置中的innodb_buffer_pool_size来修改缓冲池大小加快sql查询速度当然也需要注意设置过大会造成系统swap空间被占用导致系统变慢降低查询性能。
Buffer Pool内部组成
缓冲池对应一片连续内存我们将其划分为大小为16kb的页(与innodb对应)这些页称为缓冲页。 为了很好的管理这些页设计者为每个缓冲页都创建了一些控制信息表空间编号、页号、缓冲页在缓冲池中的地址、链表节点信息等。将每个页对应的控制信息占用的一块内存称为一个控制块。控制块与缓冲页一一对应都存放在缓冲池中。 在Mysql启动时会自己完成对缓冲池的初始化向操作系统申请内存自己划分成若干对控制块和缓冲页。
freelist
当我们从磁盘中load一个数据页到缓冲池中我们应该放到哪个缓冲页中呢 很显然我们应该把数据页放到“空闲”的缓冲页中。 设计者将所有空闲的缓冲页对应的控制块作为一个节点放到一个链表中称为freelist。每次从freelist中取出一个空闲的缓冲页中并且将该缓冲页对应的控制块信息填上然后将该节点移除表示缓冲页已经被使用了
flushlist
当一个控制块节点被从freelist中移除说明该页已经被使用了。如果这种“使用操作”是对数据进行修改的话那么必定需要将该页数据flush到磁盘上。但是每次修改一页就将那一页flush的话磁盘IO占用率高。所以每次修改缓冲页后将这些脏页控制块放入一个fulshlist上。当flush时机到了,就把flushlist节点对应的缓冲页刷新搭配磁盘上。
LRU链表管理以及改进
缓冲池内存有限当freelist中没有多余的空闲缓冲页就需要把某些旧的缓冲页从缓冲池中移除然后把新的数据页放进来。为了提高内存命中率使用LRU。 但是普通的LRU不能解决下面的问题; 1、加载到缓冲池的页不一定被用到针对于预读 2、如果有非常多的使用频率低的页被同时加载到缓冲池中则可能会把那些使用频率非常高的页从缓冲池中淘汰。针对全表扫描 关于innodb对于LRU的改进见如链接 MySQL——Innodb改进LRU算法 当然还有进一步的优化 对于young区域的缓冲页每次访问一个缓冲页就要把它移动到LRU链表的头部开销比较大。毕竟young区域的缓冲页都是热点数据。所以我们可以这样优化只有被访问的缓冲页位于young区域1/4的后面时才会被移动到LRU链表头部。也就是说我们将young的前0.25部分称为very youngvery young里面的数据访问不会移动到头部因为大家访问频率都是非常高的。 提醒一下在LRUlist的节点不是freelist节点可能是flushlist节点。不理解的话再去上面看看两个list定义。 然而这一切的目的只有一个尽量高效地提高缓冲池命中率。