我們有bash腳本(作業包裝)寫入文件,啓動作業,然後在作業完成後追加到文件信息工作。包裝器在幾千個批處理節點中的一個上運行,但只有幾個批處理機器(我相信RHEL6)訪問一個NFS服務器,並且在不同的批處理節點上使用不同的批處理節點上的至少一個已知實例NFS服務器。在所有情況下,只有一個客戶端主機正在寫入有問題的文件。有些工作需要數小時才能完成,有些需要數分鐘。隨機破壞文件創建/更新從一個單一的客戶端上的shell腳本到NFS安裝
在發生這種情況的同一時間段內,10萬個工作中似乎有10-50個問題。
以下是我認爲有效地工作包裝的(蒸餾水)版本:
#!/bin/bash
## cwd is /nfs/path/to/jobwd
## This file is /nfs/path/to/jobwd/job_wrapper
gotEXIT()
{
## end of script, however gotEXIT is called because we trap EXIT
END="EndTime: `date`\nStatus: Ended」
echo -e "${END}" >> job_info
cat job_info | sendmail [email protected]
}
trap gotEXIT EXIT
function jobSetVar { echo "job.$1: $2" >> job_info; }
export -f jobSetVar
MSG=「${email_metadata}\n${job_metadata}」
echo -e "${MSG}\nStatus: Started" | sendmail [email protected]
echo -e "${MSG}" > job_info
## At the job’s end, the output from `time` command is the first non-corrupt data in job_info
/usr/bin/time -f "Elapsed: %e\nUser: %U\nSystem: %S" -a -o job_info job_command
## 10-360 minutes later…
RC=$?
echo -e "ExitCode: ${RC}" >> job_info
所以我認爲有兩種可能:
echo -e "${MSG}" > job_info
此命令拋出淘汰腐敗數據。/usr/bin/time -f "Elapsed: %e\nUser: %U\nSystem: %S" -a -o job_info job_command
這會損壞現有數據,然後正確輸出數據。
但是,有些工作,但不是全部,調用jobSetVar,它不會最終被損壞。
因此,我深入研究time.c(從GNU時間1.7開始),以查看文件何時打開。總之,time.c有效的是這樣的:
FILE *outfp;
void main (int argc, char** argv) {
const char **command_line;
RESUSE res;
/* internally, getargs opens 「job_info」, so outfp = fopen ("job_info", "a」) */
command_line = getargs (argc, argv);
/* run_command doesn't care about outfp */
run_command (command_line, &res);
/* internally, summarize calls fprintf and putc on outfp FILE pointer */
summarize (outfp, output_format, command_line, &res);/
fflush (outfp);
}
所以,時間已經FILE *outfp
(job_info手柄)打開作業的全部時間。然後它在作業結束時寫入摘要,然後實際上並沒有出現關閉文件(不確定這對fflush是否必要?)我不知道bash是否也同時打開了文件句柄。
編輯:
損壞的文件通常將結束由損壞的部分,隨後與非損壞的部分,其可以是這樣的:
損壞的部分,這將發生之前非損壞的部分,典型地是在很大程度上一堆0x0000時,其中混合有也許有些環狀垃圾:
以下範例hexdump都:
40000000 00000000 00000000 00000000
00000000 00000000 C8B450AC 772B0000
01000000 00000000 C8B450AC 772B0000
[ 361 x 0x00]
然後,在第409個字節,它繼續與未損壞部分:
Elapsed: 879.07
User: 0.71
System: 31.49
ExitCode: 0
EndTime: Fri Dec 6 15:29:27 PST 2013
Status: Ended
另一個文件是這樣的:
01000000 04000000 805443FC 9D2B0000 E04144FC 9D2B0000 E04144FC 9D2B0000
[96 x 0x00]
[Repeat above 3 times ]
01000000 04000000 805443FC 9D2B0000 E04144FC 9D2B0000 E04144FC 9D2B0000
其次是無損壞的部分:
Elapsed: 12621.27
User: 12472.32
System: 40.37
ExitCode: 0
EndTime: Thu Nov 14 08:01:14 PST 2013
Status: Ended
還有其他文件有更多的隨機腐敗部分,但超過一些是週期性類似於上述。
編輯2:從echo -e
聲明發送的第一封電子郵件通過罰款。由於沒有郵件元數據損壞,最後的電子郵件永遠不會被髮送。所以MSG
在這一點上沒有被破壞。假設job_info 可能在這一點上也沒有損壞,但我們還沒有能夠驗證。這是一個沒有主要代碼修改的生產系統,我通過審計證實沒有任何作業可以同時運行,並且會觸及此文件。這個問題似乎是最近的(最近2個月),但它有可能發生在之前,並且滑落。此錯誤確實會阻止報告,這意味着作業被視爲失敗,因此通常會重新提交作業,但特定用戶中有一位用戶具有約9小時的作業,其中此錯誤尤其令人沮喪。我希望我能夠提供更多信息或隨意重現這一點,但我希望有人可能會看到類似的問題,特別是最近。我不管理NFS服務器,但我會嘗試與管理員交談,以瞭解在發生這些問題時(RHEL6,我相信)哪些更新NFS服務器正在運行。
有趣的效果!你能否包含一個破壞文件通常看起來像什麼的例子? –
我已經添加了幾個示例 – Brian