news 2026/11/4 7:42:26

Archery 使用手册:SQL 审核工单、回滚与 binlog 排查实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Archery 使用手册:SQL 审核工单、回滚与 binlog 排查实战

简介:《archery使用手册》是一份面向SQL审核、查询平台使用者和MySQL运维人员的实操文档,围绕Archery的审核规则、工单流程、SQL优化与实例管理展开,适合开发、测试及DBA在数据库规范落地和日常排障中参考。压缩包共1个doc文件,大小约1.2MB,内容按功能详解与实践案例组织,便于集中查阅。手册具体梳理SQL语法与规范审核、高危语句驳回、定时或立即执行及回滚SQL,也覆盖执行计划分析、慢SQL统计、binlog清理、会话与事务终止、锁信息排查、账号授权和动态参数配置;PTArchiver、Binlog2SQL、SchemaSync等插件的用途与操作示例亦有涉及。已有1479人学习,可作为快速熟悉Archery功能边界、对照实践流程与查漏补缺的参考资料。

1. Archery 不是只做审核:一次误更新之后我重新读了这份手册

凌晨收到磁盘告警,登上去发现一条没走任何审核的 UPDATE 打在大表上,备份是有的,binlog 也在,可真要从里面捞出一句正确的回滚语句,团队里没人敢拍胸脯。这种翻车现场我见过不止一次。Archery 使用手册这份材料要解决的就是这条链路上的断点:它把 SQL 审核、工单执行、回滚语句生成、会话与锁的排查、binlog 解析、表结构比对串成一个闭环,让每次变更留审核记录,让每句 DML 都有后悔药。它面向的是每天要碰库的人:研发提工单、测试做环境验证、DBA 处置慢查询和阻塞。下面按我实际拆过一遍的顺序,把流程、参数和坑位摊开。

2. SQL 审核工单怎么走:从提交检测到回滚 SQL 落盘

很多人把审核理解成"提交前点一下检测按钮",实际用下来会发现,真正的价值在于规则前置和回滚兜底这两头。审核只是中间一段,前面要有可执行的规范,后面要有能验证的回滚。这一章按规则、环境、操作、回滚四段拆。

2.1 审核规则先立住:主键、注释、高危语句三条硬线

Archery 的审核链路是先把提交的 SQL 解析成语法树,再逐条套自定义规则,返回按等级分类的结果:error 级直接阻断提交,warn 级只提示不拦。所以规则配得好不好,决定了这个平台是帮你把关还是变成走流程的橡皮图章。

我一般会把硬线压到三条:建表必须有主键、表和列必须有注释、高危语句自动驳回。第一条关系到后续数据订正和归档能不能定位到行,没主键的表在 pt-archiver 归档时几乎没法安全分批;第二条关系到后来人读不读得懂这张表,尤其是字段上百的宽表;第三条是保命的,无 where 的 update/delete、drop table、truncate 这类语句一旦放过,后面所有流程都白搭。

先看一条能顺利过检的建表语句:

-- 提交前自己先过一遍:主键、注释、字符集、索引命名都在 CREATE TABLE `order_flow` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', `order_no` varchar(32) NOT NULL COMMENT '订单号', `amount` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '金额', `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`), KEY `idx_order_no` (`order_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单流水表';

再看一条大概率被 error 拦下的:

-- 缺主键、表和列都没有注释,规范类规则会逐条报出来 CREATE TABLE order_flow_bak ( order_no varchar(32) NOT NULL, amount decimal(12,2) );

这两段的差别不在语法,语法都合法。差别在解析器把 AST 拆开后能提取到的元信息:有没有 primary key 节点、comment 属性是不是空、字段类型有没有超长、字符集是不是统一。参数上要留意规则等级,同一条规则在不同实例上可以配成 error 或 warn,比如历史库的存量表注释缺失较多,一刀切成 error 会让所有变更都卡住,这种库我一般先配 warn 跑两周,把存量问题清完再收紧。

规则项判定依据平台处置建议
建表无主键AST 中缺少 PRIMARY KEY 定义error,阻断提交所有新表强制
表/列无注释comment 属性为空error 或 warn新库 error,存量库先 warn
高危 DML无 where 的 update/delete自动驳回一律 error,不给例外
字符集不一致表字符集与库默认不同warn统一 utf8mb4
索引命名索引名不匹配约定前缀warn便于后期排查

规则配完还要有人维护。常见做法是每季度拉一次被驳回的工单,看看哪些规则误伤率高、哪些规则从来没人触发,前者放宽,后者说明开发已经养成习惯或者规则本身失效,该删就删。

2.2 开发环境与测试环境的两套流转逻辑

同一套平台,开发和测试两条流程的发起人、审核链、执行人都不一样,弄混了最容易出现"工单提错环境"的低级问题。

开发环境的链路是:研发工程师发起 → 项目经理审核 → 最后一级通过后选择立即执行或定时执行。这条链多一道业务负责人的确认,因为开发库往往是多人共用,一次表结构变更可能影响同库的其他模块。

测试环境的链路是:测试同事从 git 上取开发已提交的 SQL 文件 → 在测试环境发起审核 → 测试同事自己审核并执行。发起和审核是同一个人,看着像没审核,其实是把把关点前移到了 SQL 检测那一步:检测不过就提交不了,提交了才轮到自己点通过。

维度开发环境测试环境
发起人研发工程师测试工程师
SQL 来源本地开发整理git 上开发提交的文件
审核链项目经理测试自己(审核+执行)
执行时机立即或定时立即为主
主要风险影响多人共用库自审自执行跳过检测

测试环境这条链最容易出的问题,是测试同学拿到文件直接点提交、跳过 SQL 检测。平台的检测是提交前的独立动作,不是提交时自动跑的,漏点一次等于规则全部失效。我习惯在流程里加一条约定:任何环境提交前必须先点检测,检测结果截图跟工单一起留档。

2.3 提交、检测、审批、执行四步实操

把一次工单从头走到尾,动作其实只有四步,但每一步都有容易漏的细节。

第一步,准备 SQL 文件。文件名带上日期、库名、变更类型,语句之间用分号分隔,避免一个文件里混着 DDL 和 DML 却没标注。文件编码统一 UTF-8,中文注释才不会在解析时变成乱码导致误判。

第二步,发起工单。选实例、选库、上传文件或直接粘贴,填变更说明。点"SQL 检测"后看结果:出现 error 就必须改 SQL 重新提交,warn 可以带着说明继续。检测通过再点"SQL 提交",这时工单才真正进入审核队列。

第三步,审批。审核人登录后点右上角通知按钮看待办,逐条看 SQL 和检测结果。这一步别只看有没有 error,还要看变更窗口:大表加索引这类操作即使语句合规,也可能在业务高峰把 IO 打满。最后一级审核通过后,选择"立即执行"或"定时执行"。定时执行的价值就在这里,把变更压到低峰窗口,不用人半夜守着点按钮。

第四步,执行后验证。执行成功不等于变更正确,尤其是 DML 类工单,要回查影响行数和数据分布。

提交前我会在本地先跑一遍自检,省得来回改:

-- 1. 找出没有主键的表(返回结果为空才放心) SELECT t.table_schema, t.table_name FROM information_schema.tables t LEFT JOIN information_schema.statistics s ON s.table_schema = t.table_schema AND s.table_name = t.table_name AND s.index_name = 'PRIMARY' WHERE t.table_schema = 'baidd' AND t.table_type = 'BASE TABLE' AND s.index_name IS NULL; -- 2. 找出缺列注释的字段 SELECT table_name, column_name, column_type FROM information_schema.columns WHERE table_schema = 'baidd' AND (column_comment = '' OR column_comment IS NULL); -- 3. 看表体量,决定要不要改成定时执行 SELECT table_name, table_rows, ROUND(data_length / 1024 / 1024, 2) AS data_mb FROM information_schema.tables WHERE table_schema = 'baidd' ORDER BY data_length DESC LIMIT 10;

第一段用 left join 反查 statistics 里没有 PRIMARY 索引的表,注意要把 table_type 限定成 BASE TABLE,否则视图会被误报。第二段直接扫 columns 的 comment 字段,返回的行就是审核时会被标出来的列。第三段看表体量和数据量,data_mb 超过一定阈值(我一般按 5GB 划线)的变更就不要选立即执行了,走定时。

2.4 回滚 SQL 的生成与验证

工单执行完之后,页面上可以"查看回滚 SQL"和"下载回滚 SQL"。生成逻辑是把原语句按类型反向推导:insert 对应 delete、delete 对应 insert、update 用原值反写 where 条件。这一步是整条链路里最像后悔药的部分,但它的边界必须说清楚。

DML 能回滚,DDL 只能回滚结构、回滚不了数据。drop column 生成的回滚语句是 alter table add column,列加回来了,里面的值没了。truncate 更是连结构都不保留。所以看到工单里有 DDL 时,回滚 SQL 只能当结构参考,真正的兜底还是执行前的备份。

回滚 SQL 下载下来别急着存网盘。我一般会在影子库先执行一遍:拿一份同结构的空库,把回滚语句跑通,确认语法没问题、where 条件能命中预期行数、没有漏掉 limit。这一步花十分钟,能挡住后面几小时的排查。

原操作回滚语句形态数据能否恢复
insertdelete ... where 主键能
updateupdate ... set 原值 where 主键能
deleteinsert ... values 原行能
alter table add columnalter table drop column仅结构
alter table drop columnalter table add column数据丢失
truncate / drop无有效回滚不可恢复

提示:回滚 SQL 生成后要检查 where 条件是否带上了完整主键。缺主键的 update 生成的回滚语句会按原 where 条件反写,一旦原条件是范围匹配,回滚可能波及更多行。

3. SQL 优化与慢日志:执行计划里那几个字段到底怎么看

审核管的是"能不能执行",优化管的是"执行得快不快"。这两件事在 Archery 里是两个入口,但排查思路是连着的:慢日志告诉你哪条 SQL 慢,SQL 分析告诉你为什么慢。

3.1 SQL 分析入口与优化建议的取舍

在 SQL 优化页面贴入语句,平台会返回执行计划和优化建议。拿手册里的例子:SELECT * FROM baidd.emp WHERE ename='dan_1';分析结果会提示把select *改成具体字段,改完再分析就变成 OK。

为什么select *在这类规则里被判问题,值得说清楚。一是覆盖索引失效,本来ename上的索引能直接返回结果,带*就得回表取整行;二是宽表传输成本高,几十个字段全部拉回客户端,网络和内存都要付代价;三是表结构变更后,*的返回列会跟着变,依赖固定列序的代码容易出问题。

但优化建议不能照单全收。平台给的索引建议有时会和你已有的索引重复,或者建议的字段区分度极低(比如性别、状态位),建了也用不上,反而拖慢写入。我的判断顺序是:先看执行计划里 type 是不是 ALL,再看 rows 估算行数,最后才看建议要不要采纳。

-- 分析前先确认表上有哪些索引,避免重复建 SHOW INDEX FROM baidd.emp; -- 看语句实际走了哪个索引 EXPLAIN SELECT id, ename, dept_no FROM baidd.emp WHERE ename = 'dan_1';

第一段返回索引名、列序、基数,基数(Cardinality)越低说明这列区分度越差。第二段把*换成具体字段后再 explain,对比 key 列有没有变化,这是验证优化是否生效最直接的办法。

3.2 执行计划字段解读

执行计划里字段不少,日常排查真正需要盯的就几个。

字段含义关注点
type访问类型ALL 全表扫描要处理,index 次之,range/ref/eq_ref 可接受
possible_keys可能用到的索引为空说明压根没索引可用
key实际使用的索引与 possible_keys 不一致时要看为什么没选中
key_len索引使用长度比预期短说明联合索引只用了前几列
rows预估扫描行数数量级偏大就要考虑改写或加索引
filtered过滤后剩余比例很低说明 where 条件没被索引覆盖
Extra附加信息Using filesort、Using temporary 是需要优化的信号

type 从差到好的顺序大致是 ALL → index → range → ref → eq_ref → const。看到 ALL 不一定要立刻加索引,小表全扫可能比走索引还快,rows 只有几百行的表可以放一放。真正的血泪经验是 key_len:联合索引 (a,b,c),如果 key_len 只等于 a 的长度,说明 b 和 c 没用上,常见原因是查询条件里跳过了 b 直接用了 c。

Extra 里的 Using filesort 表示排序没走索引,数据量大时会写临时文件;Using temporary 表示用了临时表,常见于 group by 和 distinct。这两个信号同时出现,基本可以判定这条 SQL 需要改写。

3.3 慢日志统计与索引确认

慢 SQL 页面能看到慢语句列表和统计信息。统计维度一般包括执行次数、平均耗时、最大耗时、扫描行数。排序方式很关键:按总耗时排,找出来的是高频低耗的语句,优化收益大;按单次最大耗时排,找出来的是偶发的重查询,往往是某个报表或者导出任务。

慢日志本身是采样,受 long_query_time 阈值控制,低于阈值的语句不会记录。所以看到"没有慢 SQL"不等于没有问题,可能只是阈值设得太宽。我一般把阈值压到 1 秒,先跑一周看整体分布,再决定要不要放宽。

-- 按平均耗时排序,找出最该优先处理的语句 SELECT digest_text, count_star, ROUND(avg_timer_wait / 1e12, 3) AS avg_sec, ROUND(max_timer_wait / 1e12, 3) AS max_sec, sum_rows_examined FROM performance_schema.events_statements_summary_by_digest WHERE schema_name = 'baidd' ORDER BY avg_timer_wait DESC LIMIT 20;

这段查的是 statements summary 表,digest_text 是归一化后的语句模板(参数被替换成 ?),所以同一类语句会聚合成一行。avg_timer_wait 单位是皮秒,除以 1e12 换成秒。sum_rows_examined 是累计扫描行数,这个值除以 count_star 得到的平均扫描行数,比耗时更能反映索引是否合理——平均扫描几万行才返回几条记录的语句,优先处理。

拿到慢语句后回到 SQL 分析页面贴进去看执行计划,两步串起来才算闭环。只优化不加验证是另一个坑:改完 SQL 要在测试环境用相近数据量跑一遍,小数据量下执行计划可能选错索引,上线后才暴露。

4. 实例管理联动排查:binlog、会话、事务与锁

实例管理这一块默认只有管理员账号有权限,权限收紧是对的,因为这里的每个按钮都能直接影响线上。四个功能看似独立,实际排查时经常要连着用:会话列表看到阻塞,转到锁信息确认阻塞方,再看事务信息判断是不是长事务没提交。

4.1 binlog 清理的顺序陷阱

磁盘空间不足时,清理 binlog 是最快的释放手段。在实例列表里选中某个 binlog,平台会把这个文件以及它之前的所有 binlog 一起删除。注意这个"之前"是关键字:如果你选中的是中间某个文件,前面几个也会一起没。

这个设计不是平台的问题,是 MySQL 本身的机制决定的,binlog 只能按顺序从最早的开始删。但操作时很容易误判成"只删选中的这一个"。我一般按三步走:先确认从库同步到了哪个文件、确认没有延迟很大的从库还依赖旧文件、确认最近的备份对应的 binlog 起点在哪。

-- 1. 从库同步到哪个文件、延迟多少 SHOW SLAVE STATUS\G -- 关注 Master_Log_File、Read_Master_Log_Pos、Seconds_Behind_Master -- 2. 当前正在写的 binlog SHOW MASTER STATUS; -- 3. 手工清理时对比平台操作(一般在平台点,命令行仅作核对) -- PURGE BINARY LOGS TO 'mysql-bin.000020';

第一段在从库上执行,Master_Log_File 表示从库已经读到主库的哪个文件,Seconds_Behind_Master 是延迟秒数。清理前必须确认要删的文件都小于这个位置,否则从库会报错中断。第二段在主库执行,拿到当前文件号作为边界参考。第三段是 MySQL 原生命令,只用来核对平台操作的范围对不对,实际清理还是走平台,因为平台会记录操作人和时间。

注意:清理 binlog 前确认最近一次全量备份的起始位置。如果备份对应的 binlog 被删掉,这份备份就没法做基于时间点的恢复。

4.2 会话管理必须先勾"完整 INFO"

进程状态页面能看到当前正在执行的 SQL。右上角选择实例和 command 类型,默认是 query,只看查询类进程;排查问题时切到 All,把 Sleep、Binlog Dump 这些也带上,才能看到全貌。

这里有个反复踩的坑:列表里的 INFO 列默认是截断的,长 SQL 只显示前面一小段,根本看不出问题。必须先勾上"完整 INFO",否则你会对着一句残缺的 SQL 排查半天。截断不是玄学,是为了避免一次拉几百条长语句把页面拖死。

定位到具体某条 SQL 造成阻塞后,点"终止会话"就能 kill 掉。但终止前要确认两件事:这条会话是不是在跑长事务、是不是已经执行了大半。一个跑了四十分钟的 alter table 被你 kill 掉,回滚过程可能比原操作还久。

4.3 事务与锁信息联合定位阻塞

事务信息页面看当前运行的事务,关键字段是 trx_mysql_thread_id,它对应的就是进程状态里的 THREAD ID。锁信息页面看等待关系,能看到等待事务的 SQL(也就是被阻塞的那条)和阻塞方的线程 id。

手册里给了一个很干净的复现方式,我在测试库照着跑过一遍:

-- 会话 A:开事务并更新 id=2 BEGIN; UPDATE baidd.t2 SET ename = 'baidd' WHERE id = 2; -- 会话 B:另一条连接执行,会被阻塞 UPDATE baidd.t2 SET ename = 'dan' WHERE id = 2;

会话 A 执行完不提交,会话 B 就会卡住。这时候在锁信息页面能看到:等待事务的 SQL 是会话 B 那条 update,阻塞方的线程 id 指向会话 A。处理方式有两种,取决于业务:确认会话 A 是忘了提交,就直接按 trx_mysql_thread_id 在进程状态里搜到线程并终止;如果会话 A 正在跑重要的批量更新,就等它跑完,贸然 kill 会触发回滚。

排查顺序我习惯倒着来:先看锁信息确认有没有等待,再看事务信息确认阻塞事务开了多久,最后去进程状态里定位线程。反过来做的话,进程列表几百条,很难一眼找出问题。

-- 直接查锁等待关系,与平台页面对照 SELECT r.trx_id AS waiting_trx, r.trx_mysql_thread_id AS waiting_thread, r.trx_query AS waiting_query, b.trx_id AS blocking_trx, b.trx_mysql_thread_id AS blocking_thread, b.trx_query AS blocking_query FROM information_schema.innodb_lock_waits w JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id;

这段查的是 innodb_lock_waits 和 innodb_trx 的关联,waiting_thread 拿到后在平台进程页面搜,就是那个要终止的会话。blocking_query 有时为空,因为阻塞事务可能已经执行完语句处于 Sleep 状态,这时候要看 blocking_trx 的开始时间和状态判断。

4.4 账号管理与动态参数留痕

账号管理支持图形化建号、授权、改密、删号。建完账号必须单独授权,不会自动带上权限。授权时按最小权限给,一个只读报表账号就不要给 INSERT。

-- 平台授权背后的等价语句,用于核对权限是否符合预期 GRANT SELECT, INSERT, UPDATE, DELETE ON baidd.* TO 'app_rw'@'10.0.%'; SHOW GRANTS FOR 'app_rw'@'10.0.%';

第一段是读写账号的典型授权,库级粒度。第二段核对实际生效的权限,重点看有没有意外的*.*或者 GRANT OPTION。平台操作完最好用这个语句复核一遍,图形界面偶尔会有勾选遗漏。

参数配置这一块能改实例的动态参数并记录修改历史。要区分动态参数和静态参数:innodb_buffer_pool_size 在 5.7 之后支持在线调整,但调整过程会占 IO;max_connections 可以直接改;而像 innodb_log_file_size 这种改了要重启才生效的,平台上改了不会立即体现,容易误判成没生效。改完参数一定要在历史记录里留一句变更原因,不然三个月后没人知道为什么这个值被调过。

4.5 结构比对与归档入口

实例管理之外还有两个常被忽略的能力。SchemaSync 用来读源库和目标库的表结构,自动生成同步用的 DDL 和对应的回滚 SQL。它只比对表结构,不比对数据,所以拿它做上线前的结构核对很合适,但别指望它发现数据不一致。

PTArchiver 解决的是大表历史数据堆积。线上流水表只保留最近三个月,更早的数据归档到历史库,配成定时任务后不用人工干预。归档前务必确认表有主键,否则分批删除没法定位行,容易锁表。

5. 常见问题与排查:五条踩坑记录

下面这几条是实际用下来反复出现的,每条按现象、原因、解决写。

第一条:SQL 检测全绿,执行时报错。

现象是工单检测通过、审批通过,点执行后返回字段不存在或者字符集不兼容。原因是检测阶段主要做语法解析和规范匹配,不做执行环境校验,SQL 里引用的表在目标库不存在、字段类型和值不匹配这类问题它发现不了。解决方式是在提交前先在目标库跑一次EXPLAIN或者SELECT ... LIMIT 0验证对象存在,工单里附上验证结果。

第二条:回滚 SQL 执行了,数据还是没回来。

现象是 DDL 工单执行后发现问题,下载回滚 SQL 跑完,表结构恢复了但数据空了。原因是回滚语句只还原结构,drop column、truncate 这类操作的数据在语句执行时就已经丢失。解决方式是所有含 DDL 的工单执行前做表级备份,回滚 SQL 只当结构参考,别当数据恢复手段。

第三条:清理 binlog 后从库报错中断。

现象是磁盘告警处理完,第二天发现从库同步停了,报找不到 binlog 文件。原因是清理时选中的文件晚于从库已同步的位置,前面被一起删掉了。解决方式是按 4.1 的顺序先查SHOW SLAVE STATUS,确认 Master_Log_File 之后再操作;已经出问题的从库需要重新做全量同步。

第四条:会话列表里看不到完整 SQL。

现象是排查阻塞时,INFO 列只有半句话,看不出是哪个业务。原因是没勾"完整 INFO",页面默认做了截断。解决方式是进页面第一件事就勾上这个选项,再选 command 类型为 All。这条踩过一次就会记住,属于纯粹的界面习惯问题。

第五条:binlog2sql 解析不出回滚语句。

现象是填入起始和结束位置后,返回结果为空或者报格式错误。原因通常有两个:实例的 binlog_format 不是 ROW,或者选的位置区间内只有 DDL。前者需要确认参数配置,后者是 binlog2sql 的固有限制,DDL 无法生成回滚。解决方式是先在实例参数里确认binlog_format=ROW,再通过SHOW BINLOG EVENTS看区间内的事件类型,只有 Query 事件(DDL)时不要指望回滚。

6. 进阶:用 binlog2sql 做一次可验证的数据回滚演练

前面说的回滚 SQL 是平台根据原语句推的,真正的兜底能力在 binlog2sql:从 binlog 里把实际执行过的 SQL 解析出来,再生成反向语句。这两者的差别在于,前者依赖工单记录,后者依赖磁盘上的 binlog,即使有人绕过平台直接连库改数据,也能捞回来。

演练步骤我一般这么走。先确认 binlog_format 是 ROW,这是解析的前提,STATEMENT 格式拿不到行级变更。再通过SHOW MASTER STATUS和SHOW BINLOG EVENTS定位误操作落在哪个文件、哪个位置区间。然后进工具插件页面选实例、填起始文件和起止位置,点获取 SQL。如果只是想确认改了什么,这一步就够了;要回滚就点 flashback 再获取一次,平台会返回反向语句。文件大时用异步获取,执行完会通知结果。

命令行版本适合在演练环境先验证一遍:

# 解析原始 SQL:看这段区间内到底执行了什么 python binlog2sql.py -h127.0.0.1 -P3306 -uuser -p'pass' \ -d baidd -t t2 \ --start-file='mysql-bin.000009' --start-pos=857 --stop-pos=1183 # 生成回滚 SQL:加 -B 参数,输出的是反向语句 python binlog2sql.py -h127.0.0.1 -P3306 -uuser -p'pass' \ -d baidd -t t2 \ --start-file='mysql-bin.000009' --start-pos=857 --stop-pos=1183 -B

参数含义逐个数:-d指定库名,-t指定表名,两个都可省略,省略时解析全库全表但输出会很长;--start-file和--start-pos是解析起点,--stop-pos是终点,位置号可以从SHOW BINLOG EVENTS IN 'mysql-bin.000009'的结果里找;-B是 flashback 开关,输出 update 的反向 update、insert 的反向 delete。第一次跑建议先不加-B,看清楚原始变更再决定。

场景参数组合输出内容
确认改了什么不加 -B原始 SQL
生成回滚语句加 -B反向 DML
只要 insert 部分加--only-dml --sql-type INSERT插入语句
去掉主键生成加--no-primary-key无主键 insert

回滚语句生成后不要直接往生产跑。我的做法是先导入影子库,比对影响行数和主键范围,确认无误再执行。DDL 的回滚别指望这个工具,它只处理 DML。

从那以后我每次做数据订正工单,都强制走一遍"定位 binlog 位置 → 解析原始 SQL → 生成回滚 → 影子库验证"这四步,哪怕只是改一行。多花十分钟,换来的是出问题时能当场把数据摆回去,而不是对着一堆备份文件干瞪眼。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 7:42:19

系统集成项目中的网络规划与设备选型实战指南

1. 系统集成项目管理的核心挑战在IT基础设施建设项目中,系统集成往往是最具挑战性的环节。记得去年负责某大型制造企业的ERP升级项目时,网络设备与原有生产系统的兼容性问题就让整个团队熬了三个通宵。这种痛点的根源在于:系统集成不是简单的…

作者头像 李华
网站建设 2026/11/4 7:41:26

SQL Server新手入门:从安装到建表查数据的完整实践地图

简介:这是一份面向数据库初学者与SQL Server入门者的系统性学习笔记,帮助读者快速掌握关系型数据库核心概念与SQL Server管理实践。内容覆盖数据库对象操作(CREATE/DROP/ALTER)、C/S架构原理、系统数据库功能(master/m…

作者头像 李华
网站建设 2026/11/4 7:41:25

橡胶制造业能源管理系统:MyEMS架构与能效优化实践

1. 项目背景与行业痛点橡胶制品制造业作为典型的高能耗行业,其生产过程中存在三大能源管理痛点:首先,密炼、硫化等核心工序的能耗占生产成本高达30%-40%,但多数企业仍依赖人工抄表统计,数据滞后严重;其次&a…

作者头像 李华
网站建设 2026/11/4 7:41:24

Redis高并发秒杀系统架构设计与实战优化

1. 优惠券秒杀的业务挑战与技术选型去年双十一期间,我们电商平台的200元无门槛优惠券在3秒内被抢购一空,服务器却因为瞬时高并发险些崩溃。这种秒杀场景对系统架构提出了极高要求:既要保证超卖问题零容忍,又要应对突发流量冲击。R…

作者头像 李华
网站建设 2026/11/4 7:40:20

Shenandoah GC中Brooks Pointer实现机制解析

1. 面试题背景与核心考察点最近一位参加米哈游Java开发岗位面试的朋友被问到了一个相当硬核的问题:Shenandoah GC中Brooks Pointer的实现机制。这实际上是在考察候选人对现代垃圾回收器底层原理的掌握程度,特别是对并发标记-整理算法的理解深度。Shenand…

作者头像 李华
网站建设 2026/11/4 7:40:20

Gradle依赖统一管理:Version Catalog迁移与CI卡口实践

简介:面向Android开发者的Gradle依赖统一管理示例工程,适合已具备基础构建知识、希望集中维护版本号与依赖配置的开发者参考。压缩包共34个文件、约100KB,包含gradle构建脚本、properties配置、xml清单、Java源码与jar包,并以bat批…

作者头像 李华