現象描述
最近發現我們監控作業偶爾會發出帶有附件ATT00001.bin的郵件,而大部分時候,它都發出帶有內容的郵件,以指令碼mysql_slowlog_monitor.sh來說, 平時會將慢查詢分析報告放在郵件的正文發給DBA,慢查詢分析報告的內容放在郵件中,出現問題的時候,郵件正文沒有內容,它只有 一個附件ATT00001.bin
function send_slow_rpt(){
$PT_QUERY_DIGEST --since=$HOURS $SLOW_LOG_FILE > $ANALYSIS_RPT_FILE
rpt_exist_data=`cat $ANALYSIS_RPT_FILE | wc -l `
if [ $rpt_exist_data -gt 2 ]; then
MAIL_SUBJECT="MySQL slow log report on the `hostname` ($SERVER_IP) at $SLOW_RPT_DATE"
mailx -s "${MAIL_SUBJECT}" -r ${MAIL_FROM} ${MAIL_TO} < ${ANALYSIS_RPT_FILE}
fi
}
原因分析:
分析後發現原因:pt-query-digest生成的慢查詢分析報表,有些SQL語句裡面包含了特殊字元^M,它導致mail將使用回車符 (^M, \r) 字元的 非 Unix 文字檔案將被視為二進位制資料。所以mailx將將其當作附件傳送出來,具體請見下面英文,更多詳細資訊參考參考資料[1]
Mailx expects input text to be in Unix format, with lines separated by newline (^J, \n) characters only. Non-Unix text files that use carriage return (^M, \r) characters in addition will be treated as binary data; to send such files as text, strip these characters e. g. by tr -d '\015'
Mailx will, if it encounters unknown / control characters in text input, convert it into an attachment with application/octet-stream mime-type set.
文字檔案中同時包含回車符和換行符(即Windows風格的文字檔案),mailx會將其視為二進位制資料,從而將郵件正文作為附件傳送,而不是將其作為郵件正文內容。 Mailx 會將其轉換為設定了 application/octet-stream mime 型別的附件。
解決方案
解決方案就是這些特殊字元(^M, \r)置換,鑑於此處特殊情況,我們使用命令dos2unix將文字內容格式直接從Windows替換成Unix格式。簡單高效。
function send_slow_rpt(){
$PT_QUERY_DIGEST --since=$HOURS $SLOW_LOG_FILE > $ANALYSIS_RPT_FILE
rpt_exist_data=`cat $ANALYSIS_RPT_FILE | wc -l `
if [ $rpt_exist_data -gt 2 ]; then
# 有些情況,mysql慢查詢報表中會出現特殊字元(例如^M),導致郵件內容變成附件ATT00001.bin
if [ -x /usr/bin/dos2unix ];then
/usr/bin/dos2unix -k $ANALYSIS_RPT_FILE
fi
MAIL_SUBJECT="MySQL slow log report on `hostname` ($SERVER_IP) at $SLOW_RPT_DATE"
mailx -s "${MAIL_SUBJECT}" -r ${MAIL_FROM} ${MAIL_TO} < ${ANALYSIS_RPT_FILE}
fi
}
1: https://access.redhat.com/solutions/2210791