简介:《archery使用手册》面向DBA、数据库运维与后端开发人员,围绕SQL审核查询平台Archery的落地使用展开,帮助读者理解其在MySQL日常运维中的定位与典型场景。压缩包内含1个doc文档,体积约1.2MB,以文字说明与操作示例为主,便于按功能模块查阅。资源系统梳理SQL审核、SQL优化、实例管理及工具插件四部分:审核侧覆盖语法与规范检查、高危语句驳回、定时执行和回滚SQL;优化侧包含执行计划、优化建议与慢日志统计;实例管理涉及binlog清理、会话终止、事务与锁信息排查、账号授权和动态参数配置;插件部分介绍PTArchiver归档、Binlog2SQL解析及SchemaSync结构同步。文档还给出开发与测试环境的审核流程示例,可辅助团队搭建工单流转与问题排查思路。目前已有1479人学习,适合需要快速熟悉Archery功能边界和运维实践的技术人员参考。
1. 从一条被拦下的 ALTER 说起
某公司一位后端把一条ALTER TABLE直接发到生产库,被 DBA 在群里拦下来——语句本身没错,错在没走审核。这类场景在 MySQL 运维里太常见了,Archery 就是冲着这个痛点来的:它把 SQL 审核、工单流转、执行与回滚、实例排查和几个常用插件收在一个 Web 平台里。这份 archery 使用手册的价值不在安装步骤,而在把“提交一条 SQL 到安全落地”的链路拆开:审核规则看什么、工单怎么流转、回滚语句怎么拿、会话和锁怎么排查、binlog 怎么清、归档和结构同步的边界在哪。适合刚接手 MySQL 运维的后端、需要走工单的研发,以及要给团队定审核规范的人。
2. SQL审核规则与工单闭环:从“检测报错”到“回滚语句”的完整链路
SQL 审核平台最容易做成摆设:规则太松,什么都放过去;规则太严,研发绕开平台直接连库。Archery 的审核逻辑是把 SQL 做语法解析,再套一层自定义规则,输出 error 或 warning。error 直接卡住工单,warning 可以提交但会留痕。真正要让这套东西跑起来,得先把“审什么”和“谁来审”定清楚,再谈执行和回滚。
2.1 审核规则到底在审什么
Archery 的审核分两层。第一层是语法解析,语句写错、关键字拼错、引号不闭合,这一层就会报 error,连提交都过不去。第二层是规范审核,常见规则包括:建表必须有主键、表和列必须有注释、字段类型不能滥用 TEXT、索引命名要带前缀、禁止SELECT *、UPDATE/DELETE 必须带 WHERE。高危语句比如无 WHERE 的 UPDATE、DROP TABLE、TRUNCATE,通常配置成直接驳回。
下面这条建表语句在多数团队的规则集里会被拦:
-- 典型的不合规建表:无主键、无注释、用了大字段 CREATE TABLE demo_db.user_profile ( user_name varchar(64) DEFAULT NULL, id_card varchar(32) DEFAULT NULL, remark text );检测结果一般会同时报三条:缺少主键、表和列没有注释、text类型建议评估。改成下面这样就能过:
-- 补齐主键、注释,并把大字段拆出去或限制长度 CREATE TABLE demo_db.user_profile ( id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', user_name varchar(64) NOT NULL COMMENT '用户名', id_card varchar(32) NOT NULL COMMENT '证件号', remark varchar(512) DEFAULT NULL COMMENT '备注', PRIMARY KEY (id), KEY idx_user_name (user_name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户档案表';参数上要留意字符集和排序规则。Archery 的规则集里可以配“必须使用 utf8mb4”,如果实例默认还是 utf8,建表不显式指定就会踩坑。规则不是越多越好,我一般建议先上四条硬规则:主键、注释、WHERE 条件、禁止 DROP/TRUNCATE。跑两周看误报率,再把SELECT *、索引命名这类 warning 级规则加进去。
2.2 开发环境与测试环境的工单流转差异
手册里给了两条流程,差别不在工具,在人。开发环境是“研发工程师 → 项目经理”:研发提交 SQL,点“SQL 检测”,error 就改,没问题点“SQL 提交”,项目经理收到待办,审核通过后选择立即执行或定时执行。测试环境反过来,是“测试同事从 git 取开发提交的 SQL 文件 → 在测试环境发起审核 → 测试同事自己审核并执行”。
这个差异是有意设计的。开发环境让项目经理把关,防的是“研发自己审自己”;测试环境让测试同事闭环,求的是快,因为测试库本来就可以随时重建。实操里我会再加一条:测试环境的工单必须关联 git 提交号,否则回滚时找不到对应版本。具体做法是在工单备注里写 commit hash,或者把 SQL 文件名带上需求编号。
流程走起来大概是这几步:
- 研发把变更 SQL 落到
sql/目录,文件名带日期和需求号,提交到 git。 - 登录 Archery,选目标实例和库,把 SQL 贴进工单,点“SQL 检测”。
- 有 error 按提示改;只有 warning 时确认是否可接受,填写变更说明。
- 点“SQL 提交”,流转到下一级审核人。
- 审核人从右上角通知入口进待办,看检测结果和回滚语句,通过或驳回。
- 最后一级通过后选“立即执行”或“定时执行”。
定时执行适合大表变更。比如给一张千万级表加索引,直接立即执行可能卡住业务,配到凌晨低峰跑更稳。但定时任务不是万能的,后面避坑章节会讲时间窗口冲突的问题。
2.3 执行方式与回滚语句的生成逻辑
Archery 在执行前会自动生成回滚语句,这是它比“人工写 undo SQL”靠谱的地方。对 INSERT,回滚是 DELETE;对 UPDATE,回滚是反向 UPDATE;对 DELETE,回滚是把删除的数据重新 INSERT。DDL 的回滚比较特殊,ADD COLUMN 对应 DROP COLUMN,但数据已经写入的部分救不回来。
工单执行完,在详情页可以点“查看回滚 SQL”或“下载回滚 SQL”。下载下来别直接存着,先看一遍。比如下面这条变更:
-- 原工单:把状态为 0 的订单批量置为已关闭 UPDATE demo_db.biz_order SET status = 2, close_time = NOW() WHERE status = 0 AND create_time < '2024-01-01';Archery 生成的回滚语句大致是反向更新,但它依赖执行前的数据快照。如果这条 SQL 影响行数很大,回滚语句也会很长,下载下来可能几十 MB。我的习惯是执行前先跑一条 COUNT 确认影响行数,超过五千行就拆批,或者走 pt-archiver 那类工具,不硬扛。
提示:回滚语句只对 DML 有效。DDL 工单执行前必须确认有备份,或者至少确认字段可以重建,别把回滚按钮当后悔药。
3. SQL优化与慢日志:执行计划、改写验证和慢查询定位
审核解决的是“能不能执行”,优化解决的是“执行得快不快”。Archery 的 SQL 优化功能本质是帮你拿执行计划、给改写建议,再把慢日志汇总成可排序的列表。工具不替你做决策,但能把排查路径缩短。
3.1 用 SQL 优化功能拿执行计划
手册里的示例是一条带SELECT *的查询:
-- 原始 SQL:查某个员工信息 SELECT * FROM demo_db.emp WHERE ename = 'dan_1';在“SQL 优化”里提交后,平台会返回执行计划和优化建议。执行计划重点看四列:type、key、rows、Extra。type是 ALL 说明全表扫,得加索引;key为 NULL 说明没走索引;rows是预估扫描行数,和实际行数差一个数量级就要怀疑统计信息过期;Extra里出现Using filesort或Using temporary,说明排序或分组没吃到索引。
把SELECT *改成具体字段后,如果 WHERE 列上有索引,执行计划会从 ALL 变成 ref 或 range。这一步不需要改表结构,先把查询列收窄,减少回表次数。常见做法是先看EXPLAIN,再决定加索引还是改 SQL,别一上来就加索引——写多读少的表,索引多了是负担。
3.2 从 select * 到覆盖索引的改写
下面这条改写适合“列表页只展示几个字段”的场景:
-- 改写前:回表取整行 SELECT * FROM demo_db.emp WHERE dept_id = 10 ORDER BY create_time DESC LIMIT 20; -- 改写后:只取需要的列,并让索引覆盖 WHERE + ORDER BY SELECT id, ename, dept_id, create_time FROM demo_db.emp WHERE dept_id = 10 ORDER BY create_time DESC LIMIT 20;对应的索引可以建成(dept_id, create_time)。这样 WHERE 和 ORDER BY 都能走索引,如果查询列也在索引里,就是覆盖索引,连回表都省了。参数上注意LIMIT的翻页写法,LIMIT 100000, 20这种深翻页即使有索引也会扫很多行,改成“记住上一页最大 id”的写法更稳:
-- 深翻页优化:用上一页最后一条的 id 做游标 SELECT id, ename, dept_id, create_time FROM demo_db.emp WHERE dept_id = 10 AND id > 100230 ORDER BY id LIMIT 20;这种写法要求排序字段和游标字段一致,业务上要能接受“按 id 翻页”而不是“按时间翻页”。如果不能接受,就限制最大翻页深度,别让用户点到第一万页。
3.3 慢日志统计怎么用
Archery 的慢 SQL 页面会把实例上的慢查询抓过来,按执行次数、平均耗时、最大耗时排序。排查顺序我一般是这样:
| 排序维度 | 看什么 | 典型动作 |
|---|---|---|
| 平均耗时高、次数少 | 单条 SQL 本身重 | 看执行计划,改 SQL 或加索引 |
| 平均耗时低、次数多 | 高频小查询拖累 | 加缓存、合并查询、改批量 |
| 最大耗时极高 | 偶发锁等待或刷脏页 | 对照会话和锁信息排查 |
| 扫描行数/返回行数比值大 | 索引选择性差 | 调整索引列顺序或补索引 |
慢日志的统计信息要结合业务时段看。白天跑的报表 SQL 和凌晨跑的批处理 SQL,优化策略不一样。报表类可以走只读实例,批处理类可以拆批。别只看“最慢的那条”,要看“总耗时贡献最大的那类”。
4. 实例管理与工具插件:会话、事务、锁、binlog 清理与三件套边界
审核和优化是事前、事中,实例管理是出事之后的排查台。Archery 把会话、事务、锁、binlog、账号、参数这些常用入口放在一个界面里,省得每次登跳板机连客户端。工具插件则是把几个命令行工具可视化,降低使用门槛,但边界要清楚。
4.1 binlog 清理:选中一个,前面全删
实例列表里可以直接清 binlog。操作逻辑是:选中某个 binlog 文件,该文件之前的所有 binlog 都会被删除。这个设计很危险——它不给“只删一个”的选项。清理前必须先确认从库已经同步到哪个位置,否则主库删了、从库还没拉,主从就断了。
先查当前 binlog 列表和从库延迟:
-- 主库上看 binlog 列表 SHOW BINARY LOGS; -- 从库上看已经同步到哪个文件、哪个位置 SHOW SLAVE STATUS\G看Master_Log_File和Read_Master_Log_Pos,确认要删的文件都小于从库已同步的位置。如果是双主或者多从,每个从库都要看一遍。我的习惯是清理前先在工单里贴一张SHOW BINARY LOGS的截图,跑一条mysqlbinlog --stop-datetime确认目标文件里没有未备份的变更,再动手。
4.2 会话、事务与锁的排查顺序
阻塞问题排查有个固定顺序:先看进程状态,再看事务,最后看锁。进程状态页面默认只显示query类型的 command,排查时要切到All,并且勾选“完整 INFO”,否则 SQL 显示不全,只看到半截。
模拟一个锁等待:
-- 会话 A:开事务并更新一行,不提交 BEGIN; UPDATE demo_db.t2 SET ename = 'baidd' WHERE id = 2; -- 会话 B:更新同一行,被阻塞 UPDATE demo_db.t2 SET ename = 'dan' WHERE id = 2;此时在锁信息页面能看到等待事务的 SQL 和阻塞方的线程 ID。阻塞方的trx_mysql_thread_id对应进程状态里的 THREAD ID,拿这个 ID 去进程状态里搜,选中后点“终止会话”。事务信息页面也能看到当前运行的事务,同样用trx_mysql_thread_id关联。
这里有个容易翻车的点:终止会话杀的是连接,不是事务。如果应用用了连接池,杀了连接后连接池会重连,事务回滚,但业务代码可能没处理异常,直接报错给用户。所以杀之前先确认这个会话是不是可以中断的,批量任务尽量用KILL前先看它执行到哪一步。
4.3 账号管理与参数配置
账号管理是图形化建库账号、授权、改密码、删用户。授权时注意最小权限,增删改查和改表结构分开授。参数配置可以改实例的动态参数,并记录修改历史。这个功能适合临时调max_connections、long_query_time这类动态参数,静态参数改了要重启,别在平台上直接点。
参数修改前先确认范围:long_query_time改小会让慢日志暴增,磁盘吃得快;max_connections调大要评估内存,每个连接都有线程栈和缓冲区开销。改完在历史里留一条记录,方便回滚。
4.4 PT-Archiver 归档:只留最近三个月
流水表只保留最近三个月是常见需求。pt-archiver 的做法是分批把老数据搬到归档表或文件,再删原表。Archery 里可以配配置,也可以让用户提交归档申请。核心参数是--limit、--purge、--where。
# 把 2024-01-01 之前的订单归档到历史库,每批 1000 行 pt-archiver \ --source h=127.0.0.1,P=3306,u=archive,p=******,D=demo_db,t=biz_order \ --dest h=127.0.0.1,P=3306,u=archive,p=******,D=demo_archive,t=biz_order \ --where "create_time < '2024-01-01'" \ --limit 1000 \ --commit-each \ --purge \ --statistics 10--limit 1000控制每批行数,太大容易造成主从延迟;--commit-each每批提交一次,避免大事务;--purge表示归档后删除原表数据,不加就是只搬不删;--statistics 10每十批打印一次进度。归档任务要配在低峰期,并且监控从库延迟,延迟超过阈值就暂停。
4.5 Binlog2SQL 与 SchemaSync 的边界
Binlog2SQL 是把 binlog 解析成 SQL,支持生成原始 SQL、回滚 SQL、去掉主键的 INSERT。手册里明确写了:只支持 DML 回滚,DDL 回滚不了。用的时候指定 binlog 文件和起止位置:
# 解析 master-bin.000009 从 857 到 1183 位置的 SQL binlog2sql \ -h 127.0.0.1 -P 3306 -u dba -p ****** \ --start-file master-bin.000009 \ --start-pos 857 \ --stop-pos 1183 \ -B-B表示生成回滚 SQL。不加-B就是正向解析。解析出来的 SQL 最好先在测试库跑一遍,确认能回滚再上生产。如果 binlog 格式是 ROW,解析依赖行镜像,binlog_row_image必须是 FULL,否则回滚 SQL 会缺列。
SchemaSync 只比对表结构,不比对数据。它读源库和目标库的 schema,生成同步更新和回滚的 SQL。适合新环境初始化或者结构漂移排查,不适合数据修复。对比结果里只出现 DDL,别指望它帮你补数据。
| 插件 | 能做什么 | 不能做什么 | 关键参数 |
|---|---|---|---|
| PT-Archiver | 分批归档、删除老数据 | 跨库事务一致性 | --limit、--purge、--where |
| Binlog2SQL | 解析 DML、生成回滚 SQL | 回滚 DDL、缺列镜像时回滚不全 | --start-file、--start-pos、-B |
| SchemaSync | 比对表结构、生成同步/回滚 DDL | 比对数据、修复数据 | 源库/目标库连接串 |
5. 常见问题与排查:五类翻车现场
工具用顺手之后,翻车往往不是因为不会点按钮,而是因为边界没看清。下面五类场景在手册的实践案例里都能找到影子,我按“现象 → 原因 → 解决”整理了一遍。
5.1 检测通过,执行报错
现象:工单里点“SQL 检测”全是绿色,审核通过后执行却报错,比如Unknown column或Duplicate key name。原因通常是审核连接库和执行连接库不是同一个,或者审核时用了旧表结构缓存,执行时表已经被人改过。解决:提交前确认工单选中的实例和库名,执行前让审核人再看一眼当前表结构;对加索引这类操作,先用SHOW INDEX确认索引名没冲突。
5.2 回滚 SQL 下载了却用不了
现象:工单执行完下载回滚 SQL,拿到测试库一跑报语法错或者主键冲突。原因有两个:一是 DDL 工单本身没有完整回滚,平台生成的只是反向 DDL;二是 DML 回滚依赖执行前快照,如果执行后又有新数据写入,回滚会撞主键。解决:DDL 执行前手动备份表结构,DML 回滚前先确认影响行数,必要时按主键分批回滚,别一次性灌进去。
5.3 binlog 清理删多了
现象:在实例列表里选中一个 binlog 清理,结果从库报Could not find first log file name。原因就是那个“选中即删前面所有”的逻辑,把从库还没同步的文件删了。解决:清理前每个从库都跑SHOW SLAVE STATUS,确认Master_Log_File大于要删的最后一个文件;不确定就只清理一周前的,留足同步余量。
5.4 锁信息里杀错会话
现象:看到阻塞就点终止,结果业务大面积报连接断开。原因是杀的是连接池里的长连接,不是单条 SQL;或者trx_mysql_thread_id看串了,杀到了无辜的查询。解决:先在进程状态里用 THREAD ID 精确搜索,确认INFO是目标 SQL 再杀;能等就等,锁等待超时时间调短比直接杀更温和。
5.5 SchemaSync 同步后数据对不上
现象:用 SchemaSync 把测试库结构同步到目标库,结构一致了,但查询结果不一致。原因是它只比对表结构,不比对数据,目标库原本就缺数据。解决:结构同步只用于初始化或修漂移,数据一致性要用校验工具或者业务对账;同步前先备份目标库结构,生成的回滚 DDL 先看一遍再执行。
6. 上线前验证与规则调优:把审核从“能跑”推到“可回滚”
规则调优最容易走两个极端:一开始全开,研发被卡得绕开平台;或者全关,平台变成日志展示页。我的做法是分两级:主键、注释、WHERE 条件、DROP/TRUNCATE 这四条设成阻断,其余先设提醒,跑两周统计误报率,再把误报低的转成阻断。
具体操作上,先拿一个影子实例或者测试库做预演。把生产工单里的 SQL 原样贴进去,跑一遍检测、执行、下载回滚、回滚,四步都走通才算验证完成。下面这条检查 SQL 可以放在回滚验证前,确认影响范围:
-- 执行前确认影响行数,避免回滚语句过大 SELECT COUNT(*) AS affected_rows FROM demo_db.biz_order WHERE status = 0 AND create_time < '2024-01-01';如果affected_rows超过五千,就把原 SQL 按主键拆批,每批两千行左右,回滚也按批走。定时执行的时间窗口要避开备份窗口和批处理任务,两个定时任务撞在一起,锁等待会教做人。
还有一个习惯:每次 DDL 工单执行前,强制在测试库跑一遍“执行 + 回滚 + 再执行”。有次我给一张表加字段,回滚语句里DROP COLUMN写对了,但字段上有索引,回滚后索引名残留,第二次执行直接报重复。从那以后我每次上 DDL 都强制走一遍“执行—回滚—再执行”的闭环,不再只看检测结果。希望帮到你。
本文还有配套的精品资源,点击获取