
TDengine SQL 模糊测试工具 tdsqlsmith 使用与原理详解SQL 生成、崩溃保护与报告重放【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine导读tdsqlsmith是 TDengine 仓库中面向 SQL 稳定性的模糊测试fuzz testing工具位于 test/go-sql-fuzz-test/tdsqlsmith用于面向 TDengine 自动生成海量 SQL 语句并执行以发现解析器、执行器在极端输入下的崩溃与错误。本文将以官方 README 为主线结合其入口、配置解析、查询生成、监督进程与报告重放等源码实现完整讲解run / serve / replay三类入口的用法、关键参数语义、底层工作原理与常见运维方式。读完本文你将掌握如何构建并运行一次 SQL 稳定性测试、如何解读run_report.json中的崩溃事件以及如何通过 Web 服务与重放命令复现和验证崩溃。1. 项目概览三类入口tdsqlsmith提供三个子命令入口详见 cmd/tdsqlsmith/main.go 的参数分发逻辑run执行测试任务并产出run_report.json。它由 supervisor 与 worker 两级进程组成worker 被作为子进程反复拉起崩溃后自动重启并从崩溃点恢复。serve启动 API Console 服务通过 HTTP JSON API 暴露历史运行报告并托管内嵌的 Vue3 前端控制台。replay从运行报告中提取崩溃 SQL重放执行以复现事件。当前版本已将语料和规则内置到程序中internal/corpusdata与internal/queryrules等包运行时不再依赖外部sqlparse仓库目录。工具模块划分为 Go 后端与 Vue3 前端两大部分语料以go:embed编译进二进制前端构建产物同样通过go:embed内嵌见 internal/serve/serve.go。2. 项目目录与作用目录/文件作用cmd/tdsqlsmith/命令行入口解析参数并分发到run/replay/serve。internal/run/核心运行流程任务执行、覆盖统计、报告写入、崩溃处理。internal/serve/Web 服务层提供 API 与前端静态资源服务。internal/queryrules/查询规则目录解析与规则命中跟踪。internal/branchmodel/分支用例类型定义与覆盖模型。internal/corpusdata/内置语料与语法文件通过go:embed编译进程序。internal/report/运行报告数据结构与读写。internal/crashguard/崩溃保护、快照与故障上下文记录。web/console/前端控制台源码Vue3 TypeScript。internal/serve/webdist/前端构建产物目录供后端嵌入默认不提交生成文件。run_parent_child_test.sh长时运行脚本统一参数并产出会话日志/报告。run_web_service.shWeb 服务启停与状态管理脚本。Makefile统一的初始化、构建、打包命令入口。bin/本地编译产物和打包文件输出目录。out/运行时报告与日志输出目录。除 README 列出的目录外仓库中还包含internal/catalog共享 catalog 引导与建表、internal/config命令行参数解析与校验、internal/executorSQL 执行器与结果分类、internal/querygen随机 SQL 生成器、internal/replay重放实现、internal/taosdwatchtaosd 进程监视与恢复、internal/parsergateSQL 解析门禁、internal/random可序列化随机数与internal/logger、internal/impedance等支撑包共同构成完整的生成-解析-执行-报告链路。3. 快速开始3.1 初始化依赖make init对应 Makefile 中的实现该命令执行两部分工作go mod download拉取 Go 模块依赖cd web/console npm ci --includedev按package-lock.json精确安装前端依赖包含 dev 依赖供 Vite 构建使用。3.2 构建make build构建结果对应 Makefile后端二进制bin/tdsqlsmithgo build -o bin/tdsqlsmith ./cmd/tdsqlsmith前端静态资源internal/serve/webdist/npm exec vite -- build --outDir ../../internal/serve/webdist该目录将被go:embed编译进后端。注意构建顺序先构建前端产物、再编译 Go 二进制否则内嵌的前端资源会是旧版本。3.3 打包分发make package输出对应 Makefilebin/tdsqlsmith-timestamp.tar.gz时间戳格式为YYYYMMDD_HHMMSS包内包含tdsqlsmith二进制、run_parent_child_test.sh、run_web_service.sh并对三个文件赋予可执行权限后压缩。4. 命令行用法tdsqlsmith run [flags] tdsqlsmith serve [flags] tdsqlsmith replay [flags]可执行./bin/tdsqlsmith --help工具还兼容 go-sqlsmith 的经典无子命令模式第一参数以--开头时自动进入 legacy 模式见 internal/config/config.go例如tdsqlsmith --target... --max-queries1000 --verbose4.1 run 子命令参数run是核心子命令完整参数定义在 internal/config/config.go含义与默认值如下参数默认值说明--dsnroot:taosdatatcp(127.0.0.1:6030)/TDengine 连接串--target是其 sqlsmith 兼容别名。--seed当前时间纳秒随机数种子用于可复现的生成序列。--rng-state空反序列化 RNG 状态覆盖 seed 位置用于确定性恢复。--cases2000生成的查询条数--max-queries为其 sqlsmith 兼容别名0 表示仅按时长限制。--duration0运行时长如10m0 表示仅按条数限制。--stmt-timeout2s单条 SQL 执行超时。--out-dirout运行产物输出目录。--cleanup-success-run-dirtrue干净退出时清理临时子进程日志报告始终保留。--mutation-level1SQL 变异强度取值范围 [0,3]。--stop-when-coveredtrue所有必需查询规则都被覆盖后提前停止。--dry-runfalse仅做解析门禁parse-gate跳过 TDengine 执行。--verbosefalse向 stderr 输出详细进度。--dump-all-queriesfalse打印/记录每一条生成的查询。--dump-all-graphsfalse将每条语句的 AST 导出为 graphml 图。--exclude-catalogfalse保留的兼容性选项。--config空workload TOML 配置路径go-sqlsmith 风格见下。--exec-profilestrict执行档位strict\|balanced\|aggressive。参数校验要点从源码可见--cases必须 ≥ 0--cases与--duration同时为 0 时回退到 2000 条--stmt-timeout必须 0--mutation-level必须在 [0,3]--exec-profile必须是三者之一。--config指向的 workload 配置文件用于控制各类语句的生成权重仓库提供了 cmd/config.example.toml 示例其中dml-select权重最高240ddl-alter-table、ddl-create-index、dml-delete、dml-update、dml-insert均为 10~30txn-*权重为 0TDengine 不适用事务供按需调整生成分布。4.2 serve 子命令参数参数默认值说明--listen:8080监听地址。--api-tokentdsqlsmith-dev-token或环境变量TDSQLSMITH_API_TOKENAPI 鉴权 bearer token。--data-dirdata服务状态数据目录。--out-dirout运行报告输出目录。--allow-origin*CORSAccess-Control-Allow-Origin取值。4.3 replay 子命令参数参数默认值说明--dsnroot:taosdatatcp(127.0.0.1:6030)/目标数据库连接串。--file必填run_report.json路径。--count1崩溃语句的执行次数。--stmt-timeout2s单条语句执行超时。5. SQL 生成原理从 AST 到覆盖标签了解生成器实现能帮助你判断run的参数与报告的含义。核心生成器位于 internal/querygen/generator.go它基于 sqlparser 构建随机 AST 再渲染为 SQL 文本而不是直接拼接字符串。生成约束默认MaxDepth3查询表达式与表引用的最大嵌套深度、MaxSelectItems4select 列表最大项数、MaxExprDepth3标量表达式最大嵌套深度见DefaultConfig()。内置 schema默认绑定三张结构相同的表t1/t2/t3每张表 21 个列覆盖 timestamp、int/bigint/smallint/tinyint含 unsigned、float、double、bool、binary、varchar、nchar、varbinary、geometry、decimal 等 TDengine 常见类型见defaultSchema()。生成策略约 18% 概率生成 INSERT其余生成查询表达式查询可随机附加ORDER BY、SLIMIT、LIMIT子句深度允许时还会生成UNION [ALL]与子查询见Next()与queryExpressionAST。解析门禁每次生成尝试都会把 SQL 交给parsergate.Parse校验最多重试 16 次返回第一条能干净解析的语句见 generator.go。覆盖标签每条语句在生成过程中记录命中的语法标签如query_expression、union_query_expression、subquery经过去重排序后作为Tags返回供 query-rule 覆盖率统计使用。运行循环internal/run/run.go在每次迭代中按rule_seed针对缺失规则定向生成与query_random随机生成两种策略生成语句依次记录待执行语句快照、解析、按--exec-profile判断是否执行、执行并分类结果OK / DBError / Timeout / ConnLost / Fatal同时滚动保留最近 64 条已执行语句、每 20 条查询记录一次覆盖进度点、周期性刷写最小运行报告。6. run_parent_child_test.sh一键长时测试该脚本用于快速启动一次带统一参数的run任务并把输出集中到单独目录。6.1 用法./run_parent_child_test.sh duration示例./run_parent_child_test.sh 30s ./run_parent_child_test.sh 10m ./run_parent_child_test.sh 2h脚本只接受一个位置参数时长并会拒绝额外的参数见 run_parent_child_test.sh。6.2 环境变量变量默认值说明TDSQLSMITH_BIN${ROOT_DIR}/tdsqlsmith二进制路径或命令名DSNroot:taosdatatcp(127.0.0.1:6030)/连接串STMT_TIMEOUT2s单条 SQL 超时MUTATION_LEVEL1SQL 变异强度EXEC_PROFILEbalanced执行策略strict/balanced/aggressiveCHILD_CASES1000000000生成条数上限6.3 固定附加参数脚本会固定传入源码中硬编码见 run_parent_child_test.sh--cleanup-success-run-dirtrue--stop-when-coveredfalse不因覆盖目标提前结束适合长时间稳定运行--verbose同时通过环境变量TDSQLSMITH_RUN_ID与TDSQLSMITH_RUN_DIR将 run ID 与输出目录固定为本次会话目录保证日志与报告一一对应。6.4 产物路径out/pc_YYYYMMDD_HHMMSS/parent_child.log会话日志同步落盘可用tail -f跟进out/pc_YYYYMMDD_HHMMSS/run_report.json运行报告脚本还负责校验二进制可执行性找不到时回退到 PATH 查找并以脚本所在目录作为ROOT_DIR因此可以从任意目录调用。7. run_web_service.shWeb 服务启停管理用于启动和管理tdsqlsmith serve。7.1 用法./run_web_service.sh [start|stop|status|restart] [--daemon]7.2 常用示例# 前台启动 ./run_web_service.sh # 后台启动 ./run_web_service.sh start --daemon # 查看状态 ./run_web_service.sh status # 停止 ./run_web_service.sh stop7.3 主要环境变量变量默认值说明TDSQLSMITH_BINtdsqlsmith二进制路径或命令名LISTEN0.0.0.0:18080监听地址API_TOKENtdsqlsmith-dev-tokenAPI tokenDATA_DIR$(pwd)/data服务状态目录OUT_DIR$(pwd)/out报告目录ALLOW_ORIGIN*CORS 来源LOG_FILE$(pwd)/tdsqlsmith-web.log后台日志文件PID_FILE$(pwd)/tdsqlsmith-web.pid后台 PID 文件PUBLIC_HOST空可选外部健康检查提示用公网 IP如43.130.228.76脚本的进程管理细节见 run_web_service.sh值得注意健康检查通过curl请求http://host:port/api/v1/health并匹配status:ok判断服务就绪0.0.0.0/::等监听地址会被归一化为127.0.0.1做本地检查。PID 多重发现依次从 PID 文件、监听端口ss或lsof、进程命令行ps中同时匹配二进制名、serve与--listen三种途径发现运行中进程支持 PID 文件丢失/过期后的恢复。后台启动使用nohup ... 启动写 PID 文件并轮询健康接口30 次 × 0.1s确认启动成功。前台模式直接exec替换当前 shell 进程便于在终端直接观察日志。8. serve 的 API 与前端serve通过 internal/serve/serve.go 注册如下路由见registerRoutes路由作用/api/v1/health健康检查返回{status:ok}。/api/v1/auth/verifytoken 校验。/api/v1/reports报告列表。/api/v1/reports/{id}按 run ID 获取单份报告详情。/内嵌的前端静态资源Vue3 控制台登录、报告列表与详情页。服务默认--listen :8080脚本包装时改为0.0.0.0:18080API 需要携带--api-token指定的 bearer token日志中 token 会被脱敏保留前 3 位与后 2 位见maskToken。服务优雅停机收到 SIGINT/SIGTERM 后最多等待 8 秒完成现有请求再关闭serve.go。前端源码位于 web/console包含登录页、报告列表页ReportsView.vue与报告详情页ReportDetailView.vue构建产物输出到internal/serve/webdist/后由go:embed内嵌。9. replay复现崩溃 SQLreplay从指定的run_report.json中挑选最近一次含非空崩溃 SQL 的事件优先 taosd 事件其次 tdsqlsmith 事件先执行报告记录的 setup SQL 复现环境再按--count次重放该崩溃语句并返回每次执行的分类、耗时与错误信息实现见 internal/replay/replay.go。tdsqlsmith replay --file out/pc_YYYYMMDD_HHMMSS/run_report.json --count 5典型用途run阶段发现崩溃后用replay在修复前后的 taosd 上反复重放同一 SQL验证问题是否复现/是否已修复。10. 崩溃保护supervisor、crashguard 与 taosdwatch这是run命令稳定长跑的关键机制也是 README 所述“崩溃处理”的底层实现父子进程结构run启动时父进程作为 supervisor 引导共享 catalog 后反复以子进程方式拉起 fuzz worker通过环境变量TDSQLSMITH_RUN_WORKER1标记 worker 身份。worker 因信号异常退出后supervisor 分析退出信号并写入崩溃报告随后按退避间隔默认 500ms重启 worker见 cmd/tdsqlsmith/main.go。崩溃识别classifyWorkerExit区分退出码、信号名与是否产生 core dumpisCrashSignalName识别 SIGSEGVsegmentation fault、SIGABRTaborted、SIGBUSbus error、SIGILL、SIGFPE 等真实崩溃信号。崩溃点恢复crashguard 在每条语句执行前后持久化“待执行语句 序列化 RNG 状态 查询号”快照。worker 崩溃后supervisor 从快照提取query_no与rng_state通过环境变量注入重启的 worker使其从崩溃语句的下一句继续执行保证长时运行的连续性。运行目录产物运行目录下的crash_guard/保存pending.json、window.json、status.json、report.latest.json崩溃时 supervisor 额外写出coredump_report.json与人类可读的crash_summary.md含 pending SQL、前序窗口与错误信息。干净退出且无崩溃时这些临时文件会被自动清理。taosd 崩溃分流internal/taosdwatch负责判断错误是否由 taosd 崩溃引起。连接丢失且检测到 taosd 进程退出/core dump 时事件会被记录到报告的taosd_incidents只有 worker 侧段错误等且无 taosd 证据的事件才记入tdsqlsmith_incidents。检测到 taosd 崩溃后还会尝试重启并自动重连recoverConnection。软/硬截止时间--duration是软截止supervisor 会在软截止之上再追加 15 秒宽限期supervisorWorkerDeadlineGrace作为硬截止强制杀死卡住的 worker。run_report.json的MinimalRunReport结构见 internal/report/report.go聚合了 run ID、开始/生成时间、执行时长、setup SQL、已执行总数、query-rule 覆盖与进度、查询组合计数、taosd 事件与 tdsqlsmith 事件列表是后续分析与 replay 的唯一数据源。11. 测试命令# 默认全量测试 go test ./... # 含 integration tag 的测试 go test -tagsintegration ./...后者会启用依赖真实环境的集成用例例如taosd_crash_report_integration_test.go、taosd_crash_signal_integration_test.go位于 internal/run用于验证崩溃检测与报告写入链路。12. 使用注意事项internal/serve/webdist下的前端编译产物不建议入库仓库仅保留占位文件用于go:embed编译。修改前端源码后需重新make build。若run无法连接数据库请先确认taosd处于可用状态并且 DSN 正确默认连接127.0.0.1:6030账号root密码taosdata。长时间运行建议通过run_parent_child_test.sh统一入口执行它已内置 supervisor 需要的 run ID/目录注入与日志落盘stop-when-coveredfalse保证覆盖目标不会提前中断稳定性测试。serve默认 token 为开发用途的tdsqlsmith-dev-token部署到可被外部访问的地址时应通过--api-token或TDSQLSMITH_API_TOKEN显式更换。由于 crashguard 依赖 pending SQL 与 RNG 状态快照才能恢复请勿在run运行期间手工清理其运行目录报告始终保留临时快照只在干净退出后自动清理。【免费下载链接】TDengineHigh-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考