SQL 检测脚本

SQL 检测脚本

1、基本介绍
  • SQL 检测脚本通常指一段用 SQL 或相关工具编写的脚本,用来自动检查数据库中的某些问题
2、演示
(1)检测目标
  • 检查一个电商库的常见问题,假设有张订单表 orders
sql 复制代码
CREATE TABLE orders (
    id          BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id     BIGINT NOT NULL,
    amount      DECIMAL(10,2) NOT NULL,
    status      VARCHAR(20) NOT NULL,
    created_at  DATETIME NOT NULL
);
(2)检测脚本
  1. 检查主键重复(数据质量):正常应返回 0 行。有结果说明主键被破坏
sql 复制代码
SELECT id, COUNT(*) AS cnt
FROM orders
GROUP BY id
HAVING cnt > 1;
  1. 检查金额异常(业务规则):找出金额为负或异常巨大的订单
sql 复制代码
SELECT *
FROM orders
WHERE amount <= 0 OR amount > 1000000;
  1. 检查状态值是否非法(枚举校验):返回空表示所有状态都合法
sql 复制代码
SELECT DISTINCT status
FROM orders
WHERE status NOT IN ('pending', 'paid', 'shipped', 'done', 'cancelled');
  1. 检查孤儿数据(外键完整性):找出下了单但用户不存在的脏数据
sql 复制代码
SELECT o.id, o.user_id
FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE u.id IS NULL;
  1. 检查慢查询 / 长事务(性能):找出执行超过 60 秒的查询
sql 复制代码
SELECT id, user, time, state, info
FROM information_schema.processlist
WHERE command != 'Sleep'
  AND time > 60;
  1. 检查表空间占用(容量):看哪张表最大,是否异常增长
sql 复制代码
SELECT
    table_name,
    ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'your_db'
ORDER BY size_mb DESC
LIMIT 10;
(3)实际使用
  1. 实际使用时,通常会把上面这些 SQL 写进一个 SQL 文件,例如,check_orders.sql
sql 复制代码
SELECT '主键重复' AS check_item, COUNT(*) AS problem_count
FROM (SELECT id FROM orders GROUP BY id HAVING COUNT(*) > 1) t;

SELECT '金额异常' AS check_item, COUNT(*) AS problem_count
FROM orders WHERE amount <= 0 OR amount > 1000000;

SELECT '状态非法' AS check_item, COUNT(*) AS problem_count
FROM orders
WHERE status NOT IN ('pending','paid','shipped','done','cancelled');

SELECT '孤儿订单' AS check_item, COUNT(*) AS problem_count
FROM orders o LEFT JOIN users u ON o.user_id = u.id
WHERE u.id IS NULL;
shell 复制代码
mysql -u root -p 【数据库名】 < check_orders.sql
(4)shell 自动跑 + 告警
  1. 写进一个 shell 脚本,例如,check_orders.sh
shell 复制代码
#!/bin/bash
set -euo pipefail

DB_HOST="127.0.0.1"
DB_USER="root"
DB_PASS="your_password"
DB_NAME="your_db"
SQL_FILE="/opt/scripts/check_orders.sql"
LOG_FILE="/var/log/check_orders.log"
ALERT_WEBHOOK="https://your-webhook-url" # 告警接收地址,例如,钉钉、企微
ALERT_THRESHOLD=1 # 问题数达到该值就触发告警,1 表示只要有问题就告警

# 执行检测 SQL,-N 不输出列名,-B 制表符分隔,方便逐行解析
RESULT=$(mysql -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" -N -B < "$SQL_FILE")

ALERT_MSG=""
TOTAL=0

while IFS=$'\t' read -r item count; do
    [ -z "$item" ] && continue
    echo "$(date '+%F %T') [$item] = $count" >> "$LOG_FILE"
    if [ "$count" -ge "$ALERT_THRESHOLD" ]; then
        ALERT_MSG="${ALERT_MSG}${item}: ${count} 条\n"
        TOTAL=$((TOTAL + count))
    fi
done <<< "$RESULT"

# 有问题才发告警,没问题只记日志
if [ "$TOTAL" -gt 0 ]; then
    MSG="【订单表检测告警】\n${ALERT_MSG}请及时处理。"
    curl -s -X POST "$ALERT_WEBHOOK" \
        -H 'Content-Type: application/json' \
        -d "{\"msgtype\":\"text\",\"text\":{\"content\":\"$MSG\"}}"
    echo "$(date '+%F %T') 已发送告警" >> "$LOG_FILE"
else
    echo "$(date '+%F %T') 全部正常" >> "$LOG_FILE"
fi
  1. 赋予可执行权限
shell 复制代码
chmod +x /opt/scripts/check_orders.sh
  1. 测试 shell 脚本
shell 复制代码
/opt/scripts/check_orders.sh
cat /var/log/check_orders.log
  1. 配置定时任务
shell 复制代码
crontab -e
shell 复制代码
0 * * * * /opt/scripts/check_orders.sh >/dev/null 2>&1
相关推荐
逃逸线LOF1 小时前
服务网关Gateway
java·运维·gateway
灿飞屋2 小时前
Kotlin与Java虚拟机四:函数
java·python·kotlin·安卓·android jetpack
老纪的技术唠嗑局2 小时前
把 seekdb 塞进 iOS App:让混合检索嵌入手机
数据库
ClouGence3 小时前
开源数据库管理工具 CloudDM 新版本发布,支持 OpenSearch、IoTDB 数据源
数据库·开源
阡陌数智3 小时前
Claude API新版本重大变更与安全升级指南
java·linux·安全
徐小黑ACG3 小时前
Redis-基础
数据库·redis·缓存
火山引擎开发者社区3 小时前
案例实践 | 让 Agent 读懂业务口径:ContextSearch 在广告数据查询中的实践
数据库
学长毕设4 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
10年前端老司机5 小时前
Milvus 8种检索能力实践
数据库·python·agent
Decay__5 小时前
14_MySQL 高可用与容灾架构 —— MGR / InnoDB Cluster / Keepalived+VIP / 双主 / 读写分离 / 两地三中心
运维·数据库·sql·mysql·架构