[文章作者:张宴 本文版本:v1.1 最后修改:2008.06.02 转载请注明出自:http://blog.zyan.cc]
TCMalloc(Thread-Caching Malloc)是google开发的开源工具──“google-perftools”中的成员。与标准的glibc库的malloc相比,TCMalloc在内存的分配上效率和速度要高得多,可以在很大程度上提高MySQL服务器在高并发情况下的性能,降低系统负载。
TCMalloc的实现原理和测试报告请见一篇文章:《TCMalloc:线程缓存的Malloc》
为MySQL添加TCMalloc库的安装步骤(Linux环境):
1、64位操作系统请先安装libunwind库,32位操作系统不要安装。libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。
2、安装google-perftools:
3、修改MySQL启动脚本(根据你的MySQL安装位置而定):
在# executing mysqld_safe的下一行,加上:
保存后退出,然后重启MySQL服务器。
4、使用lsof命令查看tcmalloc是否起效:
如果发现以下信息,说明tcmalloc已经起效:
mysqld 10847 mysql mem REG 8,5 1203756 20484960 /usr/local/lib/libtcmalloc.so.0.0.0
注:2008年6月2日,修正了libunwind在x86_64位操作系统下的编译错误,TCMalloc无法加载等问题。
涉及修改内容:
1、libunwind的编译参数改为:
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
2、增加:
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
3、修改MySQL加载TCMalloc的语句:
export LD_PRELOAD=/usr/local/lib/libtcmalloc.so
感谢网友router。
TCMalloc(Thread-Caching Malloc)是google开发的开源工具──“google-perftools”中的成员。与标准的glibc库的malloc相比,TCMalloc在内存的分配上效率和速度要高得多,可以在很大程度上提高MySQL服务器在高并发情况下的性能,降低系统负载。
TCMalloc的实现原理和测试报告请见一篇文章:《TCMalloc:线程缓存的Malloc》
为MySQL添加TCMalloc库的安装步骤(Linux环境):
1、64位操作系统请先安装libunwind库,32位操作系统不要安装。libunwind库为基于64位CPU和操作系统的程序提供了基本的堆栈辗转开解功能,其中包括用于输出堆栈跟踪的API、用于以编程方式辗转开解堆栈的API以及支持C++异常处理机制的API。
wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz
tar zxvf libunwind-0.99-alpha.tar.gz
cd libunwind-0.99-alpha/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
tar zxvf libunwind-0.99-alpha.tar.gz
cd libunwind-0.99-alpha/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
2、安装google-perftools:
wget http://google-perftools.googlecode.com/files/google-perftools-0.97.tar.gz
tar zxvf google-perftools-0.97.tar.gz
cd google-perftools-0.97/
./configure
make && make install
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
tar zxvf google-perftools-0.97.tar.gz
cd google-perftools-0.97/
./configure
make && make install
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
3、修改MySQL启动脚本(根据你的MySQL安装位置而定):
vi /usr/local/mysql/bin/mysqld_safe
在# executing mysqld_safe的下一行,加上:
引用
export LD_PRELOAD=/usr/local/lib/libtcmalloc.so
保存后退出,然后重启MySQL服务器。
4、使用lsof命令查看tcmalloc是否起效:
/usr/sbin/lsof -n | grep tcmalloc
如果发现以下信息,说明tcmalloc已经起效:
mysqld 10847 mysql mem REG 8,5 1203756 20484960 /usr/local/lib/libtcmalloc.so.0.0.0
注:2008年6月2日,修正了libunwind在x86_64位操作系统下的编译错误,TCMalloc无法加载等问题。
涉及修改内容:
1、libunwind的编译参数改为:
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
2、增加:
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
3、修改MySQL加载TCMalloc的语句:
export LD_PRELOAD=/usr/local/lib/libtcmalloc.so
感谢网友router。
gcc: unrecognized option `-static-libcxa'
/usr/bin/ld: dwarf/.libs/Lfind_proc_info-lsb.o: relocation R_X86_64_PC32 against `_ULx86_64_dwarf_search_unwind_table' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
make[2]: *** [libunwind.la] Error 1
make[2]: Leaving directory `/usr/local/src/libunwind-0.99-alpha/src'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/usr/local/src/libunwind-0.99-alpha/src'
make: *** [all-recursive] Error 1
加上
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
就可以了
加入export LD_PRELOAD = "/usr/local/lib/libtcmalloc.so" 后启动mysql
/bin/sh /usr/local/webserver/mysql/bin/mysqld_safe --defaults-file=/usr/local/webserver/mysql/my.cnf &
报错
/usr/local/webserver/mysql/bin/mysqld_safe: line 12: export: `=': not a valid identifier
/usr/local/webserver/mysql/bin/mysqld_safe: line 12: export: `/usr/local/lib/libtcmalloc.so': not a valid identifier
Starting mysqld daemon with databases from /usr/local/webserver/mysql/data
则提示
LD_PRELOAD: command not found
mysql版本为5.0.22
老大帮忙解决下啊
# 修改 mysql 啟動, 讓他使用 TCMalloc
# 修改 第 387 行, 於此行最前面加入 LD_PRELOAD="/usr/lib/libtcmalloc.so"(在 mysql 啟動前先載入環境變數(mysql 啟動的 script 就是 /usr/bin/mysqld_safe), 讓 tcmalloc = glibc 的 malloc(), 於最前面加入環境變數即可)
387 行就是 mysql start 的那行命令, 此行修改完成如下:
LD_PRELOAD="/usr/lib/libtcmalloc.so" $NOHUP_NICENESS $ledir/$MYSQLD $defaults --basedir=$MY_BASEDIR_VERSION --datadir=$DATADIR $USER_OPTION --pid-file =$pid_file --skip-external-locking 2>&1 | $ERR_LOGGER -t mysqld & wait
但新问题又来了
使用lsof命令查看tcmalloc是否起效:
/usr/sbin/lsof -n | grep tcmalloc
没有发现tcmalloc
试着编译mysql
./configure --prefix=/usr/local/webserver/mysql/ --without-debug --with-unix-socket-path=/tmp/mysql.sock --with-client-ldflags=-all-static --with-mysqld-ldflags="-all-static -ltcmalloc" --enable-assembler --with-extra-charsets=gbk,gb2312,utf8 --with-pthread --enable-thread-safe-client
make提示
/lib/libtcmalloc.a(stacktrace.o)(.text+0xdf): In function `GetStackTrace(void**, int, int)':
src/stacktrace_libunwind-inl.h:65: undefined reference to `_ULx86_64_init_local'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x103):src/stacktrace_libunwind-inl.h:70: undefined reference to `_ULx86_64_get_reg'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x115):src/stacktrace_libunwind-inl.h:78: undefined reference to `_ULx86_64_step'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x28f): In function `GetStackFrames(void**, int*, int, int)':
src/stacktrace_libunwind-inl.h:126: undefined reference to `_ULx86_64_init_local'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x2a4):src/stacktrace_libunwind-inl.h:130: undefined reference to `_ULx86_64_step'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x2be):src/stacktrace_libunwind-inl.h:130: undefined reference to `_ULx86_64_get_reg'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x2e8):src/stacktrace_libunwind-inl.h:137: undefined reference to `_ULx86_64_get_reg'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x2f4):src/stacktrace_libunwind-inl.h:139: undefined reference to `_ULx86_64_step'
/usr/local/lib/libtcmalloc.a(stacktrace.o)(.text+0x30e):src/stacktrace_libunwind-inl.h:139: undefined reference to `_ULx86_64_get_reg'
重新写参数
CFLAGS=-fPIC LDFLAGS="-lunwind -lunwind-ULx86_64" ./configure........
make LDFLAGS="-lunwind -lunwind-ULx86_64" CFLAGS=-fPIC
提示
/usr/bin/ld: cannot find -lunwind-ULx86_64
于是
ln -s /usr/local/lib/libunwind-x86_64.so.7.0.0 /usr/local/lib/libunwind-ULx86_64.so
还是提示/usr/bin/ld: cannot find -lunwind-ULx86_64
估计是google这个工具CPU参数是x86_64而我服务器参数是ULx86_64造成的这个bug
崩溃了!老大救命啊!
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
本文已修正。
是不是不能使用外挂方式哦?
LD_PRELOAD=/usr/local/lib/libtcmalloc.so
能否告知我您的gtalk QQ 或者msn等联系方式,我想请教下,我的email gtalk : keaideala@gmail.com
然后我在make加上参数make LDFLAGS="-lunwind -lunwind-ULx86_64" CFLAGS=-fPIC
报错/usr/bin/ld: cannot find -lunwind-ULx86_64,lib里面没有unwind-ULx86_64.so类似的文件,只有unwind-x86_64,我打算放弃编译,采用外挂的方式使用TCMalloc,但以前的mysql采用的with-mysqld-ldflags=-all-static 方式编译,不支持外挂,请问应该怎么重新编译mysql才能支持外挂
但外挂搞好了
sh 29861 root mem REG 253,0 1598671 7646979 /usr/local/lib/libtcmalloc.so.0.0.0
mysqld 29882 mysql mem REG 253,0 1598671 7646979 /usr/local/lib/libtcmalloc.so.0.0.0
lsof 29913 root mem REG 253,0 1598671 7646979 /usr/local/lib/libtcmalloc.so.0.0.0
grep 29914 root mem REG 253,0 1598671 7646979 /usr/local/lib/libtcmalloc.so.0.0.0
lsof 29915 root mem REG 253,0 1598671 7646979 /usr/local/lib/libtcmalloc.so.0.0.0
具体步骤和张老师的一模一样,只是重新编译了mysql
取消掉静态链接。
需要重新编译一次MYSQL,
configure时要去掉这一个参数 with-mysqld-ldflags=-all-static
我的环境:CentOS 4.6 32bit,不需要安装libunwind库。
为安全起见,你也可以将新的MySQL程序编译安装到不同的路径,启动时数据库文件存放路径指定以前的位置即可。
在MYSQL下载的不用安装的源码不知道是否可以? 还有rpm包如何解决呢?
这个是否可以启用 tcmalloc 呢,lsof 里面没有发现,难道静态编译不进去吗?
QQ 733905
-lstacktrace 参数添加后会报错,说找不到stacktrace,但去掉这个-lstacktrace参数重新编译是可以成功的,但在执行下面的命令时:
[root@Chinarenservice oracle]# lsof -n | grep tcmalloc
[root@Chinarenservice oracle]#
什么也没有发现!说明不成功!
请问张老师,mysql使用该插件和不使用该插件,您有性能测试数据对比么?