配置推送錯誤導致DB被kill
【編者按】這是日常環境發生的一起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)
底層配置管理或者批量操作時,避免使用小眾命令,盡量使用常規命令和成熟工具。