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

推荐订阅源

V
Visual Studio Blog
MongoDB | Blog
MongoDB | Blog
Engineering at Meta
Engineering at Meta
云风的 BLOG
云风的 BLOG
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
T
The Exploit Database - CXSecurity.com
P
Privacy & Cybersecurity Law Blog
Know Your Adversary
Know Your Adversary
月光博客
月光博客
I
InfoQ
阮一峰的网络日志
阮一峰的网络日志
NISL@THU
NISL@THU
爱范儿
爱范儿
S
Securelist
博客园 - 叶小钗
C
CERT Recently Published Vulnerability Notes
Recorded Future
Recorded Future
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
aimingoo的专栏
aimingoo的专栏
D
DataBreaches.Net
G
GRAHAM CLULEY
P
Proofpoint News Feed
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
C
Cyber Attacks, Cyber Crime and Cyber Security
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Tor Project blog
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
Hugging Face - Blog
Hugging Face - Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Recent Announcements
Recent Announcements
P
Proofpoint News Feed
The GitHub Blog
The GitHub Blog
The Cloudflare Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
Jina AI
Jina AI
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
博客园 - 【当耐特】
H
Help Net Security
F
Fortinet All Blogs
T
The Blog of Author Tim Ferriss

博客园_首页

Linux实操--组管理、权限管理和定时任务 Java + EasyExcel 实现单个接口导出多个Excel Mem0 源码解析系列(二):提示词工程的深度剖析 Openclaw TaskFlow究竟是什么?和普通Skill技能有什么区别 博文阅读密码验证 - 博客园 嘉立创开源:应该是全网MicroPython教程最多的开发板 Hermes Agent 集成实践:从协议到生产 2026年AI编程工具横评:Cursor、Codex、Claude Code、Zed、Windsurf Java程序员必看的RAG入门教程 2026 AI效率神器:Superpowers + Claude Code 保姆级教程 本地大模型部署全攻略:从 0 到 1 玩转 Ollama 【从0到1构建一个ClaudeAgent】内存管理-上下文压缩 .NET 高级开发 | 设计、实现一个事件总线框架 电子小白入门之NE555 3. WorkBuddy:隐藏玩法,一键召唤专家,让 AI 以"专家身份"给你干活 和AI一起搞事情#3:Claude Teammate 游戏开发翻车实录 【OpenClaw】通过 Nanobot 源码学习架构---(7)Memory C# .NET 周刊|2026年3月3期 我在 Debian 11 上把 K8s 单机搭起来了,过程没你想的那么顺(/opt 目录版) 深度学习进阶(七)Data-efficient Image Transformer CLI+Skill搭建浏览器AI自动化框架,告别一切重复枯燥任务 告别Token账单无底洞:OpenClaw本地部署,重塑企业数据主权的唯一解 FastAPI+Vue:文件分片上传+秒传+断点续传,这坑我帮你踩平了! SBTI 爆火后,我做了个程序员版的 CBTI。。已开源 + 附开发过程 多模态检索开始进入工程期:用 Sentence Transformers 搭建可落地的 Multimodal RAG 100多行代码实现一个最简单的Agent(用ReAct) Claude Code 通关手册(八):推荐 5 个 Hooks,代码质量提升 3 倍 老板:“有人截图了!”。安全部门:“收到,马上查暗水印!” - why技术 技术之外,皆是人间 C#/.NET/.NET Core技术前沿周刊 | 第 69 期(2026年4.01-4.12) Snack JSONPath 项目架构分析 Claude Code Buddy 小析:一个非核心功能,如何体现产品的细节完成度 AI新时代下的图床管理方案-Cloudflare图床+MCP+Skills方案指南 化繁为简:顺丰速运App如何通过 HarmonyOS SDK实现专业级空间测量 从零实现富文本编辑器#13-React非编辑节点的内容渲染 AI开发-python-langchain框架(3-23-OpenAI Functions风格Tool Calling智能助手) .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 PbootCMS 网站内容数量多导致访问慢?这些实用优化方案帮你提速! - 家兴网络技术工作室 上下文工程是什么?过时了么?一文讲明白! - 一枫说码 网站漏洞怎么发现并修复?一篇实用指南(附完整流程) - 家兴网络技术工作室 开了 TUN 模式还是直连?90% 的人都踩过这个坑 Github日报|2026年04月12日 - AI一族 AScript扩展多种脚本语言 - rockey627 AI 学习笔记:Agent 的记忆机制 你能被装进一个文件里吗?——7 万人把同事"蒸馏"成了 AI - 我没有三颗心脏 Claude Code 通关手册(七):给 AI 装上技能包——Skills 完全指南 - 暮色之狐 在浏览器中快速编辑代码:VSCode Web 集成实践 - Newbe36524 蒸馏自己 skill?基于 Deepseek 的蒸馏器,丐版蒸馏方式,简单便捷 - To_Carpe_Diem Spring AI Aliababa和AgentScope,哪个更好? - 苏三说技术 Etsy 把 1000 个 MySQL 分片迁进 Vitess:425TB 数据背后的真正问题不是性能,而是运维规模 MicroPython LVGL基础知识和概念:底层渲染与性能优化 - FreakStudio 数据库草图算法 Python 潮流周刊#146:CPython 引入 Rust 的进展 - 豌豆花下猫 最小生成树 - mofei1116 红日靶场七:从外网入口、容器逃逸到 AD 接管的完整利用链复盘 - YouDiscovered1t 分享四款开源且实用的 Kafka 管理工具 - 追逐时光者 vLLM 权重加载机制全解析:从挑战到理想架构 LCT 学习笔记 - ACehomoxue Avalonia UI 12.0.0 正式发布:架构演进和性能飞跃 - 张善友 当 AI Agent 把调用链拉长,延迟开始成为一门生意 conhost.exe 无法显示 U+2717 - 145a 太秀了,我把自己蒸馏成了 Skill!已开源 - 程序员鱼皮 ASP.NET Core 内存缓存实战:一篇搞懂该怎么配、怎么避坑 基于 Ghostty 带有分割标签页和为 Claude 编程设计的通知终端 - BugShare AI 焊死入口:教育的“操作系统级”重塑 - 郝hai 初级Java开发工程师使用sql脚本编写代码的过程是简单而且不糊涂 - CoderOilStation Claude Code通关手册(六):MCP协议完全指南 - 暮色之狐 边框灯光环绕动画特效实现指南 - Newbe36524 开源:子木蒸馏版的 SEO 审计工具 seo-audit-skill v1.0 我所理解的Python元模型 【从0到1构建一个ClaudeAgent】规划与协调-TodoWrite - 程序员Seven Claude 和 Codex 在审计 Skill 上性能差异探究 - ACai_sec AScript如何实现中文脚本引擎 - rockey627 【渗透测试】HTB Season10 Garfield 全过程wp - dynasty_chenzi Android 开发者为什么必须掌握 AI 能力?端侧视角下的技术变革 树状数组正确性证明 - AC-wyr 你的 AI 焦虑,可能比 AI 本身更危险——ATM 机没有消灭银行柜员,但恐慌消灭了你的判断力 - 我没有三颗心脏 一个拉胯的分库分表方案有多绝望?整个部门都在救火! - 冰河团队 动态规划入门必学之走方格问题 - Ofnoname PostgREST 与 PostgreSQL 角色权限配置全解析(生产级实践) - SheepDog1998 使用 UEFI 图形输出协议 GOP 在屏幕上显示图像的方法 - 阿源- Claude Code通关手册(五):组建你的AI专家团队,子代理系统 - 暮色之狐 一个程序员到架构师的催婚路之感悟(整整10年后的催婚相亲感悟) - MisterLip 用 Agent Skill 自动生成工作周报 - 赵康
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,让每一次修复都有后悔药。


相关阅读