资讯详情

资讯详情

Archery SQL审核与工单执行故障排查指南

简介《archery使用手册》是一份面向DBA、研发与测试人员的Archery平台实操文档围绕SQL审核查询与MySQL日常运维展开帮助读者理解工单提交、审核执行、优化分析和实例排障的完整用法。文档系统梳理SQL语法与规范审核、高危语句拦截、立即或定时执行及回滚SQL生成并介绍慢SQL统计、执行计划查看与优化建议获取同时给出开发、测试环境的SQL审核流程示例。实例管理部分覆盖binlog清理、会话终止、事务与锁信息排查、账号授权和动态参数配置插件部分说明PTArchiver数据归档、Binlog2SQL解析回滚及SchemaSync表结构同步的适用边界。压缩包共1个doc文件约1.2MB以单一文档集中呈现功能说明与实践案例便于按章节查阅。已有1479人学习适合需要快速上手Archery、规范SQL上线流程或补足MySQL运维排错思路的读者参考。1. SQL 检测一片红工单提交按钮点不动的那个下午上周有个开发同学发来一张截图Archery 的 SQL 检测结果里十几条 error 排成一列工单提交按钮显示为灰色他问我是不是平台出了问题。这类求助在 SQL 审核平台上几乎每天都有SQL 在本地明明跑得好好的一进 Archery 就被拦住提示还只有一行“表必须包含主键”或者“高危语句已驳回”。Archery 使用手册里把 SQL 审核、SQL 优化、实例管理、Binlog2SQL、SchemaSync、PTArchiver 这些模块都过了一遍可真正让人卡住的往往不是功能不会用而是某条报错背后的审核规则、执行账号和连接状态对不上。下面按故障出现的顺序拆从检测报错到执行失败、回滚拿不到、实例连不上、锁杀不掉每一段都给出能直接复现的命令和判断依据。2. SQL 审核检测不通过语法错、规范错、高危驳回怎么分清SQL 检测报 error 是 Archery 里最高频的一类故障。很多人把三种完全不同的失败混在一起看解析器连语法都过不去、解析通过但违反规范、以及被高危规则直接驳回。三者的处理路径不一样混着看就会在错误的页面上改半天改完重新检测报错换了一条人更懵。2.1 三类报错的处理顺序第一类是语法错SQL 解析器直接失败通常连审核规则都没走到。第二类是规范错SQL 能解析但撞上了建表必须有主键、表和列必须有注释、字段类型不能用 text 之类的自定义规则。第三类是高危拦截比如没有 WHERE 的 UPDATE、DROP TABLE平台按规则直接驳回连人工审核的机会都不给。-- 第一类语法层面就过不去FORM 拼错解析器直接失败 SELECT id, name FORM t_user WHERE id 1;-- 第二类能解析但撞规范规则——无主键、无表注释、列无注释 CREATE TABLE t_order ( id BIGINT, order_no VARCHAR(64), created_at DATETIME );-- 修正后主键、注释、索引补齐规范类报错一次清掉 CREATE TABLE t_order ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 主键, order_no VARCHAR(64) NOT NULL COMMENT 订单号, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, PRIMARY KEY (id), KEY idx_order_no (order_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单表;第一段代码里FORM是拼写错误任何解析器都过不了改 SQL 即可跟平台配置无关。第二段代码能解析但缺PRIMARY KEY、缺表注释、三个列都没有COMMENT这三点正好对应三条规范规则检测结果会一次性全列出来。第三段是修正版每条COMMENT、PRIMARY KEY、KEY都是为了消掉一条具体规则不是随手加的。判断方法很简单检测结果里如果提示里带“解析失败/语法错误”先改 SQL如果提示是“必须/不允许/建议”这类措辞就是规则命中改 SQL 或者调规则都能解决。第三类高危拦截最容易被误判成平台故障。开发同学看到“高危语句自动驳回”第一反应是找管理员关规则这是最危险的做法。常见做法是保留高危规则确实需要执行的语句走人工执行通道并在工单里写清楚影响行数、回滚方式和执行窗口。规则可以调但不能为了过一条 UPDATE 把整条拦截线拆掉。2.2 规则不是越严越好实例绑定的审核规则怎么调同一个平台上测试库和生产库经常绑不同的规则集。测试库要的是快生产库要的是稳。有人在新实例上提交 SQL发现本地测试时能过的语句到了新实例全报错原因往往不是 SQL 变了而是这个实例绑了另一套更严格的规则模板。常见做法是先在规则管理里复制一份模板按环境改三处是否强制主键、是否强制注释、高危语句的拦截级别。改完之后把模板绑到对应实例上再重新检测。这里有个容易忽略的点规则调整通常只对之后提交的工单生效已经提交的工单不会自动重新检测得撤回重提。规则项测试环境常见配置生产环境常见配置说明建表必须有主键建议强制无主键表在归档和复制上都是隐患表和列注释建议强制后续排查字段含义全靠它无 WHERE 的 UPDATE/DELETE警告驳回生产环境直接拦截避免全表误更新单次影响行数上限不限制按表规模设置超过阈值转人工执行DDL 是否允许直接执行允许转人工或定时低峰执行大表 DDL 单独评估调规则之前最好在测试实例上把同一条 SQL 跑一遍确认是规则问题而不是 SQL 本身问题。规则调完要留记录谁改的、为什么改、影响哪些实例。否则过两周再来一条同样的报错没人记得当初为什么放开。2.3 检测通过、点提交却失败状态卡住的几种原因SQL 检测全绿点“SQL 提交”却弹出一行提示这是第二高频的卡点。常见原因有三类同一实例同一库下已经有未结束的工单平台不允许并发提交工单流程里某个审批节点没配人提交时流程走不下去实例没绑资源组当前账号看不到这个实例的审批链。先看工单列表按实例和状态过滤把“待审核”“待执行”“执行中”的工单翻一遍。如果确实有未结束的工单等它结束或者撤回别硬提。如果是流程配置问题用管理员账号检查审批流节点把人为空的节点补上。# 在 Archery 部署机器上抓提交阶段的异常堆栈定位是流程配置还是并发限制 tail -n 300 /opt/archery/logs/archery.log \ | grep -iE submit|workflow|traceback|error日志路径按实际部署方式调整容器部署换成docker logs 容器名 --tail 300。重点看traceback后面的第一行异常类型如果是空指针一类多半是审批流节点没配全如果是唯一约束冲突就是并发工单限制。这一步的价值在于把“平台坏了”这种模糊判断压缩到具体某一行配置上。提示检测通过不等于一定能提交提交通过也不等于一定能执行。这三道关卡分别校验规则、流程和权限排错时不要跳步。3. 工单执行失败与回滚立即执行报错、定时没跑、回滚 SQL 是空的审核通过只是拿到入场券真正让人半夜被叫起来的是执行阶段。立即执行报错、定时执行到点没动静、出事后想回滚却发现回滚 SQL 是空白的这三类问题在 Archery 的工单详情页里都能看到蛛丝马迹关键是知道先看哪一处。3.1 立即执行失败先把平台因素排除掉执行失败的报错文本通常很短比如“执行失败请查看日志”。我的习惯是先用 Archery 里配置的执行账号在 Archery 所在机器上手动跑一遍同一条 SQL。这一步能把问题切成两半手动也失败问题在账号、网络或 SQL 本身手动成功才回头查平台配置。# 用工单里配置的执行账号在 Archery 服务器上复现同一条变更 mysql -h 10.0.0.12 -P 3306 -u app_rw -p baidd \ -e ALTER TABLE t_order ADD COLUMN remark VARCHAR(255) COMMENT 备注;-h和-P填实例地址和端口-u填 Archery 里该实例绑定的执行账号baidd是目标库。密码走交互输入不要直接写在命令里避免留在 shell 历史。如果这一步报Access denied说明执行账号权限或密码有问题报Lock wait timeout说明目标表上有未提交事务报语法或字段不存在说明测试库和生产库结构不一致。三种情况处理方式完全不同先分清再动手。报错关键词常见根因先做什么Access denied执行账号无权限或密码错误用该账号手动连库执行Unknown column / syntax目标库结构与测试库不一致对比两边表结构Lock wait timeout行锁冲突有长事务未提交查锁等待别急着重试执行超时大表 DDL 或大事务拆批次或改用在线变更工具3.2 定时执行到点没跑时区、调度、执行人三处看选了定时执行到了时间工单状态还停在“待执行”这种问题排查起来有固定顺序。先看应用服务器和数据库的时区是否一致Archery 展示的时间和你以为的时间可能差几个小时再看调度任务是否正常定时执行依赖后台调度进程进程没起或者被重启打断任务就悬着最后看执行人账号是否被禁用或调岗执行人为空的工单到点也跑不动。# 对比 Archery 应用所在机器与数据库实例的当前时间及时区 date mysql -h 10.0.0.12 -P 3306 -u app_rw -p \ -e SELECT NOW(), global.time_zone, session.time_zone;两条命令输出的时间如果差整小时基本可以确定是时区问题把应用容器和数据库的时区统一即可。时间一致但任务没跑就去看调度进程状态和工单的执行人字段。这里有个血泪经验定时任务排在上线窗口前十分钟结果审批人临时改了下拉框里的执行时间页面显示的是本地时间后台按另一个时区算任务直接跨到了第二天。定时执行这种“看不见的执行”时区一定要在第一次接入实例时就对齐。3.3 回滚 SQL 拿不到先分清 DML 和 DDL工单执行完发现数据不对第一反应是找回滚。Archery 的工单详情里有“查看回滚 SQL”和“下载回滚 SQL”但点开是空白的情况很常见。原因分两类一是这条工单执行的是 DDL结构变更本身不可回滚平台自然不会凭空生成回滚语句二是 DML 工单的回滚依赖执行前记录或 binlog 解析解析范围没覆盖到回滚就是空的。DDL 的回滚只能靠上线前自己备份结构执行前把SHOW CREATE TABLE的结果存一份出问题时按备份反向改回去。DML 的回滚可以走 Binlog2SQL 的 flashback把指定 binlog 文件和位点之间的操作反转成回滚语句。# 解析指定 binlog 区间-B 表示生成回滚 SQL python binlog2sql.py \ -h 10.0.0.12 -P 3306 -u repl -p ****** \ -d baidd -t t2 \ --start-filemaster-bin.000009 \ --start-pos857 --stop-pos1183 \ -B rollback.sql-d和-t限定库和表--start-file、--start-pos、--stop-pos定位要回滚的那段操作-B是关键参数加上它输出的是反向 SQL不加则输出原始 SQL。输出重定向到文件后先人工核对一遍再执行别直接灌回生产库。需要明确的是Binlog2SQL 只能回滚 DMLDDL 语句解析出来也回滚不了这条边界在出事之前就要记住别等回滚脚本跑完才发现结构变更没回来。注意回滚窗口和 binlog 保留时长直接相关。binlog 被清理掉之后再想按位点回滚就没有原料了清理前先确认保留天数覆盖得上故障发现周期。4. 实例连不上、账号授权不生效、会话杀不掉实例管理是 Archery 里最像“运维控制台”的部分也是故障最集中的地方。连不上、授权不生效、会话杀不掉这三类问题看起来都跟权限有关实际排查路径完全不同混着查会浪费很多时间。4.1 实例连不上按网络、账号、配置的顺序查实例列表里点“测试连接”失败先别改 Archery 的配置。正确的顺序是从 Archery 所在机器验证到实例端口的连通性再用配置的账号手动登录最后才怀疑平台里的实例参数填错。这个顺序能把范围从大缩到小避免在配置页面反复改端口号。# 第一步验证 Archery 服务器到实例 3306 端口的连通性 nc -vz 10.0.0.12 3306 # 第二步用实例里配置的账号密码手动登录 mysql -h 10.0.0.12 -P 3306 -u app_rw -p -e SELECT 1;nc不通问题在网络层安全组、白名单、实例是否只监听了内网地址。nc通但mysql报Access denied问题在账号层账号不存在、host 不匹配、密码错。两步都通过测试连接仍然失败再回头检查 Archery 实例配置里的端口、库名、字符集这些字段尤其是从别的实例复制过来改了地址却没改端口的场景。还有一种反直觉的情况Archery 所在机器能连你本地连不上于是怀疑平台把网络搞坏了。实际是实例白名单只加了 Archery 服务器没加你的办公网段。判断方法就是上面两条命令各跑一遍谁通谁不通一目了然。4.2 账号建了但登录被拒host、授权、密码策略图形界面里把账号建出来了应用连上去还是Access denied十有八九是授权没做全或者 host 不匹配。Archery 的账号管理页面能看到账号列表但排查时直接查系统表更快能同时确认账号是否存在、host 是什么、有没有被锁定。-- 确认账号是否存在、host 是否匹配、是否被锁定 SELECT user, host, account_locked FROM mysql.user WHERE user app_rw; -- 查看这个账号实际拿到了哪些权限 SHOW GRANTS FOR app_rw%;第一条语句重点看host%表示任意来源10.0.0.%表示只允许这个网段localhost只允许本机。应用服务器不在这个范围里账号建得再对也连不上。第二条语句看权限是否覆盖了目标库只有USAGE说明只建了用户没授权。-- 读写权限和结构变更权限分开授按需给 GRANT SELECT, INSERT, UPDATE, DELETE ON baidd.* TO app_rw%; GRANT ALTER, CREATE, INDEX ON baidd.* TO app_rw%; FLUSH PRIVILEGES;第一条给的是数据读写第二条给的是改表结构两条分开写是为了后续收权时能精确回收。FLUSH PRIVILEGES在通过GRANT语句授权时通常不是必须的但图形化工具改完权限后执行一次能避免缓存导致的“授权了但不生效”。密码里带特殊字符时还要注意应用侧连接串的转义很多“密码错误”其实是连接串把#或截断了。4.3 会话与锁INFO 显示不全、trx 对不上、终止无效排查阻塞时进程状态页面是主战场但直接看很容易踩三个坑。第一个坑是 SQL 显示不全因为默认没勾“完整 INFO”长 SQL 被截断看起来像另一条语句。第二个坑是事务信息里的trx_mysql_thread_id在进程列表里搜不到因为事务和会话的对应关系在刷新之间会变化。第三个坑是终止了会话阻塞还在因为杀的是等待方而不是阻塞方。-- 找出等待方和阻塞方MySQL 8.0 SELECT w.requesting_engine_transaction_id AS waiting_trx, w.blocking_engine_transaction_id AS blocking_trx, r.trx_mysql_thread_id AS waiting_thread, b.trx_mysql_thread_id AS blocking_thread, r.trx_query AS waiting_sql, b.trx_query AS blocking_sql FROM performance_schema.data_lock_waits w JOIN information_schema.innodb_trx r ON r.trx_id w.requesting_engine_transaction_id JOIN information_schema.innodb_trx b ON b.trx_id w.blocking_engine_transaction_id;这条语句直接给出waiting_thread和blocking_thread两个线程号拿blocking_thread回进程状态里搜终止它才有效。MySQL 5.7 没有performance_schema.data_lock_waits换成information_schema.innodb_lock_waits字段名也不同排查前先确认版本。这一步的意义在于把“锁信息”页面里抽象的 trx id 翻译成可以直接操作的线程号不然看到一堆十六进制事务号根本无从下手。复现锁等待也有个固定套路一个会话开事务更新某行但不提交另一个会话更新同一行就会被阻塞。用上面的语句能清楚看到谁在等、谁在挡再到进程状态里终止阻塞方。4.4 binlog 清理选中一个文件删掉的是它之前的全部磁盘告警时清理 binlog 是常规操作但 Archery 的清理逻辑是按位点截断你选中某个 binlog它之前的文件会全部被删除。很多人以为只删选中的那一个结果把还没备份的文件一起清掉了主从复制直接断。-- 先看现有 binlog 列表和大小确认哪些已经备份、从库消费到哪 SHOW BINARY LOGS; -- 只保留 master-bin.000012 及之后的文件之前的全部删除 PURGE BINARY LOGS TO master-bin.000012;第一条语句确认要保留的起点文件第二条按文件名截断正在写的文件不能作为删除目标。执行前必须确认两件事从库已经消费到起点之前备份系统已经拿到这些 binlog。图形界面清理和手动执行PURGE的效果一样区别只是前者少打一条命令风险并不会因为点了按钮就变小。5. 避坑四个高频翻车现场前面几章讲的是单点故障这一章记录四个反复出现的翻车场景。它们的共同点是操作看起来都成功了问题在几小时甚至几天后才暴露排查时又很难联想到当初那一步。5.1 PTArchiver 归档跑到一半停了现象归档任务执行一段时间后失败源表数据没减少目标表却已经写进去一部分两边对不上。原因通常有三个单批数据量太大导致事务超时、归档条件没走索引导致全表扫描、目标表主键冲突。解决方式是先把批量压小再确认归档条件命中了索引。# 小批量归档每批 500 行每 500 行提交一次事务先不删源数据 pt-archiver \ --source h10.0.0.12,P3306,uarch,p******,Dbaidd,tt_order \ --dest h10.0.0.13,P3306,uarch,p******,Dbaidd,tt_order \ --where created_at DATE_SUB(NOW(), INTERVAL 3 MONTH) \ --limit 500 --txn-size 500 --commit-each --no-delete--limit控制每批取多少行--txn-size控制多久提交一次--commit-each保证每批独立提交中途失败不会留下半个大事务。--no-delete是验证阶段的后悔药先只往目标表写、不删源表核对行数无误后再去掉这个参数正式归档。--where里的时间字段必须有索引否则每批都是一次全表扫描归档任务会把线上拖慢。5.2 SchemaSync 比对结果为空或生成的 SQL 对不上现象两个库明显结构不同比对结果却是空的或者生成了同步 SQL但少了索引和注释。原因通常是连接串写错库、表名大小写敏感导致匹配不上、账号权限看不到部分表。SchemaSync 只比对表结构不比对数据这一点在结果异常时要先确认别拿它当数据校验工具用。# 源库与目标库结构比对生成同步 SQL 和对应的回滚 SQL schemasync \ mysql://user:pass10.0.0.12:3306/baidd \ mysql://user:pass10.0.0.13:3306/baidd \ --output-dir ./schema_diff两个连接串分别对应源和目标--output-dir下会生成 patch 和 revert 两个文件前者是同步语句后者是反向语句。比对结果为空时先手动在两个库各执行一次SHOW TABLES确认连的确实是目标库再看表名大小写Linux 上的实例默认区分大小写从别处导出的脚本可能大小写不一致。5.3 慢日志页面空白以为平台没采集现象实例接入了慢日志列表一直是空的怀疑采集功能坏了。原因多半在数据库侧slow_query_log没开、long_query_time设得太大、log_output是 FILE 而平台读不到文件、或者查询的时间范围里确实没有慢查询。-- 确认慢日志开关、阈值和输出方式 SHOW VARIABLES LIKE slow_query_log; SHOW VARIABLES LIKE long_query_time; SHOW VARIABLES LIKE log_output;log_output是 TABLE 时慢日志写进mysql.slow_log表平台通过 SQL 读取是 FILE 时写到磁盘文件平台需要有文件读取权限。开关没开就先开阈值太大就调小输出方式是 FILE 但平台读不到文件就改成 TABLE 或者把文件路径挂进容器。这三个参数确认完再看平台侧的时间范围筛选很多“空白”其实是查询条件选错了日期。5.4 以为有回滚就万事大吉现象工单执行前看到详情页有“回滚 SQL”入口心里踏实了出事时点开发现是空的。原因是这条工单执行的是 DDL结构变更是不可回滚的平台不会生成不存在的回滚语句。另一个版本是定时工单被重复触发同一条变更执行了两次第二次直接报字段已存在。解决方式分两头DDL 上线前手动把SHOW CREATE TABLE的结果存档回滚靠这份结构备份定时工单执行前确认状态避免同一工单被重复提交。回滚入口存在不代表回滚一定可用执行前花十秒点开看一眼比出事后再找 binlog 位点便宜得多。6. 快速定位一张顺序表和两个习惯被 Archery 的报错卡住时最耗时间的不是解决而是判断该从哪里看。我的做法是先按现象归到一张固定顺序表里再往下钻避免在平台页面和数据库之间来回跳。现象第一现场下一步SQL 检测报 error检测结果提示措辞带“解析失败”改 SQL带“必须/不允许”改规则或 SQL检测通过提交失败同实例未结束工单、审批流节点清工单、补审批人立即执行失败手动用执行账号复现报错落在账号、锁还是结构不一致定时执行没跑应用与数据库时区、调度进程统一时区检查执行人状态回滚 SQL 为空工单是 DDL 还是 DMLDDL 走结构备份DML 走 Binlog2SQL实例测试连接失败nc端口连通性不通查网络通查账号阻塞杀不掉锁等待里的阻塞线程号终止阻塞方而不是等待方慢日志空白slow_query_log、log_output先改数据库参数再看平台两个习惯值得固定下来。第一个是“先复现再改配置”任何执行类报错先用执行账号手动跑一遍手动能复现就说明问题在数据库侧改平台配置只会把水搅浑。第二个是“变更前留三样东西”表结构备份、binlog 位点、回滚 SQL 是否可用的确认。这三样在平时看着多余出事时能省掉一晚上的猜测。从那以后我每次提交工单前都会先点开回滚入口确认一眼DDL 工单额外存一份SHOW CREATE TABLE的结果定时工单执行前再扫一遍状态。这些动作加起来不到一分钟但把“回滚不了”和“重复执行”这两类最难查的故障挡在了门外。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →