请求完善Bash脚本:处理表状态未更新触发的P1告警
问题需求
当logger未更新表状态时会触发P1告警,需编写Bash脚本实现以下逻辑:
- 查询test1和test2中
status = 1且CREATED早于当前时间5分钟的记录,对应SQL语句:select * from test1 where status = 1 and CREATED < DATE_SUB(NOW(), INTERVAL 5 MINUTE); select * from test2 where status = 1 and CREATED < DATE_SUB(NOW(), INTERVAL 5 MINUTE); - 若查询到记录,将结果保存至日志,并检查对应临时表(如
TEMP_test1)是否存在; - 若临时表不存在,将对应表中符合条件记录的
status更新为0以清除告警,SQL示例:Update test1 set status = 0 where ID = [对应ID]; - 若临时表存在,通知相关团队进行排查;
- 将步骤1的查询结果发送至
xxx@gmail.com供审核。
现有代码瓶颈
目前已编写部分代码,但在保存查询结果和判断临时表存在性上遇到问题,现有代码如下:
email="pqrs@gmail.com" pid=$$ logFile="/tmp/alertlog" emailflag=0 host=XX.XX.XX.XX user=ABC passwd=XYZ alert_on_error () { echo $1 >> /tmp/$pid.count cat /tmp/$pid.count | mail -s "Error running $0 on `hostname`" $email rm -rf /tmp/$pid.* exit 1 } mysql="mysql --connect-timeout=50 --compress --quick --disable-auto-rehash --skip-column-names -u $user -h $host -p$passwd -A" ID1='$mysql -e "select * from test1 where status = 1 and CREATED < DATE_SUB(NOW(), INTERVAL 5 MINUTE);"' ID2='$mysql -e select * from test2 where status = 1 and CREATED < DATE_SUB(NOW(), INTERVAL 5 MINUTE);"'
完整解决方案脚本
#!/bin/bash # 配置参数 email_recipient="xxx@gmail.com" error_email="pqrs@gmail.com" pid=$$ logFile="/tmp/alertlog" host="XX.XX.XX.XX" user="ABC" passwd="XYZ" # 错误告警函数 alert_on_error () { echo "$1" >> "/tmp/${pid}.count" cat "/tmp/${pid}.count" | mail -s "Error running $0 on $(hostname)" "$error_email" rm -rf "/tmp/${pid}.*" exit 1 } # 定义MySQL命令模板 mysql_cmd="mysql --connect-timeout=50 --compress --quick --disable-auto-rehash -u $user -h $host -p$passwd -A" # 处理单张表的函数 process_table() { local table_name="$1" local temp_table="TEMP_${table_name}" local query_result="/tmp/${pid}_${table_name}_result.txt" # 执行查询并保存结果 $mysql_cmd -e "select * from ${table_name} where status = 1 and CREATED < DATE_SUB(NOW(), INTERVAL 5 MINUTE);" > "$query_result" || alert_on_error "查询${table_name}失败" # 检查是否有符合条件的记录 if [ -s "$query_result" ]; then # 将结果写入日志 echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${table_name}存在超时未更新记录:" >> "$logFile" cat "$query_result" >> "$logFile" echo "------------------------" >> "$logFile" # 检查临时表是否存在 table_exists=$($mysql_cmd -e "SHOW TABLES LIKE '${temp_table}';" | wc -l) if [ "$table_exists" -eq 0 ]; then # 临时表不存在,批量更新status为0 $mysql_cmd -e "UPDATE ${table_name} SET status = 0 WHERE status = 1 and CREATED < DATE_SUB(NOW(), INTERVAL 5 MINUTE);" || alert_on_error "更新${table_name}状态失败" echo "[$(date '+%Y-%m-%d %H:%M:%S')] 已将${table_name}中超时记录的status更新为0" >> "$logFile" else # 临时表存在,通知排查 echo "[$(date '+%Y-%m-%d %H:%M:%S')] ${table_name}对应的临时表${temp_table}存在,需相关团队排查" >> "$logFile" echo "${table_name}存在超时未更新记录且对应临时表${temp_table}已创建,请及时排查" | mail -s "P1告警:${table_name}状态异常" "$error_email" fi fi # 返回查询结果内容 cat "$query_result" rm -f "$query_result" } # 处理test1和test2表 result_test1=$(process_table "test1") result_test2=$(process_table "test2") # 发送查询结果至审核邮箱 if [ -n "$result_test1" ] || [ -n "$result_test2" ]; then echo "test1超时记录: $result_test1 test2超时记录: $result_test2" | mail -s "表状态超时记录审核" "$email_recipient" fi # 清理临时文件 rm -rf "/tmp/${pid}.*"
关键逻辑说明
- 查询结果保存:将MySQL查询结果重定向到临时文件,通过
-s参数判断文件是否非空,同时方便写入日志和邮件发送。 - 临时表存在性判断:使用
SHOW TABLES LIKE 'TEMP_table_name'语句,通过wc -l统计结果行数,行数为0则表示临时表不存在。 - 批量更新状态:直接复用查询条件批量更新记录,避免逐个提取ID的繁琐操作,提升脚本效率。
- 函数化处理:将单表逻辑封装为
process_table函数,减少重复代码,后续新增表只需调用该函数即可。
内容的提问来源于stack exchange,提问作者Ganesh
相关产品推荐
相关产品推荐

