一個“指令碼執行夯死”問題的分析
問題現象:
使用一個指令碼命令分發執行的指令碼,在執行時出現夯死,無法繼續進行
[root@yj01 cluster]# sh clustercmd.sh "ls -l /tmp"
問題分析
- 於是使用指令碼除錯的方式,執行結果如下:
[root@yj01 cluster]# sh -x clustercmd.sh "ls -l /tmp"
+ R_CMD='ls -l /tmp'
+ G_CURRENT_PATH=
+ G_LIB_SCRIPT=cluster_lib.sh
+ G_REMOTE_SCRIPT=remote.sh
+ G_CONF_FILE=cluster.ini
+ G_CONF_FILE_TMP=cluster.ini.tmp.645182
+ G_RESULT=0
+ G_HOSTS_ARRAY=()
+ G_PASSWDS_ARRAY=()
+ '[' /usr/bin/sh '!=' /bin/bash ']'
+ bash clustercmd.sh 'ls -l /tmp'
結果顯示在執行bash clustercmd.sh 'ls -l /tmp'時,長時間夯死,不再繼續進行。
-
繼續使用strace命令檢視指令碼執行情況:
[root@yj01 cluster]# strace sh clustercmd.sh "ls -l /tmp" execve("/usr/bin/sh", ["sh", "clustercmd.sh", "ls -l /tmp"], [/* 32 vars */]) = 0 brk(0) = 0xa17000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f0c603f0000 ...... rt_sigaction(SIGINT, {0x43e5e0, [], SA_RESTORER, 0x7f0c5fa16670}, {SIG_DFL, [], SA_RESTORER, 0x7f0c5fa16670}, 8) = 0 // 在執行到此處時,較長時間夯住,後續丟擲Can't allocate memory異常 ****wait4(-1, clustercmd.sh: fork: Cannot allocate memory*****
此處表示,新fork出一個程式進行命令操作,在等待的過程中,丟擲“Can't allocate memory”異常
-
檢視OS記憶體情況以及最大程式數
// OS的記憶體是充足的 [root@yj01 cluster]# free -g total used free shared buff/cache available Mem: 31 9 17 0 4 21 Swap: 3 0 3 // OS的最大程式數是充足的 [root@yj01 cluster]# sysctl kernel.pid_max kernel.pid_max = 798720 [root@yj01 cluster]# ps -eLf | wc -l 711 [root@yj01 cluster]#
從OS資訊來看,記憶體充足,程式數遠遠小於最大的限制. 因此懷疑在夯住的時間內,產生大量程式,os記憶體被大量佔用,最後出現了上述中的“Cannot allocate memory”
- 再次執行 sh -x clustercmd.sh "ls -l /tmp" 同時檢視OS的記憶體使用以及啟動程式數
// os可用記憶體記憶體大量減少
[root@yj01 ~]# free -g
total used free shared buff/cache available
Mem: 31 9 17 0 4 21
Swap: 3 0 3
[root@yj01 ~]# free -g
total used free shared buff/cache available
Mem: 31 10 16 0 4 20
Swap: 3 0 3
[root@yj01 ~]# free -g
total used free shared buff/cache available
Mem: 31 12 14 0 4 18
Swap: 3 0 3
//程式被大量建立
[root@yj01 ~]# ps -eLf | wc -l
9984
[root@yj01 ~]# ps -eLf | wc -l
10452
[root@yj01 ~]# ps -eLf | wc -l
10981
[root@yj01 ~]# ps -eLf | wc -l
11463
於是懷疑指令碼bug引發啟動大量的程式將OS資源耗完,最後程式執行失敗退出。
- 指令碼分析
檢視指令碼可以看出指令碼中強制使用bash來解析執行,但是在執行bash時可能使用到的不是/bin/bash從而導致程式進入死迴圈。
#!/bin/bash
....
if [ "$BASH" != "/bin/bash" ]; then
bash $0 "$@"
exit $?
fi
檢視環境發現如下:
執行which bash 發現使用的是/usr/bin/bash
[root@yj01 cluster]# which bash
/usr/bin/bash
//檢視環境變數發現 /usr/bin在/bin前面
[root@yj01 cluster]# echo $PATH
/usr/local/openssh-7.4p1/sbin:/usr/local/openssh-7.4p1/bin:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/openssh-7.4p1/bin:/root/bin:/root/bin
[root@yj01 cluster]#
可以看出在執行bash $0 "$@"
時,使用的是/usr/bin/bash 因此程式進入死迴圈
解決方案
修改if判斷條件if [ ${BASH:0-4} != "bash" ]; 只要執行的是bash命令,即可通過
相關文章
- 這樣分析一個死鎖問題
- 一個執行計劃解析的小問題分析
- Slave SQL執行緒與PXB FTWRL死鎖問題分析SQL執行緒
- 執行 shell 指令碼 \r 問題解決指令碼
- crontab不執行mysql的指令碼問題的解決!MySql指令碼
- PHP 避免同時執行一個指令碼PHP指令碼
- iOS——寫一個快速定位問題的指令碼iOS指令碼
- 一個MySQL死鎖問題的反思MySql
- sqlplus 執行大量sql指令碼時遇到問題分析(很常見)SQL指令碼
- Java NIO 執行緒 的一個問題Java執行緒
- 一個多執行緒的PushbackInputStream問題執行緒
- 殺死一個正在執行的程式 (轉)
- 問一個守護執行緒問題?執行緒
- 從一個死鎖問題分析最佳化器特性
- 多執行緒下HashMap的死迴圈問題執行緒HashMap
- 不能執行兩個指令碼的方法指令碼
- 從一個shell指令碼執行出錯聊起指令碼
- 一個MySQL死鎖問題的復現MySql
- 一個ORACLE死鎖問題的追蹤Oracle
- 請教一個多執行緒的問題執行緒
- 多執行緒-死鎖問題概述和使用執行緒
- 多執行緒 HashMap 死迴圈 問題解析執行緒HashMap
- shell指令碼放到crontab裡就執行不成功的問題指令碼
- 關於程式碼如何執行的五個問題
- MySQL 死鎖問題分析MySql
- Sqlserver分析死鎖問題SQLServer
- 線上死鎖問題分析
- Linux 作業系統指令碼格式問題導致指令碼無法執行Linux作業系統指令碼
- 請教一個關於執行緒的問題執行緒
- Linux計劃任務crontab執行指令碼不正確的問題Linux指令碼
- 多執行緒-執行緒安全問題的產生原因分析以及同步程式碼塊的方式解決執行緒安全問題執行緒
- 請教個問題執行 httprunner 遇到的問題HTTP
- 深入分析 Redis Lua 指令碼執行原理Redis指令碼
- MySQL:一個死鎖分析 (未分析出來的死鎖)MySql
- 今天寫了一個統計執行sql次數的指令碼SQL指令碼
- 多執行緒引起的效能問題分析執行緒
- 請教一個事務+多執行緒 的問題執行緒
- 請教一個關於NIO執行方式的問題