[文章作者:张宴 本文版本: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。
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


  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


  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。



技术大类 » 数据库技术 | 评论(48) | 引用(0) | 阅读(70532)
router
2008-5-31 23:45
make 报错啊,老大,怎么办?

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
张宴 回复于 2008-6-1 16:40
32位操作系统不要安装libunwind库,直接安装google-perftools即可。
router
2008-6-1 18:37
我是64位系统啊
router
2008-6-1 21:13
解决了64位libunwind编译不成功的问题
加上
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install

就可以了
router
2008-6-1 21:17
新问题:
加入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
router
2008-6-1 21:27
将export LD_PRELOAD = "/usr/local/lib/libtcmalloc.so"更改为LD_PRELOAD = "/usr/local/lib/libtcmalloc.so"

则提示
LD_PRELOAD: command not found

mysql版本为5.0.22
老大帮忙解决下啊
router
2008-6-1 21:39
把启动的问题解决了,如下:

# 修改 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
router
2008-6-2 00:24
哎,忙活了一晚上,还是不行

试着编译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
崩溃了!老大救命啊!
张宴 回复于 2008-6-2 11:36
启动MySQL之前:
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig

本文已修正。
router
2008-6-2 11:54
老大,mysql采用的静态编译with-mysqld-ldflags=-all-static
是不是不能使用外挂方式哦?
LD_PRELOAD=/usr/local/lib/libtcmalloc.so
能否告知我您的gtalk QQ 或者msn等联系方式,我想请教下,我的email gtalk : keaideala@gmail.com
jack
2008-6-2 14:09
应该是采用了with-mysqld-ldflags=-all-static 就不行!我也遇到同样问题!
router
2008-6-2 17:18
请问张老师,我本来想用编译到mysql的方式使用TCMalloc,但无法编译成功mysql,报错undefined reference to `_ULx86_64_init_local'
然后我在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才能支持外挂
router
2008-6-3 00:18
编译不成功
但外挂搞好了
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
取消掉静态链接。
odinxu
2008-6-5 00:27
终于也安装成功了,和 router 说的一样,
需要重新编译一次MYSQL,
configure时要去掉这一个参数 with-mysqld-ldflags=-all-static
我的环境:CentOS 4.6 32bit,不需要安装libunwind库。
freeke Email
2008-6-5 13:09
有没有不需要重新编译的办法,对于运营系统不能随便动啊!
freeke Email Homepage
2008-6-5 13:11
有没有不需要重新编译MYSQL的办法呢?因为运营系统哪能随便重新编译程序呢?
张宴 回复于 2008-6-5 14:19
原有MySQL不停止,重新编译MySQL,到make && make install完成,不会影响到原有服务。重启MySQL,新编译的配置生效。

为安全起见,你也可以将新的MySQL程序编译安装到不同的路径,启动时数据库文件存放路径指定以前的位置即可。
freeke Email
2008-6-5 13:12
请教博主帮忙!
xooass Email Homepage
2008-6-11 17:55
我完全按上面写的操作修改后重启了也没发现启用这个库,我的mysql是用官方提供的RPM包安装的,可能也是全静态编译了的版本。
freeke Email Homepage
2008-6-12 12:24
我按照张兄的方法重新编译了也没有看到那个tcmalloc!不知道什么原因!

在MYSQL下载的不用安装的源码不知道是否可以? 还有rpm包如何解决呢?
phpsir
2008-6-13 12:00
--with-mysqld-ldflags="-all-static -ltcmalloc -lstacktrace"

这个是否可以启用 tcmalloc 呢,lsof 里面没有发现,难道静态编译不进去吗?

QQ  733905
freeke Email
2008-8-4 12:58
--with-mysqld-ldflags="-all-static -ltcmalloc -lstacktrace"

-lstacktrace 参数添加后会报错,说找不到stacktrace,但去掉这个-lstacktrace参数重新编译是可以成功的,但在执行下面的命令时:

[root@Chinarenservice oracle]# lsof -n | grep tcmalloc            
[root@Chinarenservice oracle]#

什么也没有发现!说明不成功!
mcz
2008-8-30 23:52
tcmalloc,我已经装上了,lsof也能看到
请问张老师,mysql使用该插件和不使用该插件,您有性能测试数据对比么?
分页: 1/3 第一页 1 2 3 下页 最后页
发表评论
表情
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
emotemotemotemotemot
打开HTML
打开UBB
打开表情
隐藏
记住我
昵称   密码   游客无需密码
网址   电邮   [注册]