问题描述
最近基于MySQL自动恢复脚本做集群实例功能,发现在部分机器上触发时会存在扩展失败的情况。
具体表现为:
- 恢复失败机器为MySQL使用机器,此前是能够恢复成功。
- 通用备份机器仍然能够恢复成功。
通过查看恢复日志发现报以下错误:/bin/sh: line 1: 362302 Segmentation fault (core dumped)
注:MySQL自动恢复脚本是本人开发的一套自动备份恢复体系中的恢复模块,主要是利用innobackupex
工具+传入参数能够进行一键化进行MySQL实例恢复操作。能够只恢复指定库表数据、指定GTID位点等。
排查过程
根据报错描述,段异常。感觉是在MySQL实例恢复过程中,访问了非法地址,类似于内存溢出场景。
第一想法是innobackupex
二进制文件损坏,于是通过对比不同机器上innobackupex
工具的版本以及md5值,发现并没有区别。所以排除工具问题。
接着,怀疑是机器某些配置被修改导致的,于是询问组内伙伴和OPS团队。均得到未修改的回答。。。。此处陷入没有头绪的情况。
但是我还是肯定是机器层面的问题,于是就开始了瞎猫碰死耗子的试探之路。不断的对比成功机器和失败机器之间的系统参数区别。
在ulimit -a
时发现存在多个配置不同,于是通过一个一个修改尝试,最终确定是以下参数导致的:
失败机器:stack size (kbytes, -s) 1024
成功机器:stack size (kbytes, -s) 8192
问题原因确定,于是拿着这个参数询问。得到老大的回答,为了使DB机器配置标椎化,最近对MySQL机器的此参数进行了批量修改的操作。(此前Mongo机器都是1024)
结论
这个参数有什么用?为什么会导致MySQL恢复失败呢?
百度对stack size
的表述是:进程的栈的最大值
在程序运行时,如果程序比较大,那么就会遇到“段错误”(segmentation fault),主要就是收到了这个参数的限制。
PS:为什么不将这个值设置成默认值,而是调小呢?我老大说DB都是属于并发多的服务,这个值如果设置的太大的话,会导致存在大量无用内存的损耗。虽然没搞懂,我还是认为不应该修改这个值,当前太菜了,后面有机会再深入研究吧。