[InnoDB系列] - InnoDB Buffer Pool保存和还原补丁
参考文章:Making MySQL more usable: InnoDB save/restore buffer pool patch。
Jeremy Cole同学写了个补丁,用于将InnoDB 缓冲池(buffer pool)里的列表在关闭mysqld时保存到本地文件中,重启启动时再加载到内存中去。该补丁目前只适用于MySQL 5.1版本。作者计划该补丁至少应具备以下几点要求:
- 可以自定义本地文件名
- 可以在启动时自主选择是否需要加载到内存中
- 支持在接受用户请求前先加载一部分,剩下的可以放到后台进程中继续加载
不过,作者目前只是想到了以下几点特性,虽然有的还没有实现:
- 采用多线程来加载,这对于使用RAID阵列更有优势
- 支持在线保存/还原缓冲池,而无需重启mysqld
- 增加缓冲池的统计信息,便于在加载时能选择哪些优先级别比较高,避免所有的页都以同一优先级加载
下面我们来尝试用以下这个补丁,看看效果如何。
1、准备
下载innodb plugin 1.0.1,下载补丁buffer_pool_save_restore.patch 和 move_buf_chunk_struct.patch。下载MySQL 5.1.26源码。
然后是解压缩,打补丁,编译。
[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内容。
评论
s7v7nislands (未验证)
周五, 2008/12/12 - 13:18
Permalink
你好!
你好! 不知道你的测试环境还在不在,希望你在做一下测试下面的情况会不会提高恢复速度(没有这么高配置的测试机)。
对dump出来的文件排序,使导入的时候减小随机读。
mv ib_buf_pool_state test
sort -n test > ib_buf_pool_state
csfor (未验证)
周四, 2010/06/17 - 12:45
Permalink
XtraDB
XtraDB 最新release是支持pool buffer 的save和restore的,48G的buffer,save需要几秒,restore需要几分钟,文件大小是2.4M(page_size=16k)。