TranGuard 是由华东师范大学数据科学与工程学院数据库系统团队与腾讯云数据库团队联合科研打造的一个面向关系型数据库的事务并发测试工具,通过 LLM 驱动的变异模糊测试(Mutation Fuzzing)自动生成并执行多事务并发场景,检测数据库在不同隔离级别下的正确性。
- LLM 驱动变异:利用大语言模型分析事务依赖图,智能生成能触发并发异常的测试用例
- 冲突环路检测:自动构造并验证 Write-Read、Write-Write、Read-Write 等冲突边形成的事务依赖环路
- 差分测试:在参考数据库上重放相同操作,对比结果以发现不一致行为
- 多数据库支持:支持 MySQL、TDSQL、TiDB、OceanBase 等主流数据库
- Java 21+
- Maven 3.8+
mvn clean packagejava -jar target/tranguard-YYMMdd.jar mutation config.yaml ans_out out程序读取项目根目录下的 config.yaml 配置文件。
所有配置项均在 config.yaml 中定义,以下为各配置项的详细说明。
mutation:
# 总共生成的 Case 数量caseNumber: 10# 是否启用环路分析(冲突图验证)useAnalyze: true# 是否启用差分测试useDiff: true# 测试的隔离级别:READ_UNCOMMITTED / READ_COMMITTED / REPEATABLE_READ / SERIALIZABLEisolationLevel: REPEATABLE_READmutation:
# 可选值:# MultiStepLLMFuzzer — 纯 LLM 多步推理变异# LLMDrivenFuzzer — LLM 驱动变异# HybridFuzzer — 混合模式(LLM + 遗传算法,推荐)fuzzer: HybridFuzzerHybridFuzzer 专属配置(仅在 fuzzer: HybridFuzzer 时生效):
mutation:
hybridFuzzer:
# 触发调度 LLM 的连续失败次数阈值,默认 3consecutiveFailThreshold: 3# 距上次调度 LLM 决策的最大变异轮数(兜底),默认 20maxGedRounds: 20# 调度 LLM 失败时是否降级为遗传算法,默认 truefallbackToGed: truemutation:
# 是否开启 DDL 注入(ALTER TABLE 等操作),默认开启enableDDL: true开启后,测试过程中会随机注入 ALTER TABLE MODIFY COLUMN 等 DDL 操作,测试 DDL 与并发 DML 的交互。
mutation:
# RANDOM — 随机混合(默认)# PARTITIONED — 全部使用分区表# NORMAL — 全部使用普通表tableMode: PARTITIONEDmutation:
largeTransaction:
# 是否启用大事务生成enabled: false# 将普通事务升级为大事务的概率(0.0 ~ 1.0)probability: 0.1# 单个事务内最大填充操作数maxPaddingOps: 20# 批量操作单次影响的最大行数maxRowsPerBatchOp: 50# 初始数据量倍数:最终初始数据量 = indexCnt × initialDataMultiplierinitialDataMultiplier: 50# 值域上界:0 表示跟随 initialDataMultiplier 自动计算valueRangeMax: 10000mutation:
# SAVEPOINT 生成概率(0.0 ~ 1.0),0 表示不生成probOfSavepoint: 0.5# ROLLBACK TO SAVEPOINT 的概率(在每个 SAVEPOINT 之后)probOfRollbackToSavepoint: 0.3mutation:
llm:
# LLM 服务提供商:DEEPSEEK(默认)或 KNOTprovider: DEEPSEEKmodel: deepseek-chatapiKey: <your-api-key># 最大调用次数限制invokeCount: 10# HTTP 连接超时(秒)connectTimeoutSeconds: 30# 单次请求超时(秒)requestTimeoutSeconds: 300allowedMap 和 prohibitedMap 定义各隔离级别下允许和禁止的冲突模式,用于指导测试用例验证:
mutation:
allowedMap:
REPEATABLE_READ:
- [ ReadWrite ] # RR 下允许 RW 反依赖prohibitedMap:
REPEATABLE_READ:
- [ ReadWrite, WCR ] # RR 下禁止 RW + WCR 组合(即不允许幻读)依赖边类型说明:
| 类型 | 含义 |
|---|---|
WriteRead / WCR | Write-Read:事务 A 写入,事务 B 读取了 A 写入的版本 |
Write-Write | Write-Write:两个事务写入了同一数据项 |
ReadWrite | Read-Write:事务 A 读取了某版本,事务 B 后来写入了新版本 |
RA / WA | 含 ROLLBACK 的依赖(Read-Abort / Write-Abort) |
datasource:
# 数据库类型标识:mysql / tdsql25 / tidb / postgresql 等platform: mysqlurl: jdbc:mysql://127.0.0.1:3306/tranguard_db?serverTimezone=UTC&useServerPrepStmts=true&cachePrepStmts=trueusername: rootpassword: your_passworddriverClassName: com.mysql.cj.jdbc.Driver差分测试使用的参考数据库,通常为标准 MySQL 实例:
diffDatasource:
platform: mysqlurl: jdbc:mysql://127.0.0.1:3306/tranguard_ref_db?useSSL=false&serverTimezone=UTCusername: rootpassword: your_passworddriverClassName: com.mysql.cj.jdbc.Driverschema:
# 每个 Case 生成的表数量范围(均匀分布)tableNumber:
begin: 3# 最少 3 张表end: 10# 最多 9 张表distribution: UNIFORMtable:
attribute:
# 每张表的普通属性列数量范围attributeNumber:
begin: 1end: 6distribution: UNIFORM# 为每一列添加索引的概率(百分比)indexProbability: 10loader:
# SQL 执行超时时间(秒),建议大于数据库的 innodb_lock_wait_timeoutqueryTimeout: 5# 测试时间限制(0 或负数表示无限制)testTimeLimit: 0# 时间单位:MINUTES 或 HOURStestTimeLimitUnit: MINUTES测试运行时,日志输出到控制台,格式为:
<时间戳> <级别> <类名> <消息>
每个 Case 的执行流程:
- 生成 Case 模板(SQL 操作序列)
- 初始化数据库(建表 + 插入初始数据)
- 执行事务序列
- 一致性验证 + 冲突图验证
- 差分测试(如启用)
- LLM 变异,生成下一个 Case
详细日志结构说明请参见log-structure.md。