MySQL内核InnoDB存储引擎详解(8)

Making the Buffer Pool Scan Resistant 
新读取的数据页被插入到buffer pool的LRU列表的中间位置,默认位置是从尾部开始算起的3/8的位置。当被放入buffer pool的页被第一次访问时就开始往列表的前方移动,而这样列表的后部就是不经常访问的页甚至是从不访问的页。 
通过参数innodb_old_blocks_pct可以控制列表中”old” 数据页所占的百分比,默认是37%,等同于3/8,取值范围是5~95。

Innodb_old_blocks_time参数默认是1000毫秒,指定了页面读取到buffer pool后但没有移动到经常被访问列表位置的时间窗口。

InnoDB buffer pool预存取(read-ahead) 
Read ahead是异步地预先获取多个数据页到buffer pool的IO操作,这些数据页都是假定会随后被用到的。 InnoDB通过两种read-ahead算法提高IO性能:

线性read ahead:预测哪些页会被顺��访问。通过innodb_read_ahead_threshold参数调整顺序数据页的数量。当从一个区中顺序读取的页数量大于等于 
innodb_read_ahead_threshold时, innodb会触发异步read ahead操作将真个区都读到buffer pool中。该参数的默认值是56,取值范围是0~64。 
随机read ahead:通过已经在buffer pool中的数据页来预测哪些页会被随后访问到。如果13个连续的处于相同区的页存在于buffer pool中,则InnoDB会把同一个区的其它页都读取进来。通过设置innodb_random_read_ahead=ON来开启此方式。

通过执行show engine innodb status命令显示的三个参数判断read-ahead算法的有效性:

Innodb_buffer_pool_read_ahead
Innodb_buffer_pool_read_ahead_evicted
Innodb_buffer_pool_read_ahead_rnd

InnoDB buffer pool flushing配置

Innodb会在后台将buffer pool中的脏页(已经修改但没有写到数据文件)flush掉。当buffer pool中的脏页所占百分比达到innodb_max_dirty_pages_pct_lvm会触发flush,当所占比例达到innodb_max_dirty_pages_pct时,则innodb会“强烈” 的flush。 
针对数据修改操作频繁的系统, flush可能会严重滞后导致有大量的buffer pool内存占用,有一些参数专门针对修改繁忙的系统可以调整:

Innodb_adaptive_flushing_lwm:为防止redo log被填满,此参数设置一个阈值,如果redo log的容量超过此阈值,则执行adaptive flush操作。

Innodb_max_drity_pages_pct_lwm
Innodb_io_capacity_max
Innodb_flushing_avg_loops

重置buffer pool状态

InnoDB可以通过配置innodb_buffer_pool_dump_at_shutdown参数来确保在mysql正常重启时部分经常使用的数据页能直接加载到buffer pool中,通过批量加载的方式, 以节省重启mysql导致的warmup时间(原先在buffer pool中的数据页要从磁盘再次加载到内存中)。 

Buffer pool的状态可以在任意时刻被保存,而重置状态也可以恢复任意保存的副本。 
在数据库运行期间动态配置buffer pool数据页保留占比的方式是:

SET GLOBAL innodb_buffer_pool_dump_pct=40;
而在配置文件中的配置方法为:
[mysqld]
innodb_buffer_pool_dump_pct=40
配置当服务器关闭时保存buffer pool的当前状态的方法是:
SET GLOBAL innodb_buffer_pool_dump_at_shutdown=ON;
mysqld --innodb_buffer_pool_load_at_startup=ON;
默认情况下innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup两个配置
是开启状态

在关闭MySQL时,会把内存中的热数据保存在磁盘里ib_buffer_pool文件中,位于数据目录下。

数据库运行期间保存和重新加载buffer pool的方法是:

SET GLOBAL innodb_buffer_pool_dump_now=ON;
SET GLOBAL innodb_buffer_pool_load_now=ON;

查看buffer pool保存和重新加载的进度的方法是:

mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status';
+--------------------------------+--------------------------------------------------+
| Variable_name | Value |
+--------------------------------+--------------------------------------------------+
| Innodb_buffer_pool_dump_status | Buffer pool(s) dump completed at 170519 0:16:28 |
+--------------------------------+--------------------------------------------------+
1 row in set (0.00 sec)
mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_load_status';
+--------------------------------+--------------------------------------------------+
| Variable_name | Value |
+--------------------------------+--------------------------------------------------+
| Innodb_buffer_pool_load_status | Buffer pool(s) load completed at 170519 0:14:05 |
+--------------------------------+--------------------------------------------------+
1 row in set (0.00 sec)

监控buffer pool的状态情况

通过show engine innodb status\G;命令可以查看buffer pool的运行情况

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/1fe1e788fe1712d1b3106819c6ce028f.html