【编者按】这是日常环境发生的一起mysql收到kill信号的问题,作者维西(@维西V )将其整理如下:
【问题表现】
在功能测试时,mysql经常被kill掉,有较统一的时间间隔:
gbk可以看到是明确的kill 信号
【问题原因】
首先排除了人为后台脚本进行kill,检查环境时发现ulimit 有异常参数:
- $ ulimit -t
- 300
- (-t The maximum amount of cpu time in seconds)
- (实际上为,进程消耗cpu的总量,达到阈值后会自己被kill)
【影响范围】
SQA的DB机器8台,web app机器5台
【问题分析】
标准DB模版clone中,和ulimit相关的文件如下,(优先级低->高):
- cat /etc/security/limits.d/tops_dba_limits.conf
- * soft nofile 131070
- * hard nofile 131070
- * soft nproc 131070
- * hard nproc 131070
- cat /etc/security/limits.conf
- * soft nproc 131070
- * hard nproc 131070
- * soft nofile 131070
- * hard nofile 131070
所以ulimit -t参数为默认值unlimited,该机器上的配置文件和clone一致,但运行ulimit -t显示的竟然是300。
经排查发现,OS配置管理时,一个任务为对自己所用资源做限制,
连接进来后申明了ulimit -t 300的session参数
然后该任务不断扩展,增加了重启sshd操作,导致后续ssh进来的进程继承了300的配置,导致问题
(新进程先继承session参数,后读取OS配置文件,但配置文件未写出cpu limit,合并后取300)。
【源码】
- ./kernel/posix-cpu-timers.c:1139
- view sourceprint?
- if (psecs >= sig->rlim[RLIMIT_CPU].rlim_max) {
- /* * At the hard limit, we just die.No need to calculate anything else now.*/
- __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
- return;
- }
- if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
- /* At the soft limit, send a SIGXCPU every second. */
- __group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
- if (sig->rlim[RLIMIT_CPU].rlim_cur
- < sig->rlim[RLIMIT_CPU].rlim_max) {
- sig->rlim[RLIMIT_CPU].rlim_cur++;
- }
- }
【改进措施】
/etc/security/limits.conf中对all账号,显式注明cpu unlimited (soft/hard)
底层配置管理或者批量操作时,避免使用小众命令,尽量使用常规命令和成熟工具。