Jeremy Cole同学写了个补丁,用于将InnoDB 缓冲池(buffer pool)里的列表在关闭mysqld时保存到本地文件中,重启启动时再加载到内存中去。该补丁目前只适用于MySQL 5.1版本。作者计划该补丁至少应具备以下几点要求:
- 可以自定义本地文件名
- 可以在启动时自主选择是否需要加载到内存中
- 支持在接受用户请求前先加载一部分,剩下的可以放到后台进程中继续加载
不过,作者目前只是想到了以下几点特性,虽然有的还没有实现:
- 采用多线程来加载,这对于使用RAID阵列更有优势
- 支持在线保存/还原缓冲池,而无需重启mysqld
- 增加缓冲池的统计信息,便于在加载时能选择哪些优先级别比较高,避免所有的页都以同一优先级加载
下面我们来尝试用以下这个补丁,看看效果如何。
1、准备
[yejr@localhost yejr]# cd innodb_plugin-1.0.1
[yejr@localhost yejr]# patch -p1 < ../buffer_pool_save_restore.patch
patching file handler/ha_innodb.cc
Hunk #1 succeeded at 1986 with fuzz 2 (offset 67 lines).
patching file include/srv0start.h
patching file srv/srv0start.c
Hunk #1 succeeded at 1950 (offset 18 lines).
[yejr@localhost yejr]# cd ..; alias cp=cp; cp -rf innodb_plugin-1.0.1/* mysql-5.1.26-rc/storage/innobase/
[yejr@localhost yejr]# cd mysql-5.1.26-rc
[yejr@localhost yejr]# ./configure '-without-embedded-server' '-with-innodb' '-with-zlib-dir=bundled' '-with-big-tables' '-enable-assembler' '-enable-local-infile' '-with-pic' '-prefix=/usr/local/mysql' '-with-extra-charsets=complex' '-enable-thread-safe-client' && make && make install-strip
[yejr@localhost yejr]# strings /usr/local/mysql/libexec/mysqld | grep ib_buf_pool_state
可以看到,已经将该补丁编译进去了。在这里,也可以下载
percona 提供的源码,里面已经集成了其他的几个补丁。
2、测试
首先,模拟各种方法,将innodb buffer pool尽量填满,最快的办法就是导出全部数据。设置 innodb_buffer_pool_size 大小为 14G,然后导出全部数据,可以看到全部被填满了:
...
Buffer pool size 917503
Free buffers 0
Database pages 917503
Modified db pages 0
...
关闭mysqld,查看一下是不是产生了本地文件。
[yejr@localhost yejr]# mysqladmin shut
[yejr@localhost yejr]# ls -lh ib_buf_pool_state
-rw-rw---- 1 mysql mysql 19M Oct 8 14:34 ib_buf_pool_state
[yejr@localhost yejr]# file ib_buf_pool_state
ib_buf_pool_state: ASCII text
[yejr@localhost yejr]# head -2 ib_buf_pool_state
43 1344258 0 69 0 122
43 1344259 0 69 0 122
[yejr@localhost yejr]# wc ib_buf_pool_state
917439 5504634 19545127 ib_buf_pool_state
然后启动mysqld,可以看到日志中记录了大量类似下面的内容:
....
081008 14:36:28 mysqld_safe Starting mysqld daemon with databases from /data/mysql
081008 14:36:30 InnoDB: highest supported file format is Barracuda.
081008 14:36:35 InnoDB Plugin 1.0.1 started; log sequence number 205351853106
succeeded for space=43 offset=1344258 table_id=0 69 index_id=0 122
succeeded for space=43 offset=1344259 table_id=0 69 index_id=0 122
.....
然后,再看看buffer pool的情况:
...
Buffer pool size 917503
Free buffers 0
Database pages 917503
Modified db pages 0
...
可以看到,几乎填满了所有buffer pool,相当于还原到了重启前的内存状态,省去了需要经过一段时间运行才能使内存填满所需缓冲的过程,实在是方便。不过,它也有一个致命的缺点,那就是如果你的buffer pool较大(测试时最高用到14G),则启动可能会非常慢,有时候甚至无法忍受。我的测试服务器配置应该说还算不错了(dell 2950, 16Gb ram, MD3000盘阵),然而上面的测试中,启动mysqld居然花了几乎7个小时才完成,根本无法忍受。
把buffer pool大小调成6G,还是执行上面的测试,发现启动时间立刻缩小了很多,只需要
2min53s。
注意:不建议在非常重要的系统中使用该补丁,万一出了问题,没人为你负责 :)
附:下面是我的一些测试数据
417439 3m0.737s
617439 4m50.357s
637439 5m38.622s
667439 6m8.553s
717439 7m10.761s
727439 7m14.659s
827439 6h20m
第一列是表示 ib_buf_pool_state 文件中有多少行数据。另外,可以通过 head/tail/grep 等工具来自主选择需要被重新加载的buffer内容。
本文转自叶金荣51CTO博客,原文链接:http://blog.51cto.com/imysql/308841,如需转载请自行联系原作者