You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求完善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}.*"
关键逻辑说明
  1. 查询结果保存:将MySQL查询结果重定向到临时文件,通过-s参数判断文件是否非空,同时方便写入日志和邮件发送。
  2. 临时表存在性判断:使用SHOW TABLES LIKE 'TEMP_table_name'语句,通过wc -l统计结果行数,行数为0则表示临时表不存在。
  3. 批量更新状态:直接复用查询条件批量更新记录,避免逐个提取ID的繁琐操作,提升脚本效率。
  4. 函数化处理:将单表逻辑封装为process_table函数,减少重复代码,后续新增表只需调用该函数即可。

内容的提问来源于stack exchange,提问作者Ganesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:50:29