InnoDB缓冲池,用于把数据和索引缓存在内存中。了解InnoDB缓冲池如何工作,将频繁访问的数据保存在内存中,是MySQL调优的一个重要方面。
理想情况下,您将缓冲池的大小设置为尽可能大的值,但服务器上的其他进程需要有足够的内存。缓冲池越大,InnoDB就越像是内存数据库,从磁盘读取数据一次,随后的读取过程中从内存中访问数据。缓冲池大小是使用innodb_buffer_pool_size项配置。
对于具有大内存大小的64位系统,可以将缓冲池分为多个部分,以最大限度地减少并发操作之间对内存结构的争用。
尽管数据库操作突然激增,仍可以将经常访问的数据保留在内存中
您可以控制InnoDB何时以及如何执行预读请求,以异步预取页面到缓冲池中,预计这些页面将很快需要使用。
可以控制何时清洗缓冲池里的脏页面,以及InnoDB是否根据工作负载动态调整刷新率
您可以将InnoDB配置为保留当前的缓冲池状态,以避免重新启动服务器后长时间的热身期。您也可以在服务器运行时保存当前的缓冲池状态。
InnoDB Buffer Pool LRU Algorithm
InnoDB使用(LRU)算法的变体,将缓冲池作为list来管理。
当需要将新页面添加到池中时,InnoDB会清除最近最少使用的页面,并将新页面添加到列表的中间。这个“中点插入策略”将列表视为两个子列表:
旧的子列表包含较少使用的页面;这些网页是驱逐的候选人。
3/8的缓冲池专门用于旧的子列表。
列表的中点是新子列表的尾部与旧子列表的头部相交的边界。
当InnoDB将一个页面读入缓冲池时,它最初将它插入到中间点(旧子列表的头部)。一个页面可以被读入,因为它是用户指定的操作(如SQL查询)所必需的,或者作为InnoDB自动执行的预读操作的一部分。
在旧的子列表中访问一个页面使其变“年轻”,将其移动到缓冲池的头部(新子列表的头部)。如果页面因为需要而被读入,则第一次访问立即发生并且页面变得年轻。如果由于预读而导致页面被读入,则第一次访问不会立即发生(并且在页面被驱逐之前根本不会发生)。
默认情况下,查询读取的页面会立即移动到新的子列表中,这意味着它们停留在缓冲池中的时间更长。一个表扫描(例如执行一个mysqldump操作,或一个没有WHERE子句的SELECT语句)可以将大量数据带入缓冲池,驱逐一个等量的旧数据,即使新的数据不再被使用。同样,由预读后台线程加载,然后只访问一次的页面移动到新列表的头部。这些情况可以将经常使用的页面推送到旧的子列表,在那里他们成为驱逐的对象。