数据缓存,数据库存储数据说到底就是存储在磁盘上,数据会以页形式存储在数据库的表空间里(数据库数据文件)。
问题:磁盘的数据IO读取是比较慢的,相对于内存中读取速度是没法比的;一个是马拉车,一个是中国高铁。
InnoDB引擎在访问某个数据时,就会以页为单位,把数据所在的页所有数据,加载到内存中;然后在内存中读写数据。在读写数据之后,并没有立刻把整页所占的内存空间释放掉,而是将其缓存起来,将来再次访问该页面的时候,就会省去磁盘IO的读取开销了。
InnoDB引擎在数据库启动的时候,向操作系统申请了一片连续的内存,并起了个专业的名词“Buffer Pool”——缓存池。默认情况下Buffer Pool只有128M大小。可以通过配置参数,单位是byte(字节)。 128 M = 134 217 728 byte,256M = 268 435 456 byte。下限最小值是5M,低于5M一律按照5M大小。
innodb_buffer_pool_size = 268 435 456 是不是要考虑5%
页默认缓存大小和磁盘存储页的大小是一样,16kb。Buffer Pool不仅保存页数据,还要保存页的控制信息数据。控制信息与页数据是一一对应的。每个页的控制信息大小是808字节,innodb_buffer_pool_size并不包含页的控制信息,换算出来设置Buffer Pool大小,是页的整数倍值Val,加上这个值Val的5%。16kb * n +(16kb * n * 5%),这样就避免了buffer pool缓冲池碎片过大的问题,空间利用率较高。
Free链表,基点元素(链表的头,尾及数量信息)(单独的内存空间存储)+所有空闲的缓存页信息,一般初始化时,是整个划分的内存空间缓存页信息。每当从磁盘读取一页数据时,就会从Free链表里取一个空闲的缓存页,并把该页对应的控制信息填上,然后把缓存页信息从Free链表中移除。完成了数据库页数据加载到Buffer Pool的过程。
别急,紧跟上一步,还需要一个Hash表,存储key(表空间+页号)<:>value(缓存页的数据),这样在查询访问某个页数据时可以快速的定位到页。如果没有就从Free链接选一个空闲页,从磁盘读取页的数据加载到该缓存页中。
以上完成了数据页读取加载到缓存的流程。