惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Full Disclosure
V
Vulnerabilities – Threatpost
Attack and Defense Labs
Attack and Defense Labs
N
News and Events Feed by Topic
SecWiki News
SecWiki News
S
Security @ Cisco Blogs
Schneier on Security
Schneier on Security
B
Blog
TaoSecurity Blog
TaoSecurity Blog
The Last Watchdog
The Last Watchdog
H
Hacker News: Front Page
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园_首页
D
Docker
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Y
Y Combinator Blog
W
WeLiveSecurity
N
News and Events Feed by Topic
F
Fortinet All Blogs
PCI Perspectives
PCI Perspectives
WordPress大学
WordPress大学
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Recent Announcements
Recent Announcements
Forbes - Security
Forbes - Security
T
Tailwind CSS Blog
Hacker News: Ask HN
Hacker News: Ask HN
爱范儿
爱范儿
腾讯CDC
Last Week in AI
Last Week in AI
月光博客
月光博客
C
Cybersecurity and Infrastructure Security Agency CISA
P
Proofpoint News Feed
Help Net Security
Help Net Security
V
V2EX
C
Cyber Attacks, Cyber Crime and Cyber Security
C
CXSECURITY Database RSS Feed - CXSecurity.com
H
Heimdal Security Blog
L
LINUX DO - 最新话题
GbyAI
GbyAI
The Hacker News
The Hacker News
罗磊的独立博客
S
SegmentFault 最新的问题
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 【当耐特】
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V2EX - 技术
V2EX - 技术
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
O
OpenAI News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

博客园_首页

Plist 二进制格式 Milvus 和 PGVector,哪个更好? OpenClaw 已过时?在 VS Code 中运行 Hermes Agent! 第30篇文章:一个大三计科生的自白 Manim如何在数学公式中完美显示中文? Docker 部署 RocketMQ 5 并发编程核心概念辨析 C#事务处理最佳实践:别再让“主表存了、明细丢了”的破事发生 CLI 是什么?为什么大厂突然集体卷命令行? 【从0到1构建一个ClaudeAgent】协作-自主Agent UIImageView 设置图片不生效的原因排查 最小二乘问题详解20:无先验约束下的增量式SFM自由网平差 痞子衡嵌入式:大话双核i.MXRT1180之XIP应用里借助MU实现可靠Flash IAP的方法 AI Chat 封装, SemanticKerne.AiProvider.Unified 已发布 Windows下右键编辑js文件无法打开记事本——在注册表中使用环境变量 在后台服务中使用 Scoped 服务,为什么总是报错? H200 安装驱动并使用sglang启动模型 wireshark 抓包Trap上报告警内容 我用 AI 辅助开发了一系列小工具(2):图片压缩工具 [A Primer On MC and CC] 2.1 Memory Consistency 1 - 指令重排序和 SC 模型 Oracle数据库SCN推进技术详解与实践指南 玩转控件:封装个带图片的Label控件 Claude Code 4.7 真正该升级的不是模型,而是你的工作流 前端小白一句话,AI 帮我做了个颜值拉满的桌面媒体播放器。当代码不再是门槛,一句话编程就是现实。 5. WorkBuddy: 小龙虾的灵魂三件套,让你的小龙虾不只是工具 SQLite 分片方案实战:三种分片策略的深度对比 告别简陋 UI!一款基于 Fluent Design 和基于 WinUI 的开源免费、现代化的 Avalonia UI 控件库 关于二进制排列组合枚举的总结 AI开发-python-LangGraph框架(3-27-LangGraph从零实现大模型智能决策工作流) ElasticSearch主分片和副本分片概念详解 【002】HTTPS 粗解:证书、TLS 握手与对后端配置的影响 Hermes Agent 一周暴涨五万 Star,但我劝你别急着追 明明连接的是Redis的DB0,为什么能查到DB3的数据? 【从0到1构建一个ClaudeAgent】协作-Agent团队 熟悉电子元器件之后,电子小白下一步该怎么走? MAF快速入门(23)通过C#类定义Skills .NET 高级开发 | 手写一个对象映射框架 FastAPI数据库ORM怎么选?我肝了三个Demo后,终于不再纠结了 mysqldump 参数拾遗:在遗忘与铭记之间 C# .NET 周刊|2026年3月5期 Claude code入门 - 陈彦斌 一文学习入门 ThingsBoard 开源物联网平台 GitHub 热门项目 | 2026年04月16日 如何为GIT设置全局勾子,为每次提交追加信息 Number.isFinite和isFinite与isNaN()和Number.isNaN的区别 PortSwigger SQL注入LAB2 推荐一个测试人必备的Skills,从功能到性能全搞定(附详细实操和安装下载方式) 筑基期:掌握Odoo基础核心知识点02(Odoo XML 开发方式详解) GLM模型这么火,咱们用vllm也咧一个呗! 深入理解 AbortController:从底层原理到跨语言设计哲学 字符串学习笔记 多租户系统框架的基础模块设计和分析设计 Apache SeaTunnel Zeta 为什么能做到“又快又稳”? AI开发-python-LangGraph框架(3-26-LangGraph基本概念及第一个简单样例) Vue 3 组件通信,别只会用 Props 和 Emits 了,这几个狠活儿你得看看 ElasticSearch7.X版本配置密码 用Manim实现动态交点计算--从一个动点问题说起 团结引擎+Addressable+Instant Game打包抖音小游戏 function call 实战:让 LLM 自动判断 pod 异常、调用日志工具并完成故障分析 bubseek —— 让 Agent 的足迹,变成团队的洞察 通过 C# 读取并导出 PDF 书签 如何用 GitHub Actions 实现 Steam 自动化发布 【从0到1构建一个ClaudeAgent】并发-后台任务 .NET 高级开发 | 定制 ASP.NET Core 框架 电子小白:什么是运算放大器(运放) zero2Agent:面向大厂面试的 Agent 工程教程,从概念到生产的完整学习路线 堆上的ORW HC32F460 USB CDC通信异常:非对齐访问异常排查 20260413-Hyperbridge 攻击事件:发生在默克尔山上的验证绕过 那些喊着AI 要淘汰你的人,正在靠你的焦虑赚大钱! 深度学习进阶(八)Swin Transformer 最小二乘问题详解19:带先验约束的增量式SFM优化与实现 SnapTranslate 3.0 正式发布:全局划词翻译 + 完整英语学习闭环,一站式搞定查词、记词、复习 工作的意义、工作的困难认知再思考 .NET + AI 进阶实战:基于类的技能开发 - 打造可治理的 Agent 能力模块 【从0到1构建一个ClaudeAgent】规划与协调-技能 上周热点回顾(4.6-4.12) 电子小白的工具三件套:面包板、杜邦线、万能板 单表五亿数据的查询优化 | Mysql、StarRocks 2. WorkBuddy:从“我是谁”到“帮我干活” C# 如何减少代码运行时间:7 个实战技巧 基于HelixToolkit.SharpDX 渲染3D模型 - 笺上知微 从零开始的双臂具身VLA起源及现阶段发展综述 - SkyXZ 记对 xonsh shell 的使用, 脚本编写, 迁移及调优 - pluvium27 受够了Vibe Coding的失控?换个起点,让AI事半功倍 从开始配置漏洞环境到漏洞复现流程 - 難しい 关于10年工作经验的程序员对OpenClaw的实战经验分享以及看法 - 虚无境 Any metadata 的内存布局 C# .NET 周刊|2026年3月2期 - InCerry 我帮你测过了,测试圈排名第二的 Skill 依然很牛逼 Skill Discovery | 无监督技能发现的经典工作总结 - MoonOut 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 开了 TUN 模式还是直连?90% 的人都踩过这个坑 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术
gt-checksum v4.0.0 新功能解读系列文章(3):反向回滚 SQL——修复可审计、可回退
GreatSQL · 2026-06-18 · via 博客园_首页

在数据修复场景中,"修复容易,回滚困难"一直是个痛点。执行完修复 SQL 后发现结果不符合预期,却没有现成的回退手段。

gt-checksum v4.0.0 新增反向回滚 SQL 生成能力,让每一次修复都有"后悔药"。


一、功能简介

genRollSQL 是 gt-checksum v4.0.0 新增的核心参数,配合 maxRollRowNumrollFileDir 一起使用,用于在生成修复 SQL 的同时自动生成反向回滚 SQL

参数说明

参数 默认值 可选值 说明
genRollSQL OFF ON / OFF / 自定义表名 控制是否生成回滚 SQL
maxRollRowNum 10000 正整数 单表待修复行数超过该阈值时不生成回滚 SQL
rollFileDir rollsql 目录路径 回滚 SQL 文件存储目录

三种 genRollSQL 模式的区别:

模式 行为
OFF 不生成回滚 SQL(默认行为)
ON 对所有校验的表生成回滚 SQL
自定义表名 仅对指定的表生成回滚 SQL,支持逗号分隔多个表名,支持 % 通配符

使用方式非常简单,在配置文件 gc.conf 中添加几行:

genRollSQL=ON
rollFileDir=rollsql
maxRollRowNum=10000

二、功能作用及使用场景深入解读

2.1 为什么需要回滚 SQL?

在生产环境中执行数据修复,面临的风险远比测试环境复杂:

场景一:审计与合规

在金融、医疗等对数据变更审计要求严格的行业,不仅需要知道"改了什么",还需要知道"怎么改回去"。回滚 SQL 是修复操作可审计性的重要组成部分。

场景二:修复逻辑误判

在复杂的类型映射、字符集转换场景下,校验工具判定的"差异"可能只是格式差异而非真实数据差异(例如 DECIMAL 精度差异、utf8mb4_general_ci vs utf8mb4_0900_ai_ci 的 collation 差异)。修复后业务验证不通过,需要回退。

场景三:修复导致业务中断

修复 SQL 中的 DELETEUPDATE 可能与正在运行的业务事务产生锁冲突,或者修复了业务正在使用的数据行,导致业务报错。此时需要快速回退恢复原状。

2.2 回滚逻辑是如何工作的?

gt-checksum 的回滚 SQL 生成采用反向映射策略:对每条修复 SQL,生成一条语义相反的回滚 SQL。

核心映射关系:

修复 SQL 类型 回滚 SQL 类型 说明
DELETE FROM ... WHERE ... INSERT INTO ... VALUES(...) 目标端删除的行,回滚时重新插入
INSERT INTO ... VALUES(...) DELETE FROM ... WHERE ... 目标端插入的行,回滚时删除
TRUNCATE TABLE ... 特殊处理 仅在目标端整表为空时生成(详见 2.3)

DELETE → INSERT 的转换过程:

修复 SQL 中的 DELETE 语句包含 WHERE 条件,其中的列-值对就是被删除行的数据。回滚生成器解析 WHERE 子句,提取所有列名和对应的值,重新组装为 INSERT INTO 语句:

-- 修复 SQL(DELETE)
DELETE FROM `db1`.`orders` WHERE `id` = 1001 AND `order_no` = 'ORD-20260101';

-- 回滚 SQL(INSERT)
INSERT INTO `db1`.`orders`(`id`,`order_no`) VALUES(1001,'ORD-20260101');

对于有 LIMIT 子句的 DELETE(无主键表场景),回滚生成器会先剥离 LIMIT,再提取 WHERE 条件中的列值对。

INSERT → DELETE 的转换过程:

修复 SQL 中的 INSERT 语句包含列名和值的完整映射。回滚生成器解析列名和值列表,仅使用主键列(或唯一键列)构建 DELETEWHERE 条件:

-- 修复 SQL(INSERT)
INSERT INTO `db1`.`orders`(`id`,`order_no`,`amount`) VALUES(1001,'ORD-20260101',99.50);

-- 回滚 SQL(DELETE,仅使用 PK 列 id)
DELETE FROM `db1`.`orders` WHERE `id` = 1001;

NULL 值的特殊处理:

在 WHERE 条件中,NULL 值不能用 = NULL 表达,回滚生成器会自动转换为 IS NULL

-- 修复 SQL
DELETE FROM `db1`.`users` WHERE `id` = 500 AND `email` IS NULL;

-- 回滚 SQL
INSERT INTO `db1`.`users`(`id`,`email`) VALUES(500,NULL);

2.3 TRUNCATE 回滚:整表为空时的特殊处理

当目标端表在校验开始前整表为空(行数为 0)时,修复 SQL 会是大量 INSERT 语句。如果逐行生成回滚 DELETE,文件会非常大。此时 gt-checksum 采用一种更高效的策略:生成单条 TRUNCATE TABLE 回滚语句,忽略 maxRollRowNum 参数限
制。

关键安全约束:只有校验开始前已确认目标端整表为空(精确 COUNT(*) 为 0)时,才会生成 TRUNCATE 回滚。程序不会因为某个 chunk 的目标端为空就推断整张表为空——否则目标端非空但恰好某个 chunk 无数据时,会误生成整表 TRUNCATE
回滚,这将导致回滚时丢失目标端原有的有效数据。

同时,当 TRUNCATE 回滚已生成后,后续的逐行 INSERT 修复对应的回滚 DELETE 会被抑制,避免回滚时先 TRUNCATE 再逐行 DELETE 的重复操作。

⚠️ 重要提醒:TRUNCATE 属于 DDL 操作,执行时会隐式提交当前事务。使用 TRUNCATE 回滚 SQL 前需人工评估其影响。

2.4 回滚 SQL 文件的生成与管理

文件存储结构

回滚 SQL 文件统一存储在 rollFileDir 目录(默认 rollsql)下,文件命名规则为:

rollsql/table.{schema}.{table}.rollback-{TYPE}-{seq}.sql

其中 {TYPE}INSERTDELETETRUNCATE{seq} 为文件序号。例如:

rollsql/table.db1.orders.rollback-INSERT-1.sql
rollsql/table.db1.orders.rollback-DELETE-1.sql
rollsql/table.db1.users.rollback-TRUNCATE-1.sql

文件内容格式

每个回滚 SQL 文件包含完整的事务边界和会话设置:

SET FOREIGN_KEY_CHECKS=0;
SET UNIQUE_CHECKS=0;
BEGIN;
DELETE FROM `db1`.`orders` WHERE `id` = 1001;
DELETE FROM `db1`.`orders` WHERE `id` = 1002;
COMMIT;
BEGIN;
DELETE FROM `db1`.`orders` WHERE `id` = 1003;
COMMIT;

自动滚动切分

当单个回滚 SQL 文件的语句数量或文件大小超过阈值(由 fixTrxNumfixTrxSize 参数控制)时,会自动创建新的文件。这确保了单个文件不会过大,便于人工审计和分批执行。

与 datafix=table 的配合关系

datafix=table(在线修复模式)时,修复 SQL 会直接在目标端执行。但回滚 SQL 始终只写文件,不在线执行——这是刻意的安全设计。回滚 SQL 写入 rollFileDir 目录后,需要人工审计确认无误,再通过 repairDB ./rollsql 执行回滚。

2.5 无主键表的 DELETE 合并优化

对于没有主键和唯一键的表,修复 SQL 中可能出现多条 DELETE ... WHERE ... LIMIT 1 语句,其 WHERE 条件完全相同(因为同一组值可能在目标端出现多次)。gt-checksum 的回滚写入器内置了 mergeDuplicateDeleteLimits 优化:

-- 优化前:3 条相同 WHERE 的 DELETE
DELETE FROM `db1`.`log_data` WHERE `ts` = '2026-01-01' AND `msg` = 'test' LIMIT 1;
DELETE FROM `db1`.`log_data` WHERE `ts` = '2026-01-01' AND `msg` = 'test' LIMIT 1;
DELETE FROM `db1`.`log_data` WHERE `ts` = '2026-01-01' AND `msg` = 'test' LIMIT 1;

-- 优化后:合并为 1 条,LIMIT 累加
DELETE FROM `db1`.`log_data` WHERE `ts` = '2026-01-01' AND `msg` = 'test' LIMIT 3;

这个优化仅在表无主键/唯一键时生效,因为有主键表的每条 DELETE 的 WHERE 条件天然不同。

2.6 与断点续传的配合

resume=ON 且任务中断后续传时,回滚 SQL 的处理同样遵循安全原则:

  • 续传开始时,已有的回滚 SQL 文件会经过完整性截断:定位到最后一个完整的 COMMIT 边界,截断后续不完整的内容
  • 如果续传时某个表需要重新校验,对应的旧回滚 SQL 文件会被清理后重新生成
  • 回滚文件的序号会从上次中断的位置继续,不会覆盖已完整写入的文件

2.7 回滚 SQL 的执行方式

生成回滚 SQL 后,需要人工审计确认无误,然后通过 repairDB 工具执行:

# 审计回滚 SQL 文件
ls -la rollsql/

# 使用 repairDB 执行回滚
repairDB ./rollsql

repairDB 会自动识别目录中的 SQL 文件并按顺序执行,支持断点续传——如果回滚执行过程中断,再次运行会跳过已成功的文件。


三、功能使用演示

3.1 基本配置

在配置文件 gc.conf 中设置相关参数:

# 开启回滚 SQL 生成
genRollSQL=ON
rollFileDir=rollsql
maxRollRowNum=10000

# 其他必要参数
checkObject=data
datafix=file
tables=db1.*
srcDSN=user:ENC[...]@tcp(10.0.0.1:3306)/db1
dstDSN=user:ENC[...]@tcp(10.0.0.2:3306)/db1
chunkSize=10000

3.2 运行效果

$ gt-checksum -c gc.conf

Initializing gt-checksum
Reading configuration files
...
[CHECK] db1.orders: checksum mismatch in chunk 0-10000
[FIX]   db1.orders: DELETE 3 rows, INSERT 5 rows
[ROLL]  db1.orders: Writing rollback SQL (DELETE=5, INSERT=3)
[CHECK] db1.users: checksum mismatch in chunk 0-10000
[FIX]   db1.users: DELETE 1 row, INSERT 0 rows
[ROLL]  db1.users: Writing rollback SQL (DELETE=0, INSERT=1)
...

校验完成后,查看回滚 SQL 目录:

$ ls -la rollsql/
total 24
drwxr-xr-x 2 user user 4096 Jun 15 10:30 .
drwxr-xr-x 6 user user 4096 Jun 15 10:30 ..
-rw-r--r-- 1 user user 1256 Jun 15 10:30 table.db1.orders.rollback-DELETE-1.sql
-rw-r--r-- 1 user user  856 Jun 15 10:30 table.db1.orders.rollback-INSERT-1.sql
-rw-r--r-- 1 user user  312 Jun 15 10:30 table.db1.users.rollback-INSERT-1.sql

查看回滚 SQL 内容:

$ cat rollsql/table.db1.orders.rollback-INSERT-1.sql
SET FOREIGN_KEY_CHECKS=0;
SET UNIQUE_CHECKS=0;
BEGIN;
INSERT INTO `db1`.`orders`(`id`,`order_no`,`amount`) VALUES(1001,'ORD-20260101',99.50);
INSERT INTO `db1`.`orders`(`id`,`order_no`,`amount`) VALUES(1002,'ORD-20260102',150.00);
COMMIT;

3.3 仅对指定表生成回滚 SQL

如果只需要对特定表生成回滚 SQL,可以使用自定义表名模式:

genRollSQL="db1.orders, db1.user%"

这将仅为 db1.ordersdb1.user 开头的表生成回滚 SQL,其他表不生成。支持 % 通配符(匹配任意字符序列)。

3.4 执行回滚

确认需要回退时,使用 repairDB 执行回滚 SQL:

$ repairDB ./rollsql

[REPAIR] Processing: table.db1.orders.rollback-INSERT-1.sql ... OK
[REPAIR] Processing: table.db1.orders.rollback-DELETE-1.sql ... OK
[REPAIR] Processing: table.db1.users.rollback-INSERT-1.sql ... OK
Rollback completed: 3 files executed successfully

3.5 目标端整表为空场景的 TRUNCATE 回滚

当目标端表在校验开始前为空时(例如从零开始的数据迁移验收),回滚 SQL 会生成单条 TRUNCATE TABLE

$ cat rollsql/table.db1.orders.rollback-TRUNCATE-1.sql
SET FOREIGN_KEY_CHECKS=0;
SET UNIQUE_CHECKS=0;
BEGIN;
TRUNCATE TABLE `db1`.`orders`;
COMMIT;

此时不会为该表生成逐行 DELETE 的回滚文件,因为 TRUNCATE 已经足以清空整张表。


四、最佳实践及使用约束

4.1 最佳实践

1. 生产环境建议开启回滚 SQL

对于数据修复任务,无论使用 datafix=file(导出修复 SQL 文件)还是 datafix=table(在线修复),都建议开启 genRollSQL=ON。回滚 SQL 的生成开销很小,但在紧急回退场景下价值巨大:

genRollSQL=ON
rollFileDir=rollsql

2. 大表场景适当调整 maxRollRowNum

maxRollRowNum 用于控制单表待修复行数的回滚阈值。默认值 10000 适用于大多数场景。如果表很大但仍然需要回滚保障,可以调高该值:

# 允许单表最多 50000 行差异时也生成回滚 SQL
maxRollRowNum=50000

注意:maxRollRowNum 对 TRUNCATE 回滚不生效——目标端整表为空时始终生成 TRUNCATE 回滚。

3. 仅对关键表生成回滚 SQL

如果不需要对所有表生成回滚 SQL(例如只关心核心业务表),使用自定义表名模式减少文件量:

genRollSQL="db.orders, db.user%, db.account%"

4. 回滚 SQL 执行前务必人工审计

回滚 SQL 始终只写文件、不在线执行。执行前请:

# 1. 查看生成了哪些回滚文件
ls -la rollsql/

# 2. 检查关键表的回滚内容
cat rollsql/table.db.orders.rollback-*.sql

# 3. 确认无误后使用 repairDB 执行
repairDB ./rollsql

5. 回滚后重新校验

执行回滚后,建议重新运行一次校验,确认数据已恢复到修复前的状态:

# 先清空旧的回滚目录(因为这次不需要回滚了)
rm -rf rollsql/
# 重新校验
gt-checksum -c gc.conf

6. 结合 resume 使用时注意回滚文件累积

断点续传模式下,续传时旧的回滚文件会被安全截断或清理后重新生成。但如果多次中断-续传,可能会产生较多的回滚文件。建议在任务正常完成后整理回滚目录,保留最终版本即可。

4.2 使用约束

1. 仅适用于数据校验模式

回滚 SQL 生成仅在 checkObject=data 模式下生效。struct(结构校验)、trigger(触发器校验)、routine(存储过程/函数校验)不支持回滚 SQL 生成。

2. 必须配合 datafix=file 或 datafix=table

只有当 datafix 设置为 filetable 时,回滚 SQL 才会被生成。datafix=none(仅校验不修复)模式下不会生成回滚 SQL,因为没有修复操作也就不需要回退。

3. rollFileDir 目录非空时的行为

  • resume=OFF 模式:如果 rollFileDir 目录已存在且非空,程序会报错退出,避免覆盖旧的回滚文件
  • resume=ON/ASK 模式:允许目录非空,续传逻辑会处理已有文件(截断或清理)

4. 无主键表的回滚 INSERT 精度限制

对于没有主键和唯一键的表,回滚 INSERT 仅能基于修复 DELETE 的 WHERE 条件中可用的列值对,可能无法完全还原原始行的所有列值(如果 DELETE 语句的 WHERE 条件不包含所有列)。

5. TRUNCATE 回滚的 DDL 隐式提交风险

TRUNCATE TABLE 是 DDL 操作,执行时会隐式提交当前事务并释放表锁。在使用 TRUNCATE 回滚 SQL 时,需确认该行为不会对业务产生意外影响。建议在业务低峰期执行回滚操作。

6. 配置一致性

回滚 SQL 的目标端表名基于校验时的表映射规则。如果校验和回滚之间修改了表映射配置(如 srcdb.*:dstdb.*),可能导致回滚 SQL 中的表名与实际表名不匹配。


五、总结

gt-checksum v4.0.0 的反向回滚 SQL 生成能力,从根本上解决了数据修复"单向执行、无法回退"的痛点。通过 genRollSQL 一键开启,每条修复 SQL 都会自动生成对应的反向操作,写入结构化的回滚文件中。

针对不同场景,回滚机制做了精细化设计:

  • 有主键表:DELETE → INSERT(全列还原),INSERT → DELETE(PK 定位删除)
  • 无主键表:自动合并重复 DELETE LIMIT,回滚 INSERT 基于 WHERE 条件还原
  • 整表为空:生成 TRUNCATE TABLE 回滚,高效且不遗漏

回滚 SQL 始终只写文件、不在线执行,配合 repairDB ./rollsql 即可快速回退。整个过程可审计、可控制,满足生产环境的安全合规要求。

一句话总结genRollSQL=ON,让每一次修复都有后悔药。


相关阅读