GreatSQL启动崩溃:jemalloc依赖缺失题目排查
GreatSQL启动崩溃:jemalloc依赖缺失题目排查故障现象:
之前协助用户安装 GreatSQL 测试环境时,遇到一个 case,数据库初始化时没有报错,但是利用mysqld_safe去启动,会直接 crash ,详情报错如下:
.....
<jemalloc>: Error in munmap():Invalid argument
2025-02-13T06:32:20.617961Z InnoDB initialization has satrt.
<jemalloc>: Error in munmap():Invalid argument
2025-02-13T06:32:20Z - mysqld got signal 11;
most likely, you have hit a bug,but this error can also be caused by malfunctioning hardware.
.....用户机器系统为 kylin uos-PC 4.19.17 arm64-desktop ,aarch 64 架构, 配置8C8GB。
题目分析:
检察系统报错日志 tail -n 10000 /var/log/messages | grep memory没有明显报错;
网上查阅资料,mysqld got signal 11 报错的相关信息很少,而且每个遇到signal 11 导致crash 的原因并不相同,有的是磁盘满了,有的是内存题目等等题目。
我把重点放在了 :Error in munmap():Invalid argument 上。查阅jemalloc 官网,得知jemalloc 是一个内存管理器,可以优化内存分配策略、减少内存碎片、提升性能等方面。
检察GreatSQL源码,发如今 mysqld_safe 上找到了 jemalloc 的踪迹:
...
# Add jemalloc to ld_preload if no other malloc forced - needed for TokuDB
#
if test $load_jemalloc -eq 1
then
for libjemall in "${MY_BASEDIR_VERSION}/lib/mysql" "/usr/lib64" "/usr/lib/x86_64-linux-gnu" "/usr/lib"; do
if [ -r "$libjemall/libjemalloc.so.1" ]; then add_mysqld_ld_preload "$libjemall/libjemalloc.so.1"
break
fi
done
fi 进一步检察源码,发现参数load_jemalloc=1,也就是说利用 mysqld_safe 去启动GreatSQL 时,默认利用jemalloc 举行内存管理。
检察用户机器的jemalloc 的信息:
strings lib/libjemalloc.so | grep JEMALLOC_VERSION ,发现没有信息打印;
再次尝试全局查找:
find / -name jemalloc* , 没有找到相关软件。
至此断定,用户的PC端没有 jemalloc 的相关依赖。初步断定是由于缺少软件依赖造成的GreatSQL 服务没法启动。
题目调试
不妨假设假如不利用jemalloc 而改用其他内存管理方式呢?
尝试将 load_jemalloc=1改成 load_jemalloc=0 ,继续利用 mysqld_safe 发现数据库能正常启动。
# ps -ef | grep greatsql
root 4521 10 15:07 ? 00:00:00 /bin/sh /greatsql/svr/greatsql/bin/mysqld_safe --defaults-file=/greatsql/conf/greatsql.cnf
greatsql 617645215 15:07 ? 00:00:02 /greatsql/svr/greatsql/bin/mysqld --defaults-file=/greatsql/conf/greatsql.cnf --basedir=/greatsql/svr/greatsql --datadir=/greatsql/dbdata/data3306/data --plugin-dir=/greatsql/svr/greatsql/lib/plugin --user=greatsql --log-error=/greatsql/logs/error3306.log --pid-file=/greatsql/dbdata/data3306/data/greatsql.pid --socket=/greatsql/dbdata/data3306/data/greatsql.sock --port=3306继续检察源码,发现假如将load_jemalloc 更改成disable (value=0),GreatSQL 会利用 glibc 默认的ptmalloc 举行内存分配。
那假如改用 mysqld方式启动,不利用 mysqld_safe去启动呢?
[*]更改回 mysqld_safe 的默认值: load_jemalloc=1 (控制变量)
[*]利用 mysqld --defaults-file=greatsql.cnf & 去启动
发现数据库也能正常启动。
这时间不妨回首一下mysqld_safe和mysqld的关系:
mysqld_safe 是一个在Unix上启动GreatSQL服务器推荐的方式,可以安全地启动,监控和重启mysqld 进程。
所以假如不指定 malloc_lib 的方式,mysqld利用 glibc 默认ptmalloc举行内存分配。
这时间就有疑问了,为了适配多环境,为什么不继续利用glibc默认的ptmalloc而是利用jemalloc 呢?
网上资料大多都是推荐摒弃 glibc 原生的 ptmalloc,而改用 jemalloc 或者 tcmalloc 作为默认分配器。ptmalloc 的主要题目是内存浪费、内存碎片、以及加锁导致的性能题目。
因为笔者对内存分配原理这块不是很相识,对这一块感兴趣的可以在网上查找相关的资料研究。
[*]ptmalloc、tcmalloc与jemalloc对比分析:https://www.cyningsun.com/07-07-2018/memory-allocator-contrasts.html
而根据以上的分析,更加推荐在缺少GreatSQL 相关软件依赖时 ,手动安装软件(如jemalloc 等)去启动GreatSQL,以提升数据库性能。
总结
[*]对数据库必须的依赖建议放在前期检查里,可以参考相关文章:openEuler、龙蜥Anolis、统信UOS三大主流操作系统下编译GreatSQL二进制包:https://www.greatdb.com/Home/news/news_1/id/501.html
[*]mysqld_safe 默认利用jemalloc举行内存分配
[*]mysqld利用glibc 默认的ptmalloc 举行内存分配
[*]偶然候遇到没有头绪的故障时,可以尝试从源码找到蛛丝马迹,举行题目排查和调试
Enjoy GreatSQL
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]