基于Archery的SQL审核平台设计与落地:规则引擎、工单流程与锁排查

发布时间:2026/10/27 11:52:20
基于Archery的SQL审核平台设计与落地:规则引擎、工单流程与锁排查

简介:《archery使用手册》面向数据库开发人员、DBA及运维工程师,聚焦SQL审核查询平台Archery的落地使用,帮助读者系统掌握从SQL规范审核到MySQL实例运维的完整流程。压缩包内为1个doc文档,约1.2MB,以图文结合方式组织内容,便于按章节检索与对照操作。手册围绕SQL审核、SQL优化、实例管理与工具插件四大模块展开:审核部分涵盖语法解析、自定义规则校验、高危语句驳回及定时执行与回滚;优化部分讲解执行计划分析与慢SQL统计;实例管理涉及binlog清理、会话与事务查看、锁信息排查及账号授权;插件部分介绍PTArchiver归档、Binlog2SQL解析与SchemaSync结构同步。内容结合开发与测试环境的审核流程示例,配有具体操作截图与命令说明,可帮助读者快速理解平台能力并应用于日常数据库管理。目前已有1478人学习下载,适合需要提升SQL质量与运维效率的技术人员参考。

1. 从一条被驳回的建表语句说起:这套 SQL 审核平台方案要解决什么

一条CREATE TABLE语句在开发环境跑得好好的,推到生产前被平台直接打回,理由只有一行:缺少主键、表注释、列注释。这不是平台在找茬,而是把「数据库规范」从口头约定变成了可执行的硬约束。Archery 定位就是 SQL 审核查询平台,围绕 MySQL 把审核、优化、实例运维、工具插件四件事收进一个 Web 界面。这套方案适合两类人:需要交一份完整数据库运维平台设计的学生,以及要给团队搭一套 SQL 上线流程的从业者。下面按「需求怎么立 → 平台怎么设计 → 流程怎么落地 → 怎么验收」推一遍,中间穿插能直接抄的配置和排查思路。

2. 平台总体设计:四个能力域与审核执行链路

Archery 的功能看着多,拆开其实就四个能力域:SQL 审核、SQL 优化、实例管理、工具插件。设计时不要把它们当成并列菜单,而要看清它们共享同一条链路——SQL 从提交到执行,中间要过语法解析、规则校验、人工审批、执行与回滚。这条链路是整套方案的主干,其余功能都是围绕它长出来的枝干。

2.1 四个能力域的职责边界

SQL 审核负责「能不能上线」,核心是语法解析加自定义规则;SQL 优化负责「上线后快不快」,核心是执行计划与慢日志;实例管理负责「库本身健不健康」,覆盖 binlog、会话、事务、锁、账号、参数;工具插件负责「脏活累活自动化」,把 pt-archiver、binlog2sql、schema 比对这些命令行工具可视化。四者边界清晰,但数据是打通的:审核工单里引用的实例来自实例管理,回滚语句的生成依赖 binlog 解析能力。

设计文档里我一般会画一张分层图:接入层是 Web 与通知(钉钉),业务层是工单引擎与规则引擎,能力层是 SQL 解析器、执行器、binlog 解析器,资源层是各 MySQL 实例。分层的好处是,后面加一个审核规则或加一种通知渠道,只动一层,不牵一发动全身。

2.2 审核规则引擎:把规范写成可执行配置

审核能不能落地,全看规则引擎。Archery 的做法是先把 SQL 做语法解析成 AST,再拿自定义规则逐条比对。规则不是写死在代码里的,而是配置化的,这一点对交付很关键——不同团队规范不同,规则必须能改。下面是一份规则配置的示意结构,字段名按常见实现习惯给出,实际以部署版本的配置项为准:

{ "rule_name": "create_table_must_have_pk", "enabled": true, "level": "error", "applies_to": ["CREATE"], "description": "建表必须显式定义主键", "reject_action": "block" }

level决定这条规则是 error 还是 warning,error 直接阻断提交,warning 只提示;applies_to限定语句类型,避免把建表规则误套到查询上;reject_action为 block 时高危语句自动驳回。实际配置里还会有一组内置规则:建表需主键、表和列需注释、禁止SELECT *、禁止无 WHERE 的 UPDATE/DELETE、字段类型规范等。规则引擎的价值在于「可解释」——每条驳回都要能说清触发了哪条规则,否则开发只会觉得平台在卡人。

2.3 工单状态机:从提交到执行再到回滚

工单是审核流程的载体,必须设计成状态机,而不是一个布尔字段。典型状态流转是:待检测 → 检测失败(可回到待检测)→ 待审批 → 审批通过 → 待执行 → 执行成功/执行失败 → 已回滚。每个状态对应不同的操作权限:研发只能提交和修改,项目经理或测试负责人才能审批,执行可以选择立即或定时。

状态机的意义在于可追溯。工单一旦进入待执行,SQL 文本、审核结果、审批人、执行时间都要落库,出问题时能回答「这条语句是谁、什么时候、以什么理由放行的」。回滚能力挂在执行成功之后:平台在审核阶段就生成回滚语句并随工单保存,执行后若需回滚,直接下载或查看回滚 SQL,而不是临时去翻 binlog。DDL 的回滚要特别标注——binlog2sql 只能回滚 DML,DDL 操作无法回滚,这一点必须在工单界面上写死提示,不能靠人记。

2.4 通知与定时执行:让流程不靠人盯

审核通过后如果没人知道,流程就卡住了。钉钉通知解决的是「待办触达」:工单进入待审批、审批通过、执行完成、执行失败,各推一条。定时执行解决的是「窗口期」:大表变更放在业务低峰跑,提交时选定时,平台到点触发。这两块设计上要注意幂等——定时任务重复触发不能把同一条 SQL 执行两遍,工单状态要先做原子抢占再执行。

3. SQL 审核流程落地:开发环境与测试环境两套走法

流程设计最怕一套流程套所有环境。开发环境要快,测试环境要稳,两者审批链不同,但底层用的是同一套审核引擎。把两套流程分开配,是这个方案能真正跑起来的关键。

3.1 开发环境:研发提交、项目经理终审

开发环境的链路是「研发工程师 → 项目经理」。研发准备好 SQL 文件,在平台发起审核,填实例、库、工单说明,点「SQL 检测」。检测返回 error 就不能提交,按提示改完再检;检测通过才点「SQL 提交」,工单进入项目经理的待办。项目经理登录后从右上角通知进入待办列表,逐条看审核结果,通过后选择「立即执行」或「定时执行」。

这里有个容易被忽略的设计点:检测和执行是两次独立的数据库交互。检测阶段只做解析和规则比对,不碰目标库;执行阶段才真正连库跑语句。分开的好处是检测可以反复做而不产生副作用,坏处是检测通过不代表执行一定成功——执行时可能遇到锁等待、权限不足、字段已存在。所以执行结果必须回写工单,失败要保留原始报错,方便二次处理。

3.2 测试环境:测试取件、自审自执行

测试环境的链路是「测试同事从 git 取开发提交的 SQL → 在测试环境发起审核 → 测试同事审核并执行」。审批人和提交人可以是同一角色,流程更短。这种设计不是偷懒,而是测试环境本来就允许试错,卡太死反而拖慢联调。但「自审」不等于「免审」,SQL 检测这一步不能省,规则该拦还是拦。

两套流程共用同一份规则配置,区别只在审批节点数量。实现上,工单表里加一个env_type字段,审批链按环境类型查配置表决定走几级。这样新增一个预发环境,只加一条配置,不改代码。

3.3 回滚语句的生成与保存时机

回滚是这个流程里最容易被做错的一环。正确时机是在审核阶段就生成并随工单保存,而不是等执行完再补。原因很实际:执行完再生成,一旦 binlog 被清理或实例不可达,回滚就没了。生成方式上,DML 的回滚语句由平台根据原语句反向推导(INSERT 反成 DELETE、UPDATE 反成等值回写),复杂场景借助 binlog 解析兜底;DDL 则明确告知不可自动回滚,需要人工准备逆向 DDL。

工单界面上「下载回滚 SQL」和「查看回滚 SQL」两个入口要显眼。下载用于留档,查看用于快速核对。回滚语句本身也要过一遍语法检测,避免生成一条跑不通的回滚——这种翻车在现场很尴尬。

3.4 一个可直接套用的工单字段设计

工单表是整个流程的数据底座,字段设计直接决定后面能不能查、能不能审计。下面这张表是我在类似项目里常用的最小字段集:

字段类型说明
ticket_idbigint工单主键,自增
env_typevarchar环境类型:dev/test/prod
instance_idbigint目标实例,关联实例表
db_namevarchar目标库名
sql_texttext原始 SQL 文本
rollback_sqltext审核阶段生成的回滚语句
audit_resulttext规则检测结果明细
statusvarchar状态机当前状态
submittervarchar提交人
approvervarchar审批人
execute_typevarcharimmediate / scheduled
execute_timedatetime定时执行时间
created_atdatetime创建时间

audit_result存明细而不是只存通过与否,是为了事后复盘「当时为什么放行」。rollback_sql和执行状态解耦,保证即使执行失败,回滚语句也已就位。

4. SQL 优化与实例运维:从慢查询到锁等待的排查路径

审核管的是「上线前」,优化和实例运维管的是「上线后」。这两块合起来,才是一个完整的数据库运维闭环。设计上它们共享实例连接池和权限体系,但操作对象不同:优化面向单条 SQL,运维面向整个实例。

4.1 SQL 分析与优化建议的产出逻辑

SQL 优化功能的输入是一条 SQL,输出是执行计划加优化建议。平台把 SQL 交给目标实例做EXPLAIN,解析返回的访问类型、扫描行数、是否走索引,再映射成人类能读的建议。举个原文里的例子:SELECT * FROM baidd.emp WHERE ename='dan_1';分析后提示把SELECT *改成具体字段,改完再分析结果就是 OK。

这条建议背后的判断不复杂:SELECT *会多读不需要的列,覆盖索引失效,网络传输变大。但平台不能只给结论,要给依据——执行计划里type是 ALL 还是 ref、rows估算多少、Extra里有没有 Using filesort。建议文案我一般要求带上这三项,否则开发不知道该信哪一条。

慢日志是优化的另一半。平台采集慢 SQL 及其统计信息(执行次数、平均耗时、最大耗时、扫描行数),按耗时排序展示。设计上要注意慢日志的采集频率和存储量——高频采集会拖库,低频采集会漏。通常的做法是按实例配置采集周期,统计信息做聚合而不是存原始日志,避免存储爆炸。

4.2 会话、事务与锁:阻塞问题的三步定位

线上出现阻塞,排查路径是固定的三步:看进程状态 → 看事务信息 → 看锁信息。平台把这三步做成了三个页签,但用的时候要串起来看。

进程状态页默认只显示command=query的会话,排查时要手动切到All,并且勾选「完整 INFO」,否则 SQL 文本被截断,看不到全貌。定位到可疑会话后点「终止会话」杀掉。事务信息页展示当前运行的事务,其中trx_mysql_thread_id对应进程状态里的 THREAD ID——这是两个页签之间的连接键,杀掉事务就是拿这个 ID 回进程页搜索再终止。

锁信息页展示等待关系:哪条 SQL 在等锁、阻塞方的线程 ID 是谁。原文给了一个可复现的模拟:会话 A 执行BEGIN; UPDATE baidd.t2 SET ename='baidd' WHERE id=2;不提交,会话 B 执行UPDATE baidd.t2 SET ename='dan' WHERE id=2;被阻塞。平台锁信息页能看到 B 的 SQL 在等待,阻塞方线程 ID 指向 A。要解除阻塞,拿这个 ID 去进程页终止 A 的会话。

-- 会话A:开启事务并持有行锁,不提交 BEGIN; UPDATE baidd.t2 SET ename='baidd' WHERE id=2; -- 会话B:同一行,被阻塞 UPDATE baidd.t2 SET ename='dan' WHERE id=2;

这段模拟的价值在于可复现。验收时让评审者亲手制造一次锁等待,再用平台定位并解除,比讲十遍原理都管用。注意终止会话是破坏性操作,生产上要先确认该会话不是关键业务,平台侧最好加二次确认。

4.3 实例管理:binlog 清理、账号与参数

实例列表页承担几件日常运维:清理 binlog 释放磁盘、账号增删授权、动态参数修改并留历史。清理 binlog 的语义要讲清楚——选中某个 binlog 后,它之前的所有 binlog 都会被删除,这是 MySQL 的机制决定的,不是平台随意扩大范围。所以操作前必须确认没有从库还依赖这些文件,否则主从同步直接断。

账号管理是图形化的CREATE USER/GRANT/ALTER USER/DROP USER。建完账号要授权,比如给增删改查加改表结构权限,对应一组 GRANT 语句。平台把常用权限做成勾选项,底层拼 SQL 执行。参数配置改的是实例动态参数,每次修改记历史,出问题能回滚参数。

4.4 工具插件:归档、binlog 解析与 schema 比对

三个插件解决三类重复劳动。pt-archiver 做数据归档:流水表只留最近三个月,更早的数据归档出去,可配成自动任务。binlog2sql 把 binlog 解析可视化:指定master-bin.000009的 857 到 1183 位置,能取出这段区间的 SQL,点 flashback 还能生成回滚 SQL。schema 比对读源库和目标库的表结构,自动生成同步 DDL 和对应回滚 SQL,但只比对结构不比数据——这一点必须在界面上写明,否则有人拿它当数据同步用。

# schema 比对示意:源库 251 有 t1、t2,目标库 249 只有 t2 # 平台输出 249 相对 251 需要执行的 DDL,以及对应的回滚 DDL # 注意:仅比对表结构,不比对数据

binlog2sql 的边界要反复强调:只能回滚 DML,DDL 无法回滚。验收时专门测一条 DDL 走 binlog 解析,确认平台给出明确拒绝而不是静默失败。

5. 避坑与常见问题:上线前必须过的五道坎

这套平台功能多,踩坑点也集中。下面五条是项目里最容易翻车的地方,按「现象 → 原因 → 解决」写,照着排能省不少时间。

现象一:SQL 检测通过,执行却报错。原因:检测只做解析和规则比对,不连库验证对象是否存在、权限是否足够。解决:执行失败时保留原始报错并回写工单,工单支持「重新检测」;对高频变更的库,检测阶段可加一步轻量的对象存在性校验。

现象二:回滚时发现回滚 SQL 是空的。原因:回滚语句在执行后才生成,此时 binlog 已被清理或实例不可达。解决:回滚语句在审核阶段生成并随工单落库,执行与回滚解耦;DDL 工单强制要求人工填写逆向 DDL 才能提交。

现象三:清理 binlog 后主从同步中断。原因:清理范围是「选中文件之前的全部」,从库尚未消费的文件被一并删除。解决:清理前检查从库延迟与已消费位点,平台侧对存在从库延迟的实例禁用清理入口或强提示。

现象四:锁等待排查时看不到完整 SQL。原因:进程状态页默认只显示 query 类型且未勾选「完整 INFO」,长 SQL 被截断。解决:排查规范里写死「先切 All、再勾完整 INFO」;平台可把这两个选项做成记忆上次选择。

现象五:定时工单重复执行。原因:定时任务触发时未做状态原子抢占,多节点或重试导致同一工单跑两次。解决:执行前用状态机做条件更新(仅当状态为待执行时置为执行中),抢占失败直接跳过。

提示:这五条里前两条属于设计缺陷,后三条属于使用规范。设计缺陷靠改代码,使用规范靠写进操作手册并在验收时逐条演示。

6. 验收与答辩:用一条锁等待和一张工单把方案讲透

验收这套方案,不要从功能列表开始讲,那会变成念菜单。我的做法是准备两个现场演示,一个证明「流程能拦住问题」,一个证明「出问题能定位」。

第一个演示走审核流程:准备一条缺主键的建表语句,提交后平台报 error 并指出触发规则,现场改成合规语句再提交,走完审批、执行、查看回滚 SQL 全链路。这条演示覆盖了规则引擎、工单状态机、回滚生成三个核心设计点,评审者能直观看到「规范被强制执行」这件事。

第二个演示走阻塞排查:按第 4.2 节的模拟,两个会话制造一次行锁等待,然后在平台上从进程状态切到事务信息、再切到锁信息,拿到阻塞方线程 ID,回进程页终止会话,阻塞解除。这条演示证明实例运维不是摆设。

答辩时评审常问三个问题,提前准备好答案:规则能不能改(答:配置化,给出规则 JSON 结构);回滚覆盖哪些语句(答:DML 可自动生成,DDL 明确不可回滚需人工逆向);多环境怎么隔离(答:工单表按env_type区分,审批链按环境配置)。下面这张验收清单可以直接拿去对:

验收项通过标准演示方式
规则拦截缺主键建表被 error 阻断现场提交违规 SQL
审批流转工单按环境走对应审批链开发/测试各走一遍
回滚可用审核阶段已生成回滚 SQL工单页查看并下载
锁定位能定位阻塞方线程 ID两会话模拟锁等待
插件边界DDL 走 binlog 解析被明确拒绝提交 DDL 观察提示

血泪经验是:验收前一定自己把两个演示完整跑三遍,尤其是锁等待那个,会话顺序错一步就复现不出来。从那以后我每次交付这类平台方案,都强制走一遍「违规提交 → 审批 → 执行 → 回滚 → 制造阻塞 → 定位解除」的完整闭环,跑通了才敢让人来验。希望帮到你。

本文还有配套的精品资源,点击获取