mysqld重启之后,innodb buffer pool几乎是空的,没有任何的缓存数据。
随着sql语句的执行,table中的数据以及index 逐渐被填充到buffer pool里面,
之后的查询语句只需要在内存中操作(理想状态下),大幅度提升了mysql的性能。
这个逐渐填充的过程可能需要1-2个小时,甚至更久也说不准。在此过程中,mysql性能一般,因为需要大量的硬盘读操作。
如果能在mysqld重启之后,想办法把所需的数据立刻填充到buffer pool中,
就可以解决这个问题了。
假设所有表的数据量+索引数据量加在一起,比innodb buffer
pool还要小一些,那么就可以把这些数据全部加载到buffer pool里面:
SELECT * FROM table1;
SELECT index_col FROM table1;
SELECT * FROM table2;
SELECT index_col FROM table2;
....
....
把上面的语句保存到/tmp/a.sql
然后修改my.ini,添加一行:
init_file = /tmp/a.sql
在mysqld重启之后,会首先执行这个sql文件,之后,buffer pool就填充完毕了。
当然这是一种比较理想的状态了,如果数据量超过buffer pool的大小,就要做数据的筛选—-哪些数据需要预加载。
mysql 5.6开始,新加了一张表:
information_schema.innodb_buffer_page,里面记录了buffer page中数据的信息。
SELECT SUBSTRING_INDEX(TABLE_NAME, '/', 1) AS schema_name
, SUBSTRING_INDEX(TABLE_NAME, '/', -1) AS TABLE_NAME
, IF(index_name = 'PRIMARY', SUBSTRING_INDEX(TABLE_NAME, '/', -1)
, IF(index_name = 'GEN_CLUST_INDEX', SUBSTRING_INDEX(TABLE_NAME, '/', -1), index_name)) AS object_name
, IF(index_name = 'PRIMARY', 'TABLE', IF(index_name = 'GEN_CLUST_INDEX', 'TABLE', 'INDEX')) AS object_type
, COUNT(*) AS cnt
FROM innodb_buffer_page
WHERE SUBSTRING_INDEX(TABLE_NAME, '/', 1) IS NOT NULL
GROUP BY schema_name, TABLE_NAME, object_name, object_type
ORDER BY cnt DESC
LIMIT 10;
+-------------+--------------+----------------+-------------+------+
| schema_name | TABLE_NAME | object_name | object_type | cnt |
+-------------+--------------+----------------+-------------+------+
| zabbix | history_uint | history_uint | TABLE | 2190 |
| zabbix | history_uint | history_uint_1 | INDEX | 1202 |
| zabbix | trends_uint | trends_uint | TABLE | 362 |
| zabbix | history | history | TABLE | 205 |
| zabbix | history | history_1 | INDEX | 199 |
| zabbix | trends | trends | TABLE | 66 |
| zabbix | history_str | history_str | TABLE | 54 |
| test | test | test | TABLE | 41 |
| zabbix | history_str | history_str_1 | INDEX | 39 |
| zabbix | auditlog | auditlog | TABLE | 26 |
+-------------+--------------+----------------+-------------+------+
其实有的时候,也未必是整张表都要预加载,这个还不知道怎样去判断。
操,你全家好吗?
MySQL 5.6 Labs release 提供了一个新功能:buffer pool的导出和导入….大爷的。
The contents of the InnoDB buffer pool(s) can be saved on disk
before MySQL is shutdown and then read up after a restart so that
the warm up time is drastically shortened – the buffer pool(s) go
to the state they were before the server restart!
就像是休眠一样。
手工导出的话,可以用这个命令:
mysql> SET innodb_buffer_pool_dump_now=ON;
然后mysql会在innodb的数据目录中生成一个文件:ib_buffer_pool
关闭mysql的时候,自动导出:
mysql> SET innodb_buffer_pool_dump_at_shutdown=ON;
在my.cnf中加上 innodb_buffer_pool_load_at_startup=ON
就会在mysqld启动之后,重新加载buffer pool。
还有二个status变量可以看看:
mysql> SHOW STATUS LIKE 'innodb_buffer_pool_dump_status';
mysql> SHOW STATUS LIKE 'innodb_buffer_pool_load_status';
加载的操作也可以被打断的:
mysql> SET innodb_buffer_pool_load_abort=ON;