深色模式
SQL 审核与上线检查
摘要:SQL 审核是在 SQL 到达生产之前拦截风险:检查命名与类型、索引是否命中、DDL 是否会造成锁表、DML 是否有 WHERE 与行数限制。本文给出人工检查清单与开源审核工具用法。
适用环境
bash
# 审核工具需要能连到只读预览库或拿到 SQL 文本
mysql -uroot -p -e "SELECT @@version;"
# 安装 yearning / archery 等开源审核平台,或用轻量 CLI1
2
3
2
3
操作步骤
1. 建立硬性红线(一票否决)
| 红线 | 原因 |
|---|---|
DELETE/UPDATE 无 WHERE | 全表误改 |
DROP TABLE / TRUNCATE | 不可回滚 |
大表直接 ALTER TABLE 加列/改类型 | 长时间锁表 |
| 索引列上使用函数或隐式类型转换 | 索引失效、全表扫描 |
SELECT * 且无 LIMIT(导出类除外) | 网络与内存浪费 |
| 一次事务影响超过 1 万行 | 长事务、主从延迟 |
2. 人工审核清单
sql
-- 审核一条 UPDATE:先看影响范围
EXPLAIN SELECT * FROM orders WHERE status='INIT' AND created_at < '2026-01-01';
SELECT COUNT(*) FROM orders WHERE status='INIT' AND created_at < '2026-01-01';
-- 确认能命中索引、影响行数可控后再写 UPDATE1
2
3
4
2
3
4
sql
-- 审核 DDL:确认表大小与是否可在线变更
SELECT table_name, table_rows, ROUND(data_length/1024/1024,0) AS mb
FROM information_schema.tables WHERE table_schema='shopdb' AND table_name='orders';
ALTER TABLE orders ADD COLUMN ext varchar(64) DEFAULT NULL, ALGORITHM=INPLACE, LOCK=NONE;1
2
3
4
2
3
4
危险
ALTER TABLE 在大表上可能锁表数小时。必须显式指定 ALGORITHM=INPLACE, LOCK=NONE 并先在测试环境验证,否则改用 gh-ost / pt-online-schema-change 在线变更工具。
3. 用在线变更工具(大表 DDL)
bash
# gh-ost:影子表 + binlog 回灌,可限流、可暂停
gh-ost --user=root --password='密码' --host=127.0.0.1 --database=shopdb \
--table=orders --alter="ADD COLUMN ext varchar(64)" \
--max-load=Threads_running=50 --critical-load=Threads_running=200 \
--chunk-size=2000 --execute1
2
3
4
5
2
3
4
5
bash
# pt-online-schema-change
pt-online-schema-change --user=root --password=密码 \
--alter "ADD INDEX idx_uid (user_id)" D=shopdb,t=orders --execute1
2
3
2
3
4. 自动化审核(可选)
- 开源平台:Yearning、Archery 提供 SQL 提交、审核流程与执行回滚。
- CI 集成:把 SQL 文件纳入代码评审,用 sqlyog/soar 等工具给出优化建议。
bash
# soar:给出索引与改写建议
soar -query "SELECT * FROM orders WHERE DATE(created_at)='2026-10-09'"1
2
2
5. 上线单模板要点
- 变更内容(SQL 全文)、影响库表与预估行数
- 执行时间窗与执行人
- 回滚方案(反向 SQL 或备份位置)
- 验证方式(执行的 SELECT 检查语句)
验证
sql
-- 执行后立刻验证:行数、索引、结构
SELECT COUNT(*) FROM orders WHERE status='INIT';
SHOW CREATE TABLE orders\G
SHOW INDEX FROM orders;1
2
3
4
2
3
4
bash
# 观察是否有锁等待与慢查询突增
mysql -uroot -p -e "SELECT * FROM information_schema.innodb_trx\G" | grep -E 'trx_rows_modified|trx_started'1
2
2
常见坑
WARNING
字段类型不匹配(如 varchar 列与数字比较)会触发隐式转换导致索引失效,EXPLAIN 里 key 为 NULL 就要警惕。
WARNING
审核通过了也别在生产主库直接跑,先在预发/从库验证耗时与影响行数,再按窗口执行。
DANGER
回滚方案不能只写「用备份恢复」,必须给出精确的反向 SQL 或具体时间点恢复步骤,并提前演练过。