为了减少服务重启后的预热时间,InnoDB将每个buffer pool中一部分常用的页面保存到磁盘上,并在服务启动时恢复这些页面。存储的常用页面比例由设置项innodb_buffer_pool_dump_pct设置。
在重启一个繁忙的数据库实例后,一般会有一个预热阶段,吞吐量稳步上升,因为buffer pool中的页面被加载到内存中(因为相同的数据会被查询,更新,等等)。在启动时通过从磁盘上加载重启前buffer pool中的页面(而不是等待访问相应记录的DML操作),从而恢复buffer pool的功能缩短了预热时间。同样,I/O请求可以批量进行,使得总体I/O更快。页面加载时后台运行的,不会造成数据库启动延迟。
除了在服务关闭时保存buffer pool状态并在重启时恢复,你还可以在服务运行时,在任意时刻保存并恢复buffer pool的状态。例如,在工作负载稳定并达到稳定的吞吐量后,你可以保存buffer pool的状态。你也可以在运行报告或维护任务(这些任务带到buffer pool中的数据只适用于这些操作),或运行一些非典型工作负载后,恢复之前的buffer pool状态。
虽然一个buffer pool可以额达到数千兆字节,但是InnoDB保存到磁盘中的只是一小部分。只用来定位相关页面的表空间id和页面id才会被保存到磁盘上。这些信息来自于INFORMATION_SCHEMA库的INNODB_BUFFER_PAGE_LRU表。默认情况下,表空间id和页面id数据被保存到一个名为ib_buffer_pool的文件中,这个文件被保存在InnoDB数据目录下。文件名和位置可以通过innodb_buffer_pool_filename设置参数来配置。
因为数据会缓存到buffer pool中并从其中老化(移除),就像常规数据库操作一样(或许译为:随着常规数据库操作,数据会被缓存到buffer pool中或从中移除),如果磁盘页面最近被更新过,或者一个DML操作涉及没有被加载到buffer pool中的数据,是没有任何问题的。加载机制会跳过不存在的页面。
底层机制涉及到一个后台线程,这个后台线程会执行转储和加载操作。
压缩表的磁盘页被以压缩形式加载到buffer pool中。在进行DML操作中访问页面内容时,会解压这些页面。因为解压页面是一个cpu密集型操作,所以在在一个连接线程中执行解压操作比在执行buffer pool恢复操作的单线程中执行效率更高。
下面从以下几个方面描述保存和恢复buffer pool状态的相关操作:
- 设置转储比例
- 在关闭时保存Buffer Pool状态并在启动时恢复
- 在线保存并恢复Buffer Pool状态
- 展示Buffer Pool转储进度
- 展示Buffer Pool加载进度
- 中止Buffer Pool加载操作
- 使用Performance Schema监控Buffer Pool加载进度
设置转储比例 #
在从Buffer Pool中转储页面之前,你可以通过设置innodb_buffer_pool_dump_pct选项来设置你要转储的页面比例。如果你计划服务运行时转储页面,你可以动态设置这个选项:
SET GLOBAL innodb_buffer_pool_dump_pct=40;
如果你计划在服务关闭时转储buffer pool页面,在你的配置文件中设置innodb_buffer_pool_dump_pct。
[mysqld]
innodb_buffer_pool_dump_pct=40
innodb_buffer_pool_dump_pct的默认值是25(转储最近常用页面的25%)。
在关闭时保存Buffer Pool状态并在启动时恢复 #
要在服务关闭时保存buffer pool状态,在关闭之前执行下面的语句:
SET GLOBAL innodb_buffer_pool_dump_at_shutdown=ON;
innodb_buffer_pool_dump_at_shutdown默认开启。
要在服务启动时恢复buffer pool状态,在启动时添加–inodb-buffer-pool-load-at-startup选项:
mysqld --innodb-buffer-pool-load-at-startup=ON;
innodb_buffer_pool_load_at_startup默认开启。
在线保存并恢复Buffer Pool状态 #
要在实例运行时保存buffer pool状态,执行下面的语句:
SET GLOBAL innodb_buffer_pool_dump_now=ON;
要在实例运行时恢复buffer pool状态,执行下面的语句:
SET GLOBAL innodb_buffer_pool_load_now=ON;
展示Buffer Pool转储进度 #
要在保存buffer pool状态到磁盘时展示进度,执行下面的语句:
SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status';
如果操作没有启动,会返回"not started"。如果操作完成,会打印完成的时间(如 Finished at 110505 12:18:02)。如果操作在进行中,会提供状态信息(如 Dumping buffer pool 5/7, page 237/2873)。
展示Buffer Pool加载进度 #
要展示buffer pool加载进度,执行下面的语句:
SHOW STATUS LIKE 'Innodb_buffer_pool_load_status';
如果操作还没有启动,会返回"not restarted"。如果操作已经完成,会打印完成时间(如 Finished at 110505 12:23:24)。如果操作还在进行中,会提供状态信息(如 Loaded 123/22301 pages)。
中止Buffer Pool加载操作 #
要中止buffer pool加载操作,执行下面的语句:
SET GLOBAL innodb_buffer_pool_load_abort=ON;
使用Performance Schema监控Buffer Pool加载进度 #
你可以使用Performance Schema监控buffer pool加载进度。
下面的例子展示了怎样启用 stage/innodb/buffer pool load事件组件和相关消费者来启动对buffer pool加载进度的监控。
要了解本例中使用的buffer pool转储和加载的存储过程的信息,请查阅 本章节信息 。想了解Performance Schema事件组件和相关消费者信息,请查阅章节27.12.5,“Performance Schema Stage Event Tables”。
- 启用stage/innodb/buffer pool load事件组件:
mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES'
WHERE NAME LIKE 'stage/innodb/buffer%';
- 启用时间消费者表(包含events_stages_current,events_stages_history,和events_stages_history_long),
mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES'
WHERE NAME LIKE '%stages%';
- 通过启用innodb_buffer_pool_dump_now来转储当前buffer pool状态:
mysql> SET GLOBAL innodb_buffer_pool_dump_now=ON;
- 检查buffer pool转储状态,确认这个操作已经完成。
mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status'\G
*************************** 1. row ***************************
Variable_name: Innodb_buffer_pool_dump_status
Value: Buffer pool(s) dump completed at 150202 16:38:58
- 通过启用innodb_buffer_pool_load_now来加载buffer pool:
mysql> SET GLOBAL innodb_buffer_pool_load_now=ON;
- 通过查询Performance Schema的events_stages_current表来检查buffer pool加载操作的当前状态。WORK_COMPLETED列展示了加载的页面数量。WORK_ESTIMATED列展示了估算的剩余工作量(按页面计)。
mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED
FROM performance_schema.events_stages_current;
+-------------------------------+----------------+----------------+
| EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED |
+-------------------------------+----------------+----------------+
| stage/innodb/buffer pool load | 5353 | 7167 |
+-------------------------------+----------------+----------------+
如果buffer pool加载操作已经完成,events_stages_current表返回一个空结果接。在这种场景中,你可以通过检查events_stages_history表来查看已经完成的事件的数据。例如:
mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED
FROM performance_schema.events_stages_history;
+-------------------------------+----------------+----------------+
| EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED |
+-------------------------------+----------------+----------------+
| stage/innodb/buffer pool load | 7167 | 7167 |
+-------------------------------+----------------+----------------+
你也可以在用innodb_buffer_pool_load_at_startup加载buffer pool(启动时)时,使用Performance Schema来监控加载进度。在这种情形下,stage/innodb_buffer pool load组件和相关消费者必须在启动时启用。想了解更多信息,见章节27.3,“Performance Schema启动设置”。